feat(train): Days, the Loop's days and nights kept sealed (ADR 0030, D37, D38)

What the band read brings, from the bridge or the background job's
file (`LoopLines`), is kept by `DayRepository`: one sealed `day` and
`night` a date and the day's heart rate in chunks of three hours, every
ID made from the person and the date, a later read replacing what it
brought and keeping the rest, nothing rewritten unchanged; versioned,
gzipped JSON (`day_payload.dart`). `PolarLoop` reads the band as each
connection is ready (every half hour at most, or when asked), takes in
the background file as the app opens, and remembers up to which day
the days are sealed, which the next read then deletes on the band;
it keeps the background job on the band and from the right day, and
`Let the band go` stops it.

Home gains a Days tab, each day with its steps, active time, sleep and
Nightly Recharge, pulled to read the band; a day's page shows its
figures, its time in each class, its heart rate, the night's phases
and rating, Nightly Recharge and skin temperature.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-28 19:53:12 +01:00
commit 5250f32329
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -2,8 +2,8 @@
- **Status:** decided 27–28 Oct 2026, by the developer (D1–D38 below). The shell (D12)
is built; recording (D13–D28) is built on Android, iOS waiting for a Mac; Health
Connect (D29–D31) is built; the Loop's setup and keeping (7a, D34–D36) is built, its
daily data (7b, D37, D38) is being built.
Connect (D29–D31) is built; the Loop's setup and keeping (7a, D34–D36) and its
daily data (7b, D37, D38) are built.
- **Numbering:** 0025 is held by the federation draft (stashed), 0026–0029 by the .NET
rewrite on the local branch `rewrite-dotnet`, abandoned on 27 Oct; Train takes the next
free number so that neither is ever read as this one.
@ -666,6 +666,28 @@ Strava. What was found, 27 Oct:
`documentation/FirstTimeUse.md` gives the same tables, without saying which class
to take.
7b built so (28 Oct), with choices of mine for the developer to look at: home has two
tabs, *Workouts* and *Days*, on every device, *Days* saying where days come from
while there are none; the first read of a band goes four weeks back, later ones from
the day after those kept; the band is read as each connection is ready, at most every
half hour, and when the person pulls the list; a later read replaces what it brought
of a date (its summary, Recharge, skin temperature, heart rate, night) and keeps the
rest, and rewrites nothing unchanged; a day's heart rate goes in chunks by the three
hours each measurement began in, every row's ID made from the person and the date
(`https://halkyon.app/train/day/<person>/<date>`, `…/night/…`, `…/heart/<index>`); a
row that doesn't open on a device is left out of *Days*, as its date is sealed with
it; what is kept goes up to the day before the latest read's (`keptUntil`, in
`loop.json` with the last read's time), kept over a new setup of the same band and
forgotten for another; the background job runs every four hours while the battery
isn't low and the open app doesn't hold the band, and reads from the same day until
the app has kept what it wrote, so the file can hold a day more than once, the last
line winning; the app moves the file aside before reading it and deletes it once
sealed, so lines written meanwhile wait; the schedule is the phone's, for the last
person whose app opened with a band, and *Let the band go* stops it. Polar's
NONREM12 and NONREM3 are shown as light and deep sleep; the chart draws each 24/7
measurement's mean at its start; a night's times show in the phone's time zone. Not
yet tried with a Loop: whether the SDK's deletion includes its `until` day, and
whether the job connects to the band in the background, are for a real band.
## Consequences