mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 22:26:13 +00:00
feat(illness): Rest Mode — annotate score/recovery/streaks during an active episode + FHIR/doctor-report
An active illness/condition episode annotates, it never penalises: the measured number is untouched, only the narrative changes. - rest-mode.ts: one server-authoritative resolver (module-gated, fail-soft) for "is the account in Rest Mode + which episodes back it". iOS mirrors the resolved context, never recomputes the suppression. - health-score: /api/analytics attaches a value-free Rest Mode annotation; computeHealthScore stays pure (score never adjusted). - recovery-score: computeRecoveryScore carries the Rest Mode context as of the scored day; the persisted blend is unchanged. - coach-nudge: pause cadence-nudges during an active episode (new skippedDuringIllness counter, gate sits before the trigger search). - achievements: bridgeFrozenStreakGaps freezes (does not break) every day-streak across illness days; never invents a streak, a non-illness gap still breaks. - coincident-deviation: reframe a fired flag as illness-explained; vital numbers untouched. Surfaced as a neutral line on the insights card. - coach snapshot: illness history + active illness as load-bearing context so the coach knows about Rest Mode (no decrypted note reaches the prompt). - FHIR: illness episodes map to Condition (generic disease root, label on code.text, patient-reported/unconfirmed) + a bounding Encounter. - doctor-report: module-gated illness section in the aggregator + PDF table (retrospective, neutral palette); FHIR Condition section in the bundle. i18n x6 for the report + reframe copy. Tests: score-annotation-not- penalisation, streak-freeze, coach-nudge pause, FHIR Condition/Encounter mapping, doctor-report inclusion, Rest Mode resolver. typecheck/lint/test green, openapi in sync, knip clean.
This commit is contained in:
1 parent
8447ad90cc
commit
c59cf0b652
37 files changed
+1352
-24
No files matched your search
@@ -18,6 +18,7 @@ import {
|
||||
} from "@/lib/analytics/bp-in-target-fast-path";
|
||||
import { computeUserHealthScoreFastPath } from "@/lib/analytics/health-score-fast-path";
|
||||
import { isModuleEnabled } from "@/lib/modules/gate";
|
||||
import { resolveRestMode } from "@/lib/illness/rest-mode";
|
||||
import { buildHealthScoreBpInputs } from "@/lib/analytics/health-score-inputs";
|
||||
import { deriveBpWindow90 } from "@/lib/analytics/window-confidence";
|
||||
import { computeCorrelationHypothesesFastPath } from "@/lib/analytics/correlations-fast-path";
|
||||
@@ -444,6 +445,21 @@ async function buildAnalyticsResponse(user: AuthedUser) {
|
||||
moodEnabled,
|
||||
});
|
||||
|
||||
// v1.18.1 P4 — Rest Mode annotation. When an illness/condition episode is
|
||||
// active we frame the score (not penalise it): the number above is left
|
||||
// exactly as computed and we attach a value-free "you were unwell" context.
|
||||
// Resolved server-side so iOS mirrors the same fact, never recomputing it.
|
||||
if (healthScore) {
|
||||
const restMode = await resolveRestMode(user.id);
|
||||
healthScore.restMode = restMode.active
|
||||
? {
|
||||
active: true,
|
||||
since: restMode.since,
|
||||
episodeCount: restMode.episodeCount,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
return {
|
||||
summaries: results,
|
||||
bmi,
|
||||
|
||||
Reference in new issue
Block a user