System Overview
Browser (Edge)
→ TF.js detects faces, crops with 20% padding
→ POST /api/internal/scan to edge server (HTTP)
→ Edge server adds API key, publishes to MQTT
MQTT Broker
→ Routes scan to central
Central Server (ScanProcessor)
→ Validates API key
→ Cache Layer 1: per-face bbox (skip AWS if face hasn't moved)
→ AWS Rekognition searchFaces
→ Cache Layer 2: match dedup (suppress duplicate publishes)
→ Stores RecognitionEvent in DB
→ Publishes matched/unmatched to MQTT
→ Publishes to tenant's external MQTT (if configured)
MQTT → Edge Server → WebSocket → Browser (shows face cards)
MQTT Topics
taa-vision/
├── central/status ← Central status (every 60s, retained)
├── {tenantId}/
│ ├── status ← Tenant status with edge list (every 60s)
│ └── {locationId}/
│ ├── scan ← Edge → Central (with API key)
│ ├── matched ← Central → Edge (QoS 1)
│ ├── unmatched ← Central → Edge (QoS 1)
│ └── status ← Edge device status (retained)
Billing
Monthly Fixed
| Tenant base fee | $99.00/tenant |
| Edge device (face) | $35.00/device |
| Edge device (plate) | $45.00/device |
| Edge device (both) | $55.00/device |
| Enrollment storage | $0.10/face/month |
Per-Scan
| Identify (1:N) | $0.05/scan |
| Match surcharge | $0.01/match |
| Verify (1:1) | $0.05/scan |
| Detect | $0.01/scan |
| Extract/OCR | $0.05/scan |
Caching
Layer 1 (BBox): Per-face cache keyed by position. If face hasn't moved (IoU > 30%), skip AWS. TTL 30s.
Layer 2 (Dedup): Matched faces: suppress duplicate publish for 30s. Unmatched: 5s. Prevents duplicate billing.
Server Modes
Central
| Port | 3000 |
| AWS | Required |
| MQTT | Subscribe scans, publish results + status |
| ScanProcessor | Active |
Edge
| Port | 3001 |
| AWS | None |
| MQTT | Publish scans + status, subscribe results |
| WebSocket | ws://edge:3001/ws |
Enrollment
POST /api/v1/faces/enroll
Headers: X-API-Key: tvk_...
Body: { "imageBase64": "...", "externalId": "john_doe" }
Collection auto-created when tenant is provisioned: taa-vision-{tenantId}
Security
Browser → Edge Server → MQTT (internal) → Central → AWS
Central → MQTT (internal) → Edge Server → WebSocket → Browser
Central → MQTT (external, per-tenant) → Tenant's apps
• Browser has NO API keys or MQTT access
• Edge server adds API key from config
• Central validates API key before processing
• External MQTT receives images + metadata