Merge branch 'fix/v1437-review' into release/v1.43.7

# Conflicts:
#	src/app/api/analytics/route.ts
This commit is contained in:
Marc-André Bombeck committed 2026-10-20 06:20:42 +02:00
commit 45c027aee2
217 files changed
+3636 -2127

No files matched your search

+40 -12
View File
@@ -4203,10 +4203,13 @@ paths:
With `groupBy=day` on a cumulative type the rows are one sum per local day, and `limit` / `offset` page over
those days; every returned day is complete. `type=SLEEP_DURATION` returns one row per night, paged the same way
over nights. On both, `meta.total` counts the days or nights in the filtered window. A day-sum page takes
`limit` as asked (up to the list's 5000); a sleep page holds at most 1000 nights, and `meta.limit` echoes the
value applied.
those days; every returned day is complete, which is why `valueMin` / `valueMax` (a filter on single readings)
are refused with 422 beside `groupBy=day`. `type=SLEEP_DURATION` returns one row per night, paged the same way
over nights; every night of the page has a row, and a day whose only sleep is daytime naps carries `value` 0
with its naps in `napCount` / `napAsleepMinutes`. Its `dayKey` is the same day `/api/sleep/night?date=` answers
for. On both, `meta.total` counts the days or nights in the filtered window. A day-sum page takes `limit` as
asked (up to the list's 5000); a sleep page holds at most 1000 nights, and `meta.limit` echoes the value
applied.
parameters:
- in: query
name: type
@@ -4727,8 +4730,8 @@ paths:
source's stage segments (each with an absolute start/end), the per-stage breakdown, asleep/in-bed/awake totals,
the mid-sleep awakenings count, and same-wake-day naps surfaced separately. Session-clustered, keyed by the
local wake day, collapsed to one source via the sleep priority ladder so two sources never overlay. `date`
omitted returns the most recent night. A read-only view over existing per-stage SLEEP_DURATION rows — no schema,
no new measurement type."
omitted returns the most recent night holding sleep, however old. Any past date is answered, with no window cut.
A read-only view over existing per-stage SLEEP_DURATION rows — no schema, no new measurement type."
parameters:
- in: query
name: date
@@ -47896,7 +47899,9 @@ components:
- naps
additionalProperties: false
description: "One reconstructed sleep night: the main session's hypnogram segments + breakdown, plus same-wake-day naps
surfaced separately."
surfaced separately. A session is a nap when it holds under three hours asleep centred between 10:00 and 20:00
local time; the main session is the longest session that is not a nap. A day whose only sleep is naps has `main:
null` and its naps."
SleepRhythmResponse:
type: object
properties:
@@ -62987,14 +62992,30 @@ components:
- type: "null"
description: Non-null when two writer buckets reported clearly different asleep totals for the latest night's main
session. Observational only — the served summary stays the winning writer's totals.
recoveryEmpty:
anyOf:
- type: string
enum:
- general
- oura_permission
- oura_no_resilience
- type: "null"
description: "Why the recovery page has nothing to chart, resolved on the server; null when any recovery type
(ANS_CHARGE, DAY_STRAIN, WORKOUT_STRAIN, CARDIO_LOAD, AVERAGE_HEART_RATE, MAX_HEART_RATE,
ENERGY_EXPENDITURE_KJ, RESILIENCE) has a reading. `oura_permission`: Oura is connected and its grant leaves
out the scope the resilience level needs, one reconnect fixes it. `oura_no_resilience`: Oura is connected
and no level has arrived yet. `general`: anyone else. Clients render the empty note from this value and
never work it out from the connection status."
required:
- summaries
- bmi
- lastSeenByType
- sleepSourceDiscrepancy
- recoveryEmpty
additionalProperties: false
description: "What `?slice=summaries` answers: the per-type summaries and their freshness, and nothing thick. Four keys,
and the caller gets them from two SQL passes rather than the default slice's chain."
description: "What `?slice=summaries` answers: the per-type summaries and their freshness, the recovery page's empty
reason, and nothing thick. Five keys, and the caller gets them from two SQL passes rather than the default
slice's chain."
InsightsGenerateReadEnvelope:
type: object
properties:
@@ -88257,9 +88278,9 @@ components:
type: number
description: Effective weight after redistributing missing sub-scores.
gap:
description: "Only on a null `consistency` / `timing`: why it is withheld. `few_nights` — fewer than three nights in the
window have a main sleep on the clock (count in `rhythmNights`); `no_main_sleep` — the latest day had
only a daytime nap. Absent otherwise."
description: "Only on a null `consistency` / `timing`: why it is withheld. `few_nights` — fewer than `rhythmMinNights`
nights in the window have a main sleep on the clock (count in `rhythmNights`); `no_main_sleep` — the
latest day had only a daytime nap. Absent otherwise."
type: string
enum:
- few_nights
@@ -88281,6 +88302,12 @@ components:
maximum: 9007199254740991
description: Nights in the window with a main sleep placed on the clock — what consistency and timing are computed from.
A daytime nap is not one; a short night is.
rhythmMinNights:
type: integer
minimum: -9007199254740991
maximum: 9007199254740991
description: 'How many `rhythmNights` consistency and timing need before they are scored; below it they carry `gap:
"few_nights"`.'
series:
type: array
items:
@@ -88295,6 +88322,7 @@ components:
- subScores
- windowNights
- rhythmNights
- rhythmMinNights
- series
additionalProperties: false
parameters: