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
notificationStore.markAllRead receives only { markedCount } from the server, then marks every currently rendered matching notification as read when the response settles. A notification inserted into local state after the server selected its unread rows can therefore be marked read in the client even though it remains unread in persistence.
This is a source-backed follow-up to #3339 / PR #3340. The existing realtime-oriented store tests explicitly treat local notification insertion as a supported state transition, even though the current product lacks a user-level live channel.
Reachable schedule
markAllRead(boardId?) starts.
The backend calls GetUnreadByUserIdAsync, marks that bounded set, saves, and returns only the count.
Before the HTTP response settles in the client, a new notification enters the local collection through a concurrent authoritative load or future/live delivery.
The current response handler maps the collection as it exists at settlement and marks the new item read.
Client and server now disagree; a later refresh makes the notification appear unread again.
The board-scoped path has the same problem for a new notification on the matching board.
Expected contract
Choose and test one honest boundary:
Preferably return the committed notification IDs, or an equivalent server-issued cutoff/version, and update exactly that set; or
as a bounded client-only correction, snapshot matching stable IDs before transport and mark only that snapshot on success. This may conservatively leave a server-marked concurrent arrival unread locally until refresh, but must never invent a read that the server did not confirm.
Whichever design is used:
post-request arrivals remain unread unless explicitly confirmed by the server;
API/OpenAPI tests are updated if the response contract changes.
Exact-head frontend/backend CI and independent review pass.
Boundaries
No reminder/email implementation, no new realtime channel, and no claim of exactly-once delivery. This issue is only about honest reconciliation of the existing mark-all mutation.
Summary
notificationStore.markAllReadreceives only{ markedCount }from the server, then marks every currently rendered matching notification as read when the response settles. A notification inserted into local state after the server selected its unread rows can therefore be marked read in the client even though it remains unread in persistence.This is a source-backed follow-up to #3339 / PR #3340. The existing realtime-oriented store tests explicitly treat local notification insertion as a supported state transition, even though the current product lacks a user-level live channel.
Reachable schedule
markAllRead(boardId?)starts.GetUnreadByUserIdAsync, marks that bounded set, saves, and returns only the count.The board-scoped path has the same problem for a new notification on the matching board.
Expected contract
Choose and test one honest boundary:
Whichever design is used:
Acceptance
Boundaries
No reminder/email implementation, no new realtime channel, and no claim of exactly-once delivery. This issue is only about honest reconciliation of the existing mark-all mutation.