The dev reset-demo-data CronJob intermittently produced one Error pod per
run with `invoices_pkey` duplicate-key violations. The CTO analysis
(traced in GRO-2136) concluded the race is between the reset image's
three-step chain and a concurrent same-PRNG seeder (the dev
seed-test-data Job being recreated at the top of the hour by Flux).
GRO-2123 added `pg_advisory_lock(0x47524f4f)` around `runSeedBody`,
but `reset.ts` (DROP TABLE … CASCADE) and `drizzle-kit migrate`
ran as separate processes outside that lock — so a concurrent locked
seed could still interleave with the reset's drop+recreate, leaving
two same-seed writers emitting identical invoice ids (the
Mulberry32(seed=42) stream is fully deterministic per process).
This commit makes the whole chain a single locked unit:
- `reset.ts` now takes the same advisory lock and runs DROP → migrate
→ runSeedBody under a single Postgres session (max: 1). The lock
spans the entire chain, so any concurrent `seed.ts` invocation
(via the seed-test-data Job or CI) blocks until the reset finishes.
- `packages/db/package.json` `reset` script is now a single
`tsx src/reset.ts` invocation — `drizzle-kit migrate` no longer
runs as a separate un-locked process.
- `withSeedAdvisoryLock`, `runSeedBody`, `getProfile`, `profiles`,
`SEED_ADVISORY_LOCK_KEY`, and the `SeedProfile`/`ProfileConfig`
types are now exported from `seed.ts` so `reset.ts` can use them
while preserving the deterministic seed contract.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GRO-1325 was marked done but never implemented. This adds the missing
Better-Auth user + account seeding for UAT email+password logins.
For each SEED_UAT_*_PASSWORD env var present, the seed now:
1. Creates (or links to existing) a Better-Auth user record with
emailVerified: true
2. Creates a credential account with providerId: "credential"
and a bcrypt-hashed password (using better-auth/crypto)
3. Links the staff record to the Better-Auth user via userId
Idempotent: skips user/account creation if already seeded.
Updated UAT_PLAYBOOK.md §4.1 — TC-API-1.4 through 1.9 now reference
the new seed provisioning (GRO-1325 was the missing piece).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Use pnpm --filter consistently for all three package builds in the
Dockerfile instead of mixing filter and cd approaches. Also set
--project . explicitly on tsc invocations to ensure tsconfig resolution
from the package directory rather than workspace root.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
pnpm --filter runs in the workspace root where tsc finds the root
tsconfig.json instead of packages/db/tsconfig.json. Change into the
package directory so tsc picks up the correct local tsconfig.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
tsc without --project traverses up to workspace root, which has a
different tsconfig.json that lacks package-local paths. Fix both
@groombook/types and @groombook/db scripts consistently.
Co-Authored-By: Paperclip <noreply@paperclip.ing>