Technical
Architecture
Two services over Postgres + object storage. Where each concern lives.
Teloma is two services — a Next.js 14 web app and a FastAPI Python API — over a PostgreSQL database and an object store. In production the web app runs on Azure Static Web Apps, the API on an Azure Container App, Postgres on Neon, and object storage on Azure Blob (Microsoft BAA). Local dev runs the same two services against a Dockerized PostgreSQL 16 and MinIO. 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 (local dev)
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
In production the same web/api pair is deployed to Azure Static Web Apps + an Azure Container App, backed by Neon Postgres and Azure Blob storage.
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. In production, storage is Azure Blob (services/storage/azure_blob.py, Microsoft BAA); local dev uses a MinIO/S3-compatible store (services/storage/s3.py) behind the same signed-URL interface. The container is provisioned with CORS.