fix(GRO-2672): use drizzle-kit migrate in reset.ts to bypass HWM bug #227
Closed
Flea Flicker
wants to merge 72 commits from
fix/gro-2672-reset-migrate-hwm into dev
pull from: fix/gro-2672-reset-migrate-hwm
merge into: groombook:dev
groombook:main
groombook:promote/uat-to-main-gro-2745
groombook:uat
groombook:dev
groombook:flea/gro-2721-schema-safe-reset
groombook:fix/gro-2692-readyz-auth-bypass
groombook:fix/gro-2687-readyz-auth-bypass
groombook:revert/gro-2689-health-ready
groombook:fix/remove-gro2689-from-uat
groombook:dev-to-uat-gro-2689
groombook:fix/gro-2672-drizzle-kit-migrate
groombook:fix/GRO-2652-auth-promise-reset
groombook:fix/GRO-2652-ci-yml-corruption
groombook:feature/GRO-2652-boot-econnreset-resilience
groombook:promote/uat-to-main-gro-2586
groombook:promote/GRO-2586-cors-to-uat
groombook:feature/GRO-2586-cors-origin-reflection
groombook:frozen/gro-2425-uat-to-main
groombook:feature/GRO-2425-comma-split-cors-origin
groombook:gro-2381-agents-contributing
groombook:flea/uat-to-main-gro-2359-api
groombook:release/main-GRO-2342-api
groombook:release/main-GRO-2319-api
groombook:flea/promote-main-gro-2311
groombook:promote/GRO-2319-api-to-uat
groombook:feat/GRO-2319-portal-waitlist-surfacing
groombook:flea/promote-main-gro-2172
groombook:dev-to-uat-gro-2311
groombook:flea/gro-2311-seed-portal-statusbadge-appts
groombook:promote/gro-2172-pets-to-uat
groombook:fix/gro-2172-pet-extended-fields
groombook:uat-to-main-gro-2299
groombook:flea/promote-main-gro-2294
groombook:promote/dev-to-uat-gro-2299
groombook:gro-2299-redact-patch-settings
groombook:flea/promote-gro-2294-uat
groombook:flea/gro-2294-route-opt-hardening
groombook:flea/uat-to-main-gro-2157-frozen
groombook:promote/dev-to-uat-gro-2225
groombook:flea/gro-2157-navigation-export
groombook:flea/gro-2235-waitlist-duplicate-409
groombook:feat/gro-2225-uat-seed-route-cohort
groombook:flea/uat-to-main-gro-2234-api
groombook:flea/dev-to-uat-gro-2156
groombook:flea-flicker/gro-2234-portal-session-sliding-ttl
groombook:release/main-6120b96
groombook:flea/gro-2156-travel-buffer-reorder
groombook:release/main-eb92f99
groombook:fix/gro-2214-portal-waitlist-validation
groombook:fix/gro-2203-portal-pet-patch-uuid-validation
groombook:dev-to-uat-gro-2155
groombook:feat/gro-2155-route-optimize-endpoints-dev
groombook:fix/gro-2163-migrate-pre-dns-wait
groombook:fix/gro-2187-portal-photokey-hijack
groombook:dev-to-uat-gro-2154
groombook:feat/gro-2154-geocoding-endpoints-dev
groombook:flea-flicker/gro-2197-ci-api-gate
groombook:dev-to-uat-gro-2153
groombook:dev-to-uat-gro-2187
groombook:fix/gro-2187-portal-pets-patch
groombook:dev-to-uat-gro-2129
groombook:flea-flicker/gro-2123-cleanup-stale-seed-duplicate
groombook:dev-to-uat-gro-2123
groombook:flea-flicker/gro-2123-seed-advisory-lock
groombook:promote/dev-to-uat-gro-2100
groombook:flea/gro-2100-uat-groomer-pet-linkage
groombook:flea/gro-2062-owner-bypass-audit
groombook:flea/gro-2052-rbac-betterauth-user-autoprovision
groombook:dogfather/gro-2013-promote-uat
groombook:flea/gro-2013-owner-bypass-deployed-tree
groombook:flea/gro-2033-idempotent-pet-profile-migrations
groombook:fix/gro-2014-profile-summary-error-handling
groombook:flea/gro-2000-uat-password-source-doc
groombook:fix/gro-1999-uat-seed-extra-large
groombook:fix/gro-1983-seed-pnpm-baked
groombook:fix/GRO-1979-coat-type-pet-size-enum-fix
groombook:fleaflicker/GRO-1962-deterministic-testcoopper-rocky
groombook:flea/gro-1977-seed-idempotency
groombook:fix/GRO-1977-seed-credential-idempotency
groombook:promote/dev-to-uat-gro-1971
groombook:fix/gro-1971-coat-type-enum-missing-short
groombook:fix/GRO-1962-uat-seed-pet-medicalalerts
groombook:flea/GRO-1955-fix-uc-undefined-seed
groombook:fix/GRO-1909-migrate-corepack-offline
groombook:fix/GRO-1953-coat-type-short-missing
groombook:fleaflicker/gro-medical-alert-types-behavioral-skin
groombook:fleaflicker/gro-1921-uat-reset-full-seed
groombook:flea/GRO-1945-pets-visitcount-hotfix
groombook:fix/GRO-1935-uat-customer-client-seed
groombook:fix/GRO-1914-seed-typeof
groombook:feature/GRO-1898-extended-pet-profile-seed
groombook:seed/extended-profile-fields-gro-1898
groombook:fix/gro-1889-reset-demo-data-pnpm
groombook:promote/dev-to-uat-gro-1866
groombook:fix/gro-1866-qa-fixes
groombook:fix/gro-1866-sso-bridge
groombook:fix/gro-1850-pet-profile-migration
groombook:promote/dev-to-uat-gro-1790
groombook:flea-flicker/pet-profile-summary
groombook:ff/gro-1765-trigger-ci
groombook:promo/gro-1764-uat
groombook:ci/gro-1757-build
groombook:fix/gro-1757-sso-auto-provision
groombook:fix/gro-1754-uat-ci
groombook:fix/gro-1754-trigger-ci-v2
groombook:fix/gro-1752-factories-v2
groombook:fix/gro-1752-factories-only
groombook:fix/gro-1746-apply-uat-seed-to-root-src
groombook:fix/gro-1752-extended-pet-profile-fields
groombook:promo/gro-1749-uat
groombook:fix/gro-1749-uat-seed-sync
groombook:fix/gro-1743-uat-seed-data
groombook:fix/gro-1480-portal-pets-patch
groombook:fix/gro-1678-econnreset-robustness
groombook:fix/gro-1576-ci-provenance-false
groombook:fix/gro-1575-ci-provenance
groombook:fix/gro-1566-api-health-auth-bypass
groombook:fix/gro-1544-api-health-endpoint
groombook:fix/gro-1533-migration-0031-coat-type
groombook:fix/gro-1533-missing-migration-0032
groombook:fix/gro-1533-missing-migration-journal
groombook:revert/gro-1533-dockerfile-fix
groombook:fix/gro-1533-revert-dockefile-build-change
groombook:flea-flicker/gro-1531-seed-db-filter
groombook:fix/gro-1522-ci-images-node22
groombook:pr-44
groombook:flea-flicker/gro-1509-better-auth-account-not-linked
groombook:flea-flicker/gro-1162-pet-buffer-time
groombook:fix/gro-1461-uat-playbook-auto-provision
groombook:flea-flicker/pet-profile-editor
groombook:fix/gro-1441-remove-duplicate-coat-props
groombook:fix/gro-1390-pets-test-mock-hoisting
groombook:fix/gro-1395-drizzle-orm-root-dep
groombook:gitea/migrate-workflows
groombook:flea-flicker/fix-gro-1370-ts-and-test-errors
groombook:fix/api/add-devdep-drizzle-orm-fix-vitest
groombook:pr-19
groombook:flea-flicker/uat-email-password-seed
groombook:fleaflicker/gro-1272-v2
groombook:fleaflicker/gro-1272-auto-provision-staff
groombook:add-renovate-config
groombook:flea-flicker/gro-1231-pnpm-workspace-dockerfile
groombook:fix/GRO-1202-rate-limit-override
groombook:fix/typescript-errors
groombook:flea-flicker/pet-profile-extended-fields
groombook:fix/uat-tester-oidc-sub
groombook:flea-flicker/fix-authprovider-mock-path
groombook:flea-flicker/auto-create-staff-oauth-users-v2
groombook:flea-flicker/auto-create-staff-oauth-users
groombook:docs/GRO-1099-uat-playbook-api
groombook:flea-flicker/fix-ci-install-deps-v2
groombook:flea-flicker/fix-ci-install-deps
No Reviewers
Labels
Clear labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
Something isn't working
Improvements or additions to documentation
This issue or pull request already exists
New feature or request
Good for newcomers
Extra attention is needed
This doesn't seem right
Further information is requested
This will not be worked on
No Label
Milestone
No items
No Milestone
Projects
Clear projects
No project
Assignees
ai-review (AI Review)
gb_barkley (Barkley Trimsworth)
cpfarhood (Chris Farhood)
ci (Continuous Integration [bot])
gb_flea (Flea Flicker)
flux (Flux CD)
admin (Gitea Admin)
gb_lint (Lint Roller)
renovate (Mend Renovate)
gb_pawla (Pawla Abdul)
gb_scrubs (Scrubs McBarkley)
gb_shedward (Shedward Scissorhands)
gb_dogfather (The Dogfather)
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: groombook/api#227
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "fix/gro-2672-reset-migrate-hwm"
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?
Root cause
drizzle-orm/postgres-js/migrator'smigrate()function has the known high-water-mark (HWM) bug (GRO-1999, GRO-2033). Whenreset.tsdrops the drizzle schema and callsmigrate()on a fresh DB, it applies migration 0000 first — setting the HWM towhen = 1773771452946(2026-03-17). Migrations with stale 2025-erawhentimestamps are silently skipped:whenpets.health_alertsmissingrecurring_seriestable +appointments.series_id/series_indexmissingimpersonation_sessionstable missingMigration 0003 is the blocker. It creates the
recurring_seriestable and addsseries_id/series_indexcolumns toappointments. Sincemigrate()wraps all SQL in a single Postgres transaction, any downstream applied migration that depends on those objects fails — causing a full rollback that takes migration 0000'sstaffandservicestables with it.After reset exits 1, the DB has zero tables and no drizzle ledger. The next reset hits the same failure. The standalone
seed-test-dataK8s Job also fails because tables don't exist.The K8s
migrate-schema-552a4d9Job usesdrizzle-kit migrate(hash-based), finds the (also-missing) ledger empty, and applies all 42 migrations correctly — butreset.tswas not using the same approach.Fix
Replace
migrate()fromdrizzle-orm/postgres-js/migratorwithpnpm exec drizzle-kit migrate(hash-based). drizzle-kit checks each migration's hash against the ledger — it applies every unhashed migration regardless ofwhentimestamp ordering. This matches the K8s migrate Job's behaviour exactly.One-line diff (conceptually):
drizzle-kit reads
packages/db/drizzle.config.ts(schema, migrations folder, DATABASE_URL) from thecwd. pnpm is already in PATH in the Docker reset image (the CMD ispnpm --filter @groombook/db reset).Recovery path
Once this fix ships to prod (via the standard dev→uat→main pipeline), the next
reset-demo-dataCronJob run will apply all 42 migrations on a fresh DB (hash-based, no HWM skip) and re-seed successfully.The K8s migrate Job (
migrate-schema-<sha>) will also run on the next Flux reconcile and restore the ledger, but since reset.ts is now correct, the hourly reset will self-heal regardless.Test plan
reset-demo-dataCronJob runs clean at next :45 mark — verify via pod logs that all 42 migrations are applied and seed completes (Shedward)seed-test-datajob completes successfully after resetcc @cpfarhood
fc6c6ef7)' (#149) from dev into uatResolves conflicts in UAT_PLAYBOOK.md, src/routes/portal.ts, and src/__tests__/portal.test.ts (dev side wins — GRO-2342 changes are the only diff in scope). Carries forward GRO-2139 reset.ts advisory lock + GRO-2294 infra mcp trigger that were merged to dev but not yet promoted to uat. - src/routes/portal.ts: GET /portal/appointments now populates service: {id, name} on both the synthetic waitlist card and the appointment card (was {id} only). Same shape, no portal change required. - src/__tests__/portal.test.ts: services mock + TC-API-8.20 GRO-2342 assertions on the synthetic waitlist card service name. - UAT_PLAYBOOK.md: TC-API-8.20 (GRO-2342) appended; TC-API-8.19 (GRO-2319) retained verbatim. Co-Authored-By: Paperclip <noreply@paperclip.ing>c737bfe) (#211)Merge pull request 'GRO-2342: portal/appointments — symmetric service {id, name} on both card paths' (#211) from release/main-GRO-2342-api into main GRO-2342: GET /portal/appointments populates service: {id, name} on the synthetic waitlist card (was {id} only) and on the appointment card (consistent shape). TC-API-8.20 in UAT_PLAYBOOK.md. Approved CTO. Squashed from release/main-GRO-2342-api @c737bfe. Refs: GRO-2342, GRO-2344, GRO-2345, GRO-2346, PR #211. Co-authored-by: Flea Flicker <22+gb_flea@noreply.git.farh.net> Co-committed-by: Flea Flicker <22+gb_flea@noreply.git.farh.net>Pull request closed