mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 06:52:04 +00:00
Unify sleep-night reconstruction onto the canonical engine
Replace the divergent UTC-day night reconstructor in the Sleep Score with a thin adapter over reconstructSleepNights, the shared engine the dashboard, hypnogram, and doctor surfaces already read. The old path bucketed rows by UTC calendar day and never deduplicated writers, so a multi-source night (WHOOP + Apple Health for the same sleep) summed both writers and roughly doubled the total. The adapter inherits session-clustering, local-wake-day keying, and multi-source writer dedup, then derives the score-only fields the canonical night does not carry: REM and Deep minutes from the stage map, the stage- breakdown flag from any granular stage, and the midpoint from the asleep span. Select source and deviceType in the Sleep Score read so the writer-dedup ladder fires, and thread the user source priority through so the chosen writer matches every other sleep surface. Round emitted asleep and in-bed minutes to whole numbers, and round the per-stage map in the sleep-night DTO, matching the integer contract the native client decodes. A multi-source user's sleep score and the readiness score that folds it drop once the double-count is removed, reflecting the true single-writer night.
This commit is contained in:
1 parent
a2260d5bb8
commit
b4b9d8d9d7
7 files changed
+169
-95
No files matched your search
@@ -64,7 +64,14 @@ function serializeSession(s: SleepSession) {
|
||||
inBedMinutes: s.inBedMinutes === null ? null : Math.round(s.inBedMinutes),
|
||||
awakeMinutes: s.awakeMinutes === null ? null : Math.round(s.awakeMinutes),
|
||||
awakenings: s.awakenings,
|
||||
stages: s.stages,
|
||||
// iOS #18 — round the per-stage map too; the underlying totals sum
|
||||
// second-precision segments and otherwise serialise as e.g. 88.4999.
|
||||
stages: Object.fromEntries(
|
||||
Object.entries(s.stages).map(([stage, minutes]) => [
|
||||
stage,
|
||||
Math.round(minutes),
|
||||
]),
|
||||
),
|
||||
segments: s.segments.map((seg) => ({
|
||||
stage: seg.stage,
|
||||
start: seg.start.toISOString(),
|
||||
|
||||
Reference in new issue
Block a user