From 2217cd8dc4ccaaa0b49a2946952a6424c8a738df Mon Sep 17 00:00:00 2001 From: oak Date: Mon, 19 Oct 2026 22:16:13 +0100 Subject: [PATCH] fix(prisma): reorder webhook query indexes migration to run after table creation Prisma deploys migrations in lexicographical order by directory name. Because ASCII '0' precedes 'a', 20261003_001_add_webhook_query_indexes sorted before 20261003_add_missing_models, causing 'CREATE INDEX ON user_webhook_deliveries' to fail with relation does not exist. Renamed migration to 20261004000000_add_webhook_query_indexes so it runs after table creation, added recovery handling to fix-and-deploy-migrations.sh, and documented the incident in docs/MIGRATIONS.md. --- docs/MIGRATIONS.md | 22 +++++++++++++++++++ fix-and-deploy-migrations.sh | 1 + .../migration.sql | 0 .../rollback.sql | 0 4 files changed, 23 insertions(+) rename prisma/migrations/{20261003_001_add_webhook_query_indexes => 20261004000000_add_webhook_query_indexes}/migration.sql (100%) rename prisma/migrations/{20261003_001_add_webhook_query_indexes => 20261004000000_add_webhook_query_indexes}/rollback.sql (100%) diff --git a/docs/MIGRATIONS.md b/docs/MIGRATIONS.md index b311acf1..d2e13ec4 100644 --- a/docs/MIGRATIONS.md +++ b/docs/MIGRATIONS.md @@ -550,3 +550,25 @@ environment, resolve the failure per §6 (rolling back) instead. **Prevention:** run the rehearsal (§5) before pushing, and write idempotent SQL (`IF [NOT] EXISTS`, `DO` blocks instead of `ADD CONSTRAINT IF NOT EXISTS` for PostgreSQL < 12). + +### A.4 Lexicographical migration sorting order (indexes before tables) + +**Incident:** `20261003_001_add_webhook_query_indexes` + +**Symptom:** `npx prisma migrate deploy` fails with `ERROR: relation "user_webhook_deliveries" does not exist` (error code P3018, database code 42P01). + +**Cause:** Prisma orders migrations alphabetically (lexicographically) by directory name. Because ASCII `'0'` (48) sorts before ASCII `'a'` (97), `20261003_001_add_webhook_query_indexes` was sorted and executed *before* `20261003_add_missing_models` (which creates `user_webhook_deliveries`). + +**Recipe** + +```bash +# 1. Rename the migration folder so its timestamp sorts after the table creation: +# 20261003_001_add_webhook_query_indexes -> 20261004000000_add_webhook_query_indexes + +# 2. If the migration failed on an existing environment, resolve the failed row: +npx prisma migrate resolve --rolled-back 20261003_001_add_webhook_query_indexes +npx prisma migrate deploy +``` + +**Prevention:** always use standard 14-digit timestamps (`YYYYMMDDHHMMSS_name`) or verify sorting order with `fs.readdirSync('prisma/migrations').sort()` when creating dependent migrations. + diff --git a/fix-and-deploy-migrations.sh b/fix-and-deploy-migrations.sh index 3334883d..e1ef93bd 100755 --- a/fix-and-deploy-migrations.sh +++ b/fix-and-deploy-migrations.sh @@ -21,6 +21,7 @@ FIXED_MIGRATIONS=( "20260928180000_add_webhook_query_indexes" "20260928200000_add_totp_credentials" "20260929120000_add_collateral_loans" + "20261003_001_add_webhook_query_indexes" ) for migration in "${FIXED_MIGRATIONS[@]}"; do diff --git a/prisma/migrations/20261003_001_add_webhook_query_indexes/migration.sql b/prisma/migrations/20261004000000_add_webhook_query_indexes/migration.sql similarity index 100% rename from prisma/migrations/20261003_001_add_webhook_query_indexes/migration.sql rename to prisma/migrations/20261004000000_add_webhook_query_indexes/migration.sql diff --git a/prisma/migrations/20261003_001_add_webhook_query_indexes/rollback.sql b/prisma/migrations/20261004000000_add_webhook_query_indexes/rollback.sql similarity index 100% rename from prisma/migrations/20261003_001_add_webhook_query_indexes/rollback.sql rename to prisma/migrations/20261004000000_add_webhook_query_indexes/rollback.sql