fix(insights): align BD-Zielbereich delta math with comparison window

The tile computed `bp30 - bpAll` regardless of which baseline the
user picked under Settings → Dashboard, while rendering a caption
keyed on `comparisonBaseline` ("vs. last month" / "vs. last year").
The math therefore lied to the user. Every other trend tile uses
`tileCompareDelta()` against period-aligned `avg30LastMonth` /
`avg30LastYear` baselines.

Add `priorMonth` (now-60d…now-30d) and `priorYear` (now-395d…
now-365d) windows to `computeBpInTargetWindows()`. Ship the pcts on
the analytics envelope as `bpInTargetPctPriorMonth` /
`bpInTargetPctPriorYear`. Route the dashboard's `bpCompareDelta` to
subtract the prior window matching the user's baseline; fall back
to null for `none`.

Three new bp-in-target unit tests (priorMonth, priorYear, null
windows) and two insights-polish guards (envelope contains the
fields, page no longer subtracts `bpAll`).

Closes Code-H2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc-André BombeckandClaude Opus 4.7 committed 2026-05-10 22:08:03 +02:00
1 parent 75ccc01984
commit ef597bfbbd
5 files changed
+180 -2

No files matched your search

+14
View File
@@ -70,6 +70,16 @@ export const GET = apiHandler(async () => {
let bpInTargetPct7d: number | null = null;
let bpInTargetPct30d: number | null = null;
let bpInTargetPctAllTime: number | null = null;
/**
* v1.4.22 W5 reconcile (Code-H2) — period-aligned prior-window
* pcts so the BD-Zielbereich tile's comparison-overlay caption
* stops mismatching its math with its label. The tile's
* `compareDelta` is `last30Days - priorMonth` (or `… - priorYear`)
* matching the user's `comparisonBaseline` selection, never
* `last30Days - allTime` (the v1.4.22 A2 shortcut).
*/
let bpInTargetPctPriorMonth: number | null = null;
let bpInTargetPctPriorYear: number | null = null;
const bpTargets = getBpTargets(user.dateOfBirth);
if (bpTargets) {
const now = new Date();
@@ -99,6 +109,8 @@ export const GET = apiHandler(async () => {
bpInTargetPct7d = windows.last7Days?.pct ?? null;
bpInTargetPct30d = windows.last30Days?.pct ?? null;
bpInTargetPctAllTime = windows.allTime?.pct ?? null;
bpInTargetPctPriorMonth = windows.priorMonth?.pct ?? null;
bpInTargetPctPriorYear = windows.priorYear?.pct ?? null;
}
// Per-context glucose summaries (canonical mg/dL).
@@ -153,6 +165,8 @@ export const GET = apiHandler(async () => {
bpInTargetPct7d,
bpInTargetPct30d,
bpInTargetPctAllTime,
bpInTargetPctPriorMonth,
bpInTargetPctPriorYear,
glucoseByContext,
correlations,
healthScore,