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

12 — API Mapping (Biometric Module)

Exact wire contract for every screen → endpoint. Base /api/v1; envelope per 00-shared/07. Real endpoints from src/modules/biometric/biometric.controller.ts; planned endpoints from studylyon-blueprint/04-Modules/Biometric.md:24-31. Global guards: RateLimitGuardJwtAuthGuardRbacGuard (app.module.ts:129-131). RbacGuard needs @Permissions metadata — the ingest endpoint has none (OQ-5).


0. Module-wide request envelope & client policy

AspectContract
Basehttps://api.<domain>/api/v1
HeadersAuthorization: Bearer <accessToken>; x-request-id; JSON
response{success,message,data,meta?,timestamp,requestId}
error{success,message,error:{code,details?},timestamp,requestId}
TenancytenantId from JWT claim (BaseRepository scoping); never in body
Offlineall writes blocked; reads cached last-good
Retrybackoff on 5xx/network; no auto-retry on 429

1. Ingest punch — REAL today

EndpointPOST /biometric/ingest
Sourcebiometric.controller.ts:14-18; @Post('ingest') + @UseGuards(JwtAuthGuard) (:9,14)
Request{studentId: MongoId*, deviceId: string*, timestamp: ISO8601*, mode?: string}create-biometric-log.dto.ts:4-20
Success201 (created BiometricLogDocument) — biometric.service.ts:14-16 persists via logRepo.create
AuthJWT (controller-local guard + global chain); no @Permissions metadata — any authenticated user (OQ-5)
Errors400 validation; 401 unauthenticated; 429 rate; 5xx
Client roledevice webhook path; clerk manual entry (proposed) mirrors it (08 §5)
NoterawData not accepted (schema-only, 01 OQ-2); response exposes schema fields incl. rawData echo

Endpoint source: biometric.controller.ts:14-18, biometric.service.ts:14-16


2. Device management — (planned) blueprint contract

EndpointMethodSourceScreen
/biometric/devicesGET (list)blueprint Biometric.md:25Device List
/biometric/devicesPOST (create)blueprint :26Device Register
/biometric/devices/:idPATCH (update)blueprint :27Device Detail / Edit
/biometric/devices/:id/syncPOST (trigger sync)blueprint :28Device Detail — Sync now
/biometric/logsGET (list, filters planned)blueprint :30Log List

Request/response fields mirror biometric-device.schema.ts:15-31 (name, deviceId, model, status enum active|inactive|offline :7-11, location, config) and biometric-log.schema.ts:9-22. Unique key (tenantId, deviceId) (biometric-device.schema.ts:36) → 409 on duplicate deviceId.

No implementation exists — UI build blocked (06 §10).


3. Attendance derivation — (planned) event chain (not HTTP)

HopMechanismSource
Punch polledbiometric-sync queue, */15 * * * *queue.constants.ts:7; scheduler.service.ts:70-76
Workermissing — no @Processor('biometric-sync') anywhere (grep src/**)OQ-4
Event emittedBiometricImported → queue attendance-processblueprint EVENTS.md:18
Workerattendance.worker.ts:16 @Processor('attendance-process') (real)derives/processes attendance
Target modelAttendanceSource.BIOMETRIC = 'biometric'attendance.schema.ts:18
Existing triggerAttendanceMarked event → attendance-processevent-queue-map.ts:14-17

4. Attendance endpoints the biometric screens reuse (real)

EndpointSourceUsed by
GET /attendance/student/:studentId?startDate&endDateattendance.controller.ts:37-43Verify Check-in, Log Detail hop
PATCH /attendance/:idattendance.controller.ts:54-59dispute correction
GET /attendance/class/:classId?dateattendance.controller.ts:31-35teacher view (passive)

5. Permissions matrix

PermissionConstantEndpoint(s)permissions.constants.ts
biometric.log.createrealPOST /biometric/ingest (metadata missing — OQ-5):41
biometric.log.readrealplanned GET /biometric/logs:42
biometric.device.managerealplanned device CRUD + sync:43
biometric.sync / biometric.readblueprint names — not in constantsblueprint Biometric.md:66-68

6. Loading / streaming / realtime

ScreenLoadingStreamingRealtime
hubskeleton cards(planned) WS sync-event push
devicesskeleton list
device detailskeleton
logsskeleton list(planned) WS log push
verifyspinner

7. Client-side error mapping

ScreencodeUI
ingest400per-field (device path: log payload, no UI)
ingest429countdown; machine path → OQ-5
devices409"A device with this ID already exists"
devices403permission screen
sync5xx/networkretry banner "will retry (4× exp) — DLQ after" (RETRIES.md:38)
any401silent refresh → fail: session-expiry overlay (00-shared/07)

8. Pagination

Planned GET /biometric/logs: high-volume collection (blueprint INDEXING.md:68: insert-only) → must paginate (cursor or page+size) with meta per envelope; device list is small (non-paginated array, like auth sessions pattern).

9. Optimistic / undo

None. Register/disable/sync/enroll are server-confirm; disable is irreversible → confirm dialog, no optimistic removal (10 §5).