mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +00:00
feat(insights): batch the derived-metric reads behind one route
The Insights cold mount fired 14+ independent GET /api/insights/derived requests — Readiness, Sleep and the vitals baselines are compute-on-visit, and all of them share one Prisma pool. That is the pool-starvation class that surfaces as the app hanging then recovering. Add GET /api/insights/derived/batch?metrics=a,b,c[:type] that resolves the requested metrics server-side under a bounded p-limit(4) with the profile loaded once via the shared loadBaselineProfile, returning a map of the same flat Derived<T> envelope keyed by the request token. Add the useDerivedBatch hook + the insightsDerivedBatch query-key factory entry; the single-metric route + hook stay for the per-score detail pages. The single route now also adopts loadBaselineProfile instead of re-inlining the profile read. Honors the existing 8s ceiling, retry:0, replace-with-fallback, and warms nothing on visit. Register the new route in the OpenAPI contract.
This commit is contained in:
1 parent
3f8c8e750c
commit
b92d5cec82
8 files changed
+561
-16
No files matched your search
@@ -2484,6 +2484,40 @@ paths:
|
||||
"401": *a1
|
||||
"422": *a2
|
||||
"429": *a3
|
||||
/api/insights/derived/batch:
|
||||
get:
|
||||
tags:
|
||||
- Insights
|
||||
summary: Derived wellness metrics (batched compute-once)
|
||||
description: v1.10.0 — resolve several derived wellness metrics in ONE request. The `metrics` CSV names the metrics (a
|
||||
`metric:type` token sub-targets a VITALS_BASELINE vital); the server fans out under a bounded limiter with the
|
||||
profile loaded once and returns a map keyed by the per-request token. Collapses the Insights cold-mount fan-out
|
||||
of 14+ independent single-metric requests — the pool-starvation class that surfaces as a hang-then-recover. The
|
||||
single-metric route stays for the per-score detail pages. Auth via cookie or Bearer.
|
||||
parameters:
|
||||
- in: query
|
||||
name: metrics
|
||||
schema:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 1024
|
||||
description: Comma-separated derived-metric tokens. Each is a `<DERIVED_METRIC_ID>` or
|
||||
`<DERIVED_METRIC_ID>:<MeasurementType>` (the colon sub-targets a VITALS_BASELINE vital). An unknown id
|
||||
422s; at most 24 tokens; duplicates collapse.
|
||||
required: true
|
||||
description: Comma-separated derived-metric tokens. Each is a `<DERIVED_METRIC_ID>` or
|
||||
`<DERIVED_METRIC_ID>:<MeasurementType>` (the colon sub-targets a VITALS_BASELINE vital). An unknown id 422s;
|
||||
at most 24 tokens; duplicates collapse.
|
||||
responses:
|
||||
"200":
|
||||
description: The map of derived-metric values, keyed by token.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DerivedBatchResponseEnvelope"
|
||||
"401": *a1
|
||||
"422": *a2
|
||||
"429": *a3
|
||||
/api/insights/correlations:
|
||||
get:
|
||||
tags:
|
||||
@@ -7720,6 +7754,41 @@ components:
|
||||
- windowDays
|
||||
- computedAt
|
||||
additionalProperties: false
|
||||
DerivedBatchResponseEnvelope:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: "#/components/schemas/DerivedBatchResponse"
|
||||
error:
|
||||
type: "null"
|
||||
meta:
|
||||
type: object
|
||||
properties:
|
||||
requestId:
|
||||
type: string
|
||||
additionalProperties: false
|
||||
required:
|
||||
- data
|
||||
- error
|
||||
additionalProperties: false
|
||||
DerivedBatchResponse:
|
||||
type: object
|
||||
properties:
|
||||
metrics:
|
||||
type: object
|
||||
propertyNames:
|
||||
type: string
|
||||
additionalProperties:
|
||||
$ref: "#/components/schemas/DerivedMetricResponse"
|
||||
description: Map keyed by the per-request token (`<metric>` or `<metric>:<type>`). Each value is the same flat
|
||||
`Derived<T>` envelope the single-metric route returns, so a client decodes one shape and reads back exactly
|
||||
the tokens it asked for.
|
||||
required:
|
||||
- metrics
|
||||
additionalProperties: false
|
||||
description: Batched derived-metric values. One request resolves the whole dashboard grid (the wellness scores + the
|
||||
derived re-frames + one baseline per vital) instead of N concurrent single-metric requests sharing the Prisma
|
||||
pool. Pure compute over the rollup tier — no LLM, no narrative, no cache table.
|
||||
CorrelationDiscoveryResponseEnvelope:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in new issue
Block a user