fix migration system

This commit is contained in:
Joey Eamigh 2026-03-29 16:59:51 -04:00
parent ca4bc288c9
commit 273a862cdf
No known key found for this signature in database
GPG Key ID: CE8C05DFFC53C9CB
8 changed files with 549 additions and 10 deletions

View File

@ -28,21 +28,22 @@ WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
# Standalone server + static assets
# Standalone server + static assets (includes postgres + drizzle-orm via serverExternalPackages)
COPY --from=builder /app/labelapp/.next/standalone ./
COPY --from=builder /app/labelapp/.next/static ./labelapp/.next/static
COPY --from=builder /app/labelapp/public ./labelapp/public
# Drizzle migration tooling
COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/labelapp/node_modules ./labelapp/node_modules
COPY --from=builder /app/labelapp/drizzle.config.ts ./labelapp/
# Entrypoint scripts need drizzle-orm (migrator) + postgres beyond what standalone traces.
# Standalone copies the full package.json; swap it for a clean one so bun add works.
RUN cd labelapp && mv package.json package.json.bak && echo '{}' > package.json \
&& bun add postgres drizzle-orm \
&& mv package.json.bak package.json
# Drizzle migrations + schema (migrate.ts uses drizzle-orm programmatically — no drizzle-kit needed)
COPY --from=builder /app/labelapp/drizzle/ ./labelapp/drizzle/
COPY --from=builder /app/labelapp/db/ ./labelapp/db/
COPY --from=builder /app/packages/schemas/ ./packages/schemas/
COPY --from=builder /app/package.json ./
# Seed/sample/assign scripts
# Seed/sample/assign scripts + lib utilities
COPY --from=builder /app/labelapp/scripts/ ./labelapp/scripts/
COPY --from=builder /app/labelapp/lib/ ./labelapp/lib/

View File

@ -0,0 +1 @@
ALTER TABLE "human_labels" ADD COLUMN IF NOT EXISTS "active_ms" integer;

View File

@ -0,0 +1,510 @@
{
"id": "392c9bd4-1b68-4e32-86b0-be7abc632b44",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.adjudications": {
"name": "adjudications",
"schema": "",
"columns": {
"paragraph_id": {
"name": "paragraph_id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"final_category": {
"name": "final_category",
"type": "text",
"primaryKey": false,
"notNull": true
},
"final_specificity": {
"name": "final_specificity",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"method": {
"name": "method",
"type": "text",
"primaryKey": false,
"notNull": true
},
"adjudicator_id": {
"name": "adjudicator_id",
"type": "text",
"primaryKey": false,
"notNull": false
},
"notes": {
"name": "notes",
"type": "text",
"primaryKey": false,
"notNull": false
},
"resolved_at": {
"name": "resolved_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"adjudications_paragraph_id_paragraphs_id_fk": {
"name": "adjudications_paragraph_id_paragraphs_id_fk",
"tableFrom": "adjudications",
"tableTo": "paragraphs",
"columnsFrom": [
"paragraph_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.annotators": {
"name": "annotators",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"display_name": {
"name": "display_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"password": {
"name": "password",
"type": "text",
"primaryKey": false,
"notNull": true
},
"onboarded_at": {
"name": "onboarded_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.assignments": {
"name": "assignments",
"schema": "",
"columns": {
"paragraph_id": {
"name": "paragraph_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"annotator_id": {
"name": "annotator_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"assigned_at": {
"name": "assigned_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"is_warmup": {
"name": "is_warmup",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
}
},
"indexes": {},
"foreignKeys": {
"assignments_paragraph_id_paragraphs_id_fk": {
"name": "assignments_paragraph_id_paragraphs_id_fk",
"tableFrom": "assignments",
"tableTo": "paragraphs",
"columnsFrom": [
"paragraph_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"assignments_annotator_id_annotators_id_fk": {
"name": "assignments_annotator_id_annotators_id_fk",
"tableFrom": "assignments",
"tableTo": "annotators",
"columnsFrom": [
"annotator_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"assignments_paragraph_id_annotator_id_unique": {
"name": "assignments_paragraph_id_annotator_id_unique",
"nullsNotDistinct": false,
"columns": [
"paragraph_id",
"annotator_id"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.human_labels": {
"name": "human_labels",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"identity": {
"type": "always",
"name": "human_labels_id_seq",
"schema": "public",
"increment": "1",
"startWith": "1",
"minValue": "1",
"maxValue": "2147483647",
"cache": "1",
"cycle": false
}
},
"paragraph_id": {
"name": "paragraph_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"annotator_id": {
"name": "annotator_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"content_category": {
"name": "content_category",
"type": "text",
"primaryKey": false,
"notNull": true
},
"specificity_level": {
"name": "specificity_level",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"notes": {
"name": "notes",
"type": "text",
"primaryKey": false,
"notNull": false
},
"labeled_at": {
"name": "labeled_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"session_id": {
"name": "session_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"duration_ms": {
"name": "duration_ms",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"active_ms": {
"name": "active_ms",
"type": "integer",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {
"human_labels_paragraph_id_paragraphs_id_fk": {
"name": "human_labels_paragraph_id_paragraphs_id_fk",
"tableFrom": "human_labels",
"tableTo": "paragraphs",
"columnsFrom": [
"paragraph_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"human_labels_annotator_id_annotators_id_fk": {
"name": "human_labels_annotator_id_annotators_id_fk",
"tableFrom": "human_labels",
"tableTo": "annotators",
"columnsFrom": [
"annotator_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"human_labels_paragraph_id_annotator_id_unique": {
"name": "human_labels_paragraph_id_annotator_id_unique",
"nullsNotDistinct": false,
"columns": [
"paragraph_id",
"annotator_id"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.paragraphs": {
"name": "paragraphs",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"text": {
"name": "text",
"type": "text",
"primaryKey": false,
"notNull": true
},
"word_count": {
"name": "word_count",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"paragraph_index": {
"name": "paragraph_index",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"company_name": {
"name": "company_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"cik": {
"name": "cik",
"type": "text",
"primaryKey": false,
"notNull": true
},
"ticker": {
"name": "ticker",
"type": "text",
"primaryKey": false,
"notNull": false
},
"filing_type": {
"name": "filing_type",
"type": "text",
"primaryKey": false,
"notNull": true
},
"filing_date": {
"name": "filing_date",
"type": "text",
"primaryKey": false,
"notNull": true
},
"fiscal_year": {
"name": "fiscal_year",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"accession_number": {
"name": "accession_number",
"type": "text",
"primaryKey": false,
"notNull": true
},
"sec_item": {
"name": "sec_item",
"type": "text",
"primaryKey": false,
"notNull": true
},
"stage1_category": {
"name": "stage1_category",
"type": "text",
"primaryKey": false,
"notNull": false
},
"stage1_specificity": {
"name": "stage1_specificity",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"stage1_method": {
"name": "stage1_method",
"type": "text",
"primaryKey": false,
"notNull": false
},
"stage1_confidence": {
"name": "stage1_confidence",
"type": "real",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.quiz_sessions": {
"name": "quiz_sessions",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"annotator_id": {
"name": "annotator_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"started_at": {
"name": "started_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"completed_at": {
"name": "completed_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"passed": {
"name": "passed",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"score": {
"name": "score",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
},
"total_questions": {
"name": "total_questions",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"answers": {
"name": "answers",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'[]'"
}
},
"indexes": {},
"foreignKeys": {
"quiz_sessions_annotator_id_annotators_id_fk": {
"name": "quiz_sessions_annotator_id_annotators_id_fk",
"tableFrom": "quiz_sessions",
"tableTo": "annotators",
"columnsFrom": [
"annotator_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}

View File

@ -8,6 +8,13 @@
"when": 1774815564792,
"tag": "0000_baseline",
"breakpoints": true
},
{
"idx": 1,
"version": "7",
"when": 1774822800000,
"tag": "0001_add-active-ms",
"breakpoints": true
}
]
}

View File

@ -7,7 +7,7 @@ echo "==> Ensuring migration baseline..."
bun run scripts/ensure-migration-baseline.ts
echo "==> Running Drizzle migrations..."
bunx drizzle-kit migrate
bun run scripts/migrate.ts
echo "==> Checking if database needs seeding..."
ROW_COUNT=$(bun --eval "

View File

@ -4,6 +4,7 @@ import path from "node:path";
const nextConfig: NextConfig = {
output: "standalone",
outputFileTracingRoot: path.join(import.meta.dirname, "../"),
serverExternalPackages: ["postgres", "drizzle-orm", "drizzle-kit"],
};
export default nextConfig;

View File

@ -9,7 +9,7 @@
"typecheck": "tsc --noEmit",
"lint": "eslint",
"db:generate": "drizzle-kit generate",
"db:migrate": "drizzle-kit migrate",
"db:migrate": "bun run scripts/migrate.ts",
"db:push": "drizzle-kit push",
"db:studio": "drizzle-kit studio",
"seed": "bun run scripts/seed.ts",

View File

@ -0,0 +1,19 @@
/**
* Programmatic Drizzle migration runner.
* Uses drizzle-orm/postgres-js/migrator instead of drizzle-kit CLI,
* so drizzle-kit is not needed at runtime.
*/
import { drizzle } from "drizzle-orm/postgres-js";
import { migrate } from "drizzle-orm/postgres-js/migrator";
import postgres from "postgres";
import { resolve } from "path";
const sql = postgres(process.env.DATABASE_URL!, { max: 1 });
const db = drizzle(sql);
await migrate(db, {
migrationsFolder: resolve(import.meta.dirname!, "../drizzle"),
});
console.log("Migrations applied.");
await sql.end();