|
| 1 | +// Pending-status check for the `trigger_dashboard_agent` schema (sibling of |
| 2 | +// migrate.mjs). Exit 0 = up to date, 1 = pending, 2 = error. |
| 3 | +import { readFileSync } from "node:fs"; |
| 4 | +import { dirname, join } from "node:path"; |
| 5 | +import { fileURLToPath } from "node:url"; |
| 6 | +import postgres from "postgres"; |
| 7 | + |
| 8 | +const MIGRATIONS_SCHEMA = "drizzle"; |
| 9 | +const MIGRATIONS_TABLE = "__dashboard_agent_migrations"; |
| 10 | + |
| 11 | +const connectionString = process.env.DASHBOARD_AGENT_DATABASE_URL ?? process.env.DATABASE_URL; |
| 12 | + |
| 13 | +if (!connectionString) { |
| 14 | + console.error( |
| 15 | + "[dashboard-agent-db] DASHBOARD_AGENT_DATABASE_URL / DATABASE_URL not set; cannot check status." |
| 16 | + ); |
| 17 | + process.exit(2); |
| 18 | +} |
| 19 | + |
| 20 | +// Match migrate.mjs: drop the Prisma-style `?schema=` param postgres.js forwards. |
| 21 | +function normalizeConnectionString(value) { |
| 22 | + try { |
| 23 | + const url = new URL(value); |
| 24 | + url.searchParams.delete("schema"); |
| 25 | + return url.toString(); |
| 26 | + } catch { |
| 27 | + return value; |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +const journalPath = join( |
| 32 | + dirname(fileURLToPath(import.meta.url)), |
| 33 | + "drizzle/meta/_journal.json" |
| 34 | +); |
| 35 | +const sql = postgres(normalizeConnectionString(connectionString), { |
| 36 | + max: 1, |
| 37 | + prepare: false, |
| 38 | + onnotice: () => {}, |
| 39 | +}); |
| 40 | + |
| 41 | +async function main() { |
| 42 | + const journal = JSON.parse(readFileSync(journalPath, "utf-8")); |
| 43 | + const entries = [...journal.entries].sort((a, b) => a.when - b.when); |
| 44 | + |
| 45 | + let lastAppliedAt = -1; |
| 46 | + try { |
| 47 | + const rows = await sql`SELECT MAX(created_at)::bigint AS last FROM ${sql( |
| 48 | + MIGRATIONS_SCHEMA |
| 49 | + )}.${sql(MIGRATIONS_TABLE)}`; |
| 50 | + lastAppliedAt = rows[0].last === null ? -1 : Number(rows[0].last); |
| 51 | + } catch (err) { |
| 52 | + // 42P01: journal table absent (fresh database), so nothing is applied. |
| 53 | + if (err.code !== "42P01") throw err; |
| 54 | + } |
| 55 | + |
| 56 | + const pending = entries.filter((e) => e.when > lastAppliedAt); |
| 57 | + console.log( |
| 58 | + `${entries.length} migration(s) found, ${entries.length - pending.length} applied` |
| 59 | + ); |
| 60 | + |
| 61 | + if (pending.length > 0) { |
| 62 | + console.log(`${pending.length} pending migration(s):`); |
| 63 | + for (const e of pending) console.log(` - ${e.tag}`); |
| 64 | + return 1; |
| 65 | + } |
| 66 | + |
| 67 | + console.log("Dashboard agent schema is up to date"); |
| 68 | + return 0; |
| 69 | +} |
| 70 | + |
| 71 | +main() |
| 72 | + .then((code) => sql.end({ timeout: 5 }).then(() => process.exit(code))) |
| 73 | + .catch((err) => { |
| 74 | + console.error(err); |
| 75 | + sql.end({ timeout: 5 }).finally(() => process.exit(2)); |
| 76 | + }); |
0 commit comments