Skip to main content

Patient Chart Service — Deployment Topology

Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 03 platform-services

1. Runtime

AttributeValue
RuntimeNestJS 11 / Node 22 LTS / TypeScript 5.x
Container imageghasi/patient-chart-service:latest
Base imagenode:22-alpine
Port3010 (internal)
Health endpointGET /health (liveness + readiness)
Readiness probeDB connectivity + NATS connection

2. Kubernetes deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: patient-chart-service
namespace: ghasi-ehealth
spec:
replicas: 3 # minimum; HPA scales to 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
spec:
containers:
- name: patient-chart-service
image: ghasi/patient-chart-service
resources:
requests: { cpu: 250m, memory: 512Mi }
limits: { cpu: 1000m, memory: 1Gi }
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: patient-chart-db-secret
key: url
- name: NATS_URL
valueFrom:
configMapKeyRef:
name: nats-config
key: url

3. Scaling

MetricTargetMin replicasMax replicas
CPU utilisation70 %310
NATS consumer lag> 500 msgsTriggers alert
HTTP P95 latency< 800 msTriggers alert

HPA (Horizontal Pod Autoscaler) monitors CPU and custom patient_chart_http_request_duration_p95 metric via KEDA if available.

4. Regions and data residency

DeploymentRegionNotes
PrimaryAfghanistan (AF)MoPH data-residency requirement; Postgres and NATS co-located in-country
DR passiveBackup cloud region (UAE or on-prem secondary)Async replica; activated via DNS failover
Dev / stagingShared cloud environmentNo real patient data; synthetic seed data only

5. Database topology

ComponentTechnologyNotes
Primary DBPostgreSQL 16Single logical schema patient_chart; monthly range partitions on time-series tables
ReplicaPostgres streaming replica (1 async)Read queries for summary/timeline widgets may be directed here
MigrationsDrizzle KitApplied by CI pipeline before pod rollout; never auto-run on startup
BackupDaily pg_dump + WAL archiving7-year retention per MoPH policy

6. NATS JetStream streams

StreamSubjectsRetentionConsumers
PATIENT_CHARTpatient_chart.>WorkQueue 7 daysaudit-service, medication-service, communication-service, population-health-service, patient-portal-service
REGISTRATION (consume)registration.patient.*, registration.encounter.created.v1WorkQueuepatient-chart-service inbox consumer
GDPR (consume)gdpr.subject_request.received.v1WorkQueuepatient-chart-service inbox consumer

7. External HTTP dependencies (sync)

DependencyPatternTimeoutRetry
terminology-serviceSync REST2 s3x exponential
registration-serviceSync REST2 s3x
provider-directory-serviceSync REST2 s2x
facility-serviceSync REST2 s2x
ai-gateway-serviceSync REST30 sNo retry (AI assist; timeout ≠ retry)
document-serviceSync REST5 s3x
medication-serviceSync REST (summary widget)3 s2x
laboratory-serviceSync REST (summary widget)3 s2x
radiology-serviceSync REST (summary widget)3 s2x
immunizations-serviceSync REST (summary widget)3 s2x
care-plan-serviceSync REST (summary widget)3 s2x

All downstream calls wrapped in HttpClientAdapter with per-service circuit breaker.

8. Security and network

ControlValue
IngressKong edge gateway only; no direct pod access
mTLSEnabled in-cluster (Linkerd or Istio mesh)
SecretsKubernetes Secrets backed by Vault (Vault Agent Injector)
RLSPostgreSQL RLS; app.tenant_id set per-request from JWT
Network policyDeny-all default; allow list per service

9. Canary and rollout strategy

StageTraffic %DurationValidation
Canary5 %30 minError rate < 0.1 %; P99 < 1.5 s; NATS event count stable
Progressive25 % → 50 % → 100 %15 min eachSame SLO gates
Rollback triggerError rate > 1 % or P99 > 2 sAutomated via Argo Rollouts

10. Open questions

  • Confirm DR region (UAE cloud vs. second on-prem site for AF MoPH).
  • Read replica enablement for summary/timeline queries — decision needed before M1.