mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 04:32:42 +00:00
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.