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

Expected behaviour patterns and the server facts that shape them. Behavior analytics (proposed) throughout; no analytics SDK in repo (00-shared/10 §8).


1. Behavioural patterns

B1 — Submit-and-watch (dominant)

User submits → lands on S4 → watches status go queued → processing → completed. Average wait: seconds (attendance/fee) to minutes (term-end card batches). Server fact: no WebSocket topic, no progress % — polling is the only mechanism (reports.controller.ts:20-24).

Implications:

  • Default poll 2 s (10); show elapsed time so the wait feels productive.
  • Do not block navigation — user can leave S4; job continues (server-owned).

B2 — Submit-and-come-back

User submits then leaves; returns later via job list. Server fact: job doc persists with params + result (report-job.schema.ts:33-36) — result is re-readable indefinitely (no TTL in schema; blueprint TTL cleanup is for files, 04-Modules/Reports.md:50).

Implication: S4 must render a terminal job from a single GET — no re-poll.

B3 — Re-run with tweaks

Completed fee summary → "New report from these params" (S4 CTA) — users regenerate monthly with same/edited params. Server: cheap, new job per POST (reports.service.ts:31-43). Form prefills from params (:33).

B4 — Failure → retry

Job failed → user retries. Server facts: error string stored (report-job.schema.ts:39, reports.service.ts:79-82); retry = new POST; known async failures: missing student/exam (:91), student not found (:94), unknown type (:75).

Implication: surface the exact error; if it says "studentId and examId required", send user to the form, not retry.

B5 — Scheduled report consumption

Daily/weekly attendance jobs (attendance-report.job.ts:13-24) appear in job list. Today there is no list API (S3 gap) and no completion notification (ReportGenerated unmapped, event-queue-map.ts) — users discover via history (forward-looking).

2. Behavioural anti-patterns to design out

Anti-patternDesign response
Double-submit → duplicate jobsdisable CTA while in flight (B1)
Staring at an eternal spinner after network lossbanner + pause polling + manual retry (S4)
Confusing failed with a server errordistinct failed state + error text + Retry vs form CTA
Expecting a PDF that doesn't existhide export CTAs until (planned) download endpoint lands
Filtering a job list that has no APIlocal history only; label clearly; no fake "all jobs" count

3. Behavioural metrics (proposed)

MetricEventTarget
Generate → completed seenreports.job.status terminal≥ 90% of polls reach terminal
Time-to-complete (per type)reports.job.status(completed) + createdAtfee/attendance < 5 s p95
Retry ratereports.job.retry< 5%
Repeat generation"new from params"≥ 20% monthly of fee summaries
Export adoptionreports.result.downloadn/a until (planned)