04 — Information Architecture (Attendance Module)
- 1. Position in the app shell
- 2. Attendance IA tree
- 3. Navigation model (per
00-shared/05 §3) - 4. Routing table (module)
- 5. Cross-links (inbound/outbound)
- 6. Modal hierarchy (per
00-shared/05 §5) - 7. Quick actions & FABs
- 8. Role → surface map
Where attendance screens live in the app shell (00-shared/05), what links into them, and what they own. Role gating derives from
role.schema.ts:8-65andpermissions.constants.ts:29-30,39-43; routes usestudylyon://deep-link convention (00-shared/05 §4).
1. Position in the app shell
Attendance is a top-level destination /attendance for teacher and admin
(00-shared/05 §2); default landing for teacher = "Attendance/Today" (00-shared/05 §2).
Parents/students reach attendance through the student profile surface (S7), not the
top-level tab.
AppShell (role-aware, 00-shared/05 §1)
├─ /home Dashboard (admin) / Home (teacher)
├─ /attendance ATTENDANCE MODULE (this doc) — teacher, admin
├─ /students student profile → S7 Attendance tab
├─ /reports admin → S5 Monthly report entry (proposed)
└─ /notifications parent alert deep-link → S7 day view
2. Attendance IA tree
/attendance
├─ S1 Today's roster — my classes → pick class (default today)
│ └─ S2 Marking grid — roster rows × StatusChip
│ ├─ S3 Batch edit sheet — multi-select → one status for N rows
│ └─ StatusChip popover — per-row: 6 statuses + checkIn/checkOut/remarks
├─ S4 History / calendar — pick class, month → heatmap → day detail
├─ S5 Monthly report — class × range → summary + report job (admin)
│ └─ S6 Report detail — per-status breakdown + drill to S4/S7
└─ S8 Biometric device status — devices, last punch, ingest trend (admin/operator)
/students/:id → S7 Student attendance profile tab (self: student, child: parent)
/notifications → absent alert → studylyon://attendance/:date (parent)
Screen numbering matches 05_Screen_Inventory.md.
3. Navigation model (per 00-shared/05 §3)
- Phone:
/attendancestack: S1 → S2 → S3 (sheet, half-height); S4/S5 tabbed or pushed from S1 context menu; S8 pushed from S1 app-bar menu. - Tablet/desktop: master-detail — left: class + month list; right: S2 grid or S4
heatmap (≥ 840 dp,
02_Design_Tokens.md §8). - Tabs within attendance (teacher):
Today(S1) ·History(S4) ·Devices(S8, admin only) —AppTabs(00-shared/03). - Breadcrumbs (desktop only): Attendance › Class › Date.
4. Routing table (module)
| Route | Screen | Guard |
|---|---|---|
/attendance | S1 Today's roster (default today) | attendance.mark (teacher) or student.read+report perms (admin) |
/attendance/class/:classId/date/:date | S2 Marking grid (read/mark) | attendance.mark (read: student.read) |
/attendance/class/:classId/history | S4 History/calendar | attendance.mark / attendance.edit |
/attendance/class/:classId/report/:month | S5 Monthly report | report.generate/report.read (admin) |
/attendance/reports/:jobId | S6 Report detail | report.read |
/attendance/devices | S8 Biometric device status | biometric.device.manage / biometric.log.read |
/students/:id → tab attendance | S7 Student attendance profile | student.read (OQ-7) |
studylyon://attendance/:date | Deep link → S7 day view (parent alert) | student.read (OQ-7) |
Guard model: route guards check user.permissions; server remains authoritative
(00-shared/05 §9, 00-shared/06 §5 — 403 → permission screen or hidden destination).
Note: backend has no per-endpoint RBAC metadata on attendance yet (OQ-5) — client gating
must not promise 403 where server might 200.
5. Cross-links (inbound/outbound)
| From | To | Why |
|---|---|---|
| Home dashboard KPI ("Today: 94% present") | S2 grid for the class | KPI from dashboard.service.ts:54-65 |
| Timetable class card | S2 "Mark attendance" (from docs/user-flows/END_TO_END_USER_FLOWS.md:27) | Daily teaching flow |
| S2 grid | Students module (student profile) | view student, check context |
| S4 heatmap day | S2 grid for that date | day drill-down (read mode) |
| S5 report | S4/S7 | investigate an anomaly |
Notifications (absent alert, (planned)) | S7 day view | parent sees the day |
Organization settings (attendance {gracePeriod,lateThreshold,...}) | S2 late chip behavior (planned) — embedded settings exist (organizations/update-organization-settings.dto.ts:8, organizations/schemas/organization.schema.ts:98) but attendance service does not consume them today (OQ-8) | future late-threshold logic |
6. Modal hierarchy (per 00-shared/05 §5)
- Snackbar — "Marked absent" / "Saved (3)" / undo.
- Bottom sheet — S3 batch edit, StatusChip popover (half-height), date/class pickers.
- Dialog — confirm bulk "Mark 34 as absent?" when selection is large (> 10, or leaving grid with unsaved offline queue); destructive confirms only.
- Full-screen — S6 report detail; S8 device add/edit
(planned). - Loader — only grid refresh when nothing cached; skeletons otherwise.
7. Quick actions & FABs
- FAB on S1/S2: "Mark attendance" (opens S2 for default class/date) — one FAB per screen
(
00-shared/05 §7). - Context menu on S2 row: edit details (checkIn/checkOut/remarks), view student, copy.
- Swipe on S4 day cell: mark-as-present/late quick fix (desktop: right-click).
- Keyboard (desktop):
P/A/L/H/V/Dcycle status on focused row (see10_Interaction_Specification.md).
8. Role → surface map
| Surface | Teacher | Admin | Parent | Student | Operator |
|---|---|---|---|---|---|
| S1/S2 Today's roster + grid | ✅ mark | ✅ | — | — | — |
| S3 Batch edit | ✅ | ✅ | — | — | — |
| S4 History/calendar | ✅ | ✅ | — | — | — |
| S5/S6 Reports | ❌ (report perms not seeded for teacher) | ✅ | — | — | — |
| S7 Student profile | ✅ (own class) | ✅ | ✅ child | ✅ self | — |
| S8 Device status | — | ✅ | — | — | ✅ |
Teacher has no report.* permission (role.schema.ts:31) — S5/S6 are admin-only today
(OQ: confirm if teacher monthly view should be granted report.read).