Skip to content

Notification preference saves can commit and settle out of user order #3341

Description

@Chris0Jeky

Summary

notificationStore.updatePreferences starts every save immediately. The API carries no expected revision, and NotificationPreferenceConfiguration does not configure UpdatedAt or another field as a concurrency token. Two saves from one client can therefore commit or settle in an order different from the user’s submissions.

This is a source-backed follow-up to #3339 / PR #3340. It should be implemented as a stacked child only after the parent’s read/session ownership contract is stable.

Reachable race

  1. Submit preference set A.
  2. Before A settles, submit preference set B.
  3. Both PUT requests run concurrently against the same unique user preference row.
  4. Server commit order and HTTP response order are unconstrained.
  5. The client assigns every response to preferences, so an older intent can finish last and appear authoritative. The persisted server row may also reflect the opposite order from the UI.

There is no request version or If-Match field to resolve this after the fact.

Expected contract

  • One preference-mutation lane preserves submission order for this client.
  • The first save starts transport immediately; later saves wait for their predecessor.
  • A failed predecessor does not cancel the next submitted save.
  • Queued saves hold truthful loading ownership from submission through settlement.
  • Immediately before transport, queued work rechecks the credential epoch established by Notification reads can overwrite confirmed or replacement-session state #3339; pre-refresh/logout intent cannot run with later credentials.
  • A queued save clears an error only if that receipt belongs to its own predecessor, never an independent inbox operation.
  • Successful saves retain Notification reads can overwrite confirmed or replacement-session state #3339’s preference-read invalidation.

This client queue does not solve cross-device concurrency. A future server-side revision contract may still be warranted.

Acceptance

  • Deferred Pinia regression for two preference saves whose uncoordinated transports would settle in reverse order.
  • First transport starts synchronously; second does not start before the first settles.
  • Failed-predecessor continuation.
  • Queued old-credential intent is dropped before transport after token rotation.
  • Loading remains true while queued work exists.
  • An inbox failure that occurs while the preference save waits is not erased by queued start.
  • Existing preference view/store tests and Notification reads can overwrite confirmed or replacement-session state #3339 ownership tests remain green.
  • Exact-head frontend/full CI and independent review pass.

Boundaries

No automatic retries, backend schema change, cross-device ordering claim, or notification-feature expansion. Keep this separate from mark-all/read semantics and reminder/email epic #2010.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfrontendPrimary implementation impact in Vue/TypeScript UI and client runtime.

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions