#!/usr/bin/env node /** * Preflight check + migration repair runner. * Called by .gitea/workflows/deploy.yml before running migrations. * * 1. Verify neon_auth schema exists (prerequisite for 0001_init.sql FKs) * 2. Ensure 0001_init.sql is tracked in _migrations if admin_users already exists * (repair for DBs that had 0001_init.sql applied before _migrations was added) */ const { Client } = require("pg"); async function main() { const url = process.env.DATABASE_URL; if (!url) { console.error("No DATABASE_URL"); process.exit(1); } const c = new Client({ connectionString: url }); await c.connect(); try { // 1. Pre-flight: check neon_auth schema console.log("=== Pre-flight: checking for neon_auth schema (required by 0001_init.sql for FKs to neon_auth.user and related RPCs) ==="); const schemaRes = await c.query( "SELECT 1 FROM information_schema.schemata WHERE schema_name = 'neon_auth'" ); if (schemaRes.rows.length === 0) { console.error("✗ FATAL: neon_auth schema does not exist in the target database."); console.error("Enable Neon Auth on the Neon project/branch that this DATABASE_URL points to first."); console.error("Run: neonctl neon-auth (or equivalent) against the correct Neon branch."); console.error("The neon_auth schema is created by Neon Auth and is a prerequisite for 0001_init.sql."); process.exit(1); } console.log("✓ neon_auth schema exists"); // 2. Pre-repair: ensure 0001_init.sql is tracked if admin_users already exists // This handles DBs where 0001_init.sql was applied before _migrations tracking existed. console.log("=== Pre-repair: checking _migrations tracking (best-effort) ==="); try { const tableRes = await c.query( "SELECT 1 FROM information_schema.tables WHERE table_name = 'admin_users' LIMIT 1" ); if (tableRes.rows.length > 0) { await c.query(` CREATE TABLE IF NOT EXISTS _migrations ( filename TEXT PRIMARY KEY, applied_at TIMESTAMPTZ NOT NULL DEFAULT now() ); INSERT INTO _migrations (filename) VALUES ('0001_init.sql') ON CONFLICT (filename) DO NOTHING; `); console.log("✓ 0001_init.sql tracking repaired (admin_users already present)"); } } catch (e) { // best-effort console.log("(pre-repair skipped: " + e.message + ")"); } console.log("Preflight complete. Proceeding to migrations..."); process.exit(0); } catch (e) { console.error("Preflight failed:", e.message); process.exit(1); } finally { await c.end(); } } main();