API Contract
The frontend and backend are intentionally coupled through typed DTOs and helper functions. When an endpoint changes, update every layer in the same change.
Backend Pattern
- Define or update request models in
server/app/schemas.py. - Implement the route in
server/app/routers/. - Enforce auth and authorization server-side.
- Query through SQLAlchemy models from
server/app/models.py. - Serialize responses with
server/app/serializers.py. - Add or adjust tests under
server/tests/.
Do not return ORM rows directly. Serializers keep enum casing, computed fields, and nullable shapes stable for the web app.
Frontend Pattern
- Update DTOs in
web/src/types.ts. - Add or update a typed helper in
web/src/lib/api.ts. - Use that helper from screens/components.
- Handle loading, empty, and error states.
- Keep UI-only state out of API DTOs.
README Route Table
README.md contains the public API overview. Add rows there when routes are
added or response behavior changes in a way developers need to know.
Error Contract
Routes should raise helpers from server/app/errors.py:
badRequestunauthorizedforbiddennotFoundconflict
FastAPI handlers convert these to the standard response envelope. Validation errors are normalized by the app factory.
Contract Checklist
Use this checklist for endpoint work:
- Body validated by Pydantic.
- Auth and authorization enforced in the backend.
- Response serialized through a serializer.
- Frontend DTO matches the serializer.
- Frontend call goes through
web/src/lib/api.ts. - README route table updated.
- Features page updated when behavior changed.