# 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.
