# Phase 8: Visitor Management & Access Control ## 1. Overview A comprehensive system to track visitors, contractors, and inspectors. Replaces paper logs with a digital kiosk, digital badges, and an admin "Panopticon" for real-time facility oversight. ## 2. Core Features (Sprint 1) ### 2.1 Digital Kiosk - **Self-Service Check-in:** Tablet-friendly UI for visitors to input details. - **Data Capture:** Name, Company, Purpose, Host (Employee), Photo (Webcam), NDA Signature. - **Badge Generation:** Instant creation of a visit record. ### 2.2 Digital Badge (No Printer Required) - **Workflow:** 1. Visitor completes check-in. 2. Kiosk displays a unique QR code. 3. Visitor scans QR code with their own phone. 4. Phone opens `https://app.domain/badge/:visitId` (Public/Tokenized URL). - **Badge UI:** - Visitor Photo & Name (Large) - "Valid" Status (Pulsing Green Animation) - Host Name - Zone Access Level - Expiry Time (Countdown) - **Dynamic State:** If admin revokes access, the phone screen updates to "INVALID" (Red) via polling/socket. ### 2.3 Host Notification - Employee receives an alert (In-app/Email) when their visitor checks in. ## 3. "Panopticon" Admin View (Sprint 2) ### 3.1 Real-Time Dashboard - **Active Visitors:** List of all currently checked-in guests. - **Visual Status:** Time on site, host, assigned zone. - **Actions:** - **Force Checkout:** Clock them out remotely. - **Revoke Badge:** Instantly turn their digital badge RED. ### 3.2 Badge Confirmation Suite - **Verification Scan:** Security guards can scan the Visitor's phone screen to verify authenticity (prevents screenshots). - **Audit Log:** Track every check-in, check-out, and access revocation. ## 4. Data Model ```prisma model Visitor { id String @id @default(uuid()) name String company String? email String? phone String? type VisitorType @default(VISITOR) ndaSigned Boolean @default(false) visits Visit[] createdAt DateTime @default(now()) } model Visit { id String @id @default(uuid()) visitorId String visitor Visitor @relation(fields: [visitorId], references: [id]) hostId String? host User? @relation(fields: [hostId], references: [id]) photoUrl String? // Check-in photo purpose String? status VisitStatus @default(ACTIVE) // ACTIVE, COMPLETED, REVOKED checkIn DateTime @default(now()) checkOut DateTime? token String @unique // For public badge URL zones String[] // Allowed zones } enum VisitStatus { ACTIVE COMPLETED REVOKED } ``` ## 5. API Routes - `POST /api/visitors/check-in`: Create visitor/visit, upload photo, return badge token. - `GET /api/public/badge/:token`: Public endpoint to view badge status. - `POST /api/visits/:id/check-out`: End the visit. - `POST /api/visits/:id/revoke`: Invalidate the badge immediately.