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

08 — Form Specifications (Reports Module)

The single form: Generate Report (S2). Fields mirror GenerateReportDto (generate-report.dto.ts:5-34). Field-level contract, validation, and conditional visibility per report type.


1. Generate report — field table

Server DTO: generate-report.dto.ts:5-34. All params @IsOptional; only type is required and enum-validated (:6-8).

FieldControlTypeRequired (DTO)Required (service)Notes
typefixed selector (from catalog)enum3 values (report-job.schema.ts:7-11)
studentIdstudent pickerMongoId✅ for report_cardreports.service.ts:91client must require
classIdclass pickerMongoIdattendance filter reports.service.ts:118
examIdexam pickerMongoId✅ for report_cardreports.service.ts:91
startDatedate pickerstring$gte filter reports.service.ts:120-121
endDatedate pickerstring$lte filter reports.service.ts:122

DTO format checks: @IsMongoId on id fields (:11-13,17-19,22-23), @IsString on dates (:27-33) — no ISO/date-format validation server-side.

2. Conditional visibility

TypeVisible fieldsHidden
report_cardstudentId, examIdclassId, dates
attendance_summaryclassId (optional), startDate, endDate (optional)studentId, examId
fee_summarynone — info cardall

Hidden fields must NOT be sent (server echoes params blindly: reports.service.ts:31-33; sending junk pollutes the job doc).

3. Client-side validation rules

  1. report_card: studentId + examId required before submit — the service fails the job asynchronously otherwise: "studentId and examId required" (reports.service.ts:91). This is the only real required rule.
  2. startDate ≤ endDate (client check; server does no comparison — reports.service.ts:119-123 builds a range regardless).
  3. Dates serialized ISO YYYY-MM-DD (server treats as strings, reports.service.ts:120-122).
  4. No duplicate submit while in flight (server has no idempotency key — each POST = new job, reports.service.ts:31-43).

4. Submit payloads (examples)

{ "type": "report_card", "studentId": "64f…", "examId": "65a…" }
{ "type": "attendance_summary", "classId": "64e…", "startDate": "2026-08-01" }
{ "type": "fee_summary" }

5. Server-side error mapping

FailureSourceClient handling
400 invalid typeDTO @IsEnum (:6-8)inline, catalog shouldn't produce it
400 malformed id@IsMongoId (:11-13)inline field error
429 rate limitglobal (00-shared/07)countdown, no auto-retry
401 expired tokenJWT guard (reports.controller.ts:9)silent refresh → resubmit
5xxfilter (http-exception.filter.ts)snackbar + form kept (re-POST safe)
job failed (async)reports.service.ts:79-82surfaced on S4, NOT the form

6. Accessibility / behavior

  • Picker fields: searchable dropdowns; semantics "select
  • Dates via AppDatePicker (00-shared/03), range constraint (2).
  • Keyboard: TextInputAction.next chain; submit on last field done (mobile).
  • Errors: inline + live-region announcement, focus first invalid field.