Files
vigilar/docs/architecture/conventions.md
2026-04-05 09:39:47 -04:00

68 lines
2.5 KiB
Markdown

# Coding Conventions
These are the rules a contributor needs in their head before touching Vigilar.
They are distilled from `CLAUDE.md` and from the patterns already in the codebase.
## Language and style
- Python 3.11+.
- Ruff for linting. Line length 100 (see `pyproject.toml`).
- Type hints on all public functions. Internal helpers may omit them when the
types are obvious from context.
- No docstrings unless the logic is non-obvious. Short, well-named functions
should speak for themselves.
## String constants
All string constants referenced in more than one place live in
`vigilar/constants.py`. The file uses `StrEnum` for enumerated values —
`ArmState`, `Severity`, `EventType`, `SensorType`, `AlertChannel`,
`RecordingTrigger`, and friends — and a `Topics` class for MQTT topic builders.
If you are about to write `"MOTION_START"` or `"vigilar/camera/..."` in a second
place, stop and add it to the appropriate enum or the `Topics` class instead.
Defaults like `DEFAULT_IDLE_FPS` also live in this module.
## Database access
- SQLite in WAL mode, opened through `vigilar/storage/db.py`.
- SQLAlchemy Core expressions only — no mapped classes, no ORM session.
- Schema lives in `vigilar/storage/schema.py`. Named query helpers live in
`vigilar/storage/queries.py`.
- New tables go in `schema.py`. New query helpers go in `queries.py`. Do not
scatter ad-hoc SQL across subsystem code.
## Processes and the MQTT bus
- Each subsystem runs in its own `multiprocessing.Process`, spawned by the
supervisor in `vigilar/main.py` via the `SubsystemProcess` wrapper. Cameras
are the exception: `CameraManager` owns one child process per camera
directly.
- Subsystems communicate only through the local MQTT broker at
`127.0.0.1:1883`. No direct imports or function calls across subsystem
boundaries.
- Topic naming: `vigilar/<domain>/<id>/<event>`. Every topic comes from the
`Topics` class in `vigilar/constants.py` — do not construct topic strings
ad hoc.
- If you are tempted to reach into another subsystem directly, publish a
topic instead.
## Configuration
- `config/vigilar.toml` is the only config file the app reads at runtime.
- It is validated by Pydantic v2 models in `vigilar/config.py`. Add new fields
to the Pydantic models, not just to the TOML.
- Secrets are file paths, not inline values. Never put a key, password, or
token directly in the TOML.
## Testing
- `pytest` from the repo root.
- Tests live under `tests/`.
## Committing
- `ruff check vigilar/` must pass.
- `pytest` must pass.
- One logical change per commit. Commit often.