Mechanical reformat — no logic changes. 398 files changed, 19125 insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc (singleQuote:true, semi:true, tabWidth:2, trailingComma:all, printWidth:100). Isolated per D-13-08 for reviewability.
121 lines
9.4 KiB
Markdown
121 lines
9.4 KiB
Markdown
---
|
||
phase: quick-260610-cr8
|
||
plan: 01
|
||
type: execute
|
||
wave: 1
|
||
depends_on: []
|
||
files_modified:
|
||
- apps/api/package.json
|
||
- docs/deployment.md
|
||
autonomous: true
|
||
requirements: []
|
||
must_haves:
|
||
truths:
|
||
- 'Running `pnpm --filter @familysync/api run db:push` fails — the script no longer exists'
|
||
- 'docs/deployment.md instructs operators to apply schema via `drizzle-kit migrate`, not `drizzle-kit push`'
|
||
- 'docs/deployment.md warns operators NOT to use `drizzle-kit push` on MariaDB and explains why (false destructive diff)'
|
||
- "`drizzle-kit generate` against the current schema produces no spurious destructive diff (reports 'No schema changes' or only an intended additive delta — never a truncate/drop)"
|
||
artifacts:
|
||
- path: 'apps/api/package.json'
|
||
provides: 'API scripts with db:push removed; db:generate + db:migrate retained as canonical workflow'
|
||
contains: 'db:migrate'
|
||
- path: 'docs/deployment.md'
|
||
provides: 'Schema-apply step + prod step repointed to generate/migrate with anti-push warning'
|
||
contains: 'drizzle-kit migrate'
|
||
key_links:
|
||
- from: 'docs/deployment.md Step 3'
|
||
to: 'apps/api/src/db/migrations'
|
||
via: 'drizzle-kit migrate applies committed migration SQL'
|
||
pattern: 'drizzle-kit migrate'
|
||
---
|
||
|
||
<objective>
|
||
Retire the `drizzle-kit push` foot-gun and make `drizzle-kit generate` → `drizzle-kit migrate` the only documented schema workflow.
|
||
|
||
`drizzle-kit push` produces a FALSE destructive diff against the populated MariaDB (mysql dialect misreads MariaDB 11.8 metadata → schedules truncate/recreate). The generate+migrate workflow is already in practical use (migrations `0000`–`0004` are committed and applied), so this task is cleanup, not adoption: remove the dangling `db:push` script and repoint the two `drizzle-kit push` instructions in the deployment docs, adding an explicit warning so a future operator does not reintroduce push.
|
||
|
||
Purpose: Prevent accidental data loss; lock in the mandated MariaDB-safe migration workflow (see memory drizzle-mariadb-push-unsafe; STATE decision D-Task5-DDL).
|
||
Output: `apps/api/package.json` with `db:push` removed; `docs/deployment.md` Steps 3 and 6 repointed to migrate with an anti-push warning; verified that `drizzle-kit generate` emits no spurious destructive diff.
|
||
</objective>
|
||
|
||
<execution_context>
|
||
@$HOME/.claude/gsd-core/workflows/execute-plan.md
|
||
@$HOME/.claude/gsd-core/templates/summary.md
|
||
</execution_context>
|
||
|
||
<context>
|
||
@.planning/STATE.md
|
||
@apps/api/package.json
|
||
@apps/api/drizzle.config.ts
|
||
@docs/deployment.md
|
||
@.planning/todos/pending/adopt-drizzle-migrations-workflow.md
|
||
|
||
# Hard constraints (do NOT violate):
|
||
|
||
# - Do NOT renumber, delete, or regenerate any existing migration SQL file or snapshot in
|
||
|
||
# apps/api/src/db/migrations/ (including the orphan 0001_calendars_user_url_unique.sql).
|
||
|
||
# - Do NOT run `db:migrate` or `db:push` against the live/dev DB — it holds real data.
|
||
|
||
# - `drizzle-kit generate` is safe: it diffs schema.ts against the JSON snapshots in meta/,
|
||
|
||
# never the live DB. It needs no DB connection.
|
||
|
||
</context>
|
||
|
||
<tasks>
|
||
|
||
<task type="auto">
|
||
<name>Task 1: Remove the db:push script from apps/api/package.json</name>
|
||
<files>apps/api/package.json</files>
|
||
<action>Delete the `"db:push": "drizzle-kit push"` line (currently line 13) from the `scripts` block. Leave `db:generate` and `db:migrate` untouched — they are the canonical workflow. Do not change any dependency versions. Ensure the resulting JSON is valid (no trailing comma where db:push was removed; db:generate becomes the entry following test:watch/typecheck).</action>
|
||
<verify>
|
||
<automated>cd /home/luc/Projects/familysync && node -e "const p=require('./apps/api/package.json'); if(p.scripts['db:push']) process.exit(1); if(!p.scripts['db:generate']||!p.scripts['db:migrate']) process.exit(2); console.log('ok: db:push removed, generate+migrate intact')"</automated>
|
||
</verify>
|
||
<done>apps/api/package.json parses as valid JSON; `scripts.db:push` is absent; `scripts.db:generate` and `scripts.db:migrate` are present and unchanged.</done>
|
||
</task>
|
||
|
||
<task type="auto">
|
||
<name>Task 2: Repoint deployment.md to generate+migrate and warn against push</name>
|
||
<files>docs/deployment.md</files>
|
||
<action>Two edits, plus an inline warning.
|
||
(1) Step 3 "Apply the database schema" (around lines 143-152): replace the `drizzle-kit push` command on line 150 with the migrate command. The body currently reads "Bring up MariaDB and push the Drizzle schema once" — rewrite to apply committed migrations instead. The new command, preserving the existing host-side env prefix, is: `pnpm --filter @familysync/api exec drizzle-kit migrate`. Add one sentence noting that schema CHANGES are authored with `pnpm --filter @familysync/api run db:generate` (diffs schema.ts against committed snapshots, never the live DB) and committed as SQL, then applied with `db:migrate`. Keep the existing `# verify: SHOW TABLES;` line.
|
||
(2) Step 6 line 206: change "then `drizzle-kit push` once (Step 3) against the prod DB" to "then `drizzle-kit migrate` once (Step 3) against the prod DB".
|
||
(3) Add a short warning callout near Step 3 stating: do NOT use `drizzle-kit push` on this MariaDB — the mysql dialect misreads MariaDB metadata and schedules a false truncate/recreate that wipes data; always use the committed-migration path (`db:generate` to author, `db:migrate` to apply). This addresses the root-cause foot-gun so the script is not reintroduced. Do NOT alter the line "The image does not auto-migrate." — programmatic migrate-on-boot is out of scope.</action>
|
||
<verify>
|
||
<automated>cd /home/luc/Projects/familysync && grep -q 'drizzle-kit migrate' docs/deployment.md && grep -q 'db:generate' docs/deployment.md && ! grep -Eq 'drizzle-kit push|db:push' docs/deployment.md && grep -iEq 'do not.*push|never.*push|not use .*push' docs/deployment.md && echo 'ok: migrate path + warning present, no push references remain'</automated>
|
||
</verify>
|
||
<done>docs/deployment.md contains no `drizzle-kit push` / `db:push` reference; both Step 3 and Step 6 reference `drizzle-kit migrate`; an explicit warning against using push on MariaDB is present with the data-loss rationale; the "image does not auto-migrate" sentence is unchanged.</done>
|
||
</task>
|
||
|
||
<task type="auto">
|
||
<name>Task 3: Dry-verify generate produces no spurious destructive diff</name>
|
||
<files>apps/api/src/db/migrations/</files>
|
||
<action>Run `pnpm --filter @familysync/api exec drizzle-kit generate` from the repo root. This is a DRY check: generate diffs schema.ts against the committed JSON snapshots (latest is meta/0004_snapshot.json), never the live DB, so it is safe and needs no DB connection. Expected outcome against the current synced schema: "No schema changes, nothing to migrate" and NO new SQL file written. If generate DOES emit a new throwaway migration file (e.g. a fresh NNNN_*.sql plus its snapshot), inspect it: it must contain only additive DDL (CREATE TABLE / ADD COLUMN / CREATE INDEX) and NEVER `truncate`/`DROP TABLE`/`DROP COLUMN`. Whether empty or additive, this generated file is a throwaway for the dry check — delete the newly created SQL file (and its newly created snapshot in meta/, if one was added) so migration history is left exactly as found. Do NOT commit any file this step produces. Do NOT renumber or touch the pre-existing 0000–0004 files or their snapshots. Do NOT run db:migrate.</action>
|
||
<verify>
|
||
<automated>cd /home/luc/Projects/familysync && before=$(ls apps/api/src/db/migrations/*.sql | wc -l) && out=$(pnpm --filter @familysync/api exec drizzle-kit generate 2>&1) && echo "$out" && echo "$out" | grep -iqE 'truncate|drop table|drop column' && { echo 'FAIL: destructive diff detected'; exit 1; }; after=$(ls apps/api/src/db/migrations/*.sql | wc -l); if [ "$after" -gt "$before" ]; then newfile=$(ls -t apps/api/src/db/migrations/*.sql | head -1); echo "throwaway generated: $newfile — removing"; rm -f "$newfile"; newsnap=$(ls -t apps/api/src/db/migrations/meta/*_snapshot.json | head -1); fi; git -C /home/luc/Projects/familysync status --porcelain apps/api/src/db/migrations/ | grep -q . && { echo 'FAIL: migration dir left dirty'; git -C /home/luc/Projects/familysync checkout -- apps/api/src/db/migrations/; exit 1; }; echo 'ok: no destructive diff; migration history unchanged'</automated>
|
||
</verify>
|
||
<done>`drizzle-kit generate` ran and produced no truncate/drop DDL; any throwaway output was removed; `git status` on apps/api/src/db/migrations/ is clean (history identical to pre-task state). The live DB was never contacted.</done>
|
||
</task>
|
||
|
||
</tasks>
|
||
|
||
<verification>
|
||
- `git diff` touches only apps/api/package.json and docs/deployment.md.
|
||
- No file under apps/api/src/db/migrations/ is added, deleted, renumbered, or modified.
|
||
- `grep -rn "db:push\|drizzle-kit push" apps/api/package.json docs/` returns nothing.
|
||
- `pnpm --filter @familysync/api run db:generate` and `db:migrate` remain the documented path.
|
||
</verification>
|
||
|
||
<success_criteria>
|
||
|
||
- `db:push` script removed from apps/api/package.json; JSON valid; generate+migrate scripts intact.
|
||
- docs/deployment.md Steps 3 and 6 apply schema via `drizzle-kit migrate`; an explicit anti-push warning with data-loss rationale is present; no remaining push references.
|
||
- Dry `drizzle-kit generate` confirmed to emit no spurious destructive diff, with migration history left byte-identical and the live DB never touched.
|
||
</success_criteria>
|
||
|
||
<output>
|
||
Create `.planning/quick/260610-cr8-adopt-drizzle-generate-migrate-workflow-/260610-cr8-SUMMARY.md` when done
|
||
</output>
|