mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 04:50:59 +00:00
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:
1 parent
b2bb81cac3
commit
4e7beb797c
7 files changed
+396
-29
No files matched your search
@@ -913,13 +913,20 @@ export const analyticsRangeQuery = z
|
||||
|
||||
export const analyticsWindowAggregate = z
|
||||
.object({
|
||||
count: z.number().int().describe("Reading count composed across buckets."),
|
||||
count: z
|
||||
.number()
|
||||
.int()
|
||||
.describe(
|
||||
"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: z.number().nullable().describe("Window minimum; null when empty."),
|
||||
max: z.number().nullable().describe("Window maximum; null when empty."),
|
||||
mean: z
|
||||
.number()
|
||||
.nullable()
|
||||
.describe("Count-weighted mean across buckets; null when empty."),
|
||||
.describe(
|
||||
"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: z
|
||||
.number()
|
||||
.nullable()
|
||||
@@ -941,7 +948,7 @@ export const analyticsRangeResponse = z
|
||||
granularity: z
|
||||
.string()
|
||||
.describe(
|
||||
"Rollup granularity the read resolved against (`DAY` / `WEEK` / `MONTH` / `YEAR`, or `none` on a coverage miss).",
|
||||
"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: analyticsWindowAggregate.describe(
|
||||
"Aggregate over the current window `[now-N, now)`.",
|
||||
@@ -965,7 +972,7 @@ export const analyticsRangeResponse = z
|
||||
.meta({
|
||||
id: "AnalyticsRangeResponse",
|
||||
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).",
|
||||
"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).",
|
||||
});
|
||||
|
||||
export const insightsPregenerateRequest = z.object({}).meta({
|
||||
|
||||
Reference in new issue
Block a user