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

03 — User Journey (Reports Module)

End-to-end journeys through the async generate → poll → view/download flow. All three journeys share the same server contract: POST /reports/generate{jobId, status:'queued'} (reports.service.ts:28-44), then poll GET /reports/:jobId (reports.service.ts:46-50) until completed/failed (report-job.schema.ts:13-18).


J1 — Generate a fee summary (Org Admin / Accountant)

  1. Entry: Dashboard → "Reports" → "New report".
  2. Form: select type fee_summary; no required params (generate-report.dto.ts:6-33 — all params optional).
  3. SubmitPOST /reports/generate (reports.controller.ts:14-18).
    • Success: navigate to Job detail with jobId, status queued.
    • Error 400/429/5xx: inline error, form preserved.
  4. Poll: client polls GET /reports/:jobId every 2 s (reports.service.ts:46-50).
  5. Completed: result card with totalInvoices, totalCollected, totalPending, totalOverdue (reports.service.ts:154-158); CTA "Download CSV" (planned).
  6. Failed: status failed with error (report-job.schema.ts:39); CTA "Retry" = re-POST same params (new job) — reports.service.ts:31-41.
  7. Exit: back to job list; job persists for later reads.

Happiness metric: request → visible progress < 1 s; result < 5 s.

J2 — Generate an attendance summary for a class (Teacher)

  1. Entry: Reports catalog → attendance_summary template.
  2. Form: classId optional, startDate/endDate optional (generate-report.dto.ts:17-33); no dates = all records (reports.service.ts:117-123).
  3. Submit/poll as J1.
  4. Completed: summary of counts per attendance status (reports.service.ts:126-129) + total + period (reports.service.ts:131-136).
  5. View: status-pie (present/late/absent/excused) + totals.
  6. Edge: empty range → {total: 0, summary: {}} — render empty state, no error.

J3 — Generate a report card (Teacher / Principal)

  1. Entry: Student profile → "Report card" → prefill studentId.
  2. Form: studentId + examId required by the service, not the DTO — missing → job failed with error: "studentId and examId required" (reports.service.ts:91). DTO only enforces Mongo-Id format (generate-report.dto.ts:11-13,22-23). Client MUST validate presence before POST (gap flagged in 08).
  3. Submit/poll as J1.
  4. Completed: card data — studentName (note: currently the admission number, reports.service.ts:98), subjects[], totalMarksObtained, totalMaximumMarks, percentage, grade (reports.service.ts:96-107). Grade bands A+…D from result.service.ts:130-136.
  5. View: subject table + grade badge; "Share as PDF" (planned) — the blueprint's PDF export does not exist yet.
  6. Student not foundfailed with error: "Student not found" (reports.service.ts:94); UI shows retry.

J4 — Scheduled report lands in job list (any role with report.read)

  1. Entry: scheduler fires daily/weekly attendance report (attendance-report.job.ts:13-24) — actorId: 'scheduler'.
  2. Job appears in the shared job list with source badge "Scheduled".
  3. User polls/opens as J1 — no difference in contract (reports.service.ts:52-83).
  4. (forward-looking): notification on completion via ReportGenerated event (04-Modules/Reports.md:33) — no queue mapping today (event-queue-map.ts has no report route).

Journey map

flowchart LR
  A[Catalog] --> B[Generate form]
  B -->|POST generate| C[Job detail queued]
  C --> D{GET jobId poll 2s}
  D -->|processing| D
  D -->|completed| E[Result view]
  D -->|failed| F[Error + retry]
  E --> G[Download (planned)]
  F --> B

Common failure paths

PathServer behaviorClient UX
Invalid type400 (enum validation, generate-report.dto.ts:6-8)inline field error
Unknown jobId404 Report job not found. (reports.service.ts:48)"not found" state, back to list
Worker crash mid-jobjob stays processing (no timeout/requeue in code)stale spinner; QA item in 14
Duplicate submitnew job per POST (no idempotency key)disable submit while in flight