feat(dashboard): resolve the selected score rings on the snapshot

Resolve the selected rings server-side and publish them as scoreRings
on the dashboard snapshot (additive, optional for cached payloads).
READINESS, RECOVERY_SCORE and SLEEP_SCORE go through the same
computeDerivedMetric dispatcher the derived batch route calls, with the
profile loaded once via the shared loader; MED_COMPLIANCE pools the
7-day adherence across active non-PRN medications through the canonical
compliance engine (taken over taken-plus-missed, skips out of the
denominator) and bands on the targets-tile thresholds. Rings gate on
their owning module plus the insights gate for the derived trio, drop
out when no data backs them, and resolve fail-soft per ring so a
throwing engine never sinks the snapshot. OpenAPI regenerated.
This commit is contained in:
Marc-André Bombeck committed 2026-07-05 15:08:09 +02:00
1 parent ed6911bb03
commit 5c0cde207f
6 files changed
+707 -25

No files matched your search

+32
View File
@@ -21417,6 +21417,38 @@ components:
description: Personal health score summary (0..100 score, traffic-light band, week-over-week delta). Null on a
rollup-coverage miss (it rides the thick phase alongside `extras`) and when no pillar is computable.
Component breakdown is deliberately not serialised here.
scoreRings:
description: "User-selected hero score rings (max 3, `selectedScoreRings` on the dashboard layout), resolved
server-side: READINESS / RECOVERY_SCORE / SLEEP_SCORE via the derived engines (module-gated like
`/api/insights/derived`), MED_COMPLIANCE as the pooled 7-day medication adherence (0..100, banded ≥90 green
/ ≥70 yellow / else red). Only rings with data appear, in selection order — a missing entry means no data or
a disabled module, never zero. Clients render what arrives and never recompute."
type: array
items:
type: object
properties:
id:
type: string
enum:
- READINESS
- RECOVERY_SCORE
- SLEEP_SCORE
- MED_COMPLIANCE
score:
type: integer
minimum: -9007199254740991
maximum: 9007199254740991
band:
type: string
enum:
- green
- yellow
- red
required:
- id
- score
- band
additionalProperties: false
briefing:
anyOf:
- type: object