# Vigilar — Project Conventions ## What is this? DIY offline-first home security system. Python 3.11+, Flask + Bootstrap 5 dark theme, SQLite, MQTT internal bus, FFmpeg recording, HLS streaming. ## Stack - **Web**: Flask, Jinja2 templates, Bootstrap 5 (dark), hls.js for camera streams - **Backend**: Python 3.11+, multiprocessing for subsystem isolation, paho-mqtt for internal bus - **Database**: SQLite WAL mode via SQLAlchemy Core (not ORM) - **Camera**: OpenCV (RTSP capture, MOG2 motion detection), FFmpeg subprocess (recording, HLS) - **Config**: TOML (`config/vigilar.toml`) validated by Pydantic v2 - **CLI**: Click ## Code Style - Ruff for linting, line length 100 - Type hints on all public functions - No docstrings unless logic is non-obvious - StrEnum for all string constants (see `vigilar/constants.py`) - SQLAlchemy Core expressions, not ORM — no mapped classes ## Architecture - Each subsystem (camera, sensors, ups, events, alerts) runs in its own `multiprocessing.Process` - All inter-process communication via local Mosquitto MQTT on 127.0.0.1:1883 - Web UI is Flask with Blueprints in `vigilar/web/blueprints/` - Templates in `vigilar/web/templates/`, static assets in `vigilar/web/static/` ## Key Design Decisions - Adaptive FPS: 2 FPS idle, 30 FPS on motion, 5-second ring buffer for pre-motion context - HLS for multi-camera grid (bandwidth efficient), MJPEG fallback for single-camera low-latency view - PWA with Web Push (VAPID) for mobile notifications - AES-256 encrypted recordings (.vge files), key in /etc/vigilar/secrets/ - No cloud dependency, no external service calls in critical path ## Commands - `pip install -e ".[dev]"` — install with dev deps - `vigilar start` — launch all services - `vigilar config validate` — check config - `pytest` — run tests - `ruff check vigilar/` — lint