Skip to main content

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)

CommandHandlerDescription
CreateCohortCommandCreateCohortUseCaseValidate DSL, persist definition v1, emit cohort.created
TriggerCohortRefreshCommandTriggerCohortRefreshUseCaseCoalesce duplicate, enqueue worker job
ComputeRiskScoreCommandComputeRiskScoreUseCaseEnqueue scoring job for cohort or patient set
OverrideRiskTierCommandOverrideRiskTierUseCaseRecord manual override with reason; emit risk_score.overridden
GenerateOutreachListCommandGenerateOutreachListUseCaseValidate cohort exists; enqueue generation job
UpdateOutreachItemCommandUpdateOutreachItemUseCaseFSM transition with validation; emit outreach_item.status_changed
TriggerQualityMetricSnapshotCommandTriggerQualityMetricSnapshotUseCaseEnqueue quality compute job per program/metric
TriggerHmisExportCommandTriggerHmisExportUseCaseValidate indicator family, deduplicate, enqueue DHIS2 push
CreateDeidentExportJobCommandCreateDeidentExportJobUseCaseConsent check → de-identification → release dataset

2. Queries (Read Use Cases)

QueryHandlerDescription
GetDashboardQueryGetDashboardUseCaseAggregate metrics scoped by tenant/facility/department/provider
GetCohortListQueryGetCohortListUseCasePaginated cohort list with ownership filter
GetCohortDetailQueryGetCohortDetailUseCaseCohort metadata + membership stats
GetRegistryListQueryGetRegistryListUseCaseDisease registry rows with risk/status filters
GetScreeningComplianceQueryGetScreeningComplianceUseCaseAggregate compliance rates by type
GetImmunizationCoverageQueryGetImmunizationCoverageUseCaseCoverage by age band and vaccine type
GetQualityMetricsQueryGetQualityMetricsUseCaseSnapshots + trend series per program
GetOutreachListQueryGetOutreachListUseCasePaginated outreach items with status filter
GetExportStatusQueryGetExportStatusUseCaseExport job status and download link

3. Ports (Interfaces)

PortTypeImplementation
CohortRepositoryRepositorypostgres-cohort.adapter.ts
RegistryRepositoryRepositorypostgres-registry.adapter.ts
RiskScoreRepositoryRepositorypostgres-risk-score.adapter.ts
OutreachRepositoryRepositorypostgres-outreach.adapter.ts
QualityMetricRepositoryRepositorypostgres-quality-metric.adapter.ts
HmisExportRepositoryRepositorypostgres-hmis-export.adapter.ts
CohortWorkerPortOutboundnats-cohort-worker.adapter.ts
RiskScoringPortOutboundnats-risk-worker.adapter.ts
Dhis2ApiPortOutbounddhis2-rest.adapter.ts
DeidentPipelinePortOutbounddeident-pipeline.adapter.ts
EventPublisherPortOutboundnats-event-publisher.adapter.ts (outbox relay)
ConsentPolicyPortOutboundaccess-policy.adapter.ts
AuditPortOutboundnats-audit.adapter.ts
FhirGatewayPortOutboundfhir-gateway.adapter.ts (MeasureReport push)
OfflineReportPortOutboundoffline-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

PatternWhere used
Outbox relayAll domain events published via transactional outbox in population_health_outbox table; NATS relay reads and deletes after delivery
Inbox deduplicationConsumed scheduling and clinical events deduped via population_health_inbox table by CloudEvent id
Idempotent cohort jobsCohort refresh and HMIS export jobs keyed by (tenantId, cohortId, periodKey) — duplicate enqueue is no-op
Compensating actionFailed HMIS export after max retries emits hmis_export.failed event; ops team is paged via alert rule

6. Error Handling

ErrorHTTPCodeAction
Invalid cohort DSL400INVALID_COHORT_DSLReturn field-level validation errors
Cohort not found404COHORT_NOT_FOUNDReturn 404 with cohortId
Refresh already running202Return existing jobId
Consent check failed403CONSENT_REQUIREDBlock export, log attempt
De-identification k-threshold not met422DEIDENT_K_THRESHOLD_VIOLATIONAbort export, log suppression count
DHIS2 unreachable503DHIS2_UNAVAILABLEEnqueue retry; alert if max retries
Export rate limit429EXPORT_RATE_LIMITReturn retry-after header
Cross-tenant scope violation403CROSS_TENANT_SCOPE_VIOLATIONLog security event; return 403