fix(db): renumber api_tokens to 0019 so production can boot #131
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/migration-0017-collision"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Production is down on
main. It exits at boot with:What happened
Two branches both took the number
0017:0017_provision_detail— landed on main via #104, "migration 0017 ahead of the RC"0017_api_tokens— landed on main 188 commits later via #123, from a branch cut earlierProduction was running a build from the window between those two merges, so its ledger has
0017_provision_detailat index 16 and has never seen0017_api_tokens. When #123 merged, its migration inserted itself alphabetically ahead of one production had already executed. kysely requires the executed ledger to be a prefix of the sorted migration list, so it refuses to start.Nothing is corrupted. The schema is intact; the migrator declines to run.
There is an irony worth recording: #104 existed specifically to claim
0017early and avoid a collision. #123's branch had already claimed it.The fix
Move
0017_api_tokens→0019_api_tokens, after0018_session_attention. Every migration has its own number again and kysely's ordering check stays strict.Renumbering is safe here for one specific reason, checked rather than assumed: production has never executed
0017_api_tokens. Its ledger has no such row and the database has noapi_tokenstable. It is also the only live instance, so no database anywhere holds the old spelling.That window is narrow, and worth stating plainly: once two databases have run the same number in different orders, no renaming can satisfy both — renaming to fix one trips a different, unrelaxable check on the other (
previously executed migration ... is missing). This was recoverable only because nothing had run the loser of the collision.Verification
Ran the real
runMigrationsagainst a copy of the production database:0018_session_attention, then0019_api_tokenssqlite_mastercomparison)lintclean,typecheckclean (0 errors), full suite green 1501/1501Guard
migrations/migration-numbers.test.tsfails on any duplicate migration number, so the next collision is caught in CI rather than at boot. Proven to fail by reintroducing the exact0017collision — it reports both filenames.This is deliberately the weaker of two guards, and the one that needs no git context. The stronger rule — every migration a branch adds must sort after the newest migration already on the base branch — catches the whole family, including a stale branch merging late under any naming scheme. Measured against real history, it flags #123 at the merge that broke production and passes this PR. It needs the base ref in CI (
fetch-depth: 0), so it is a follow-up rather than a change to the PR that has to merge to end the outage.Note for whoever deploys
Merge, rebuild, redeploy. The first boot will apply
0018_session_attentionand0019_api_tokensto the existing database; no manual database work is needed.df8c447a12ab7feae3b6fix(db): let the two 0017 migrations coexist so production can bootto fix(db): renumber api_tokens to 0019 so production can boot