⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
src/db/repositories.ts:2239-2256's .orderBy(desc(notificationDeliveries.createdAt)) (line 2253) has no secondary sort key. evaluateAndEnqueueNotificationDeliveries (src/notifications/service.ts:214-232) loops over a batch of events (e.g. an issue_watch_match fan-out to many miners) calling insertNotificationDeliveryIfAbsent, which stamps createdAt via nowIso() per call -- several rows in one fan-out can share an identical millisecond timestamp. Display order (and the limit-boundary row) is therefore undefined for tied rows -- same bug class as the ai_review_cache tiebreak issue.
Requirements
Add , desc(notificationDeliveries.id) (or an equivalent monotonic tiebreaker) to the orderBy clause in listNotificationDeliveriesForRecipient.
Deliverables
All of the above Deliverables are required in the same PR unless the deliverable text itself states otherwise.
Test Coverage Requirements
src/** -- 99%+ patch coverage, branch-counted, including the new tiebreak test.
Expected Outcome
The notification badge feed returns a deterministic, stable order even when a fan-out produces multiple deliveries within the same millisecond.
Links & Resources
src/db/repositories.ts:2239-2256
src/notifications/service.ts:214-232
Context
src/db/repositories.ts:2239-2256's.orderBy(desc(notificationDeliveries.createdAt))(line 2253) has no secondary sort key.evaluateAndEnqueueNotificationDeliveries(src/notifications/service.ts:214-232) loops over a batch of events (e.g. anissue_watch_matchfan-out to many miners) callinginsertNotificationDeliveryIfAbsent, which stampscreatedAtvianowIso()per call -- several rows in one fan-out can share an identical millisecond timestamp. Display order (and thelimit-boundary row) is therefore undefined for tied rows -- same bug class as theai_review_cachetiebreak issue.Requirements
Add
, desc(notificationDeliveries.id)(or an equivalent monotonic tiebreaker) to theorderByclause inlistNotificationDeliveriesForRecipient.Deliverables
listNotificationDeliveriesForRecipient's query includes a monotonic tiebreaker aftercreatedAtcreatedAt, asserting stable, deterministic orderAll of the above Deliverables are required in the same PR unless the deliverable text itself states otherwise.
Test Coverage Requirements
src/**-- 99%+ patch coverage, branch-counted, including the new tiebreak test.Expected Outcome
The notification badge feed returns a deterministic, stable order even when a fan-out produces multiple deliveries within the same millisecond.
Links & Resources
src/db/repositories.ts:2239-2256src/notifications/service.ts:214-232