Skip to content

feat(sleep): split same-day sleep into sessions + Day carousel (#59)#83

Merged
saksham2001 merged 7 commits into
saksham2001:mainfrom
rgvxsthi:feat/sleep-session-carousel
Jul 16, 2026
Merged

feat(sleep): split same-day sleep into sessions + Day carousel (#59)#83
saksham2001 merged 7 commits into
saksham2001:mainfrom
rgvxsthi:feat/sleep-session-carousel

Conversation

@rgvxsthi

Copy link
Copy Markdown
Contributor

Closes #59.

Problem

When a day held more than one sleep (a nap plus the main night), ring history for that waking day was merged into a single ~16 h SleepSession with a broken hypnogram — the "UI breaks" reported in the issue.

What this does

Splits sleep into distinct sessions and lets you page between a day's sessions on the Sleep → Day view.

  • SleepSegmentation.segment + SleepService.reconcileWakingDay — derive a day's sessions from its stage blocks; a run of ≥ 60 min with no recorded sleep starts a new session. Idempotent.
  • persistSleepTimeline — accumulate a packet's blocks, then reconcile the day into sessions.
  • migrateSleepSessionSegmentsIfNeeded (sleepSessionSegment.v1) — one-time re-split of legacy merged days, gated + off the render path.
  • Day view carousel — horizontal paged sessions + dot indicator + per-session caption; single-session days render exactly as before (no regression).
  • SleepInsights.collapseByDay — Week/Month/Year count each day once, so a nap never skews the nightly average or "nights tracked".
  • sleepForDate returns the day's longest session.

Tests

11 new tests (segmentation, reconcileWakingDay idempotency, migration). Full SleepServiceTests suite: 23 passing.

Notes

Two follow-ups build on this branch: day navigation (browse past days) and a dev-only seed update for multi-session demo data.

…am2001#59)

Ring history holding a nap plus the main night on one waking day was
merged into a single ~16h SleepSession with a broken hypnogram. Split
sleep into distinct sessions and page between them on the Day view.

- SleepSegmentation.segment + SleepService.reconcileWakingDay derive a
  day's sessions from its stage blocks (a >=60 min gap in recorded sleep
  starts a new session); idempotent.
- persistSleepTimeline accumulates a packet's blocks, then reconciles.
- migrateSleepSessionSegmentsIfNeeded (sleepSessionSegment.v1) one-time
  re-splits legacy merged days.
- Sleep > Day: horizontal carousel + dots + per-session caption;
  single-session days render unchanged.
- SleepInsights.collapseByDay: aggregate views count each day once, so a
  nap never skews the nightly average or "nights tracked".
- sleepForDate returns the day's longest session.
- 11 new tests (segmentation, reconcile idempotency, migration).

Closes saksham2001#59
rgvxsthi and others added 6 commits July 13, 2026 09:49
…are aggregates

Follow-up review of this branch surfaced four issues; fix them before merge:

- reconcileWakingDay reused day-rows by positional index after sorting by
  startAt, so an out-of-order sync (a nap arriving before the night it
  precedes) silently flipped a row's identity — misattributing anything
  keyed to that SleepSession.id (e.g. a coach summary). Match each segment
  to the existing row whose prior time-range overlaps it instead.
- reconcileWakingDay inserted a DerivedUpdateRow (and bumped syncedAt) per
  segment on every call, unconditionally — re-syncing an unchanged day
  spammed the audit table. Emit the change signal only when a row's bounds
  or block set actually changed.
- durationConsistency computed variance over non-collapsed sessions against
  a collapsed mean, so a nap spuriously inflated the SD and flipped the
  "Variable nights" chip. Collapse first.
- aggregateCoach and the aggregate hero counted naps as extra "nights
  tracked" while their averages collapsed by day. Collapse the count too.
@saksham2001
saksham2001 merged commit 2367d23 into saksham2001:main Jul 16, 2026
2 checks passed
@rgvxsthi
rgvxsthi deleted the feat/sleep-session-carousel branch July 16, 2026 04:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Carousel to show different sleep sessions within a day

2 participants