feat(train): strength plans and sessions (ADR 0035)
Strength plans of exercises from a catalogue or the person's own, in blocks of one exercise or several done in turn (supersets, circuits), each with its sets, reps or seconds, weights and rests; each a sealed `strength_plan` row. Plans are marked with what the place chosen lacks, and a session offers swaps moving the same way that the place allows. A session runs on every device, set by set with the rest counted down, each weight made up from the place's plates, bars and fixed weights with the plate changes between sets, kept in strength_session.json after each change so one cut off is carried on, and saved as a workout of the new activity Strength with its sets, listed on its page; strength training in Health Connect and FIT, no GPX. Migration 20261102113104496-strength-plans is purely additive: it creates the table strength_plan (id uuid v7, spaceId, keyId, the sealed payload and its nonce), its index on spaceId, and a foreign key to offline_sync_spaces with ON DELETE CASCADE, so deleting a person's sync spaces deletes their plans; then the modules' version rows. The gen_random_uuid_v7 function is created or replaced as in every migration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
064b911aa2
commit
508994be3a
1 changed files with 27612 additions and 25 deletions
99
docs/adr/0035-train-strength-plans.md
Normal file
99
docs/adr/0035-train-strength-plans.md
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
# ADR 0035: Train's strength plans and sessions
|
||||
|
||||
- **Status:** decided 2 Nov 2026, by the developer (D1–D4, three of them the agent's
|
||||
recommendations, D2 the developer's own choice), the rest proposed by the agent and
|
||||
flagged where it chose.
|
||||
- **Builds on:** [ADR 0034](0034-train-equipment-and-plate-maths.md) (the places, their
|
||||
equipment and the plate maths), ADR 0030 (Train: D7 sealed rows, D42 interval plans,
|
||||
D60 the tabs).
|
||||
|
||||
## Context
|
||||
|
||||
ADR 0034 built the inventory and the plate maths, and left strength plans as the next
|
||||
step: a plan naming its exercises, sets, repetitions and weights, the plate changes
|
||||
between its sets ordered by the plate maths, and "the training offered adjusting" to the
|
||||
place chosen. Train records cardio alone so far: no model holds an exercise, a set or a
|
||||
repetition.
|
||||
|
||||
## Decision
|
||||
|
||||
1. **Exercises come from a catalogue, with the person's own beside them** (D1, the
|
||||
recommendation taken). The catalogue (`exercise_catalogue.dart`) holds some 45 common
|
||||
exercises (squats, hinges, presses, rows, pull-ups, curls, extensions, raises, core,
|
||||
carries), each with:
|
||||
- what it **needs** (`ExerciseNeed`: a barbell, an EZ bar, a trap bar, dumbbells, a
|
||||
kettlebell, a bench, a rack, a pull-up bar, dip bars, a cable machine, bands), each
|
||||
met by a place's equipment (dumbbells by fixed dumbbells or by handles with plates);
|
||||
- what it is **loaded** with (`ExerciseLoad`: a barbell, an EZ bar or a trap bar with
|
||||
plates, a pair of dumbbells, one dumbbell, a kettlebell, a cable's stack, a band, the
|
||||
body), which decides how its weight is made up;
|
||||
- its **pattern** (`MovementPattern`: squat, lunge, hinge, horizontal and vertical push
|
||||
and pull, curl, extension, raise, calf, core, carry), by which swaps are found (D4);
|
||||
- whether it is counted in **repetitions or held for a time**.
|
||||
Its names are the app's texts, by the exercise's id. The person's own exercise is a
|
||||
name with the needs, load, pattern and measure they pick; it lives in the plans that
|
||||
use it (no table of its own), and the editor offers those of every plan again.
|
||||
|
||||
2. **A plan is blocks of exercises, a block of several done in turn** (D2, the
|
||||
developer's choice: supersets and circuits too). A block holds one exercise or more,
|
||||
each with its sets (repetitions or seconds, and a weight in grams where it is
|
||||
loaded), and a rest:
|
||||
- one exercise: its sets one after the other, the rest between them;
|
||||
- two (a superset) or more (a circuit): a round is each exercise's next set in turn,
|
||||
the rest after each round, and a rest between the exercises within a round (none by
|
||||
default). An exercise with fewer sets drops out of the later rounds.
|
||||
What a block is called (exercise, superset, circuit) follows from how many it holds.
|
||||
|
||||
3. **This step records a session too** (D3, the recommendation taken), on every device,
|
||||
as nothing in it needs the phone's sensors. The session screen leads set by set: the
|
||||
exercise, the set and round, the weight made up at the place chosen (D5) with the
|
||||
plates to change since the exercise's set before, the repetitions or the time, and
|
||||
Done; after it the rest counts down (a tone and a vibration as it ends, where the
|
||||
device has them), skippable. What was actually done is typed over what the plan said.
|
||||
A set can be skipped, an exercise swapped (D4), the session ended at any point.
|
||||
Saved, it is a workout of the new activity **strength** with what was done
|
||||
(`WorkoutStrength`: the plan's name, the place's, and each set done: its exercise,
|
||||
repetitions or seconds, weight and time), shown on the workout's page as the
|
||||
exercises with their sets. A session under way is kept in the person's
|
||||
`strength_session.json` after every change, so one cut off is offered again.
|
||||
|
||||
4. **The place marks what it can't do and offers swaps** (D4, the recommendation taken).
|
||||
A plan whose exercises the chosen place lacks something for is marked in the list,
|
||||
naming what is missing; a session's exercise the place can't do offers, in its place,
|
||||
the catalogue's exercises of the same pattern the place can, and any exercise can be
|
||||
swapped so. A swap holds for the session alone.
|
||||
|
||||
5. **A strength plan is a sealed, synced row of its own** (the agent's): the table
|
||||
`strength_plan`, as `plan` and `training_place` are, rather than a kind of `plan`,
|
||||
whose readers in released apps would show it as locked. The migration only creates the
|
||||
table, its space index and its cascade to the sync engine's spaces.
|
||||
|
||||
6. **A strength workout keeps workout schema 1** (the agent's): the activity `strength`
|
||||
is new, and apps that don't know an activity already skip the workout rather than show
|
||||
it half (`decodeWorkout`); its sets are a field only strength workouts have. It goes
|
||||
to Health Connect as strength training, to FIT as training/strength training, to TCX
|
||||
as Other; it has no track, so no GPX.
|
||||
|
||||
7. **How the weight is made up** (the agent's): for a bar, the plate maths of ADR 0034 on
|
||||
the place's bar of that kind, the plates of the exercise's sets ordered by `loadSeries`
|
||||
so that its plate changes are fewest; for a pair of dumbbells, the place's fixed pair
|
||||
nearest at or below the weight, else two handles with plates; for one dumbbell or a
|
||||
kettlebell, the nearest at or below; a cable's stack, a band and the body take the
|
||||
weight as typed. Where nothing at the place makes the weight up, the session says so
|
||||
and takes it as typed.
|
||||
|
||||
8. **Where it shows** (the agent's): the Record tab gets a *Strength* card beside the
|
||||
activities, its Start offering the strength plans, and the strength plans are listed
|
||||
under the interval plans; where the device doesn't record, Profile's Plans tab lists
|
||||
both, a strength plan's Start there too.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Progression (raising a weight once every set was done) and a one-repetition maximum
|
||||
with weights as a share of it are left for later; the sets done are kept so that both
|
||||
can be worked out from them.
|
||||
- A session runs in the app alone, not in a service: on Android a session left in the
|
||||
background keeps its time but rings its rest's end only while the app is open; the
|
||||
next step can hand it to the recorder's service if that matters in use.
|
||||
- The catalogue grows by adding to it and its texts; an exercise's id never changes, as
|
||||
plans and workouts keep it.
|
||||
Loading…
Reference in a new issue