Files
HealthLog/tests/integration
Marc-André Bombeck 67d05c0de9 perf(analytics): slim /api/analytics?slice=summaries slice (C1)
The default `/api/analytics` path fans out 30+ `Promise.all`-wrapped
chunked findMany reads to feed `summarize()` for every
MeasurementType. For a multi-year HealthKit user the PULSE branch
alone walks hundreds of thousands of rows before the dashboard tile
strip can paint a single arrow — even though the strip only consumes
`count / latest / avg7 / avg30 / min / max / mean` plus the three
slope tuples per type.

Add `?slice=summaries` that resolves the same `DataSummary` shape
from two SQL passes (no JS-side spread anywhere along the chain):

  1. One `$queryRaw` carrying `GROUP BY type` with `COUNT`/`MIN`/
     `MAX`/`AVG` plus 7d/30d windowed averages via `FILTER` plus
     Postgres `regr_slope` + `regr_r2` at 7/30/90-day windows.

  2. One `DISTINCT ON (type)` `$queryRaw` returning the most-recent
     `(type, value)` pair per type so the slim shape can populate
     `latest` (the value at MAX(measured_at), not MAX(value)).

Slope `direction` keeps the JS helper's 0.01-units-per-day "stable"
threshold; `confidence` is `regr_r2` rounded to 2 d.p. — both match
the existing `trendSlope()` contract so the dashboard's arrow / color
logic does not have to branch on slice. Anomaly count, lastMonth, and
lastYear means stay at `null` / `0` because the dashboard tile strip
does not paint them on first paint; the comparison-baseline widget
already opts into the default slice.

The thick `correlations` / `healthScore` / `bpInTargetPct` /
`glucoseByContext` / `sleepStages` / `bmi` blocks stay on the default
path behind a hover-prefetch / explicit slice param. C1 is purely
additive — the route's default behaviour is byte-identical.

Pinned by a 4-case unit test (mocked `$queryRaw`, slope thresholds,
null-slope branch) and a 3-case real-Postgres integration test
covering the empty user, the populated descending-WEIGHT fixture,
and the default-slice-still-thick contract. 199 unit tests pass
across `src/lib/analytics` + `src/app/api/analytics`; the
integration suite picks up `tests/integration/analytics-summaries-slice.test.ts`
on next `pnpm test:integration` run.
2026-05-16 17:33:58 +02:00
..