Skip to main content

Billing Service — Deployment Topology

Status: populated Owner: TBD Last updated: 2026-04-17 Companion: Service Template · 17 tech stack

1. Runtime

PropertyValue
RuntimeNode.js 22 LTS
FrameworkNestJS 11
LanguageTypeScript 5.x (strict)
ORMDrizzle
DBPostgreSQL 16 (RLS enforced)
EventsNATS JetStream
CacheRedis (optional — rate limit, idempotency)
Object storeS3-compatible (MinIO local, AWS S3 / MoPH-approved cloud in prod)
TelemetryOpenTelemetry → Grafana Tempo + Loki + Prometheus

2. Containers

ContainerImagePurpose
billing-apighasi/service-billing:{sha}HTTP + event handlers
billing-workersame image with WORKER=trueStatement run, GL export, outbox relay
billing-migratesame imageDrizzle migrations (Job, not a long-running container)

3. Kubernetes topology

# deployment (API)
spec:
replicas: 3
strategy: RollingUpdate
maxSurge: 1
maxUnavailable: 0

# deployment (worker)
spec:
replicas: 2

# hpa
metrics:
- cpu: target 60 %
- custom: billing_http_requests_total rate
minReplicas: 3
maxReplicas: 10
ComponentReplicas (prod)Autoscale
billing-api3–10CPU + request-rate
billing-worker2–6Queue depth

4. Networking

PortUse
3035HTTP (Kong upstream)
9464Prometheus scrape
  • Ingress via Kong with per-route JWT verification.
  • Intra-service traffic via service mesh (mTLS).
  • Egress allowlist: tenant-service, terminology-service, interop-service, ai-gateway-service, payment gateway host (tenant-config).

5. Dependencies

DependencyProtocolFallback
PostgreSQL primary + read replicaTLSRead replica for query-only endpoints
NATS JetStream 3-node clustermTLSOutbox retains events; relay retries
tenant-serviceHTTPS mTLSShort-TTL cache for entitlement checks
terminology-serviceHTTPS mTLSFail closed on charge code validation
interop-service (fhir-gateway)HTTPS mTLSAsync retry on transient failure
ai-gateway-serviceHTTPS mTLSFeature disabled if unavailable
payment gateway (adapter)HTTPSBounded circuit breaker per tenant
audit-serviceasync via NATSOutbox retention covers outage

6. Regions & data residency

Country profileRegionData residency
Afghanistan (AFG)MoPH-approved cloud regionAll PHI stays in-country or per MoPH allowance
UAEUAE regionUAE-only residency; no cross-border without tenant opt-in
Multi-tenant defaultRegional cluster per countryTenants cannot share region across borders without policy flag

7. Secrets

SecretStoreRotation
DATABASE_URLKubernetes Secret sourced from Vault90 d
NATS_CREDSVault90 d
JWKS_URLconfig (public)
PAYMENT_GATEWAY_API_KEY_{TENANT}Vault per tenanttenant policy, default 30 d
KMS_KEY_ARNenv

8. Env vars

See .env.example. Critical: DATABASE_URL, NATS_URL, JWKS_URL, TENANT_SERVICE_URL, TERMINOLOGY_SERVICE_URL, FHIR_GATEWAY_URL, OBJECT_STORE_BUCKET, OTEL_EXPORTER_OTLP_ENDPOINT.

9. Canary + rollback

  • Canary 5 % traffic for 30 min.
  • Rollback triggers: availability < 99.5 %, payment latency p95 > 3 s, ledger integrity mismatch > 0, error rate > 2 %.
  • Blue/green fallback for DB migrations: expand → migrate → contract.

10. Scaling notes

  • Statement runs are tenant-partitioned and offloaded to worker pool; can scale independently.
  • POST /payments is DB-bound — increase Postgres connection pool (default 20 per replica) before scaling replicas.
  • Outbox relay scales vertically; one relay per replica; NATS consumer-group fan-out.