2.1 KiB
Architecture
Runtime
Single FastAPI process with server-rendered HTML and a SQLite database volume. This keeps deployment suitable for a small VPS, NAS or home server.
Layers
models.py: persistence schema.migrations/: Alembic revisions. The app upgrades toheadon start; a database created before Alembic existed is stamped at the baseline revision and then upgraded.scheduling.py: deterministic month/rotation generation.web.py: authentication, admin editing and change-request orchestration.notifications.py: synchronous SMTP adapter + durable send log.cli.py: maintenance commands that can be run manually or by cron.
Data lifecycle
- Visiting a month calls
ensure_month_assignments. - Missing Night rows use the repeating monthly pattern, or remain unassigned for unconfigured days.
- Missing lunch rows are created from each independent rotation.
- Admin assigns/overrides rows on each schedule's own configuration page (the night pattern, or a lunch month view).
- Member change requests operate on concrete assignment IDs.
- Email is attempted after the database action commits.
Deployment
docker-compose.yml mounts ./data at /app/data, so the SQLite DB persists across image rebuilds. It is the service stack only. docker-compose.dev.yml is the development stack: it builds the dev image target, bind-mounts app/ and tests/ for auto-reload, and hosts the containerized test runner.
The deployment stack builds the production target (also the default Docker image target), which inherits the non-reloading runtime from base. Development also mounts Alembic configuration and migrations so schema changes can be authored in a container. make database commands use the host virtualenv by default, or a one-off development container with RUNTIME=docker. Both use the same data/ directory by default. The checks service has independent settings and no persistent data mount, allowing app data entry and automated tests to run concurrently.
For larger installations, the SQLAlchemy configuration can point to PostgreSQL, but the project intentionally ships only the SQLite deployment path today.