fix(migrations): make 983 CHECK constraint idempotent via DO block

Migration 983 was crashing backend startup on my local DB because
(a) I'd manually applied it via psql during B day 3 development
before the migration runner saw it, so the constraint existed but
was not tracked; (b) the migration used plain ADD CONSTRAINT which
Postgres doesn't support with IF NOT EXISTS for CHECK constraints.

Fix: wrap the ALTER TABLE in a DO block that catches
`duplicate_object` — re-running the migration becomes a no-op,
matches the idempotency contract the other migrations in this
directory observe. Any env where the constraint already exists
(manual apply, prior successful run) now proceeds cleanly.

Verified: backend starts cleanly after the fix. Pre-rc1 blocker
resolved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
senke 2026-04-18 04:08:14 +02:00
parent 6773f66dd3
commit d359a74a5f

View file

@ -21,10 +21,22 @@
-- legitimately NULL in the other statuses (pending, completed,
-- failed without pending retry, reversed, permanently_failed).
ALTER TABLE seller_transfers
ADD CONSTRAINT chk_reversal_pending_has_next_retry_at
CHECK (status <> 'reversal_pending' OR next_retry_at IS NOT NULL)
NOT VALID;
-- ADD CONSTRAINT is not natively IF NOT EXISTS in Postgres — the
-- DO block catches `duplicate_object` so re-running the migration
-- (test runs, manual psql apply, re-deploys) is a no-op. Same shape
-- the runner expects from other idempotent migrations in this
-- directory.
DO $$
BEGIN
ALTER TABLE seller_transfers
ADD CONSTRAINT chk_reversal_pending_has_next_retry_at
CHECK (status <> 'reversal_pending' OR next_retry_at IS NOT NULL)
NOT VALID;
EXCEPTION
WHEN duplicate_object THEN
-- constraint already present (prior manual apply or prior run)
NULL;
END $$;
-- NOT VALID creates the constraint without scanning existing rows.
-- Pre-v1.0.7.2 rows are grandfathered — item A + day 2 of B don't