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.