Track walks as timed exercise

A walk is a start and an end, so it reuses the shape sleep already has rather
than inventing one: walk-start / walk-end events, paired into windows, with a
trailing unmatched start meaning "out right now". The server stores type as an
opaque string, so nothing there changes and the events ride the existing sync.

Pairing boundaries into windows was written out twice already, once for sleep
and once for its inverse, so this pulls the scan into pairWindows(open, close)
and makes all three callers of it. Same for the latest-boundary lookup behind
currentSleepState, which currentWalkState now shares — including the updatedAt
tie-break, which matters as soon as a start and an end land in the same minute.

They are called walks, not exercise. "Exercise" is already taken by the
training definitions (their own synced collection, and exerciseId on training
events), and two meanings of the word in one app would be worse than the
slightly narrower name.

The day's total leads the overview tile with the count underneath, since the
question is how much exercise the puppy got rather than how many outings it
took. The Walks panel lists the day's windows and carries the total in its
heading so a collapsed panel still answers it, and the daily charts gain a
minutes-per-day bar chart that stays hidden until there is a walk to draw —
the grams chart's rule. The panel also states the five-minute rule for the
puppy's current age, the same way the sleep trend states a goal band.

Walk boundaries answer to the walk state, not the sleep one, so "Walk end" is
disabled with no walk running and stays undimmed mid-walk even while the puppy
is logged asleep.
This commit is contained in:
Alexander Heldt
2026-08-31 21:23:40 +00:00
parent ead575df2c
commit f162ac5732
5 changed files with 243 additions and 56 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
# puppy-tracker
A tiny offline-first PWA for tracking your puppy's sleep, meals, pees, poos,
weight, and training.
A tiny offline-first PWA for tracking your puppy's sleep, walks, meals, pees,
poos, weight, and training.
The browser is the primary client; a small Go server provides a shared
source-of-truth and sync between devices.