Files
2026-10-07 01:47:55 +01:00

91 lines
4.8 KiB
Markdown

# Repository guide
## Project and layout
Contínuos CRR is a server-rendered shift rota application. It uses Python
(the Docker runtime is 3.12), FastAPI, synchronous SQLAlchemy, SQLite, Jinja2,
and Alembic. Dependencies live in `requirements.txt`; development dependencies
live in `requirements-dev.txt`.
- `app/main.py`: FastAPI application, lifespan, middleware, templates, static files.
- `app/web.py`: routes, session authentication, CSRF, administration, swap workflows.
- `app/models.py`: SQLAlchemy schema and relationships.
- `app/database.py`: engine, sessions, migrations, SQLite backups.
- `app/config.py`: Pydantic settings, environment/`.env` loading, proxy-path helpers.
- `app/scheduling.py`: monthly pattern and rotation generation.
- `app/bootstrap.py`: initial administrator and seeded schedules.
- `app/calendar.py`: iCalendar feeds; `app/i18n.py`: Portuguese labels and formatting.
- `app/pdf.py`: single-page A4 schedule lists using ReportLab.
- `app/notifications.py`: synchronous SMTP delivery and notification history.
- `app/security.py`: password hashing and CSRF token generation.
- `app/cli.py`: database initialization/migration, demo seeding, shell, reminders.
- `app/templates/`, `app/static/`: Jinja HTML and CSS/assets; no frontend build step.
- `migrations/`: Alembic environment and the squashed `0001_initial` revision.
- `alembic.ini`: migration paths and logging; the database URL comes from settings.
- `compose.yaml`: example production deployment with persistent SQLite storage.
- `tests/`: export behavior tests and isolated database/client fixtures.
Read `docs/DOMAIN.md` for business rules and `docs/ARCHITECTURE.md` for lifecycle
and deployment details. See `README.md` for the test workflow.
## Local development
Run `make dev` to create/reuse `.venv`, install development dependencies, create
`data/`, and start Uvicorn with auto-reload on `127.0.0.1:8000`. Use
`make dev PORT=8001` to change the port. Application settings come from the
environment and optional `.env`; database migrations and initial seeding run on
startup. No separate setup command is needed.
## Development conventions
- Follow existing typed Python, snake_case names, and SQLAlchemy 2 mapped models.
Keep database and request handling synchronous, consistent with the application.
- Keep scheduling calculations in `app/scheduling.py`, persistence in models/database,
and HTTP orchestration in `app/web.py`. Reuse existing helpers.
- Keep user-facing text in Portuguese and reuse `app/i18n.py` and template filters.
- Build internal links with `settings.url()` (`app_path` in templates) and use
`_redirect()` in routes so deployments under `ROOT_PATH` keep working.
- Preserve session authorization and CSRF checks when adding form actions.
- Change the model and add an Alembic revision together for schema changes.
`app/database.py` builds the migration configuration using the root `alembic.ini`
and the database URL from settings.
## Domain invariants
- Users are logins; teams own shifts. One user may control several teams.
- Night assignments follow a repeating day-of-month pattern. Saturday and Sunday
lunch rotations are independent and continue from the previous actual assignee.
- Ordinary generation fills missing assignments only. Existing assignments change
through explicit administration or swap actions; preserve manual/swapped rows
when an operation calls for changing only generated rows.
- Swaps exchange two shifts in the same schedule atomically. Check current ownership
and cancel conflicting open requests when assignments change.
- Commit scheduling changes before notifications. Email failures must not undo them.
## Testing
Run from the repository root:
```sh
make test
```
This creates/reuses `.venv`, installs development dependencies, and runs pytest.
No activation, application server, Docker service, or separate setup command is
needed. Python 3.12+ with `venv`/pip and `make` are prerequisites.
- Use pytest functions and plain assertions in `tests/test_*.py`.
- Use FastAPI's `TestClient` (backed by HTTPX) for HTTP tests.
- Add shared fixtures to `tests/conftest.py` when needed. Fixtures must manage
temporary databases, initialization, dependency overrides, and cleanup so
`make test` remains the only command required.
- Settings and the database engine are created at import time. Set test environment
values before importing app modules; use temporary SQLite data, disable real SMTP,
and keep tests independent of local `.env` values and persistent application data.
- Prefer behavior and domain invariants over assertions about implementation details.
- An empty suite succeeds through `make test`; test failures and pytest errors still
fail the command. PDF tests inspect downloaded documents with pypdf.
Run `make test` after relevant changes and report its result accurately. An empty
suite verifies the runner only, not application behavior.