feat(migrations): reconcile favorites system missed by initial-schema backfill (B4) #152
No reviewers
Labels
No labels
agent-context-drift
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: rstillwell/deckhearth#152
Loading…
Reference in a new issue
No description provided.
Delete branch "convoy/reconcile-b4-favorites-system"
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?
Summary
Brief B4 of the
reconcile-historical-add-scriptsconvoy (commit22ebef2).Adds
migrations/1781000000004_reconcile-favorites-system.js, anidempotent reconciliation migration that captures the DDL effects of
the historical
scripts/add-favorites-system.jsjob (a no-go-zonescript per
.cursor/rules/no-go-zones.mdc). After this lands, abrand-new Neon branch onboarded via
npm install→npm run setup-dbhas the same
user_favoritestable + four supporting indexes thatprod has acquired via the historical script.
Shape parity
Byte-equivalent in intent to the historical script and to the runtime
API at
pages/api/favorites.js:user_favorites(id SERIAL PK, user_id INTEGER FK CASCADE, item_type VARCHAR(50) NOT NULL, item_id INTEGER NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(user_id, item_type, item_id))idx_user_favorites_user_ididx_user_favorites_item_typeidx_user_favorites_item_ididx_user_favorites_user_type(composite onuser_id, item_type)FK style follows
migrations/1779853647564_initial-schema.js(
INTEGER REFERENCES users(id) ON DELETE CASCADE).Idempotency (D2)
Every statement is guarded with
IF NOT EXISTS. Re-runningnpm run migrate upagainst any long-lived env where the historical scriptalready ran is a documented no-op — only the new
pgmigrationsrow iswritten. The
UNIQUEconstraint is declared inline on the table so itis created at the same moment as the table and never needs a separate
ADD CONSTRAINTpath.Down migration
Hard-stub throw. This is a reconciliation migration whose purpose is
to bring fresh envs to parity with prod; rolling back would drop
user_favorites(and every row in it) on whatever env it runsagainst. Removing the favorites surface deserves its own scoped
convoy that audits readers first.
Files changed
migrations/1781000000004_reconcile-favorites-system.js(new)Acceptance criteria
scripts/add-favorites-system.js(table +4 indexes) — verified line-by-line against the source script.
(
CREATE TABLE IF NOT EXISTS+ 4 ×CREATE INDEX IF NOT EXISTS).pages/api/favorites.js(polymorphic
item_type∈ {'card','collection','deck'} +polymorphic
item_id, keyed by(user_id, item_type, item_id)).1781000000004(no collision withsibling B1/B2/B3/B5/B6 timestamps per convoy § Brief outline
"Timestamp coordination").
down()is a hard-stub throw.(
files: [migrations/<ts4>_reconcile-favorites-system.js]).scripts/add-favorites-system.jsor any otherno-go-zone artifact.
Test plan
Static verification (run locally on the worktree):
node --check migrations/1781000000004_*.js→ exit 0.npm run lint→ 0 errors (baseline; 1 pre-existing warning incomponents/CollectionsPageView.jsunrelated to this change).npm run test:run→ 26 files / 131 tests pass (baseline; nonew tests needed — pure DDL reconciliation, no JS-level code).
IF NOT EXISTS; the inlineUNIQUEis created at table-creationtime so it cannot collide on re-run.
user_favoritesis not declared by any existingmigration (
migrations/grep foruser_favorites/favoritesreturns zero matches pre-this-PR).Optional Neon-branch test (per convoy § Verification plan D5) — defer
to B7's post-B1-B6 prod-vs-fresh-branch diff runbook; not blocking
this PR.
Notes
Runtime evidence audit:
pages/api/favorites.jsissues fivedistinct SQL statements against
user_favorites—SELECT(withoptional
item_typefilter),SELECTfor the duplicate-detectioncheck,
INSERT, andDELETE. Every column it references(
user_id,item_type,item_id,created_at, plusuf.*) iscovered by this migration. The polymorphic
item_idis correctlytyped as
INTEGERand joins againstcollections.id,cards.id,and
decks.id— all SERIAL PKs frominitial-schema.The
.cursor/rules/schema-map.mdc§ "Common reference" entry listsfavorites (user_id, card_id)— that's a minimal shorthand anddoes NOT match the actual prod table (
user_favorites, polymorphicon
item_type+item_id). The rule's wording will be correctedby B7 of this convoy alongside the
docs/SCHEMA_MAP.mdrefresh;this migration follows the runtime evidence.
Per convoy § Slice dependencies, this brief's
depends_on: []andthe only file in
files:is the new migration — disjoint fromB1/B2/B3/B5/B6, so the implementer dispatched in parallel with the
other briefs.
Base is
main(not the parent convoy branch) per theparallel-implementer dispatch pattern documented in the brief.
Made with Cursor
The latest updates on your projects. Learn more about Vercel for GitHub.
Pipeline Health
Build + CI gates
Build runs on Vercel; this CI runs lint and schema-map drift only (no duplicate build).
Role reports
See individual comments above for details. This rollup updates automatically.