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

05 — Screen Inventory (Biometric Module)

Every screen of the Biometric module, its intent, route, composition, states, permissions, platform behavior and events. Authoritative components in 00-shared/03; this file enumerates which ones each screen uses with module specifics. Screens marked (planned) have no backend endpoint yet — inventory is design-forward.


Legend

States = idle / loading / success / empty / error(offline, sync, queue) / disabled / permission. Analytics events follow {module}.{screen}.{action} (proposed; SDK open — 00-shared/10 §8).


1. Biometric Hub / Sync Status (/biometric) (planned)

FieldDetail
PurposeFleet health at a glance; the ops manager's landing (persona Riya)
EntrySettings → Biometric
Exit→ device list, → logs, → verify check-in
Widgetsstatus summary card (devices: active/offline counts), last-sync row, failed-sync banner, queue depth chip (Bull-Board link for Dev)
Statesloading skeleton; empty ("No devices — register one"); error (queue down); offline
Sourceplanned: GET /biometric/devices + queue health; no real API today
Analyticsbiometric.hub.open, biometric.hub.sync_status (proposed)
Permissionany biometric.* (hub visibility)

2. Device List (/biometric/devices) (planned)

FieldDetail
PurposeManage all devices: register, open, disable
Entryhub → Devices
Exit/biometric/devices/new; → /biometric/devices/:id
Sourceplanned GET /biometric/devices; unique key (tenantId, deviceId) (biometric-device.schema.ts:36)
RowAppListTile: name, subtitle model · location, trailing status badge (DeviceStatus: active/inactive/offline, biometric-device.schema.ts:7-11)
Pull-to-refreshRefreshIndicator
EmptyAppEmptyState "No devices registered"
CTAAppFAB "Register device"
Row menuAppMenu → Detail / Disable (confirm)
Permissionbiometric.device.manage (permissions.constants.ts:43)

3. Device Register (/biometric/devices/new) (planned)

FieldDetail
PurposeAdd a gate device to the tenant fleet
Formname*, deviceId*, model?, location?, config? (schema fields biometric-device.schema.ts:15-31)
Sourceplanned POST /biometric/devices (blueprint Biometric.md:26)
Primary CTA"Register device"
Statesloading; 409 duplicate deviceId inline; success → detail
Permissionbiometric.device.manage

4. Device Detail (/biometric/devices/:id) (planned — sync action part of it)`

FieldDetail
PurposeOne device: config, status, sync, enrollment entry
Headername + status badge + model/location; config collapsible (raw, biometric-device.schema.ts:30-31)
ActionsSync now (POST /biometric/devices/:id/sync, blueprint Biometric.md:28), Enroll/enroll, Disable (confirm), Edit (PATCH /biometric/devices/:id, blueprint :27)
Sync statesidle → running (spinner) → success (punch count) / failed (retry; 4× exp backoff, blueprint RETRIES.md:38 → DLQ)
Punch previewlast N logs for this device (biometric-log.schema.ts:26 index tenantId+deviceId+timestamp)
Permissionbiometric.device.manage; punch preview needs biometric.log.read

5. Enrollment (/biometric/devices/:id/enroll) (planned)

FieldDetail
PurposeCapture a student's template on a device (clerk, persona Arjun)
Stepsselect student → device capture → confirm → success chip
Sourceblueprint: employeeCode mapping (COLLECTIONS.md:1878-1879); no endpoint/schema/template format today (OQ-3)
Statesper-step loading; capture-failed (re-try, dry-hands hint); duplicate-enrollment warning
Exitsuccess → device detail ("Enrolled: {name}")
Permissionbiometric.device.manage
Blockersvendor SDK (FEATURE_ROADMAP.md:56); template storage decision; "maps to verified student record" (ACCEPTANCE_CRITERIA.md:39)

6. Biometric Log List (/biometric/logs) (planned — read path has no endpoint yet)

FieldDetail
PurposeEvidence trail: search punches by student/device/date; dispute resolution (journey 4)
Sourceplanned GET /biometric/logs (blueprint Biometric.md:30); log fields biometric-log.schema.ts:9-22
Filtersstudent (deep-link ?student=:id), device, date range, mode
RowAppListTile: student name, deviceId · mode, timestamp
EmptyAppEmptyState "No punches found"
Row tap→ Log Detail sheet
Permissionbiometric.log.read (permissions.constants.ts:42)

7. Biometric Log Detail (bottom sheet) (planned)

FieldDetail
PurposeFull immutable record incl. forensic payload
ContentstudentId, deviceId, timestamp, mode, rawData (raw JSON), createdAt; "immutable — never updated" note (blueprint COLLECTIONS.md:1866)
Action"Open attendance record" → student attendance list (GET /attendance/student/:studentId, attendance.controller.ts:37-43)
Permissionbiometric.log.read

8. Attendance-Verification Check-in (/biometric/verify) (planned)

FieldDetail
PurposeProve a student checked in (dispute) or preview today's biometric-fed marks
Inputstudent search → date
Contentpunch timeline (logs) + derived attendance status per day; flags AttendanceSource.BIOMETRIC rows (attendance.schema.ts:18)
Statesno punches (evidence absent), matched (punch → attendance present), mismatched (punch without derived record — derivation gap)
Exit→ attendance record edit (PATCH /attendance/:id)
Permissionbiometric.log.read (+ attendance.edit for the edit hop)

9. QR/Push Check-in (forward-looking)

Phone-as-badge capture surface under the same hub; no server support; keep route dormant.


Shared components used

AppCard, AppListTile, AppButton, AppSnackbar, AppDialog, AppMenu, AppFAB, AppSkeleton, AppEmptyState, AppOfflineBanner, AppBadge, AppChips, AppAvatar, AppRefreshIndicator. Module-specific: DeviceStatusBadge, SyncStatusTile, PunchRow, PunchTimeline, EnrollStepBar — defined in 07_Component_Library.md.

Analytics events (proposed)

biometric.hub.{open,sync_status}, biometric.device.{list,register,open,sync,disable}, biometric.enroll.{start,capture_ok,capture_fail,complete}, biometric.log.{search,open}, biometric.verify.{matched,mismatch,no_punch}.

Keyboard, landscape, tablet, desktop

  • Forms (register/enroll): portrait-first, keyboard avoidance.
  • Devices/Logs: two-pane master-detail ≥ 840 px; desktop hover row highlight.
  • Sync Status: single column up to 600 dp; three-column tiles ≥ 1200 px.