refactor: adopt in-TS startup-migrations as schema convention (PR #88 Phase 3)#89
Merged
petterlindstrom79 merged 1 commit intoMay 11, 2026
Conversation
…phase 3 harden) Codify the in-startup-migrations.ts pattern as the official schema-change convention for the api service. Retire the dual-track Drizzle SQL surface that misled PR #88 into a healthcheck failure. Background. PR #88 (2026-05-11) added apps/api/drizzle/0063_*.sql expecting the file to apply at deploy time. Nothing in this codebase applies Drizzle SQL files anywhere in the deploy pipeline — the Dockerfile CMD runs node dist/index.js, which calls runStartupMigrations() (in-TS blocks), which never invokes drizzle-kit migrate. The drizzle.__drizzle_migrations tracking table exists under the `drizzle` schema with 60 historical entries but its last apply was ~2026-04-04; since then, in-TS blocks have been doing the schema work. PR #88's healthcheck failed because in-TS block 0066 referenced the new column before anything created it. Phase 1 (Contain) and Phase 2 (Understand) shipped 2026-05-11. This is Phase 3 (Harden) per DEC-20260511-C. Changes - apps/api/src/lib/startup-migrations.ts — block 0066 renamed to runMigration0066_ensureEligibilityColumnAndReconcile and the SQL now starts with ALTER TABLE ADD COLUMN IF NOT EXISTS before the existing reconciliation UPDATE. Idempotent on existing prod (column already there from Phase 1 manual recovery); functional on fresh DBs. - apps/api/drizzle/ — directory deleted (63 SQL files + meta/ + README.md). - apps/api/drizzle.config.ts — deleted. - apps/api/scripts/check-migration-prefixes.mjs — deleted (vestigial with the dir gone). - apps/api/scripts/verify-migration-rename.ts — deleted (forensic script for an already-resolved 0046 collision). - .github/workflows/ci.yml — check-migration-prefixes step removed. - apps/api/package.json — db:generate/db:migrate/db:push scripts removed, drizzle-kit devDependency removed. - package-lock.json — refreshed. - apps/api/src/lib/schema-validator.ts — fix hint now points at startup-migrations.ts blocks (was: cd apps/api && npx drizzle-kit migrate). - apps/api/src/db/schema.ts — integrity_hash_status external-managed comment reworded (was referencing drizzle-kit generate). - apps/api/src/lib/startup-migrations.test.ts — BLOCKS-list assertion updated to the renamed block. - handoff/_general/from-code/2026-05-11-in-ts-migrations-convention-pr88-phase3.md — session summary + drift inventory + PR B implication note. Verification - Type-check: clean (pre-existing routes/mcp.ts strale-mcp/tools errors unchanged). - vitest: 540 passing / 11 skipped / 1 pre-existing failure (app.classify-error.test.ts, unrelated). - BLOCKS-list canonical test passes with renamed block. DEC-20260420-A (hand-written discipline) and DEC-20260420-B (schema.ts sync) are preserved — we still hand-write, schema.ts edits still ship alongside. Neither is superseded by DEC-20260511-C. Rule 11 does not fire. Closes Notion P1 To-do 35d67c87082c810bbe04e597c38f6d89 (Harden schema-migration deploy pipeline). The canonical Rule 8 in cc-prompts skill is amended in lockstep; the Notion Working rules page header references DEC-20260511-C. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2 tasks
petterlindstrom79
added a commit
that referenced
this pull request
May 11, 2026
Two reference-content handoffs from earlier 2026-05-11 sessions. Per Rule G (handoff note hygiene, DEC-20260510-A), notes with substantive "Landed" / "Outcome" / runbook content are promoted; pure session narration is deleted. Promoted: - 2026-05-11-decouple-scheduled-testing-eligible-pr-a.md (PR #88 PR A shipped state — landed-list, decisions locked, follow-ups). - 2026-05-11-haiku-cost-leak-audit-contain-cleanup.md (4-PR incident arc: #84/#85/#86/#87 with outcomes, audits, decisions). Deleted (not in this commit; rm'd locally) the third 2026-05-11 note: - 2026-05-11-pr88-deploy-recovery-and-phase3-halt.md Pure session-progress narration. Phase 3 halt was resolved by PR #89 (merged 2026-05-11); content superseded by DEC-20260511-C + PR #89's handoff note (2026-05-11-in-ts-migrations-convention-pr88-phase3.md). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
petterlindstrom79
added a commit
that referenced
this pull request
May 13, 2026
Five from-code handoffs authored during the 2026-05-13 sessions are staged but uncommitted; promoting to tracked per the standing chore PR pattern (Rule G handoff-promotion). Contents: - 2026-05-13-beacon-hosting-verification.md — verifies scan.strale.io is on Vercel, high confidence - 2026-05-13-drizzle-quirks-verification.md — original Outcome B was wrong; correction header added mid-session (PR #89 had fully shipped DEC-20260511-C; the report was reading stale branch state from the strale trunk) - 2026-05-13-lovable-cancellation-audit.md — verdict SAFE TO CANCEL; zero runtime dependencies confirmed across DNS, headers, webhooks, CI, commit activity - 2026-05-13-structural-backstops-and-readiness-audits.md — session-arc summary covering the deploy-health monitor + capabilities list↔detail contract invariant PRs - 2026-05-13-lovable-cancellation-cleanup-execution.md — session-arc summary of the cleanup PRs (#9 frontend, #105 backend) + the deploy-health monitor catching PR #9's silent CF Pages failure + the bun-lockfile hotfix (#10) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
scheduled_testing_eligiblecolumn lifecycle:ALTER TABLE ADD COLUMN IF NOT EXISTS+ existing reconciliation UPDATE. RenamedrunMigration0066_ensureEligibilityColumnAndReconcile. Idempotent on existing prod; functional on fresh DBs.apps/api/drizzle/(63 SQL files + meta + README),apps/api/drizzle.config.ts,check-migration-prefixes.mjs,verify-migration-rename.ts, the matching CI step,db:*package scripts,drizzle-kitdevDependency. Updatedschema-validator.tsfix hint andschema.tsexternal-managed comment.Why now
PR #88 (commit
cb4e8c1) addedapps/api/drizzle/0063_decouple_scheduled_testing_eligibility.sqlexpecting the file to apply at deploy time. The Dockerfile CMD runsnode dist/index.js→runStartupMigrations()(in-TS blocks) → never invokesdrizzle-kit migrate. Deploy healthcheck-failed when in-TS block 0066 referenced the missing column. Phase 1 (Contain) applied the column manually viarailway ssh; Phase 2 (Journal course-correction) named the failure pattern. This PR closes the class.Audit-phase correction (vs Phase 2 finding)
Phase 2's stated reason ("
__drizzle_migrationsdoesn't exist in prod") was wrong — the table EXISTS under thedrizzleschema (notpublic) with 60 historical entries; last applied ~2026-04-04. The conclusion (Drizzle SQL files not part of deploy pipeline; in-TS is the working convention) was correct; the reason for it was wrong. Corrected understanding actually strengthens Option B: the SQL files were a manual-run footgun (npm run db:migrateagainst prod would have hit non-idempotent DDL errors). Detailed in the handoff note.Notion
Harden schema-migration deploy pipeline→ status moved to Done.Downloads/closing-steps-checklist.mdRule 8 text updated. Chat-environment skill files (/mnt/project/SKILL.mdfamily) need a separate re-sync — not reachable from this Claude Code env. Documented in handoff.Verification
routes/mcp.tsstrale-mcp/toolserrors unchanged).app.classify-error.test.ts).ADD COLUMN IF NOT EXISTSis no-op on existing prod (column exists from Phase 1 manual recovery); reconciliation UPDATE filtersIS DISTINCT FROMso re-runs match zero rows.Closing-steps rule walk
## After deploymentmigrate step.Test plan
"column ensured; no rows to reconcile (already aligned)"(column already exists in prod from Phase 1)/health/deepreturns 200🤖 Generated with Claude Code