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.