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 (Dashboard Module)

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: StaleBanner with 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 / InvoiceGenerated just fired (Dashboard.md:34), they expect the dashboard to reflect it within seconds. The WS bridge already broadcasts every domain event to tenant:{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 AppEmptyState hero (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 KpiCard is tappable → students list, fees invoices (filtered to issued/partial/overduedashboard.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 per IMPLEMENTATION_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).