fix(validation): stop a future timestamp emitting a spurious past-bound error

Review follow-up to the shared entry-instant guard. The past-floor refine
re-ran the full plausibility predicate, so a future-dated instant tripped
both refines and the 422 carried a nonsensical "too far in the past" message
alongside the correct future one. The floor refine now checks the past bound
alone; a future value emits only the future message, matching the pre-refactor
single-message contract.

Also harden the Health-Score BP inputs and de-duplicate the tile-window
derivation surfaced in the same review:

- the prior-week graded score now keys off the prior-week window's own
  sufficiency rather than the current window's, so the week-over-week graded
  delta never pairs a confident current value against a thin-sample prior one;
- the BD-Zielbereich 90-day count + effective span derive through one shared
  `deriveBpWindow90` helper, so the dashboard snapshot and the analytics thick
  slice can never compute the gate or the label span differently.
This commit is contained in:
Marc-André Bombeck committed 2026-06-14 13:59:56 +02:00
1 parent 3e7aa49eb0
commit 3bb130d4a1
8 files changed
+99 -27

No files matched your search

+8 -7
View File
@@ -18,7 +18,7 @@ import {
} from "@/lib/analytics/bp-in-target-fast-path";
import { computeUserHealthScoreFastPath } from "@/lib/analytics/health-score-fast-path";
import { buildHealthScoreBpInputs } from "@/lib/analytics/health-score-inputs";
import { computeWindowConfidence } from "@/lib/analytics/window-confidence";
import { deriveBpWindow90 } from "@/lib/analytics/window-confidence";
import { computeCorrelationHypothesesFastPath } from "@/lib/analytics/correlations-fast-path";
export const dynamic = "force-dynamic";
@@ -327,13 +327,14 @@ async function buildAnalyticsResponse(user: AuthedUser) {
bpInTargetPctPriorYear = windows.priorYear?.pct ?? null;
// v1.17 W1b — count + effective span for the BD-Zielbereich tile's
// confidence gate (thin-data → "collecting data"; dynamic span label).
bpInTargetCount90 = windows.last90Days?.pairs ?? 0;
bpInTargetSpanDays90 = computeWindowConfidence({
windowDays: 90,
readingCount: bpInTargetCount90,
earliestReadingAt: windows.last90EarliestAt,
// Shared helper keeps this identical to the dashboard snapshot.
const bpWindow = deriveBpWindow90(
windows.last90Days,
windows.last90EarliestAt,
now,
}).effectiveSpanDays;
);
bpInTargetCount90 = bpWindow.count;
bpInTargetSpanDays90 = bpWindow.spanDays;
}
// Per-context glucose summaries (canonical mg/dL).