Narrower and more current than the FK bullet in #52, and with a hazard that one does not mention.
Problem
./buddy doctor:
✗ Database FKs 25/33 declared FKs missing from live schema:
review_photos.judge_review_id → judge_reviews.id,
review_photos.user_id → users.id,
judges.court_house_id → court_houses.id,
social_posts.user_id → users.id,
email_list_subscribers.email_list_id → email_lists.id
(+20 more). Run `buddy migrate:fresh` (will reset data) or
`buddy migrate` against a clean DB.The models declare 33 foreign keys; 25 are absent from the live SQLite schema. Note judges.court_house_id → court_houses.id is in that list — the single most load-bearing relationship in the app, across 2,740 judges and 202 courthouses.
One mitigating fact: PRAGMA foreign_key_check is clean, so there are no orphan rows today. The constraints are missing, not violated.
Why the suggested remedies are not available
buddy migrate:freshresets data. The database holds 2,740 judges and 202 courthouses ingested from CourtListener + Wikidata. Not an option.- "
buddy migrateagainst a clean DB" is the same thing by another route.
So this needs per-table rebuilds (SQLite cannot add a FK to an existing table), which is exactly what the framework's own model-migration phase attempts.
The hazard, learned the hard way
A rebuild applies every current model constraint, not just the FK. That already bit once this week: the generated court_houses rebuild carried "image" TEXT not null while all 202 rows held NULL, and failed with
NOT NULL constraint failed: _qb_tmp_court_houses.imageIt rolled back cleanly, and the fix was to correct the model (CourtHouse.image is now optional) rather than the data — the live table had always allowed NULL. Expect more of these: each table's rebuild needs its model checked against the data it already holds before it will apply.
Secondary finding, same root cause
EmailSubscription declares useUuid: true, but the email_subscriptions table has no uuid column at all. It was skipped when the 30 missing UNIQUE indexes were added, because an index cannot be created on a column that does not exist. This one needs a column, not an index.
What to do
- Enumerate the 25 from
./buddy doctor(it truncates at 5) - For each table, diff its model constraints against the rows it holds — identify the
image-shaped mismatches before running anything - Fix the model where the model is wrong; migrate the data where the data is wrong. Decide per table, do not assume the model is right
- Rebuild per table, one migration at a time, so a failure names one table
- Add the missing
email_subscriptions.uuidcolumn PRAGMA foreign_key_checkclean afterwards, and./buddy doctorFK check green
Already done in this area: 30 missing UNIQUE indexes added, 59 dead .ts migrations deleted, 33 orphaned scaffold tables dropped.