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

14 — QA Checklist (Attendance Module)

Module-specific checklist layered on 00-shared/10_QA_Baseline.md + 00-shared/09 accessibility baseline. Every item is testable; backend-rule items cite the source line.


1. Data correctness — uniqueness & upsert

  • Marking the same student+date twice → one doc, second write overwrites (attendance.repository.ts:23-29); grid shows single chip state, no duplicates.
  • Unique index {tenantId, studentId, date} (attendance.schema.ts:59-62) enforced: two concurrent POSTs for same student+date → one doc, other gets 409 or converges.
  • Same student marked from a second class on the same date → original classId is retained (attendance.repository.ts:29-33); grid shows "already marked in Class A" tooltip.
  • Batch: N records → N docs, order preserved; one AttendanceMarked event per record (attendance.service.ts:48-54).
  • PATCH sends only changed fields: unchanged fields untouched ($set, base.repository.ts:57-66); version increments on every update.
  • PATCH status with valid enum values only (OQ-6: server does not validate — client enforces; test that UI cannot submit invalid).
  • Cross-tenant: reading another tenant's record id → 404 RESOURCE_NOT_FOUND (scoped filter, base.repository.ts:20-30), no existence leak.

2. Edit-after-notification / correction flows

  • Correct a record after a notification was sent (when dispatch (planned) lands): PATCH works on the same doc id; AttendanceUpdated {changes:[...]} emitted (attendance.service.ts:88-99).
  • Wrong-date fix: mark correct day; wrong-day record found in S4 day view; PATCH to correct status; no delete endpoint exists (OQ-11) — verify the "holiday/remark" guidance is reachable.
  • Undo: UndoBar re-sends previous status; after 4 s it's gone; grid reflects server state after refresh.

3. Timezone & date handling

  • date sent as YYYY-MM-DD in tenant-local calendar day — client never sends UTC-shifted dates (mark-attendance.dto.ts:21; stored as Date attendance.schema.ts:31-32).
  • Marking at 23:50 local ≠ next-day doc; at 00:10 local ≠ previous-day doc.
  • checkIn/checkOut ISO-8601 with correct timezone offset survive round-trip (attendance.service.ts:32-33).
  • DST boundary day: month heatmap has 28/29/30/31 days correctly (client month-math); server stores UTC, client displays local.
  • Scheduler context: attendance-report-daily 07:00 UTC (scheduler.service.ts:99-104) — report periods use UTC boundaries; UI must not imply tenant-local "7 AM" semantics.

4. Large-class & performance

  • 60+ student class: grid scrolls at 60 fps (0 dropped frames profiled — 00-shared/10 §1); ListView.builder + itemExtent verified.
  • Month heatmap (S4, 30 fan-out day fetches) shows skeleton first, fills as days arrive; cache prevents refetch on month switch.
  • Bulk of 60 records: request completes < 5 s (sequential server loop, attendance.service.ts:48-54); UI shows progress, not freeze.
  • GET /attendance/summary on a full term returns within budget or shows progressive loading (in-memory aggregation, attendance.service.ts:103-113 — OQ-8).
  • Report job: no request timeout during queued/processing; polling capped; UI terminal on completed|failed (report-job.schema.ts:13-18).

5. Offline marking

  • Airplane mode: cached roster renders, AppOfflineBanner shown, marks queue locally, rows flagged dashed+cloud (00-shared/10 §2; 13_State_Management.md §4).
  • Kill app offline → relaunch → queue intact (persisted Hive box).
  • Reconnect: auto-flush, Idempotency-Key per op, snackbar "Synced N marks".
  • Retry: idempotent — a duplicate flush does not create duplicates (upsert).
  • Offline collision (server has newer data): 409/conflict preview sheet; user chooses overwrite or discard; no silent data loss.
  • Offline PATCH correction: blocked (pessimistic policy, 13 §3) with guidance.

6. Idempotent retries & partial failures

  • Double-tap submit on chip → one request (anti-double-submit, 00-shared/08 §6).
  • Bulk partial failure simulation (server down mid-loop): failed subset retried alone; no duplicates for the succeeded subset.
  • Worker bulk-import behavior (OQ-2): per-record failures swallowed → if surfaced in UI later, failure report matches actual saved count (attendance.worker.ts:91-101).
  • 409 on single mark → grid refresh, no ghost chip.

7. Permissions & roles

  • Teacher (role default ['student.read','attendance.mark','attendance.edit'], role.schema.ts:31): can mark + correct; cannot see S5/S6 reports (no report.*, role.schema.ts:31) — verify server-side response & hidden UI.
  • Parent/student (no attendance perms, role.schema.ts:55,63): S7 read-only per OQ-7 decision; test 403 handling once server enforces.
  • All write endpoints reject requests from tokens lacking attendance.mark/editcurrently not decorator-enforced (OQ-5): assert current behavior and track.
  • 403 vs 404: cross-tenant read = 404; same-tenant wrong role = 403 (if enforced) — UI matches (00-shared/06 §5).

8. Biometric integration

  • POST /biometric/ingest with valid {studentId, deviceId, timestamp} → 201 log doc; no attendance doc created (current behavior — OQ-3); S8 shows "captured, not applied" honestly.
  • Invalid studentId → 400 VALIDATION_ERROR (@IsMongoId, create-biometric-log.dto.ts:7).
  • Device status mapping: active/inactive/offline (biometric-device.schema.ts:7-11); "active but no punches 24 h" warning.
  • Biometric-sourced docs (when pipeline (planned) lands): source:'biometric' (attendance.schema.ts:16-21) displayed in S7 day detail.

9. Accessibility (module additions to 00-shared/09 §12)

  • Grid: TalkBack/VoiceOver full marking flow without sight; chips announce status + "double-tap to change"; count bar live region.
  • No color-only status anywhere (icons + labels; 00-shared/09:76).
  • Keyboard-only: P/A/L/H/V/D shortcuts, Esc selection exit, focus ring visible.
  • Text scale 2×: chips collapse gracefully; heatmap readable; no clipped rows.
  • Conflict banner announced; undo announced; haptics off in reduced-motion.

10. Localization & formatting

  • Status labels/i18n keys (att.status.*); date formats via Intl tenant locale; YYYY-MM-DD wire format independent of display format.
  • Long student names + long remarks do not break chip/row layout (RTL ready).

11. Performance budgets (module)

CheckBudget
Grid first frame (cached)< 300 ms (00-shared/10 §1)
Grid scroll 60 rows0 dropped frames
Chip mark round-trip feelpending indicator ≤ 100 ms after tap
Month heatmap full render< 2 s network, skeleton first
Report poll cycle≤ 5 min cap, no leaks

12. Release gates (module additions)

  • e2e parity: p1-operations.e2e-spec.ts:200-228 (mark 201, class read 200, invalid status 400) pass against live backend.
  • Golden tests: grid, chips, heatmap, batch sheet — light/dark × 3 sizes.
  • Offline matrix (§5) fully green on mid-range device.