You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(cardService): wrap title + linkIds updates in single atomic transaction
updateCard previously executed card.update (title) and the cardLink delete/create cycle as two independent operations. A process crash, DB timeout, or FK violation between them left the card with a new title but stale links — a permanently inconsistent state with no rollback path.
Changes:
- Move both the card.update (title) and the cardLink.deleteMany / cardLink.createMany calls inside a single app.prisma. block so that either all changes commit or none do.
- Hoist the platformLink ownership check to before the transaction is opened, eliminating the TOCTOU window where a concurrent request could delete a platformLink between validation and createMany. Ownership validation on user-owned immutable rows is safe to perform outside the transaction.
Tests added (cards.test.ts):
- Happy path: both title and links commit in one call.
- Rollback path: createMany failure after card.update → 500, no findUnique called, both operations ran inside the same tx.
- Pre-transaction 403: foreign linkId → never called, no writes of any kind.
- Title-only update: linkIds absent → deleteMany not called.
- Links-only update: title absent → card.update not called.
0 commit comments