09 — User Behaviour (Dashboard Module)
- B1 — The glance is the unit of use
- B2 — Trust decays with staleness
- B3 — Event-synchrony expectation
- B4 — Zero-reading is a real state, not an error
- B5 — Card taps expect module context
- B6 — Roles expect their own dashboard
- B7 — Periodic check-ins > continuous watching
- B8 — Offline read-over-write preference
- B9 — Trust in server, not client math
Observed behavioural patterns the design must serve, derived from the KPI payload (
dashboard.service.ts:50-70), the caching contract (Dashboard.md:41,49-52), and the WS bridge (ws-bridge.service.ts:16-22). Behavioural patterns are statements of intent, not UI rules — those are in 10_Interaction_Specification.md.
B1 — The glance is the unit of use
- Admin behaviour: read KPI row in under 10 seconds, decide, leave. The screen must paint numbers first (skeleton → values in service order), no interstitial navigation or "loading module" steps.
- Consequence: KPI cards are the first paintable content; charts below the fold are non-blocking (06_Screen_Specifications.md §1.1).
B2 — Trust decays with staleness
- Users notice when numbers stop moving. The 60 s TTL (
Dashboard.md:41) plus client cache means a payload can render minutes old. Behavioural pattern: users double-check by re-reading a card after events they know happened (a payment was just recorded). - Consequence:
StaleBannerwith age + one-tap refresh; WS events trigger silent refresh so the number visibly moves when the underlying data does.
B3 — Event-synchrony expectation
- When the user knows
AttendanceMarked/PaymentRecorded/InvoiceGeneratedjust fired (Dashboard.md:34), they expect the dashboard to reflect it within seconds. The WS bridge already broadcasts every domain event totenant:{id}(ws-bridge.service.ts:16-22;ws.gateway.ts:50). - Consequence: listen for exactly those 4 event types; debounce to coalesce bursts (a bulk attendance mark fires many events in seconds).
B4 — Zero-reading is a real state, not an error
- Fresh tenants get real zeros (
dashboard.service.ts:31-33; rate 0 at:64). Users read "0" as "nothing set up yet", not "broken". - Consequence: zero cards carry muted setup hints; the all-zero dashboard
shows one
AppEmptyStatehero (06_Screen_Specifications.md §1.3).
B5 — Card taps expect module context
- A KPI number invites drill-down (dues → which invoices?). Behavioural pattern: users tap the number, not a separate link.
- Consequence: whole
KpiCardis tappable → students list, fees invoices (filtered toissued/partial/overdue—dashboard.service.ts:36-37), attendance day view. Dashboard stays read-only; the target module owns the interaction.
B6 — Roles expect their own dashboard
- Non-admin roles today have no
dashboard.read(role.schema.ts:31,39,47,55,63) yet behave as if a dashboard exists (teachers check their attendance; accountants check dues). - Consequence
(planned): role-scoped views perIMPLEMENTATION_PLAN.md:232; UI must already structure itself as a permission-filtered widget set (Dashboard.md:52) so the finance-only accountant layout is a data-driven outcome, not a rewrite.
B7 — Periodic check-ins > continuous watching
- Users check the dashboard on a beat (morning, after classes, month-end), not continuously. Polling every 60 s while visible + WS invalidation covers the gaps; background polling is wasteful.
- Consequence: poll timer pauses when app is backgrounded or route is not the dashboard (06_Screen_Specifications.md §1.4).
B8 — Offline read-over-write preference
- Reading is tolerated offline if the last-good numbers remain visible and honest. Users prefer a stale-but-labelled number over a dead screen.
- Consequence: last-good payload +
StaleBanner/AppOfflineBanner(06_Screen_Specifications.md §1.3); no writes in the module today (08_Form_Specifications.md §4).
B9 — Trust in server, not client math
- Users (admins) know numbers are aggregated server-side. The client must
format, never recalculate — attendance rate arrives pre-rounded
(
dashboard.service.ts:57-64), dues pre-summed (:45-48). - Consequence: no client-side derivation; trend deltas only when the server
ships them
(planned)(07_Component_Library.md §2).