Repository navigation
Conversation
Run the Prisma migration status check in the boot sequence before the HTTP server starts listening, and make its outcome configurable via DATABASE_MIGRATION_CHECK (strict | warn | off). Production defaults to strict: pending or failed migrations, or an unreadable migration history, abort startup with remediation steps in the log. Other environments default to warn so local development is never blocked. - Ignore rolled-back rows in _prisma_migrations so they count as pending - Rethrow query failures other than a missing migrations table instead of silently treating them as "nothing applied" - Add DATABASE_MIGRATIONS_DIR to locate migrations in custom layouts - Replace the log-only PrismaService.validateMigrations with verifyMigrations, called from main.ts before app.listen() - Add unit tests and an integration spec with a real PrismaService and on-disk migrations folder
|
@Deb-Auth Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Merge Conflict — Action NeededThis pull request has merge conflicts with the base branch ( What to do: update your branch by merging or rebasing against |
Merge Conflict — Action NeededThis pull request has merge conflicts with the base branch ( What to do: update your branch by merging or rebasing against |
|
CI fails in migration verification because prisma/migrations contains two folders with the same timestamp prefix |
CI Checks Failed — Action NeededThe current CI run has failing checks, so this PR remains unmergeable. Please inspect the failed jobs, fix the underlying issues, and push the correction to this PR branch. Failing checks:
I will not merge while these checks are failing. |
A bad merge left prisma.service.ts with a duplicate onModuleInit (the first truncated mid-body, with constructor $extends fragments spliced into its catch block) and verifyMigrations()'s body merged directly into validateMigrations()'s declaration with no closing brace — both unparseable. main.ts had the same issue: two `const prisma` declarations and both the legacy halt/warn migrationCheckEnabled block and the new verifyMigrations() call still present. Restored both migration-check methods since each has its own test suite requiring it: validateMigrations() (unconditional, run from onModuleInit via prisma.service.spec.ts) and verifyMigrations() (the configurable strict/warn/off gate from migration-startup.integration.spec.ts, called by main.ts). Dropped the superseded migrationCheckEnabled/ migrationCheckMode halt block from main.ts in favor of the single verifyMigrations() call its own test now covers. Also documented the two migration-check env vars this surfaced as missing from docs/configuration.md, and filled in DatabaseConfig fields the integration spec's fixture was missing.
Summary
Adds a migration status gate to the boot sequence. It runs before the HTTP server starts listening, so an instance whose database has pending or failed Prisma migrations aborts in production instead of serving traffic against a mismatched schema.
Why
PrismaService.onModuleInitalready comparedprisma/migrationswith_prisma_migrations. However, it only logged the result, and it ran inside atry/catchthat swallowed every error. An out-of-date schema therefore never stopped startup, and failures surfaced later as runtime query errors. The checker also treated any query failure (including an unreachable database) as "nothing applied", and it counted rolled-back migrations as applied.What changed
main.tscallsPrismaService.verifyMigrations()right after the logger is set up and beforeapp.listen().DATABASE_MIGRATION_CHECKsetting:strict, the default whenNODE_ENV=production: pending or failed migrations throwPendingMigrationsError, and an unreadable migration history throwsMigrationStatusUnavailableError. Either one exits the process with code 1.warn, the default everywhere else: logs the same information and keeps booting, so local development is never blocked.off: skips the check.npm run prisma:deploy, orprisma migrate resolve --rolled-back|--applied <name>).src/database/migration-checker.ts:rolled_back_atset are ignored, so rolled-back migrations are reported as pending again, matchingprisma migrate deploy._prisma_migrationstable (Postgres42P01) is treated as a fresh database. Any other query error is rethrown instead of being reported as "all pending".DATABASE_MIGRATIONS_DIR: optional override for images that don't keep migrations at<cwd>/prisma/migrations. When no migrations are found on disk, the check logs a warning instead of passing silently.PrismaService.validateMigrations()is replaced byverifyMigrations(). It had no other callers.docs/database.md(new "Startup Migration Check" section) and.env.example.Type of change
Testing
src/database/migration-checker.spec.ts: new unit tests for:verifyMigrationsOnStartuppath: up to date, pending, failed, database unreachable,off, and no migrations on disksrc/database/migration-startup.integration.spec.ts(new): runs a realPrismaServiceagainst a real temporary migrations folder, with only the_prisma_migrationsquery simulated. It covers mock migration states in which startup either proceeds or aborts.Notes for reviewers
onModuleInithooks (e.g. queue workers) duringNestFactory.create, before this gate runs. The gate guarantees that no HTTP traffic is accepted on a bad schema, and the process then exits. Making non-HTTP components wait for the check would mean moving it into a provider that those modules depend on. I've left that out of scope, but can follow up if you want it.src/index.tsandsrc/database/migrationChecker.ts. The equivalents in this repo aresrc/main.tsand the existingsrc/database/migration-checker.ts, which this PR extends.Related issue
Closes #343
Checklist
npm run buildpassesnpm testpassesnpm run lintpassesnpm run typecheckpasses