fix(03): WR-04 rank failed/dead outbox row above done in sync-status

This commit is contained in:
Lucas Berger
2026-06-09 11:04:00 -04:00
parent 5b720ffdb8
commit fd13852eb9
2 changed files with 53 additions and 1 deletions
+13 -1
View File
@@ -529,6 +529,14 @@ eventsRouter.get('/sync-status', zValidator('query', syncStatusQuerySchema), asy
try {
// Scope strictly to current member's rows (T-03-07 — never leak another member's outbox).
//
// WR-04: rapid successive same-uid edits enqueue multiple outbox rows. A plain
// "newest row" pick (ORDER BY createdAt DESC LIMIT 1) reports only the latest row's
// status — so if the newest succeeds but an older row dead-lettered, the user sees
// "Saved" while a queued write silently failed. Rank an unsettled/failed row ABOVE a
// done row: a row in pending/failed/dead for the uid outranks a done row, and only
// among same-priority rows do we fall back to newest-first. This surfaces a failure
// for ANY row of the uid instead of masking it behind a later success.
const rows = await db
.select({
uid: calendarOutbox.uid,
@@ -537,7 +545,11 @@ eventsRouter.get('/sync-status', zValidator('query', syncStatusQuerySchema), asy
})
.from(calendarOutbox)
.where(and(eq(calendarOutbox.userId, currentUserId), eq(calendarOutbox.uid, uid)))
.orderBy(desc(calendarOutbox.createdAt))
// status priority: failed/dead first, then pending, then done.
.orderBy(
sql`case ${calendarOutbox.status} when 'failed' then 0 when 'dead' then 0 when 'pending' then 1 else 2 end`,
desc(calendarOutbox.createdAt),
)
.limit(1)
if (!rows.length) {