spb/autoscholar
Public
1import {2 bigint,3 boolean,4 index,5 integer,6 jsonb,7 pgTable,8 text,9 timestamp,10 uniqueIndex,11 uuid,12} from "drizzle-orm/pg-core";13import { researchRuns } from "./runs.js";1415export const researchSources = pgTable(16 "research_sources",17 {18 id: uuid("id").primaryKey().defaultRandom(),19 runId: uuid("run_id")20 .notNull()21 .references(() => researchRuns.id, { onDelete: "cascade" }),22 key: text("key").notNull(),23 kind: text("kind").notNull(),24 identifier: text("identifier").notNull(),25 title: text("title").notNull(),26 authors: jsonb("authors").$type<string[]>().notNull().default([]),27 year: integer("year"),28 venue: text("venue"),29 url: text("url"),30 verified: boolean("verified").notNull().default(false),31 verifiedAt: timestamp("verified_at", { withTimezone: true }),32 verification: jsonb("verification").$type<Record<string, unknown>>().notNull().default({}),33 accessLevel: text("access_level").notNull().default("metadata"),34 },35 (t) => [uniqueIndex("sources_run_key_uq").on(t.runId, t.key)],36);3738export const citations = pgTable(39 "citations",40 {41 id: uuid("id").primaryKey().defaultRandom(),42 runId: uuid("run_id")43 .notNull()44 .references(() => researchRuns.id, { onDelete: "cascade" }),45 claim: text("claim").notNull(),46 location: text("location"),47 kind: text("kind").notNull().default("literature"),48 sourceKeys: text("source_keys").array().notNull().default([]),49 artifactPaths: text("artifact_paths").array().notNull().default([]),50 },51 (t) => [index("citations_run_idx").on(t.runId)],52);5354export const datasets = pgTable(55 "datasets",56 {57 id: uuid("id").primaryKey().defaultRandom(),58 runId: uuid("run_id")59 .notNull()60 .references(() => researchRuns.id, { onDelete: "cascade" }),61 name: text("name").notNull(),62 source: text("source").notNull(),63 url: text("url"),64 license: text("license").notNull(),65 acquiredAt: text("acquired_at").notNull(),66 sha256: text("sha256"),67 bytes: bigint("bytes", { mode: "number" }),68 synthetic: boolean("synthetic").notNull().default(false),69 transformations: text("transformations").array().notNull().default([]),70 notes: text("notes"),71 },72 (t) => [index("datasets_run_idx").on(t.runId)],73);7475export const experimentRecords = pgTable(76 "experiment_records",77 {78 id: uuid("id").primaryKey().defaultRandom(),79 runId: uuid("run_id")80 .notNull()81 .references(() => researchRuns.id, { onDelete: "cascade" }),82 name: text("name").notNull(),83 command: text("command").notNull(),84 startedAt: text("started_at").notNull(),85 endedAt: text("ended_at").notNull(),86 exitCode: integer("exit_code").notNull(),87 seed: text("seed"),88 environment: jsonb("environment").$type<Record<string, string>>(),89 outputs: text("outputs").array().notNull().default([]),90 synthetic: boolean("synthetic").notNull().default(false),91 },92 (t) => [index("experiments_run_idx").on(t.runId)],93);9495export const reviewFindings = pgTable(96 "review_findings",97 {98 id: uuid("id").primaryKey().defaultRandom(),99 runId: uuid("run_id")100 .notNull()101 .references(() => researchRuns.id, { onDelete: "cascade" }),102 round: integer("round").notNull(),103 findingKey: text("finding_key").notNull(),104 severity: text("severity").notNull(),105 category: text("category").notNull(),106 title: text("title").notNull(),107 detail: text("detail").notNull(),108 proposedTest: text("proposed_test"),109 resolution: text("resolution").notNull().default("open"),110 resolutionNote: text("resolution_note"),111 createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),112 },113 (t) => [uniqueIndex("review_findings_uq").on(t.runId, t.round, t.findingKey)],114);115116/** Every artifact of a run; immutable once written (new version = new row). */117export const artifacts = pgTable(118 "artifacts",119 {120 id: uuid("id").primaryKey().defaultRandom(),121 runId: uuid("run_id")122 .notNull()123 .references(() => researchRuns.id, { onDelete: "cascade" }),124 attemptId: uuid("attempt_id"),125 stage: text("stage").notNull(),126 path: text("path").notNull(),127 version: integer("version").notNull().default(1),128 kind: text("kind").notNull(),129 sha256: text("sha256").notNull(),130 bytes: bigint("bytes", { mode: "number" }).notNull(),131 contentType: text("content_type").notNull().default("application/octet-stream"),132 storageKey: text("storage_key").notNull(),133 visibility: text("visibility").notNull().default("private"),134 synthetic: boolean("synthetic").notNull().default(false),135 createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),136 },137 (t) => [138 uniqueIndex("artifacts_run_path_version_uq").on(t.runId, t.path, t.version),139 index("artifacts_run_idx").on(t.runId),140 ],141);142