Bar Rota
Small self-hosted rota application for a non-profit bar/club.
What it does
- One Night assignment for every calendar day.
- Independent rotating Saturday Lunch and Sunday Lunch schedules.
- Admins can override any generated assignment.
- Members can request that another person (or anyone available) takes an assignment.
- Optional manager approval before a change becomes final.
- Optional email and phone on each user; username is used for login.
- SMTP email notifications and a notification log.
- Daily reminder command suitable for cron.
- SQLite by default, packaged for Docker.
Quick start with Docker
docker-compose.yml is the service stack (production/self-hosting):
cp .env.example .env
# Edit SECRET_KEY and INITIAL_ADMIN_PASSWORD before first start.
docker compose up -d --build
Open http://localhost:8000 and sign in with the values in .env.
docker-compose.dev.yml is the development stack (bind mounts, auto-reload, no restart policy):
docker compose -f docker-compose.dev.yml up --build
# or
make dev-up
Important: the initial admin is only created when the database has no users. Changing INITIAL_ADMIN_PASSWORD later does not reset that account; reset it from the People screen.
Local development
Run it on the host for fast debugging (checks still run in Docker, see Tests):
make dev-setup # creates .venv and installs requirements-dev.txt
make dev # uvicorn with auto-reload on http://localhost:8000
make dev uses ./.venv directly, so no activation is needed; use make dev PORT=8080 for another port. The SQLite database lives in ./data and is created on first run. Equivalent manual steps:
python -m venv .venv
. .venv/bin/activate
pip install -r requirements-dev.txt
cp .env.example .env
python -m app.cli init-db
uvicorn app.main:app --reload
Demo data:
make seed-demo
Demo member password: demo-password.
Set SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, SMTP_FROM and SMTP_STARTTLS in .env. If SMTP is not configured, email attempts are safely recorded as skipped in Email log.
To send reminders from cron:
python -m app.cli send-reminders
Example cron entry at 09:00 every day:
0 9 * * * cd /path/to/bar-rota && docker compose exec -T bar-rota python -m app.cli send-reminders
Database
The schema is managed with Alembic. The app runs alembic upgrade head on start, so starting it is enough to apply pending migrations.
make migrate # apply pending migrations
make revision m="add phone field" # generate a revision after editing app/models.py
A database created before Alembic existed has no version stamp; it is adopted at the baseline revision 0001_initial and upgraded from there. tests/test_migrations.py fails if the models and the migrations drift apart.
Tests
Checks run in a container, so the host Python environment does not matter:
make check
# or
docker compose -f docker-compose.dev.yml --profile check run --rm checks
make check runs python -m compileall -q app && pytest -ra against the working tree.
Project documentation
AGENTS.md— instructions and guardrails for coding agents/LLMs.docs/DOMAIN.md— scheduling rules and terminology.docs/ARCHITECTURE.md— implementation overview.docs/ROADMAP.md— intentionally deferred work.