Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

09 — User Behaviour (Notifications Module)

Behavioural patterns observed/assumed for the inbox, grounded in the API contract (notifications.controller.ts) and the event fan-in (notifications.handler.ts).


1. Badge-First Behaviour

  • Users judge the inbox by the badge number before opening it; they expect the number to equal what the list shows. Contract requirement: unread-count (controller.ts:31-35) must agree with the count of readAt == null rows in the list — same source collection, same filter (repository.ts:31-35 vs repository.ts:45-50), so it is consistent by construction. Client must still reconcile after mark-read mutations (see 13_State_Management).

2. Read-on-Tap

  • Typical pattern: tap item → mark read → return. The read flag must update optimistically on the tile and the badge; server 200 null (foreign id) must not crash the tile (service.ts:54-59).

3. Mark-All-Read Session

  • Users batch-clear the inbox when unread exceeds ~10. After read-all, they expect the badge to drop to 0 immediately; partial failures are invisible server-side (bulk update has no per-item error — repository.ts:45-50). Client treats the response as success if the request succeeds.

4. Ordering Expectation

  • Users read newest-first and assume page 1 = today's items. Server sorts createdAt: -1 (repository.ts:66); never client-sort.

5. Notification Fatigue (planned-feature guard)

  • Per docs/IMPLEMENTATION_PLAN.md:769 coaching tenants will generate high-volume events (test reminders, DPP due alerts, batch starts). Without per-type preferences (Notifications.md:27-28(planned)) the inbox will flood. V1 mitigation: only four account-lifecycle events are wired today (handler.ts:8-50) — the event map is the volume governor. Add prefs before fanning out homework/exam events (14_QA_Checklist §G).

6. Time Perception

  • Relative timestamps ("5m ago") dominate; absolute timestamps only in accessibility text. Derived from createdAt (timestamps: true, schema:14).
  • Users expect a notification tap to open the thing it announces. Today data is the raw event payload (handler.ts:96 — e.g. { userId }), with no targetUrl convention. Until v2 defines data.targetUrl, most taps only mark read — acceptable for v1 account-lifecycle content (welcome/verify/reset).

8. Error Resilience

  • Users retry after transient failures; pagination failure must not nuke the loaded list (footer retry, 06 §1.4). Offline first-load shows cached copy when available (00-shared/06 hydration).