fix(db): GRO-2722 schema-safe reset — TRUNCATE, no DROP #240

Merged
Flea Flicker merged 2 commits from flea/gro-2721-schema-safe-reset into dev 2026-08-16 13:17:00 +00:00
Member

Summary

GRO-2722 — rewrite packages/db/src/reset.ts to be schema-safe for prod.

Root cause recap

GRO-2678 prod outage: reset.ts issued DROP TABLE ... CASCADE for every public table, then DROP SCHEMA drizzle CASCADE. The subsequent drizzle-kit migrate no-op'd on an empty DB → outage.

Changes

packages/db/src/reset.ts (the deployed image entrypoint — pnpm --filter @groombook/db reset):

  • Replaced four DROP-based DO-blocks (DROP TABLE loop, DROP TYPE loop, DROP drizzle migrations, DROP drizzle schema) with a single:
    TRUNCATE "t1", "t2", ... RESTART IDENTITY CASCADE
    
    Tables enumerated dynamically via pg_tables WHERE schemaname='public'.
  • drizzle schema and __drizzle_migrations are in a different schema — excluded automatically, drizzle-kit migrate stays a no-op.
  • Advisory lock, migrations, seed, and production guard all preserved.

apps/api/src/db/reset.ts (dev-only artifact, not shipped — delegates to packages/db):

  • Same TRUNCATE treatment for consistency.

UAT_PLAYBOOK.md §3 — added TC-API-3.30: manual CronJob trigger, schema-survival check, /api/readyz 200 verification.

Acceptance criteria

  • grep -iE 'DROP (TABLE|TYPE|SCHEMA|DATABASE)' packages/db/src/reset.ts → no output
  • reset.ts uses TRUNCATE ... RESTART IDENTITY CASCADE
  • Production guard retained (NODE_ENV=production && ALLOW_RESET!='true')
  • UAT Playbook updated §3 — TC-API-3.30

cc @cpfarhood

## Summary **GRO-2722** — rewrite `packages/db/src/reset.ts` to be schema-safe for prod. ### Root cause recap GRO-2678 prod outage: `reset.ts` issued `DROP TABLE ... CASCADE` for every public table, then `DROP SCHEMA drizzle CASCADE`. The subsequent `drizzle-kit migrate` no-op'd on an empty DB → outage. ### Changes **`packages/db/src/reset.ts`** (the deployed image entrypoint — `pnpm --filter @groombook/db reset`): - Replaced four `DROP`-based DO-blocks (DROP TABLE loop, DROP TYPE loop, DROP drizzle migrations, DROP drizzle schema) with a single: ```sql TRUNCATE "t1", "t2", ... RESTART IDENTITY CASCADE ``` Tables enumerated dynamically via `pg_tables WHERE schemaname='public'`. - `drizzle` schema and `__drizzle_migrations` are in a different schema — excluded automatically, drizzle-kit migrate stays a no-op. - Advisory lock, migrations, seed, and production guard all preserved. **`apps/api/src/db/reset.ts`** (dev-only artifact, not shipped — delegates to packages/db): - Same TRUNCATE treatment for consistency. **`UAT_PLAYBOOK.md` §3** — added TC-API-3.30: manual CronJob trigger, schema-survival check, /api/readyz 200 verification. ### Acceptance criteria - [x] `grep -iE 'DROP (TABLE|TYPE|SCHEMA|DATABASE)' packages/db/src/reset.ts` → no output - [x] `reset.ts` uses `TRUNCATE ... RESTART IDENTITY CASCADE` - [x] Production guard retained (`NODE_ENV=production && ALLOW_RESET!='true'`) - [x] UAT Playbook updated §3 — TC-API-3.30 cc @cpfarhood
Flea Flicker added 2 commits 2026-08-16 13:15:01 +00:00
GRO-2722: packages/db/src/reset.ts and apps/api/src/db/reset.ts no longer
emit any DROP TABLE / DROP TYPE / DROP SCHEMA / DROP DATABASE DDL. The four
destructive DO-blocks are replaced with a single:

  TRUNCATE <all public tables> RESTART IDENTITY CASCADE

Table names are enumerated dynamically via pg_tables WHERE schemaname='public'
so new tables are picked up automatically. The drizzle schema and
__drizzle_migrations table are untouched (different schema), keeping
drizzle-kit migrate a no-op on an already-migrated DB.

Preserves: production guard (NODE_ENV=production && ALLOW_RESET!='true'),
advisory lock, migrations (drizzle-kit migrate), and seed (runSeedBody).

Fixes the GRO-2678 prod outage root cause.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
docs(uat): add TC-API-3.30 schema-safe reset verification (GRO-2722)
CI / Lint & Typecheck (pull_request) Successful in 21s
CI / Test (pull_request) Successful in 23s
CI / Build & Push Docker Images (pull_request) Successful in 1m12s
7c6346c799
UAT_PLAYBOOK.md §3 — new test case TC-API-3.30:
trigger reset-demo-data CronJob manually, confirm job succeeds,
public tables/enums and drizzle schema survive, demo data reseeded,
/api/readyz stays 200.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
Flea Flicker merged commit 38380d0398 into dev 2026-08-16 13:17:00 +00:00
Sign in to join this conversation.