03

System topology

Executive summary

One application service on Cloud Run — a Node.js modular monolith — serves the web app and its API, backed by Cloud SQL PostgreSQL 16, Cloud Storage and Cloud KMS. Work that needs different hardware or a hard isolation boundary runs as a small number of satellite services: a document renderer, an imaging pre-processor, and GPU inference workers. Everything runs in approved EU regions; there is no message broker — asynchronous work is carried by Postgres outboxes drained on a schedule.

System context (C4 level 1)

  • Clinicians & staff
    web · iOS · Android
  • Patients
    aftercare links · Patient Mode
  • Investors & auditors
    Data Room
  • Research readers
    annotation app
  • Faurenis platform
    Google Cloud · EU
  • Vertex AI (EU)
    Gemini models
  • Speech providers (EU)
    Soniox · Google STT · TTS
  • Open literature
    PubMed · Europe PMC · …
  • Practice systems
    PMS · FHIR · Stripe
Connections (8)
  • Clinicians & staff → Faurenis platform
  • Patients → Faurenis platform
  • Investors & auditors → Faurenis platform
  • Research readers → Faurenis platform
  • Faurenis platform → Vertex AI (EU)
  • Faurenis platform → Speech providers (EU)
  • Faurenis platform → Open literature · de-identified
  • Faurenis platform ⇢ Practice systems
People and external systems around Faurenis. Model and speech providers are reached only from the server, only in EU endpoints.

Containers (C4 level 2)

Edge
  • Load balancer + Cloud Armor
    WAF · rate limits
  • Cloud Scheduler
    OIDC-signed cron calls
  • Native shells
    Capacitor 8
Compute
  • Application service
    Express API · SPA · WebSockets · workers
Satellites
  • Document renderer
    Chromium → PDF/A
  • Imaging pre-processor
    DICOM decode · derivatives
  • Clinical LLM worker
    vLLM · embeddings · NLI (GPU)
  • Imaging inference
    signed model releases (GPU)
Data
  • Cloud SQL PostgreSQL 16
    clinical plane · RLS
  • Research database
    physically separate
  • Cloud Storage
    imaging · renditions · models
  • Cloud KMS + Secret Manager
    per-clinic keys · signing
Connections (10)
  • Load balancer + Cloud Armor → Application service
  • Cloud Scheduler ⇢ Application service
  • Application service → Document renderer
  • Application service ⇢ Imaging pre-processor
  • Application service → Clinical LLM worker
  • Application service ⇢ Imaging inference
  • Application service → Cloud SQL PostgreSQL 16
  • Application service → Cloud KMS + Secret Manager
  • Imaging pre-processor → Cloud Storage
  • Clinical LLM worker → Cloud Storage · read-only models
Runtime containers. Satellites have their own service accounts and internal ingress; none of them holds database credentials.

Container inventory

  • Application service
    Responsibility
    Every API route, the SPA, the four WebSocket endpoints, cron handlers and in-process workers
    Isolation
    Clinic scope per transaction; blue-green revisions
    Status
    Production
  • Document renderer
    Responsibility
    Renders clinical documents to archival PDF/A-2b
    Isolation
    IAM-only invocation, no database access
    Status
    Production
  • Imaging pre-processor
    Responsibility
    Decodes and validates DICOM, writes viewer derivatives to storage
    Isolation
    Internal ingress, own service account
    Status
    Production
  • Clinical LLM worker
    Responsibility
    Self-hosted open-weight models, embeddings and entailment on an NVIDIA L4 GPU
    Isolation
    Internal ingress; refuses to start if database credentials are present; read-only model mount; no egress
    Status
    Rolling out
  • Imaging inference
    Responsibility
    Runs signed imaging model releases
    Isolation
    Internal ingress; accepts only verified release packages
    Status
    Rolling out
  • Research annotation app
    Responsibility
    Blinded imaging annotation for model development
    Isolation
    Separate origin, separate identity provider, separate database
    Status
    Rolling out

Every container here is Node.js except where models execute: the document renderer drives headless Chromium, and the clinical LLM and imaging workers are Node gatekeepers in front of vLLM and text-embeddings-inference on the GPU. Only the application service holds database credentials. Today it serves HTTP, server-sent events, the WebSocket voice paths and the scheduled jobs from one deployment; splitting those into separate deployments of the same image is a proposed next step.

Regions and data residency

The approved-region list in server/config/approvedEuRegions.ts names nine EU regions and excludes London and every non-EU multi-region. Gemini 3 models are served only from Vertex AI’s EU jurisdictional endpoint, which is approved explicitly. At boot, production validates its KMS location, residency region and enforcement flag and exits if any is missing or wrong — a misconfigured revision never takes traffic.

  • Application service and satellites
    Region
    europe-west1 (Belgium)
  • Cloud SQL
    Region
    europe-west3 (Frankfurt)
  • GPU inference workers
    Region
    EU regions with L4 capacity, on the approved list
  • Vertex AI models
    Region
    EU jurisdictional endpoint
  • Speech recognition
    Region
    Provider EU endpoints

Asynchronous work without a broker

There is no Pub/Sub, task queue or Redis. Every asynchronous effect is written to a Postgres outbox in the same transaction as the change that caused it, then drained by an OIDC-authenticated cron endpoint invoked by Cloud Scheduler. Exactly-once-enough delivery comes from idempotency keys and SKIP LOCKED leases rather than from broker semantics, and an outbox row can never describe a write that rolled back.

  • Audit outbox
    Carries
    Audit events whose chain write must not block the request
  • AI decision outbox
    Carries
    Per-call AI decision records, buffered on disk and drained at boot
  • AI provenance outbox
    Carries
    Links from artifacts to the AI decisions that produced them, with dead letters and reconciliation
  • Imaging outbox
    Carries
    Ingestion, derivative and inference jobs
  • Integration inbox / outbox
    Carries
    Practice-management sync in both directions, with a dead-letter queue
  • Clinical document bundle queue
    Carries
    Document generation for newly reviewed sources

Around forty scheduled endpoints cover reminders, appointment lifecycle, KPI snapshots, anomaly scans, backups, audit-chain verification, usage settlement, push reconciliation and purges.

Real-time channels

  • General transcription (WebSocket)
    Purpose
    Streaming speech recognition for Scribe, dictation and commands
  • Perio transcription (WebSocket)
    Purpose
    Low-latency recognition tuned for probing grammar
  • Live voice (WebSocket)
    Purpose
    Speech-to-speech sessions bridged to Vertex AI
  • Voice synthesis (WebSocket)
    Purpose
    Streaming text-to-speech
  • Server-sent events (8)
    Purpose
    Copilot answers, appointment board changes, job progress

WebSocket sessions authenticate with a short-lived signed ticket obtained over REST and presented in the subprotocol header; query-string tokens are refused. Every instance re-checks open sessions against the revocation registry every 15 seconds and closes revoked ones.

SOURCE OF TRUTH
  • server/config/approvedEuRegions.ts
  • server/services/dataResidencyValidator.ts
  • infra/
  • services/
  • docs/ARCHITECTURE.md
Every figure in this specification is generated from the repository and checked in CI.