chore: update docs

This commit is contained in:
voltsrage
2026-06-25 00:46:54 +08:00
parent 7bb9124230
commit df6fbed401
3 changed files with 132 additions and 63 deletions
+43 -26
View File
@@ -243,27 +243,55 @@ Grafana dashboard JSON template for alert quality overview.
| Clinical Usage | 10 |
| Composite | 9.0 |
> **Status:** Complete — see [phase-34-plan.md](plans/phase-34-plan.md) for full implementation detail, tests, and file inventory.
Architecture: Each alert carries a structured explanation payload alongside the existing `Details` string. A new `AlertExplanation` value object captures score contributors, trend context, and medication context at alert creation time. Scoring consumers (NEWS2, SOFA, GCS) emit contributor breakdowns. The `TrendDetector` attaches trend summaries. `MedicationCorrelationHelper` attaches recent medication context. All explanation data is serialized as JSONB on the `ClinicalAlert` row so the explanation is immutable — it reflects the state at alert time, not query time.
> **Prerequisite:** Phase 33 for feedback loop. No hard technical dependency but sequencing allows feedback data to inform which explanations clinicians value.
### What exists
After Phase 33:
After Phase 34 (implemented):
- `ClinicalAlert.Details` is a free-text string, sometimes containing score values
- `TrendDetector` returns `TrendOutcome` enum but no narrative description
- `MedicationCorrelationHelper.TryAnnotateDetailsAsync()` appends drug info to the details string
- NEWS2, SOFA, GCS scoring returns aggregate scores but not per-component breakdowns to the alert layer
- No structured explanation model
- `AlertExplanation` value object with `ScoreContributor`, `TrendContext`, `MedicationContext`, and `NarrativeSummary`
- `ClinicalAlert.Explanation` — nullable JSONB column, immutable at alert creation
- NEWS2, SOFA, GCS, and Trend detectors assemble explanation at alert creation; `alert.generated` outbox/Kafka payloads include `explanation`
- `MedicationCorrelationHelper.TryGetContextAsync()` — structured medication context (replaces string-append to `Details`)
- Scoring results carry contributors: `News2Result`, `SofaScoringResult`, `GcsResult`, `TrendResult`
- `AlertResponse` DTO with `Explanation`; GET/list/acknowledge/resolve endpoints return it
- Dashboard `AlertReasoning.vue` and alert surfaces consume structured explanation; legacy alerts fall back to `Details`
- Simulator `AlertResponse.Explanation` + `ExpectedOutcomeValidator` with `narrativeContains` on key scenarios
- Elasticsearch indexes `NarrativeSummary`; data lake Parquet includes `explanation_json`; ward gateway sync forwards explanation
- `ExplainableAlertsTests` (10 tests) + `scripts/run-phase34-verification.sh`
- `Details` string unchanged for backward compatibility with threshold-only and legacy alerts
### What needs to be built
Six steps, in order.
Nothing — Phase 34 is complete. **Next:** [Phase 35 — Alert Lifecycle Analytics](#phase-35--alert-lifecycle-analytics).
### Verification Checklist (Phase 34)
- [x] NEWS2 alert includes per-component score contributors in explanation
- [x] SOFA alert includes per-organ-system contributors
- [x] GCS alert includes Eye/Verbal/Motor breakdown
- [x] Trend-triggered alerts include trend context with percent change and duration
- [x] Medication-correlated alerts include drug context
- [x] Narrative summary is human-readable and accurate
- [x] Existing alerts with null explanation still serialize correctly
- [x] Alert GET endpoints return explanation object
- [x] No change to scoring algorithm outputs (same scores, same thresholds)
- [x] Migration applies cleanly on existing data
- [x] Dashboard and simulator consume explanation
- [x] Downstream consumers (ES, data lake, gateway sync) include explanation fields
---
#### Step 1 — Explanation Value Objects
#### Implementation reference (Steps 17)
The step-by-step design below is retained for interview prep and onboarding. All steps are implemented; see [phase-34-plan.md](plans/phase-34-plan.md) for code paths and tests.
<details>
<summary>Original step-by-step design (Steps 16)</summary>
**`Domains/ValueObjects/AlertExplanation.cs`** (NEW):
@@ -380,20 +408,7 @@ Extend alert GET endpoints to include the `Explanation` object. The explanation
}
```
---
### Verification Checklist (Phase 34)
- [ ] NEWS2 alert includes per-component score contributors in explanation
- [ ] SOFA alert includes per-organ-system contributors
- [ ] GCS alert includes Eye/Verbal/Motor breakdown
- [ ] Trend-triggered alerts include trend context with percent change and duration
- [ ] Medication-correlated alerts include drug context
- [ ] Narrative summary is human-readable and accurate
- [ ] Existing alerts with null explanation still serialize correctly
- [ ] Alert GET endpoints return explanation object
- [ ] No change to scoring algorithm outputs (same scores, same thresholds)
- [ ] Migration applies cleanly on existing data
</details>
---
@@ -415,6 +430,8 @@ After Phase 34:
- `ClinicalAlert` has `Status` transitions: Open → Acknowledged → Resolved, Open → Escalated → Acknowledged → Resolved
- `AcknowledgedAt`, `ResolvedAt` timestamps exist on the entity
- `ClinicalAlert.Explanation` JSONB with immutable score contributors, trend, and medication context at alert time
- `AlertResponse` exposes explanation to dashboard and simulator; `Details` retained for legacy consumers
- `ClinicalAuditLog` captures some transitions but is not structured for time-series analytics
- No dedicated lifecycle event log
- No computed lifecycle metrics (median ack time, escalation rate)
@@ -673,7 +690,7 @@ Authorized for `Admin` role only. PUT upserts a rule and invalidates the Redis c
Architecture: A correlation engine groups alerts that fire within a configurable time window for the same patient into a single clinical narrative. Correlated alerts are linked by a shared `CorrelationGroupId`. The first alert in a group becomes the primary; subsequent alerts within the window attach as secondary. The group carries a composite explanation built from Phase 34 individual explanations. Clinicians see one bundled notification with the full picture instead of multiple independent alerts.
> **Prerequisite:** Phase 34 (Explainable Alerts) for structured explanations to compose into bundles.
> **Prerequisite:** Phase 34 (Explainable Alerts) **complete** — structured explanations compose into bundle narratives.
### What exists
@@ -681,9 +698,9 @@ After Phase 36:
- Alerts fire independently per scoring consumer and trend detector
- No correlation between simultaneous alerts for the same patient
- Phase 34 `AlertExplanation` provides structured per-alert context
- Phase 34 `AlertExplanation` **shipped** — per-alert `NarrativeSummary`, score contributors, trend, and medication context available on `AlertResponse`
- `AlertSuppressionService` prevents duplicate alert types but not cross-type bundling
- Medication correlation annotates individual alerts but does not group them
- Medication correlation attaches structured context to individual alerts but does not group them
### What needs to be built
@@ -953,7 +970,7 @@ After Phase 38:
- qSOFA scoring implementation in dedicated service
- GCS scoring implementation in dedicated service
- Each has different input shapes, output shapes, and integration points
- Phase 34 added contributor extraction but each scoring system returns it differently
- Phase 34 added contributor extraction but each scoring system returns it differently (**implemented** — unify via `ScoreResult.Contributors` in Phase 39)
### What needs to be built