Population Health Service — Domain Model
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 03 platform-services · 02 DDD
1. Aggregates
1.1 PopulationCohort
The central analytical artifact. Defines a patient set via a boolean DSL expression and tracks versioned membership.
Invariants:
- Definition must be a valid expression tree; parser rejects on creation.
- Version is immutable once created; new predicates create new version.
- Refresh jobs for the same cohort must be coalesced (no concurrent duplicate jobs).
membershipCountis never negative.
State machine:
| State | Meaning |
|---|---|
| Draft | Definition saved; not yet evaluated |
| Active | Membership evaluated; ready for use |
| Refreshing | Background job running |
| Archived | Soft-deleted; read-only |
1.2 DiseaseRegistryEntry
Per-patient, per-registry-type row capturing clinical control status.
Invariants:
registryTypemust be from the allowed enum (TB, malaria, MCH, diabetes, hypertension, COPD, asthma, CHF, CKD, mental_health, obesity).- One active entry per (tenantId, patientId, registryType, nodeId).
riskTiervalues: low | medium | high | critical.
1.3 RiskScore
Stores computed and manually-overridden risk tiers for a patient within a model.
Invariants:
- Computed baseline is immutable after write.
- Manual override requires
overrideReason(non-empty). - Override must be auditable; emits domain event.
1.4 OutreachItem
Represents a single patient contact within an outreach list.
State machine:
1.5 QualityMetricSnapshot
Immutable point-in-time measurement of a quality indicator.
Invariants:
denominatormust be ≥numerator.rate = numerator / (denominator - exclusions); if denominator = exclusions, rate is null withreason: empty_denominator.- Once persisted, a snapshot is never mutated; a new snapshot supersedes it.
1.6 HmisExportJob
Tracks a scheduled or on-demand DHIS2 indicator push.
States: queued → running → completed | failed | retrying
Invariants:
- One active job per (tenantId, indicatorFamily, period); duplicates are rejected.
- Failed job retries ≤ 3 before terminal failure with alert.
1.7 DeidentExportJob
Tracks a research export after de-identification pipeline.
Invariants:
- De-identification run must complete (k-verified, ε-budget consumed) before output is released.
- Output is never linkable to source cohort IDs post-release.
- Consent check must pass before job creation.
2. Value Objects
| Value Object | Fields | Notes |
|---|---|---|
CohortDefinition | version, expressionTree (JSON) | Immutable; parser validates on construction |
RiskTier | low | medium | high | critical | Branded enum |
OutreachStatus | see state machine above | Branded string |
IndicatorPeriod | start: Date, end: Date, frequency: daily|weekly|monthly | For HMIS scheduling |
DeidentConfig | kAnonymityK: number, dpEpsilon: number, suppressionThreshold: number | Validated: k≥5, ε≤1.0 |
QualityProgram | hedis | qof | ohip_qip | moph_custom | donor | Determines measure pack |
3. Domain Events
| Event | Aggregate | Trigger |
|---|---|---|
population_health.cohort.created.v1 | PopulationCohort | Cohort definition persisted |
population_health.cohort.refreshed.v1 | PopulationCohort | Membership refresh job completes |
population_health.risk_score.computed.v1 | RiskScore | Scoring job completes for patient set |
population_health.risk_score.overridden.v1 | RiskScore | Manual tier override recorded |
population_health.care_gap.detected.v1 | (projection) | Care-gap run identifies interventions |
population_health.outreach_list.generated.v1 | OutreachItem | List creation job completes |
population_health.outreach_item.status_changed.v1 | OutreachItem | Lifecycle state transition |
population_health.quality_metric.calculated.v1 | QualityMetricSnapshot | Snapshot job completes |
population_health.hmis_export.completed.v1 | HmisExportJob | DHIS2 push succeeds |
population_health.hmis_export.failed.v1 | HmisExportJob | DHIS2 push fails after retries |
population_health.deident_export.released.v1 | DeidentExportJob | De-identified dataset released to researcher |
4. Ubiquitous Language
| Term | Definition |
|---|---|
| Cohort | A named, versioned patient set defined by boolean predicates |
| Cohort refresh | Re-evaluation of cohort membership against current clinical data |
| Registry | Disease-specific patient tracking table (e.g., Diabetes Registry) |
| Care gap | An overdue or missed clinical intervention for a patient |
| Risk tier | Patient stratification: low / medium / high / critical |
| Quality measure | A numerator/denominator calculation measuring care delivery performance |
| HMIS | Health Management Information System — national aggregate reporting infrastructure |
| DHIS2 | District Health Information Software version 2; the MoPH HMIS platform |
| De-identification | Process applying k-anonymity + differential privacy before data export |
| k-anonymity | Privacy model ensuring each record is indistinguishable from ≥k-1 others |
| Differential privacy (ε) | Statistical privacy guarantee; ε≤1.0 required for all research exports |
| Outreach list | An ordered set of patients requiring contact for care-gap or recall |
| Secondary use | Any use of clinical data beyond direct care (research, quality, surveillance) |
| Facility aggregate | Pre-computed aggregate for a single facility; offline-safe |
| Indicator family | A grouping of HMIS indicators sharing a reporting schedule and push adapter |