dev → uat: GRO-2123 seed advisory lock #156
Reference in New Issue
Block a user
Delete Branch "dev-to-uat-gro-2123"
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?
dev → uat: GRO-2123 seed advisory lock
Phase 2 promotion of the GRO-2123 fix from dev to uat. See PR #155 for the original PR, root-cause investigation, and review history.
Diff vs
uat: one commit, one logical change.packages/db/src/seed.ts—withSeedAdvisoryLockhelper +runSeedBodyextraction; seed now holds a session-levelpg_advisory_lock(0x47524f4f)for the full body via a reserved connection (postgres-js pooling gotcha), so overlappingreset-demo-dataCronJob invocations block then proceed instead of clobbering each other.UAT_PLAYBOOK.md§3.29 — new regression test case for the FK 23503 scenario.UAT step (per CTO spec): this is a backend log/k8s smoke, not a browser flow. Verification:
cc @cpfarhood — handing to QA (Lint Roller) for review per AGENTS.md Phase 2.
🤖 Generated with Claude Code
The reset-demo-data CronJob in groombook-uat intermittently failed with FK 23503 on invoice_tip_splits because two pods could run the seed concurrently: the new pod's TRUNCATE deleted rows the old pod was still inserting. Acquire a session-level advisory lock for the full duration of the seed. CRITICAL: with postgres-js connection pooling, a pg_advisory_lock acquired on one pooled connection and released on a different one is a no-op (the lock is bound to the pg-backend that took it). We therefore reserve a dedicated connection for the lock, take pg_advisory_lock(KEY) on it, run the seed on the pooled connections, and release the lock + reserved connection in a try/finally so a thrown seed error cannot leak the lock or the connection. Defence-in-depth with the infra PR that switches concurrencyPolicy: Replace → Forbid on the reset-demo-data CronJob. - Adds withSeedAdvisoryLock helper and runSeedBody extracted function - Wraps seed() body in the helper; client.end() runs after the lock releases so a reserved connection is not returned to a closed pool - SEED_ADVISORY_LOCK_KEY = 0x47524f4f ("GROO" in ASCII) — arbitrary stable 32-bit key, referenced in runbooks - UAT_PLAYBOOK.md §3.29 documents the regression check cc @cpfarhood Co-Authored-By: Paperclip <noreply@paperclip.ing>QA PASS - GRO-2123 seed advisory lock: CI all 6 checks pass. withSeedAdvisoryLock correctly uses reserved connection for postgres-js pooling. lockHeld flag ensures release on exception. runSeedBody extraction clean, client.end() correctly placed. seedUatStaffAccounts null-return + seedUatGroomerLinkage null guard correct. UAT_PLAYBOOK TC-API-3.29 added. No issues found.