fix(analytics): all-time extremes and range deltas count one source per day

The all-time weight, blood-pressure and pulse figures the insight features
carry averaged every raw row, so a device that samples densely outweighed the
readings the source ladder prefers on the same days. They now keep one source
per day, like the dashboard's all-time figures.

The period-over-period range delta averaged readings. For step-like totals
the current window still holds the last day and a half as many small
samples, so the average collapsed; it now compares average daily totals. For
sleep it averaged stage segments and in-bed envelopes; it now compares
average nights of time asleep. The API descriptions say which.
This commit is contained in:
Marc-André Bombeck committed 2026-09-26 16:07:45 +02:00
1 parent b2bb81cac3
commit 4e7beb797c
7 files changed
+396 -29

No files matched your search

+10 -7
View File
@@ -54940,8 +54940,8 @@ components:
description: Trailing-window length in days for the chosen range.
granularity:
type: string
description: Rollup granularity the read resolved against (`DAY` / `WEEK` / `MONTH` / `YEAR`, or `none` on a coverage
miss).
description: Rollup granularity the read resolved against (`DAY` / `WEEK` / `MONTH` / `YEAR`), `live` for SLEEP_DURATION
(nights are reconstructed from the stage rows), or `none` when there is no data.
current:
description: Aggregate over the current window `[now-N, now)`.
$ref: "#/components/schemas/AnalyticsWindowAggregate"
@@ -54968,9 +54968,10 @@ components:
- delta
- deltaPct
additionalProperties: false
description: Single-metric period-over-period aggregate. Reads the current and previous comparable windows from the WMY
rollup tier and composes a count-weighted-mean delta. `count/min/max/mean/sum` are linearly composable across
buckets; SD/slope/r² are intentionally excluded (not composable).
description: Single-metric period-over-period aggregate. Reads the current and previous comparable windows from the
rollup tier and composes a count-weighted-mean delta, one source per day. Step-like totals compare average daily
totals and SLEEP_DURATION compares average nights, not per-reading means. `count/min/max/mean/sum` are linearly
composable across buckets; SD/slope/r² are intentionally excluded (not composable).
AnalyticsWindowAggregate:
type: object
properties:
@@ -54978,7 +54979,8 @@ components:
type: integer
minimum: -9007199254740991
maximum: 9007199254740991
description: Reading count composed across buckets.
description: Reading count composed across buckets. For step-like totals it is the number of days with a total, for
SLEEP_DURATION the number of nights.
min:
anyOf:
- type: number
@@ -54993,7 +54995,8 @@ components:
anyOf:
- type: number
- type: "null"
description: Count-weighted mean across buckets; null when empty.
description: Count-weighted mean across buckets; null when empty. For step-like totals (steps, energy, distance,
flights) it is the average daily total, for SLEEP_DURATION the average time asleep per night.
sum:
anyOf:
- type: number