fix(GRO-2672): use drizzle-kit migrate in reset.ts (dev→uat) #229
Reference in New Issue
Block a user
Delete Branch "dev"
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?
Summary
Promotes fix for GRO-2672 to UAT. One commit:
f7f90a7reset.tswas usingdrizzle-orm'smigrate()which has a high-water-mark (HWM) bug — it silently skips migrations 0001, 0003, 0010, 0011 because theirwhentimestamps predate the watermark set by migration 0000 on a fresh DB. Migration 0003 (recurring_series) creates non-idempotent objects; when skipped, a downstream migration insidemigrate()'s single Postgres transaction fails, rolling back everything — includingstaffandservicestables created by 0000. The DB ends up with zero tables.Fix: replace
migrate()withpnpm exec drizzle-kit migrate(hash-based), which matches the K8s migrate Job's behaviour exactly.Dev CI: https://git.farh.net/groombook/api/actions/runs/4293 — all green (lint, typecheck, tests, all 4 image builds + smoke tests)
UAT validation (Shedward)
reset-demo-dataCronJob runs clean at next :45 mark — verify pod logs show all 42 migrations applied and seed completesseed-test-dataJob completes successfully after resetcc @cpfarhood
QA review (Phase 2, dev→uat) — APPROVED ✅
Reviewed for GRO-2672. Single-file, single-purpose change (
packages/db/src/reset.ts, +11/-4): swaps drizzle-orm's HWM-basedmigrate()forexecSync("pnpm exec drizzle-kit migrate").Code correctness — verified against the deploy context
db:resetis not exercised by CI, so I validated the runtime path by hand against the Dockerfile + infra manifests:resetruns viatsx src/reset.ts(not compiled dist), so__dirname=packages/db/srcandcwd: resolve(__dirname, "..")=packages/db, exactly wheredrizzle.config.tslives. drizzle-kit resolvesout: "./migrations"→packages/db/migrations.FROM builder, which runs a fullpnpm install --frozen-lockfile(devDependencies incl.drizzle-kit+tsx) before building. pnpm is baked at/usr/local/bin/pnpm(GRO-2028) andHOME=/tmpis set with a writable emptyDir. The prod-prunedrunnerstage is a different target and isn't used here.migratestage CMD isdrizzle-kit migrate; reset now invokes the same hash-based applier, so the reset path and the K8smigrate-schemaJob apply migrations identically.postgres(url, { max: 6 })and thewithSeedAdvisoryLockinvariant (≥2) are preserved; the childdrizzle-kitprocess uses its own connection and doesn't contend with the reserved lock session.seed-test-datarelation "services" does not existreconcile loop; no seed.ts change needed.CI
All 6 checks green on head
f7f90a7(Lint & Typecheck, Test, Build & Push Docker Images — push + pull_request).UAT_PLAYBOOK.md
Not required — this is internal DB tooling, not user-facing behaviour. Runtime verification of the
reset-demo-dataCronJob andseed-test-dataJob is correctly deferred to Shedward (UAT regression), per the PR checklist.Minor (non-blocking, pre-existing): the file header still reads "Intended for local development only. Never run against production." while this path runs in the
groombooknamespace via the reset CronJob — worth tidying in a future pass, out of scope here.Approving. Reassigning GRO-2672 back to @gb_flea (status
todo) for self-merge.cc @cpfarhood