Files
nvr-shield/ARCHITECTURE.md
root 9615f0263f Initial project documentation: NVR Shield — Reolink NVR monitoring agent
- README: project overview, pricing, deployment model
- ARCHITECTURE: system design, data flow, components, security
- DECISIONS: Pi Zero 2W, Tailscale, reolink-aio, Wasabi S3 choices
- ROADMAP: 3-phase plan (MVP, monetization, expansion)
- CHANGELOG: concept (Aug 1) and full documentation (Aug 5)
- Customer onboarding information request sheet
2026-08-05 07:34:08 -04:00

131 lines
6.3 KiB
Markdown

# NVR Shield — Architecture
## System Overview
```
┌─────────────────────────────────────────────────────────┐
│ CUSTOMER SITE │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ NVR #1 │ │ NVR #2 │ │ NVR #3 │ (Reolink) │
│ │ 192.168.x│ │ 192.168.x│ │ 192.168.x│ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ └──────────────┼──────────────┘ │
│ │ HTTP API (port 80/443) │
│ ┌───────┴────────┐ │
│ │ Pi Zero 2W │ │
│ │ NVR Shield │ │
│ │ Agent │ │
│ └───────┬────────┘ │
│ │ Tailscale (WireGuard) │
└──────────────────────┼───────────────────────────────────┘
INTERNET │
┌──────────────────────┼───────────────────────────────────┐
│ ITPP CORE (netcup) │
│ │ │
│ ┌───────┴────────┐ │
│ │ NVR Shield │ │
│ │ Dashboard │ │
│ │ API (:8090) │ │
│ └───────┬────────┘ │
│ │ │
│ ┌────────────┼────────────┐ │
│ │ │ │ │
│ ┌────┴────┐ ┌────┴────┐ ┌───┴──────┐ │
│ │ Wasabi │ │ Alerting │ │ Monthly │ │
│ │ S3 │ │ (Email/ │ │ Reports │ │
│ │ Backups │ │ SMS) │ │ Generator│ │
│ └─────────┘ └─────────┘ └──────────┘ │
└───────────────────────────────────────────────────────────┘
```
## Components
### 1. Pi Zero 2W Agent (`agent.py`)
Runs on Raspberry Pi Zero 2W at customer site. Python 3.
**Responsibilities:**
- Poll each configured NVR every 60s via Reolink HTTP API (`reolink-aio`)
- Collect: camera online status, HDD health, storage %, firmware version, uptime
- Push metrics to Core heartbeat endpoint
- Dump full NVR config to Wasabi S3 nightly
- Capture motion/AI-triggered clips and upload to S3 (Pro/Enterprise tiers)
- Accept remote config and update commands from Core
- Run custom AI filtering rules (Enterprise tier)
**Config schema (`config.yaml`):**
```yaml
site_id: "cust-shortname"
heartbeat_url: "https://core.itpropartner.com/nvr-shield/heartbeat"
s3_bucket: "nvr-shield-customer-backups"
s3_prefix: "cust-shortname/"
poll_interval: 60 # seconds
config_backup_time: "03:00" # daily
nvrs:
- name: "Warehouse"
ip: "192.168.1.10"
port: 443
user: "admin"
password: "${NVR_PASSWORD_WAREHOUSE}"
- name: "Front Office"
ip: "192.168.1.11"
port: 443
user: "admin"
password: "${NVR_PASSWORD_FRONTOFFICE}"
```
### 2. Core Dashboard / API
FastAPI backend on Core (:8090 path `/nvr-shield/`).
**Endpoints:**
| Method | Path | Purpose |
|---|---|---|
| POST | `/nvr-shield/heartbeat` | Agent pushes metrics (site_id, nvrs[], metrics) |
| GET | `/nvr-shield/dashboard` | Admin dashboard — all sites, health, alerts |
| GET | `/nvr-shield/site/{id}` | Per-site detail (cameras, history, clips) |
| GET | `/nvr-shield/report/{id}/{month}` | Monthly report PDF/HTML |
| POST | `/nvr-shield/agent/{id}/config` | Push updated config to agent |
### 3. Wasabi S3 Storage
**Bucket:** `nvr-shield-customer-backups`
**Structure:**
```
s3://nvr-shield-customer-backups/
{site_id}/
configs/
2026-08-01-config.json
2026-08-02-config.json
clips/
2026-08-01/
14-32-15-NVR-Warehouse-Cam3-motion.mp4
reports/
2026-07-monthly-report.pdf
```
### 4. Tailscale Network
All Pi Zero 2W devices connect via Tailscale to ITPP's tailnet. Each device tagged `tag:nvr-shield`. Core communicates with agents over Tailscale IPs, not public internet.
## Data Flow
1. **Health polling (every 60s):** Agent → NVR HTTP API → metrics JSON → Core heartbeat endpoint
2. **Nightly config backup:** Agent → NVR HTTP API → config JSON → Wasabi S3
3. **Incident clips (Pro/Enterprise):** NVR motion/AI event → agent detects → clip upload to S3 → notification to Core
4. **Monthly report:** Core cron (1st of month) → aggregates metrics from DB + S3 → generates PDF → emails customer
5. **Alerts:** Core evaluates heartbeat gaps (>2 min = alert), disk thresholds (>90% = alert), camera offline
## Security
- Pi filesystem is read-only (overlayfs) to prevent SD card corruption
- SSH key-only, no password auth
- NVR passwords stored in env vars, never in git
- Tailscale WireGuard for all agent-Core communication
- S3 credentials scoped to per-customer prefix only