mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
v1.4.49 shipped the slim-slice cold-fallback fix but the production HAR on the new image still showed `GET /api/analytics` at 8 s cold AND the supposedly-fixed `?slice=summaries` request hit the same 8 s when fired concurrently. Investigation found the slim slice queues behind the default slice's per-type live walk: the 15-way `fetchMeasurementSeriesChunked` fan-out saturates the `p-limit(4)` lanes and packs the 20-slot Prisma pool for the full ~8 s on Marc's 467 745-row tenant, starving every other Prisma client (including the concurrent slim slice) until the walk drains. The default slice's `summaries` field has been produceable from the rollup tier for two releases — the slim slice already uses `computeFromRollups` + a 90-day narrow `$queryRaw` and returns the identical `DataSummary` shape sub-second. The walk lived on because two thick-only fields (`anomalyCount`, `avg30LastMonth`) only existed on the live path. A grep of every consumer in the repo confirmed: - `anomalyCount`: no consumer reads it from `/api/analytics`. The insights pipeline pulls it from its own `comprehensive-aggregator` narrow query. Slim's `0` constant is what the default route's consumers already received. - `avg30LastMonth`: read by `src/app/page.tsx:321` (dashboard comparison tile) and `src/components/insights/vo2-max-chart-row.tsx`. Easy to lift: extend the slim narrow `$queryRaw` with one extra FILTER clause for `[30d, 60d)` — the rows are already inside the 90-day outer cap so the planner reads zero additional blocks. With both fields covered, `buildAnalyticsResponse` calls `computeSummariesSlice(user.id)` once and uses its `summaries` + `lastSeenByType` directly. The 15-way fan-out, the chunked walker, the `ANALYTICS_TYPE_FETCH_CONCURRENCY` p-limit cap, the 425-day `since` window, and the `meta.analytics.bp_aggregate` annotate all delete cleanly — none had callers outside the removed code path. Net diff: -418 LOC across the route + its tests. Test updates: - `route.test.ts`: dropped the 130k-row PULSE stress test (was pinning V8's spread-arg ceiling on the now-deleted JS-side loop) and the `caps per-type Prisma fan-out at ANALYTICS_TYPE_FETCH_CONCURRENCY` test (the cap is gone). Added a negative assertion that `prisma.measurement.findMany` is never called with the chunked-walk shape `(select.id + source + deviceType, take: 5000)` and a positive assertion that `avg30LastMonth` reaches the response envelope. - `since-cap.test.ts`: dropped the `where.measuredAt.gte` per-type assertion and the `bp_aggregate.live_since` annotation assertion (both pinned the removed walk). The slim-slice no-per-type-loop invariant survives. Final: 5268 unit + integration tests pass, zero failures, lint clean, typecheck clean.