Population Health Service — Application Logic
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 03 platform-services · 02 DDD
1. Commands (Write Use Cases)
| Command | Handler | Description |
|---|---|---|
CreateCohortCommand | CreateCohortUseCase | Validate DSL, persist definition v1, emit cohort.created |
TriggerCohortRefreshCommand | TriggerCohortRefreshUseCase | Coalesce duplicate, enqueue worker job |
ComputeRiskScoreCommand | ComputeRiskScoreUseCase | Enqueue scoring job for cohort or patient set |
OverrideRiskTierCommand | OverrideRiskTierUseCase | Record manual override with reason; emit risk_score.overridden |
GenerateOutreachListCommand | GenerateOutreachListUseCase | Validate cohort exists; enqueue generation job |
UpdateOutreachItemCommand | UpdateOutreachItemUseCase | FSM transition with validation; emit outreach_item.status_changed |
TriggerQualityMetricSnapshotCommand | TriggerQualityMetricSnapshotUseCase | Enqueue quality compute job per program/metric |
TriggerHmisExportCommand | TriggerHmisExportUseCase | Validate indicator family, deduplicate, enqueue DHIS2 push |
CreateDeidentExportJobCommand | CreateDeidentExportJobUseCase | Consent check → de-identification → release dataset |
2. Queries (Read Use Cases)
| Query | Handler | Description |
|---|---|---|
GetDashboardQuery | GetDashboardUseCase | Aggregate metrics scoped by tenant/facility/department/provider |
GetCohortListQuery | GetCohortListUseCase | Paginated cohort list with ownership filter |
GetCohortDetailQuery | GetCohortDetailUseCase | Cohort metadata + membership stats |
GetRegistryListQuery | GetRegistryListUseCase | Disease registry rows with risk/status filters |
GetScreeningComplianceQuery | GetScreeningComplianceUseCase | Aggregate compliance rates by type |
GetImmunizationCoverageQuery | GetImmunizationCoverageUseCase | Coverage by age band and vaccine type |
GetQualityMetricsQuery | GetQualityMetricsUseCase | Snapshots + trend series per program |
GetOutreachListQuery | GetOutreachListUseCase | Paginated outreach items with status filter |
GetExportStatusQuery | GetExportStatusUseCase | Export job status and download link |
3. Ports (Interfaces)
| Port | Type | Implementation |
|---|---|---|
CohortRepository | Repository | postgres-cohort.adapter.ts |
RegistryRepository | Repository | postgres-registry.adapter.ts |
RiskScoreRepository | Repository | postgres-risk-score.adapter.ts |
OutreachRepository | Repository | postgres-outreach.adapter.ts |
QualityMetricRepository | Repository | postgres-quality-metric.adapter.ts |
HmisExportRepository | Repository | postgres-hmis-export.adapter.ts |
CohortWorkerPort | Outbound | nats-cohort-worker.adapter.ts |
RiskScoringPort | Outbound | nats-risk-worker.adapter.ts |
Dhis2ApiPort | Outbound | dhis2-rest.adapter.ts |
DeidentPipelinePort | Outbound | deident-pipeline.adapter.ts |
EventPublisherPort | Outbound | nats-event-publisher.adapter.ts (outbox relay) |
ConsentPolicyPort | Outbound | access-policy.adapter.ts |
AuditPort | Outbound | nats-audit.adapter.ts |
FhirGatewayPort | Outbound | fhir-gateway.adapter.ts (MeasureReport push) |
OfflineReportPort | Outbound | offline-report-writer.adapter.ts |
4. Orchestration Flows
4.1 Cohort Refresh Flow
4.2 HMIS DHIS2 Export Flow
4.3 De-Identified Research Export Flow
5. Saga / Outbox Patterns
| Pattern | Where used |
|---|---|
| Outbox relay | All domain events published via transactional outbox in population_health_outbox table; NATS relay reads and deletes after delivery |
| Inbox deduplication | Consumed scheduling and clinical events deduped via population_health_inbox table by CloudEvent id |
| Idempotent cohort jobs | Cohort refresh and HMIS export jobs keyed by (tenantId, cohortId, periodKey) — duplicate enqueue is no-op |
| Compensating action | Failed HMIS export after max retries emits hmis_export.failed event; ops team is paged via alert rule |
6. Error Handling
| Error | HTTP | Code | Action |
|---|---|---|---|
| Invalid cohort DSL | 400 | INVALID_COHORT_DSL | Return field-level validation errors |
| Cohort not found | 404 | COHORT_NOT_FOUND | Return 404 with cohortId |
| Refresh already running | 202 | — | Return existing jobId |
| Consent check failed | 403 | CONSENT_REQUIRED | Block export, log attempt |
| De-identification k-threshold not met | 422 | DEIDENT_K_THRESHOLD_VIOLATION | Abort export, log suppression count |
| DHIS2 unreachable | 503 | DHIS2_UNAVAILABLE | Enqueue retry; alert if max retries |
| Export rate limit | 429 | EXPORT_RATE_LIMIT | Return retry-after header |
| Cross-tenant scope violation | 403 | CROSS_TENANT_SCOPE_VIOLATION | Log security event; return 403 |