Files
video-surveillance-portal/AGENTS.md
T
2026-05-19 14:53:36 +02:00

68 lines
2.1 KiB
Markdown

# Video Surveillance Portal — AGENTS.md
## Project
Web portal for video surveillance. IP cameras, smart devices, person detection alerts via email/SMS.
## Stack (confirmed)
- Backend: Python 3.12 + FastAPI
- Stream relay: MediaMTX (RTSP → WebRTC/HLS)
- Detection: Camera built-in human detection (ONVIF events) — NO local AI on Celeron N4000
- Message broker: Redis pub/sub
- Database: SQLite (128GB SSD, single-user)
- Frontend: Vanilla HTML/CSS/JS (single page, no framework)
- Deployment: Docker Compose (4 containers: nginx, app, redis, mediamtx)
- Notifications: SMTP (email), Twilio (SMS), Telegram
- ANPR: PlateRecognizer Cloud API (free tier, 2500 calls/month)
## Directory Structure
```
src/
api/ FastAPI routes
detection/ Person detection engine
streams/ Camera stream management
alerts/ Alert dispatch (email, sms, webhook)
devices/ Smart device integration
storage/ Recording management
config/ App configuration
tests/
config/ Nginx, docker, default configs
scripts/ Dev helpers
```
## Commands
```
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
docker compose up -d
make fmt # ruff format
make lint # ruff check + mypy
make test # pytest -q
```
## Conventions
- Black formatting, 88 chars
- snake_case files, CapWords classes
- Type hints everywhere
- pytest tests mirroring src/ structure
- Conventional Commits
## Key Design Goals
- Person detection → alert latency under 5 seconds (camera does detection)
- ONVIF PullPoint for event capture (fallback: FTP watchdog)
- RTSP stream relay with WebRTC for low-latency browser viewing
- Alert cooldown per camera to prevent spam
- Phone camera ingest via WebRTC WHIP (no native app)
- HTTPS required for mobile browser getUserMedia
## Running
```
docker compose up -d # http://localhost:8081 + https://10.0.50.210:8444
docker compose down
make lint
make test
```
## Handoff
- See `HANDOFF.md` for latest session state and pending tasks
- Sessions: `.sessions/latest.json` + global `.codex/sessions/`