Files
HealthLog/src/lib/report-selection/template.ts
T
Marc-André Bombeck 9e2a0681b2 feat(doctor-report): add sleep, HRV, steps, workouts and the medication effect
The standard report template now carries sleep duration, heart-rate
variability as two labelled rows (SDNN and RMSSD), daily steps, a
per-sport workout summary and the change around each medication start.
Each still rides its module, and the template is still only applied by
the button that names it; saved selections and share links are
untouched.

Two structured leaves join the catalogue: WORKOUTS (activity group,
workouts module) and MEDICATION_EFFECT (medications group). The workout
block reads narrow rows through the canonical-workout picker and sums
them per sport. The effect block reuses the efficacy loader with the
report's end as its horizon, carries a target only when that target's
own measurement leaf is admitted, and is capped at eight medications.

In the PDF the wearable series chart at half width, two to a row, in
the units the table prints; the workout and effect blocks are compact
tables with short notes. The clinician view renders both blocks from
the same payload. RMSSD joins the dense day-bucket path so long windows
stay aggregated.
2026-10-21 21:55:57 +02:00

78 lines
2.8 KiB
TypeScript

/**
* The one shipped template: what a general doctor's visit usually needs.
*
* Nothing applies it on its own. It reaches a selection only when a person
* presses the button that carries its name, on a panel they are looking at —
* never on load, never on a stored selection, never on a share link, never on
* a surface that cannot ask a human. A set that arrives without being asked
* for is a preselection whatever it is called, and the one thing this release
* refuses is material in a report nobody ticked.
*
* The template intersects the fenced tier at zero leaves, and
* `catalogue-guard.test.ts` fails the build if that stops being true.
*/
import { type ReportLeafId } from "./catalogue";
/**
* Identity and insurer (the cover page a practice files the document under),
* the three classic vitals, weight and BMI, the glucose series and its panel,
* labs, the drug list, adherence and the effect around each start, sleep,
* both heart-rate-variability statistics, daily steps and the workout summary,
* allergies, past illness episodes, the surgical history and the immunization
* record.
*
* The wearable picks (v1.44) are the four a general visit reads: sleep
* duration, SDNN and RMSSD as two labelled rows, steps and the per-sport
* workout block. Each is one table row or one compact block, and each still
* rides its module: an account with sleep or workouts switched off gets none
* of it.
*
* Deliberately not in it: the rest of what a wearable produces, gait and
* mobility, environment exposure, the per-dose administration ledger (a
* clinician asks for adherence, not for every logged dose), the GLP-1 block,
* and the whole fenced tier.
*/
export const STANDARD_TEMPLATE_LEAVES: readonly ReportLeafId[] = [
"PATIENT_IDENTITY",
"EMERGENCY",
"INSURANCE",
"BLOOD_PRESSURE_SYS",
"BLOOD_PRESSURE_DIA",
"PULSE",
"WEIGHT",
"BODY_MASS_INDEX",
"BLOOD_GLUCOSE",
"GLUCOSE_PANEL",
"LAB_RESULTS",
"MEDICATION_LIST",
"MEDICATION_COMPLIANCE",
"MEDICATION_EFFECT",
"SLEEP_DURATION",
"HEART_RATE_VARIABILITY",
"HRV_RMSSD",
"ACTIVITY_STEPS",
"WORKOUTS",
"ALLERGIES",
"ILLNESS_EPISODES",
"SURGICAL_HISTORY",
"IMMUNIZATIONS",
];
/** The template's i18n label — it is named on the button, never anonymous. */
export const STANDARD_TEMPLATE_LABEL_KEY = "reportSelection.templateStandard";
/**
* The template as one surface can offer it: the shipped set minus the leaves
* that surface may not carry (the share-link form hides the insurance leaf,
* which the server refuses anyway).
*
* Pure, so "one click applies exactly the standard set and nothing outside it"
* is provable without a DOM.
*/
export function standardTemplateFor(
hiddenLeaves: readonly ReportLeafId[] = [],
): ReportLeafId[] {
const hidden = new Set(hiddenLeaves);
return STANDARD_TEMPLATE_LEAVES.filter((leaf) => !hidden.has(leaf));
}