diff --git a/backend/scripts/apply-tenant-export-lock-migration.ts b/backend/scripts/apply-tenant-export-lock-migration.ts new file mode 100644 index 0000000..2104bb1 --- /dev/null +++ b/backend/scripts/apply-tenant-export-lock-migration.ts @@ -0,0 +1,89 @@ +import "dotenv/config" +import { drizzle } from "drizzle-orm/node-postgres" +import { sql } from "drizzle-orm" +import { Pool } from "pg" + +import { loadSecrets, secrets } from "../src/utils/secrets" + +async function run() { + let connectionString = process.env.DATABASE_URL + + if (!connectionString) { + await loadSecrets() + connectionString = secrets.DATABASE_URL + } + + if (!connectionString) { + throw new Error("DATABASE_URL not configured") + } + + const pool = new Pool({ + connectionString, + max: 1, + }) + + try { + const db = drizzle(pool) + + await db.execute(sql` + ALTER TABLE "tenant_export_jobs" + ADD COLUMN IF NOT EXISTS "operation" text DEFAULT 'export' NOT NULL, + ADD COLUMN IF NOT EXISTS "previous_tenant_locked" "locked_tenant"; + `) + + await db.execute(sql` + ALTER TABLE "tenants" + ADD COLUMN IF NOT EXISTS "locked_by_export_job_id" uuid; + `) + + await db.execute(sql` + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM information_schema.table_constraints + WHERE constraint_schema = 'public' + AND constraint_name = 'tenants_locked_by_export_job_id_tenant_export_jobs_id_fk' + ) THEN + ALTER TABLE "tenants" + ADD CONSTRAINT "tenants_locked_by_export_job_id_tenant_export_jobs_id_fk" + FOREIGN KEY ("locked_by_export_job_id") + REFERENCES "tenant_export_jobs"("id") + ON DELETE SET NULL; + END IF; + END $$; + `) + + await db.execute(sql` + CREATE SCHEMA IF NOT EXISTS drizzle; + `) + + await db.execute(sql` + CREATE TABLE IF NOT EXISTS drizzle.__drizzle_migrations ( + id SERIAL PRIMARY KEY, + hash text NOT NULL, + created_at bigint + ); + `) + + await db.execute(sql` + INSERT INTO drizzle.__drizzle_migrations (hash, created_at) + SELECT 'manual-0055_tenant_export_maintenance_lock', 1784021669805 + WHERE NOT EXISTS ( + SELECT 1 + FROM drizzle.__drizzle_migrations + WHERE created_at >= 1784021669805 + ); + `) + + console.log("✅ Tenant export lock migration applied") + } finally { + await pool.end() + } +} + +run().catch((err) => { + console.error("❌ Tenant export lock migration failed") + console.error(err) + process.exit(1) +})