Dental Platform · Internal Docs
Architecture

System Overview

Owner: Platform EngineeringLast reviewed:

System context

Service responsibilities

ServiceResponsibilityOwns dataMust never
core-apiAll domain REST APIs, authorization, tenancy, audit, event publicationPostgreSQL schemaCall OpenAI; render PDFs inline
realtime-gatewayAuthenticated WebSocket fan-out of NATS events (recording, transcription, jobs, island state)Nothing durablePersist PHI; accept writes other than presence/acks
ai-gatewayPrompt registry, model routing, privacy gate, de-identification, structured outputs, validation, cost accountingai_* metadata via core-api callbacksBe reachable from browsers; log payloads
workerDurable async jobs: transcription assembly, generation, rendering, delivery, retentionJob state in PostgreSQLSkip idempotency keys
document-serviceHTML template → Gotenberg PDF/Office renderingRendered assets in MinIOFetch arbitrary URLs (SSRF-guarded)
integration-serviceVendor adapter execution, webhook verification, reconciliationintegration_* tables via core-apiStore vendor credentials outside OpenBao

clinic-web, patient-portal, and platform-admin are BFF-style Next.js apps: session cookie (HttpOnly, encrypted) in the app, access token attached server-side, zero tokens in browser storage.

Trust boundaries

  1. Browser ⇄ Next.js BFF — TLS, session cookie, CSRF-safe (SameSite=Lax + origin checks on mutations).
  2. BFF ⇄ core-api — TLS, short-lived Keycloak access token, tenant claims verified server-side.
  3. core-api ⇄ data plane — mTLS in-cluster (Cilium), per-service credentials.
  4. worker/ai-gateway ⇄ OpenAI — egress-controlled, AI_PHI_MODE gate, store:false, minimized payloads.
  5. integration-service ⇄ vendors — allow-listed egress, credentials from OpenBao, signed webhooks.

Primary data flows

Recording → transcript → drafts → approval

Approved document → patient

core-api → NATS document.approved → worker → document-service (Gotenberg) → MinIO versioned asset → delivery request (portal-first; email is a notification with a secure expiring link, never a PHI attachment by default) → patient portal → signature / acceptance → audit.

Environments

EnvironmentDataTopology
developmentsynthetic onlyDocker Compose (compose.yaml), one command
stagingsynthetic / approved de-identifiedRKE2, production-like, separate credentials
productionreal PHIRKE2 ≥3 CP + ≥3 app workers + dedicated DB/storage nodes, Canadian DCs, DR site

Degraded modes

  • OpenAI unavailable → recording, transcript editing, manual documentation, charts, portal all keep working; generation queues with visible status.
  • NATS unavailable → synchronous APIs keep working; async pipelines pause with backlog alerts.
  • Redis unavailable → sessions fall back to DB-backed checks; rate limits fail closed for auth endpoints, open for reads.

On this page