Contínuos CRR
A shift rota application built with FastAPI, SQLite/SQLAlchemy, and server-rendered Jinja templates. It manages night and lunch schedules, teams, shared user logins, shift swaps, calendar subscriptions, and optional email notifications.
Run locally
With Python 3.12+ (including venv/pip) and make installed, run:
make dev
This creates/reuses .venv, installs development dependencies, creates data/,
and starts Uvicorn with auto-reload at http://localhost:8000. Startup applies
migrations and seeds the initial administrator and schedules. Stop it with Ctrl+C.
No virtualenv activation, Docker, or separate database setup is needed.
The app reads .env if present; otherwise it uses its development defaults,
including data/bar_rota.db and the initial login admin / change-me-now.
Use a local SQLite path in DATABASE_URL and SESSION_HTTPS_ONLY=false for local
HTTP development. Settings such as INITIAL_ADMIN_USERNAME and
INITIAL_ADMIN_PASSWORD override the defaults when the database is first seeded.
To use another port:
make dev PORT=8001
Update BASE_URL to match if using email notification links. The Makefile port
defaults to 8000; override it on the command line or through an exported PORT.
Run with Docker Compose
compose.yaml is a minimal deployment example. With Docker and Docker Compose
installed, copy the example settings and edit .env:
cp .env.example .env
Set SECRET_KEY to a long random value and choose INITIAL_ADMIN_PASSWORD before
the first start. Set BASE_URL to the address users will access; SMTP is optional.
Build and start the application:
docker compose up --build -d
Open http://localhost:8000 and sign in with INITIAL_ADMIN_USERNAME and
INITIAL_ADMIN_PASSWORD. Startup applies database migrations and creates the initial
administrator and schedules automatically. Initial administrator settings only apply
when the database is first seeded.
PORTselects the host port (default8000); updateBASE_URLif you change it.DATA_DIRselects the host data directory (default./data). The SQLite database and default startup backups persist there across container rebuilds and restarts.- Compose sets
DATABASE_URLtosqlite:////app/data/bar_rota.dbso the database stays inside the persistent mount. If settingBACKUP_DIR, use a container path beneath/app/datato persist backups too. - For a reverse proxy, set
BASE_URLto the public URL,ROOT_PATHif served under a sub-path, andSESSION_HTTPS_ONLY=truewhen served over HTTPS.
View logs or stop the service:
docker compose logs -f app
docker compose down
Stopping the service leaves the host data directory intact.
Add shifts to a phone's calendar
Sign in, open Calendário from the rota, and choose your team's calendar (administrators can also choose Rota completa):
- iPhone / Apple Calendar opens the native subscription confirmation.
- Google Calendar / Android opens Google Calendar on the web. Google requires its desktop interface to add subscriptions: request the desktop site in your phone's browser, or add it on a computer, then enable the calendar in the mobile app.
- Outlook opens the web subscription screen; use the same account as the mobile app.
- Copiar endereço supplies the feed URL for another app or manual setup.
The page includes step-by-step instructions for each platform. Subscribe by URL
rather than importing a downloaded .ics file so future changes appear automatically.
Providers control refresh timing; updates may take several hours. Google and Outlook
need an Internet-accessible feed address.
Run tests
From the repository root, run one command:
make test
You need Python 3.12+ with venv/pip and make. The command automatically creates
.venv if needed, installs requirements-dev.txt (including application
dependencies), and runs pytest. Dependency installation needs package-index access
on the first run. You do not need to activate a virtualenv, start the application,
or run Docker or database setup commands.
The framework is pytest, with HTTPX available for FastAPI's TestClient.
Configuration is in pyproject.toml; tests are discovered under tests/.
There are no tests yet: pytest will report no tests ran, and make test treats
that result as success. Actual failures and pytest errors return a nonzero status.
Optional pytest arguments use the same command:
make test ARGS="-k rotation -v"
Adding tests later
- Put files in
tests/test_*.py, name functionstest_*, and use plainassert. - Use pytest's
tmp_pathandmonkeypatchfor isolated data and settings. - Add database and HTTP client fixtures to
tests/conftest.pyas they become needed. Fixtures should initialize a fresh temporary SQLite database and clean up FastAPI dependency overrides automatically. Do not require manual migrations or seeding. - Set environment variables before importing app modules: settings read
.env, and the SQLAlchemy engine is created at import time. Tests must use temporary databases and disable real SMTP rather than inherit local application settings. - HTTP tests use
fastapi.testclient.TestClient. Its context manager runs the app's lifespan, including backups, migrations, and initial data; configure those against temporary storage before entering it. - Test observable behavior: scheduling boundaries, preservation of existing shifts, permissions/CSRF, swap ownership and transitions, calendar output, and email failure handling. Use fixed dates and explicit data so tests do not depend on execution order.