Skip to main content

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

  1. Define or update request models in server/app/schemas.py.
  2. Implement the route in server/app/routers/.
  3. Enforce auth and authorization server-side.
  4. Query through SQLAlchemy models from server/app/models.py.
  5. Serialize responses with server/app/serializers.py.
  6. 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

  1. Update DTOs in web/src/types.ts.
  2. Add or update a typed helper in web/src/lib/api.ts.
  3. Use that helper from screens/components.
  4. Handle loading, empty, and error states.
  5. 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:

  • badRequest
  • unauthorized
  • forbidden
  • notFound
  • conflict

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.