04 — Information Architecture (Exams Module)
- 1. Placement in global nav
- 2. Information hierarchy
- 3. Screen tree
- 4. Route map (forward-looking Flutter routes)
- 5. Navigation rules
- 6. Content model (from schemas)
- 7. Naming conventions
- 8. Empty & edge IA states
App IA for the Exams module on top of the global structure in 00-shared/05_Global_Information_Architecture.md. The exams feature is a vertical slice under Academics: list → detail → slot → marks, with a read-only Results branch for students/parents. All routes are forward-looking client routes.
1. Placement in global nav
- Teachers / coordinator / admin:
Academics → Exams(list, detail, slot marks, publish) andAcademics → Results(report cards). - Student / parent:
My School → Results(own marks + report cards). No exam planning surfaces — read-only branch of the same endpoints (GET /results/student/:studentId,GET /results/report-card/:studentId/:examId,result.controller.ts:16-37). - Permission gating: server RBAC
(planned)—exam.*/result.*permissions not yet seeded (permissions.constants.ts:1-97, see 01_Product_Overview.md §10 OQ-4). Client gates by role claim; server authoritative when RBAC lands.
2. Information hierarchy
Academics
└── Exams (S1 — list)
└── Exam Detail (S2)
├── Slot Detail / Marks Entry (S3 — per subject slot)
│ └── (roster rows = Students module by classId)
├── Add Subject Slot (S4 — form, from detail FAB)
└── Publish (S5 — dialog, from detail action bar)
Results (shared read branch)
└── Student Results (S6 — marks list by studentId)
└── Report Card (S7 — per student+exam)
3. Screen tree
S1 Exams List ──tap row──▶ S2 Exam Detail
│ ▲ (FAB "New exam" → S8 Create Exam form)
│ │
│ └──(edit)──▶ S8 Create/Edit Exam form (S8a edit: same form, PATCH)
│
S2 Exam Detail
├── tap slot ──▶ S3 Marks Entry
├── FAB "Add subject" ──▶ S4 Add Subject Slot form
├── action "Publish" ──▶ S5 Publish confirm dialog
└── action "Edit"/"Delete" ──▶ S8a / confirm
S6 Student Results ──tap exam row──▶ S7 Report Card
4. Route map (forward-looking Flutter routes)
| Route | Screen | Guard (target (planned)) |
|---|---|---|
/exams | S1 Exams List | exam.read |
/exams/:examId | S2 Exam Detail | exam.read |
/exams/:examId/slots/:slotId/marks | S3 Marks Entry | exam.mark |
/exams/:examId/slots/new | S4 Add Subject Slot | exam.update |
/exams/new · /exams/:examId/edit | S8 / S8a Create/Edit Exam | exam.create / exam.update |
/results | S6 Student Results (mine) | result.read |
/results/:examId/report-card | S7 Report Card (mine) | result.read |
Deep links studylyon://exams/:id, studylyon://exams/:id/slots/:slotId/marks,
studylyon://results/:examId — (forward-looking), no notification payload defines
them yet (only results-published in-app job exists, event-queue-map.ts:27).
5. Navigation rules
- Depth: list → detail → slot marks = 3 levels, the max allowed
(
00-shared/05 §4); marks entry is a page, not a deeper sheet. - Return semantics: marks screen back = save-in-progress banner if unsaved edits; publish dialog is modal and non-dismissable on confirm (progress state).
- Tabs: no module-local tabs on the list (single dimension: exams). The detail uses one segmented control: Schedule (slots) / Coverage (marks status per slot — computed from slot results counts).
- Cross-links: slot rows link to the Class (Students module roster) and Subject
(Academics module) — resolved names,
(forward-looking)module deps.
6. Content model (from schemas)
| Entity | Source | Key fields exposed |
|---|---|---|
| Exam | examination.schema.ts:9-36 | academicYearId, name, type (5-value enum), startDate, endDate, status (4-value enum), gradingSchemeId? |
| Subject slot | examination-subject.schema.ts:9-31 | examinationId, subjectId, classId, date, startTime/endTime (HH:mm strings), maximumMarks, passingMarks |
| Mark/Result | examination-result.schema.ts:9-25 | studentId, examinationSubjectId, marksObtained?, grade?, remarks?, publishedAt? |
| Report card | result.service.ts:8-26 | subjects[] (subjectId, subjectName=raw id, marksObtained, maximumMarks, grade?, remarks?), totalMarksObtained, totalMaximumMarks, percentage, overallGrade, generatedAt |
7. Naming conventions
- Plural nouns for lists (
examinations,subjects), singular for detail (examination,subject); status labels in sentence case (Unit test,Final exam); slot label pattern:Subject · Class · date HH:mm–HH:mm.
8. Empty & edge IA states
- No exams: list empty state + "New exam" CTA (create-first design).
- Exam with no slots: detail shows empty schedule + "Add subject" CTA; report
card from such an exam → server 404 "No subjects found for this examination."
(
result.service.ts:51-53) — client shows "No subjects scheduled yet". - Slot with no marks: marks screen empty state (roster unloaded).
- Deleted/cross-tenant: 404 → auto-return to list with snackbar
(
examination.service.ts:63, 87, 101, 144).