80 lines
5.0 KiB
Markdown
80 lines
5.0 KiB
Markdown
# Спецификация 03: экран «Тренировка»
|
||
|
||
Источники: Ф-3 (экран активной тренировки), Ф-11.1–11.2 (план/факт),
|
||
Ф-13.3 (RPE/боль по сетам), m09 `WorkoutCore.logSet`/`PlanMatch`,
|
||
ui-ux разд. 3. Единицы 4 + 11 (ProgramView).
|
||
|
||
## 1. Состояние экрана
|
||
|
||
`WorkoutViewModel`: `activeWorkout` (Flow, m09 DAO), `sets(workoutId)`
|
||
(Flow), план сессии — `ProgramView.sessionFor(activeBody,
|
||
dayOfWeekIso(startedAt))` (spec 04), последний вес упражнения —
|
||
последний `workout_set` этого упражнения в истории (DAO-чтение).
|
||
Нет активной тренировки — заглушка «Нет активной тренировки» +
|
||
кнопка «К экрану "Сегодня"».
|
||
|
||
## 2. Статус-строка (Ф-3.1/3.2)
|
||
|
||
| Элемент | v1 (m10) | m12 |
|
||
|---|---|---|
|
||
| Связь с часами | серый индикатор + текст «часы: нет связи» | зелёный/красный |
|
||
| Заряд часов | «—» | % |
|
||
| Пульс | крупный «—» (прочерк) | живое значение |
|
||
| Сеть | онлайн/офлайн (текст) | — |
|
||
|
||
## 3. Блок упражнения и форма подхода
|
||
|
||
- «Текущее упражнение» — первый элемент плана сессии с незакрытыми
|
||
подходами (план: вес × повторы × осталось), иначе последний
|
||
записанный; селектор упражнения — план сессии + активная
|
||
библиотека (сохранённый выбор запоминается до смены);
|
||
- форма (нижняя треть, ≤ 4 активных элемента одновременно):
|
||
- вес — пикер шаг **2,5 кг**, диапазон 0–500; умолчание — вес из
|
||
плана для этого упражнения, иначе последний фактический;
|
||
- повторы — пикер шаг 1 (0–50), умолчание — план;
|
||
- RPE — сегмент 1–10, необязательно (пропуск = null);
|
||
- боль в колене — сегмент 0–10, показывается только для группы
|
||
«ноги» (Ф-13.3), необязательно;
|
||
- «Записать подход» → `WorkoutCore.logSet` (seq, in_plan, дата —
|
||
считает ядро m09);
|
||
- список подходов тренировки (компакт): упражнение, вес × повторы,
|
||
метка «по плану» / «отклонение» (текст, не только цвет 🛡),
|
||
RPE если есть.
|
||
|
||
## 4. Таймер отдыха (Ф-3.3)
|
||
|
||
- кнопка «Отдых (Rest.DefaultSec с)» — старт обратного отсчёта
|
||
(значение из настроек);
|
||
- фазы: «идёт отдых» (фон карточки красный-приглушённый + текст),
|
||
«последние 10 с» (жёлтый + текст), «пора начинать» (зелёный +
|
||
текст; остаётся до следующего действия) — цвет всегда дублирован
|
||
текстом 🛡;
|
||
- повторный тап — рестарт; сбрасывается при записи подхода;
|
||
- автостарт после подхода в v1 не делается (старт — кнопка или
|
||
голосовая команда «Отдых S» в m11 — Ф-3.3).
|
||
|
||
## 5. Завершение
|
||
|
||
- «Закончить» → `finishWorkout(id, avgHr=null)` (пульс появится
|
||
в m12) → переход в историю (карточка);
|
||
- «Сбросить» → диалог подтверждения («Тренировка сохранится
|
||
в истории как отменённая») → `cancelWorkout(id)` (Ф-3.5);
|
||
- кнопка-микрофон — открывает форму подхода (заглушка ручного
|
||
ввода; STT-контур — m11).
|
||
|
||
## 6. Правила
|
||
|
||
- 🛡 запись подхода только через `WorkoutCore.logSet`; экран не
|
||
пишет в DAO;
|
||
- метка «по плану» — только расчёт ядра (± 2,5 кг / ± 0 повторов,
|
||
Ф-11.2), UI метку не вычисляет и не подделывает;
|
||
- экран полностью работоспособен офлайн.
|
||
|
||
## 7. Тесты (unit, pure JVM)
|
||
|
||
| # | Проверка | Ожидание |
|
||
|---|---|---|
|
||
| 1 | Умолчания формы: план сессии существует | вес/повторы = план; плана нет — последний фактический |
|
||
| 2 | Группа «ноги» → сегмент боли виден; «жим» — скрыт | видимость по groupCode |
|
||
| 3 | Фазы таймера по остатку (>10 / ≤10 / 0) | подписи фаз соответствуют |
|