mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
* feat(insights): inline charts in AI findings via allowlisted metric tokens Lets the AI insight advisor inline a Recharts panel directly under the prose paragraph it talks about — e.g. a finding centred on systolic BP renders the BP chart immediately beneath itself, instead of forcing the user to scroll back to the dashboard charts. Tokens are routed through a server-side allowlist: - 13 fixed strings (one per MeasurementType plus MOOD and COMPLIANCE). - A drift test fails if a new MeasurementType is added without a token. - The greedy `[A-Z_]+` regex caps the parse so trailing junk like `metric:WEIGHT' onclick='alert(1)'` cleaves cleanly into the safe metric and inert React text — there is no markdown / no eval path. - Hallucinated tokens (`metric:NUKE`) are silently dropped. - The visible prose is run through `stripChartTokens` so the literal token never reaches the DOM. Prompts (base + 7 domain prompts, EN + DE) tell the model it may embed exactly one of the allowlisted tokens inside `summary` or a finding's `label`/`guideline` — nothing else has any effect. Co-Authored-By: Marc-André Bombeck <mbombeck@gmail.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(insights): drop metric:MOOD and metric:COMPLIANCE until dedicated charts exist Review-pass M1: those two tokens routed through HealthChart, which validates `type` against the `MeasurementType` Zod enum. MOOD and COMPLIANCE aren't in the enum, so the request 422'd and the chart panel rendered "no data" — silently degrading the most-promoted UX path under prose that explicitly talked about the user's mood or adherence. Allowlist + every prompt now lists only the 11 tokens that actually render a real chart. The drift test inverts the previous "must include MOOD/COMPLIANCE" assertion to "must NOT include them", locking the contract until dedicated MoodChart / ComplianceChart components ship. 494 tests green, typecheck clean. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>