bug-attachment-fk-migration-drift Every `prisma migrate dev` re-proposes dropping the hand-managed attachment FK
Type: bug · Parent: Epic 3 · Discovered in: Subtask 3.3.2 (board swimlaneGroupBy enum + migration) · Root cause owned by: Story 2.3.7 (the attachment table + add_attachment_and_rls migration) · Status: open.
There is persistent drift between prisma/schema.prisma and the migration history on main: the attachment table carries an attachment_uploader_user_id_fkey foreign key created in raw SQL by 20260603120000_add_attachment_and_rls, but the Prisma model Attachment deliberately declares uploaderUserId as a plain scalar with no Prisma @relation (so the User model needs no back-relation — see the model comment). Because the FK exists in the migration-built shadow DB but NOT in the schema graph, every prisma migrate dev invocation auto-generates a spurious ALTER TABLE "attachment" DROP CONSTRAINT "attachment_uploader_user_id_fkey"; at the top of the new migration.
Impact. It is a recurring foot-gun, not a runtime bug: any author who runs migrate dev and commits the generated SQL verbatim will silently drop a real FK (losing referential integrity on attachment.uploader_user_id). Each migration must be hand-curated to delete that line — 3.1.1 (boards) and 3.3.2 (swimlane enum) both had to. It also makes migrate dev output noisy and easy to misread.
Repro: on main, edit any model in prisma/schema.prisma, run pnpm prisma migrate dev --name probe, and observe the generated migration begins with a DROP CONSTRAINT "attachment_uploader_user_id_fkey" unrelated to the edit.
Fix options (decide at fix time):
- Model the relation in Prisma — add the
uploader User @relation(...)(+ theUserback-relation) so the schema graph matches the DB, eliminating the diff. This is the clean fix but adds the back-relation the 2.3.7 comment intentionally avoided; weigh that trade-off. - Drop the FK from the DB too and rely on the application layer (mirrors how some other scalar FKs are handled) — only if the referential guarantee is not wanted.
Either way, land a corrective migration so the schema and migration history agree and
migrate devstops re-proposing the drop. Until then, every migration PR must curate the spuriousDROP CONSTRAINTline out (note it in the migration header, as 3.3.2 did).
Acceptance criteria
pnpm prisma migrate devon an otherwise-unchanged schema produces no migration (empty diff) — i.e. no spuriousattachment_uploader_user_id_fkeydrop.- The chosen fix lands as one corrective migration that applies cleanly on a fresh DB and is idempotent;
attachment.uploader_user_idintegrity ends up in the intended state (FK kept-and-modeled, or intentionally dropped — whichever option is chosen). - A short note in
motir-core/CLAUDE.md(migration conventions) records the decision so the pattern is not reintroduced.
Context refs
prisma/schema.prisma— theAttachmentmodel (uploaderUserIdscalar, no relation) + theUsermodelprisma/migrations/20260603120000_add_attachment_and_rls/migration.sql— where the FK is created in raw SQL (Story 2.3.7)- 3.3.2 feature PR — the curated migration whose header documents this drift;
motir-core/CLAUDE.md— migration conventions