Immunizations Service — Local Dev Setup
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template
1. Prerequisites
- Node.js 22 LTS
- pnpm 9+
- Docker Desktop (or Podman)
ghasi-ehealthmonorepo cloned
2. docker-compose.yml
version: "3.9"
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: ghasi_immunizations_dev
POSTGRES_USER: ghasi
POSTGRES_PASSWORD: ghasi_dev_secret
ports:
- "5434:5432"
volumes:
- immunizations_pg_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6381:6379"
nats:
image: nats:2.10-alpine
command: ["-js", "-m", "8222"]
ports:
- "4222:4222"
- "8222:8222"
keycloak:
image: quay.io/keycloak/keycloak:24.0
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
command: start-dev --import-realm
volumes:
- ../../dev/keycloak/ghasi-realm.json:/opt/keycloak/data/import/ghasi-realm.json
ports:
- "8080:8080"
volumes:
immunizations_pg_data:
3. .env.example
# App
NODE_ENV=development
PORT=3007
LOG_LEVEL=debug
# Database
DATABASE_URL=postgresql://ghasi:ghasi_dev_secret@localhost:5434/ghasi_immunizations_dev
DATABASE_SCHEMA=immunizations
# Redis
REDIS_URL=redis://localhost:6381
# NATS
NATS_URL=nats://localhost:4222
NATS_STREAM=IMMUNIZATIONS
# Keycloak
KEYCLOAK_ISSUER=http://localhost:8080/realms/ghasi-dev
KEYCLOAK_JWKS_URI=http://localhost:8080/realms/ghasi-dev/protocol/openid-connect/certs
# Inter-service
REGISTRATION_SERVICE_URL=http://localhost:3001
TERMINOLOGY_SERVICE_URL=http://localhost:3010
INTEROP_SERVICE_URL=http://localhost:3009
AI_GATEWAY_URL=http://localhost:3011
# EPI schedule
EPI_SCHEDULE_CACHE_TTL_SECONDS=86400
# Registry sync
REGISTRY_SYNC_CRON=0 2 * * *
REGISTRY_SYNC_MAX_RETRIES=5
# Forecast worker
FORECAST_REFRESH_JOB_TTL_MS=60000
FORECAST_REFRESH_MAX_RETRIES=3
# Idempotency
IDEMPOTENCY_CACHE_TTL_SECONDS=86400
4. Setup Commands
# 1. Start infrastructure
docker compose -f services/immunizations-service/docker-compose.yml up -d
# 2. Install dependencies
pnpm install
# 3. Run DB migrations
pnpm --filter immunizations-service db:migrate
# 4. Seed EPI schedule and test data
pnpm --filter immunizations-service db:seed
# 5. Start service in watch mode
pnpm --filter immunizations-service dev
# 6. Run tests
pnpm --filter immunizations-service test
# 7. Run integration tests
pnpm --filter immunizations-service test:integration
5. Seed Data
The seed script (src/infrastructure/database/seed.ts) creates:
- 1 dev tenant (
tenant_dev_01) - 3 test patients (infant, child, adult) via registration-service stub
- Afghanistan EPI schedule loaded from
config/epi-schedule.json - Sample immunization records for the infant (BCG, OPV-0, HepB-0 completed; DTP-1 due)
- Sample contraindication for the adult patient (egg allergy → influenza)
- 1 defaulter (child missing DTP-3 dose)
6. Testing Against NATS
To observe events locally:
# Subscribe to all IMMUNIZATIONS events
nats sub "IMMUNIZATIONS.>" --server nats://localhost:4222
7. EPI Schedule Configuration
The Afghanistan EPI schedule is loaded from config/epi-schedule.json. To update the schedule without code deployment, replace this file and restart the service (or trigger a cache refresh via admin API).