# Спецификация 02: экран «Сегодня» и поток «Допуск» Источники: Ф-13.1 (дневник-минимум), Ф-13.2 (предстартовый допуск), Ф-14.5 (session_kind), m09 `WorkoutCore`/`AdmissionChecker`/spec 02. Единицы 2–3. ## 1. «Сегодня» (дневник) `TodayViewModel`: `dailyLog(today)` (Flow), `pendingCount` (Flow), сохранение — `WorkoutCore.saveDailyLog` (merge, день уникален). Поля (ввод за 2–3 касания — заполненные поля не переспрашиваются, пустые необязательны, кроме самочувствия-подсказки): | Поле | Ввод | Диапазон | |---|---|---| | АД систола | пикер шаг 5 | 70–250 | | АД диастола | пикер шаг 5 | 40–150 | | Вес тела | пикер шаг 0,5 кг | 30–300 | | Пульс покоя | пикер шаг 1 | 30–130 | | Самочувствие | сегмент 1–5 (подписи: 1 плохо … 5 отлично) | 1–5 | Кнопка «Сохранить» (нижняя треть) — доступна всегда; после — тихое подтверждение «Сохранено». Кнопка «Начать тренировку» → «Допуск». Счётчик «в очереди: N» — из баннер-состояния (spec 01). ## 2. «Допуск» (модальный экран перед стартом силовой) `AdmissionViewModel`: читает дневник дня (АД), поля: «АД из дневника за сегодня» (если пусто — пикеры прямо здесь, сохранение в дневник), «Пульс сидя» (пикер 30–180, вручную — с часов подтянется в m12). Расчёт: `AdmissionChecker.check(safety, bpSys?, bpDias?, hrSitting?)` (порядок CANCEL → CARDIO_ONLY → POSTPONE → ALLOW; null пропускает проверку — m09 spec 02). Если и АД, и пульс не введены — проверка не выполняется, исход ALLOW с пометкой «данные не введены». Экран исхода (спокойные формулировки, статус дублируется текстом): | Исход | Заголовок/текст | Кнопки | |---|---|---| | ALLOW | «Допуск получен» | «Начать тренировку» (+ выбор вида) | | CARDIO_ONLY | «Давление повышено — сегодня только лёгкое кардио или дыхание. Силовые заблокированы.» | «Закрыть»; тихая ссылка «Всё равно начать силовую» (2 тапа) 🛡 | | CANCEL | «Давление высокое — тренировку не начинаем. Рекомендуется прогулка.» | «Отменить» (закрыть); тихая ссылка «Всё равно начать» (2 тапа) 🛡 | | POSTPONE | «Пульс сиди высокий — лучше перенести тренировку.» | «Перенести» (закрыть); тихая ссылка «Всё равно начать» (2 тапа) 🛡 | 🛡 Обход блокировки (любой из трёх): «Всё равно начать» → подтверждение вторым тапом → `WorkoutCore.startAnyway(programVersionId)` — в журнал команд пишется `accepted=false, semantics={"override":"permission"}` (Ф-13.5, m09). Обход всегда виден в журнале. Выбор вида тренировки (при «Начать»): сегмент — обычная (normal, умолчание) / возврат (return) / делоад (deload) / тест (test) — Ф-14.5. Старт: `startWorkout(activeVersionId, kind)` → переход на вкладку «Тренировка». Активная версия отсутствует — старт без привязки (`startWorkout(null, kind)`), на экране тренировки пометка «вне программы». ## 3. Правила - пороги — только из `Safety.*` настроек (Р3-А), в потоке допуска не редактируются; - п. 1 «дневник» и п. 2 «допуск» пишут через `saveDailyLog` (merge) — повторное сохранение не затирает утренние значения, введённые раньше (одна запись на день); - после старта — `SyncWorker.schedule` (spec 01 п. 4). ## 4. Тесты (unit, pure JVM) | # | Проверка | Ожидание | |---|---|---| | 1 | Слияние дневника: утро (АД 120/80) + допуск ввёл пульс | запись дня одна: 120/80 + пульс | | 2 | Допуск без данных (все null) | ALLOW, пометка «данные не введены» | | 3 | Исходы CANCEL/CARDIO_ONLY/POSTPONE → «всё равно» | вызов startAnyway, лог override (по m09 — уже покрыто тестами ядра; здесь — маппинг исход→кнопка) |