# Спецификация 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) | подписи фаз соответствуют |