feat(insights): add composite scores, score-anatomy view, and correlation discovery

Build the composite tier of the derived-metrics layer on the shared seam:

- Sleep score — a transparent 0–100 composite from sufficiency, efficiency,
  consistency, timing and composition sub-scores over the per-stage sleep
  rows, reweighting around any sub-score the data cannot support (a legacy
  asleep-only night drops composition gracefully rather than fabricating it).
- Wellness/readiness index — extends the health-score null-redistribution
  blend with resting-HR, HRV (SDNN), sleep, respiratory-rate and mood
  deviation-from-baseline components; returns insufficient below two present
  components so it never headlines from one signal.
- Coincident-deviation flag — counts vitals outside their personal band on
  the latest day and fires when two or more coincide, listing the
  contributing vitals as possible factors, never a cause or a diagnosis.

Each composite cites its standard, carries coverage + confidence +
provenance, and reweights around missing inputs.

Add an FDR-controlled correlation discovery engine behind
GET /api/insights/correlations: it scans a curated behaviour x outcome
matrix, lag-joins each behaviour day to the next day's outcome, runs Pearson
with the exact Student-t p-value, and applies Benjamini-Hochberg control
across every tested pair so only statistically-defensible patterns surface —
each tagged with n, r, p and the adjusted q, framed descriptive not causal.

Add the score-anatomy detail view at /insights/scores/<metric>: a full
score ring, ranked contributor rows each showing its push/pull and weight
share, and the cited-standard provenance explainer — reused by every
composite, mobile-first and accessible.

Regenerate the OpenAPI contract for the new metric values + the correlation
discovery response, and add the i18n keys across all six locales.
This commit is contained in:
Marc-André Bombeck committed 2026-06-02 21:19:56 +02:00
1 parent 663a3ee09d
commit 95a2a7692f
29 files changed
+3087 -30

No files matched your search

+107
View File
@@ -2371,6 +2371,26 @@ paths:
"401": *a1
"422": *a2
"429": *a3
/api/insights/correlations:
get:
tags:
- Insights
summary: Correlation discovery (FDR-controlled)
description: v1.10.0 — scans a curated behaviour × outcome matrix (daylight / mood / glucose / BP / steps × sleep / HRV
/ resting HR / weight), lag-joins each behaviour day to the next day's outcome, runs Pearson with the exact
Student-t p-value, and applies Benjamini-Hochberg FDR control across every tested pair. Only
statistically-defensible pairs surface, each carrying n, r, p, and the BH-adjusted q. Descriptive, never causal.
Gated by the operator `correlations` assistant surface. Auth via cookie or Bearer.
responses:
"200":
description: The discovered correlations + the tested-pair count.
content:
application/json:
schema:
$ref: "#/components/schemas/CorrelationDiscoveryResponseEnvelope"
"401": *a1
"422": *a2
"429": *a3
components:
schemas:
PasskeyLoginVerifyRequest:
@@ -7461,6 +7481,93 @@ components:
- windowDays
- computedAt
additionalProperties: false
CorrelationDiscoveryResponseEnvelope:
type: object
properties:
data:
$ref: "#/components/schemas/CorrelationDiscoveryResponse"
error:
type: "null"
meta:
type: object
properties:
requestId:
type: string
additionalProperties: false
required:
- data
- error
additionalProperties: false
CorrelationDiscoveryResponse:
type: object
properties:
discovered:
type: array
items:
$ref: "#/components/schemas/DiscoveredCorrelation"
description: Pairs surviving n ≥ 20, p < 0.05, AND the BH-FDR control.
pairsTested:
type: integer
minimum: -9007199254740991
maximum: 9007199254740991
description: Behaviour × outcome pairs assessed (for the honest footer).
fdrQ:
type: number
description: The FDR target the surface used.
minPairs:
type: integer
minimum: -9007199254740991
maximum: 9007199254740991
description: Minimum paired-day count enforced per pair.
required:
- discovered
- pairsTested
- fdrQ
- minPairs
additionalProperties: false
description: v1.10.0 — FDR-controlled correlation discovery over a curated behaviour × outcome matrix, lagged behaviour
→ next-day outcome. Only statistically-defensible pairs surface; descriptive, never causal.
DiscoveredCorrelation:
type: object
properties:
behaviour:
type: string
description: Behaviour channel (lag source), e.g. TIME_IN_DAYLIGHT, MOOD.
outcome:
type: string
description: Outcome channel (lag target), e.g. SLEEP_DURATION, HEART_RATE_VARIABILITY.
n:
type: integer
minimum: -9007199254740991
maximum: 9007199254740991
description: Paired-day count after the day+1 lag join (≥ 20).
r:
type: number
description: Pearson r over the lag-joined daily series.
pValue:
type: number
description: Two-sided exact Student-t p-value (< 0.05).
qValue:
type: number
description: Benjamini-Hochberg FDR-adjusted q-value (≤ the surface threshold).
interpretation:
type: string
description: Conservative, descriptive interpretation — never causal.
lagDays:
type: integer
minimum: -9007199254740991
maximum: 9007199254740991
description: Lag in days applied (1).
required:
- behaviour
- outcome
- n
- r
- pValue
- qValue
- interpretation
- lagDays
additionalProperties: false
MedicationScheduleOutput:
type: object
properties: