feat(insights): TRAJECTORY forecasting derived metric with a widening band

Add a short-horizon OLS projection over the DAY-native per-day mean
series, extending the existing trendSlope. The fit, residual standard
error and prediction interval are computed at DAY granularity only — the
rollup invariant forbids composing a slope/sd from WEEK/MONTH buckets.

The projection is gated on fit quality (R squared), in-window history and
staleness: below any floor the engine returns insufficient rather than a
weak line, so noise is never extrapolated. The prediction-interval band
widens with the horizon distance from the data centre, so the fan
visibly communicates uncertainty.

Register TRAJECTORY in the derived registry and dispatch (additive,
iOS-forward-compatible; the capabilities endpoint and drift-guard pick it
up automatically). Surface it on the weight detail page as a forecast
band beneath the chart, labelled a projection with the cited method and
a conditional, range-only headline — never a prediction or a dated
event. i18n across all six locales.
This commit is contained in:
Marc-André Bombeck committed 2026-06-04 01:40:27 +02:00
1 parent dd1071158f
commit 0be484c8a3
16 files changed
+1080 -2

No files matched your search

+8
View File
@@ -17,6 +17,7 @@ import { MeasurementDiversityNudge } from "@/components/insights/measurement-div
import { MetricRangeControls } from "@/components/insights/metric-range-controls";
import { MetricTargetSummary } from "@/components/insights/metric-target-summary";
import { SubPageShell } from "@/components/insights/sub-page-shell";
import { TrajectoryForecastCard } from "@/components/insights/derived/trajectory-forecast-card";
import { buildWeightBandsFromHeight } from "@/lib/analytics/value-bands";
/**
@@ -103,6 +104,13 @@ export default function InsightsGewichtPage() {
<MetricTargetSummary slug="weight" />
<TrajectoryForecastCard
type="WEIGHT"
unit="kg"
color="#bd93f9"
enabled={!isEmpty}
/>
<InsightStatusCard
title={t("insights.assessmentTitle")}
icon={<Scale className="h-5 w-5" />}