Technical

Architecture

Two services over Postgres + object storage. Where each concern lives.

Teloma is two services — a Next.js 14 web app (port 3010) and a FastAPI Python API (port 8000) — sharing a PostgreSQL 16 database and a MinIO object store in dev. Auth.js v5 owns sign-in in the web app and mints a short-lived HS256 JWT; the API verifies the JWT and is the authoritative RBAC enforcement point.

Layout

web/   Next.js App Router + Auth.js v5 + Tailwind   port 3010
api/   FastAPI + SQLAlchemy 2.0 + Alembic + Pydantic port 8000
db     PostgreSQL 16 (Docker)                       teloma-db-1
obj    MinIO (S3-compatible, Docker)                signed URLs only

Web ↔ API handshake

On every authenticated request, the web app attaches an HS256 JWT (or X-Dev-Email / X-Dev-Role headers in dev). FastAPI verifies the JWT in core/security/jwt.py, then RBAC dependencies in core/deps.py (require_roles, resolve_patient) resolve scope. Every dependency invocation auditable via core/audit.py — DENY is written for failed checks too.

Object storage

Clients never see raw object paths. The API issues short-lived signed URLs for both upload and download via services/storage/s3.py. The bucket is created on boot with CORS.