/** * Applies database migrations on container start. * * Databases created before migrations were used (via `prisma db push`) have no * `_prisma_migrations` table. Those are brought up to date with a non-destructive * `db push` (which refuses to drop data) and then baselined, so every later deploy * can use plain `prisma migrate deploy`. */ const { execSync } = require('child_process'); const fs = require('fs'); const path = require('path'); const { PrismaClient } = require('@prisma/client'); function run(command) { console.log(`[deploy] ${command}`); execSync(command, { stdio: 'inherit' }); } async function main() { const prisma = new PrismaClient(); let hasMigrationsTable; let hasTables; try { const [{ migrations, tables }] = await prisma.$queryRaw` SELECT to_regclass('public._prisma_migrations') IS NOT NULL AS migrations, EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public') AS tables`; hasMigrationsTable = migrations; hasTables = tables; } finally { await prisma.$disconnect(); } if (!hasMigrationsTable && hasTables) { console.log('[deploy] Existing database without migration history, baselining'); run('npx prisma db push --skip-generate'); const migrationsDir = path.join(__dirname, 'migrations'); const migrations = fs .readdirSync(migrationsDir, { withFileTypes: true }) .filter((entry) => entry.isDirectory()) .map((entry) => entry.name) .sort(); for (const name of migrations) { run(`npx prisma migrate resolve --applied ${name}`); } } run('npx prisma migrate deploy'); } main().catch((error) => { console.error('[deploy] Migration failed:', error); process.exit(1); });