Интеграция документа перерывов (vision 1.4, Ф-14: auto-break + вопрос атлету, формула возврата, правила 12-17, breaks/session_kind) + волна 1 errata ревью (З-5,6,9-14) + З-2 архитектура
This commit is contained in:
parent
0554f176ba
commit
1034c152f5
|
|
@ -0,0 +1,214 @@
|
||||||
|
# Ревью документации от 2026-10-17 — задания к исполнению
|
||||||
|
|
||||||
|
> **Исполнитель:** агент сопровождения документации WatchBody.
|
||||||
|
> **Источник:** архитектурная проверка документации шагов 1–6 на соответствие
|
||||||
|
> канону std1 (`I:\Kit\Kit.DevAi\std1`: процесс `_process\process.md`, правила
|
||||||
|
> `_rules\d\d-db.md`, `d-dev.md`, `d-req.md`, `d-drg.md`, `_rules\glossary.md`)
|
||||||
|
> и исходной задаче (`Техническое задание.md`, `Требование.md`, документы
|
||||||
|
> «Метрики…», «Архитектура LLM…», «Форматы…»).
|
||||||
|
> **Состояние репозитория на момент проверки:** коммит `0554f17`, все ссылки
|
||||||
|
> на строки даны по нему; после правок ориентироваться по разделам, а не строкам.
|
||||||
|
> **Статусная модель заданий:** ⬜ не начато → 🔄 в работе → ✅ готово
|
||||||
|
> (утверждено владельцем). Отметки проставляются в разделе 6 по мере работы.
|
||||||
|
> **Общие правила исполнения:**
|
||||||
|
> 1. Правки вносятся новыми версиями утверждённых документов (перечень версий —
|
||||||
|
> раздел 5). Каждая новая версия — точка утверждения **Пользователь!** (d-dev-4).
|
||||||
|
> 2. Содержание утверждённых документов меняется только в объёме заданий;
|
||||||
|
> инварианты 🛡 не ослабляются; трассировка «Ф → БЦ → КУ → версия» (раздел 6
|
||||||
|
> requirements) сохраняется.
|
||||||
|
> 3. Задания, зависящие от решений Р1–Р3 (раздел 1), не вносятся до выбора
|
||||||
|
> владельцем. Остальные можно выполнять сразу.
|
||||||
|
> 4. Код (`3-app\`, `2-db\`) не трогается — задание касается только `1-docs\`
|
||||||
|
> и корневого `readme.md`.
|
||||||
|
> 5. ~~Push не выполняется (учётные данные remote не настроены)~~ — уточнение
|
||||||
|
> исполнителя 2026-10-17: push настроен и работает (credentials в
|
||||||
|
> Credential Manager); коммиты пушатся после каждой волны.
|
||||||
|
|
||||||
|
## 0. Сводка ревью
|
||||||
|
|
||||||
|
Документация в целом соответствует std1 и исходной задаче: шаги 1–6 пройдены
|
||||||
|
с точками утверждения, все 9 позиций MVP ТЗ покрыты (Ф-1–Ф-9), трассировка
|
||||||
|
полная, стеки соответствуют `Требование.md`, решения LLM-дизайна и документа
|
||||||
|
метрик перенесены. Найдено: **4 существенных дефекта (P1)** — два логических
|
||||||
|
противоречия «v1-требования ↔ v1-данные», неактуальная архитектура после
|
||||||
|
изменения 1.3 и разрыв схемы синхронизации; **4 средних (P2)**; **7 мелких
|
||||||
|
(P3, гигиена)**. Позиции внедрения MVP документа метрик (п. 5) и порядок
|
||||||
|
шагов 1–3 LLM-дизайна перенесены в требования верно, кроме данных правила 1
|
||||||
|
(см. Р1).
|
||||||
|
|
||||||
|
## 1. Решения владельца (блокируют волну 2)
|
||||||
|
|
||||||
|
| Код | Вопрос | Варианты | Рекомендация ревью |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **Р1** | Данные правила 1 (пульс покоя +8 два дня / самочувствие ≤ 2) отсутствуют в v1: `daily_log` v1 хранит только АД и вес; `hr_resting`, `wellbeing` помечены v2 — а Ф-12.5, БЦ-6 и КУ-7 требуют их в v1 | **А:** добавить `hr_resting`, `wellbeing` в v1-дневник (2 касания ввода) — КУ-7 закрывается целиком. **Б:** правило 1 → v2 (в v1 правила 2–6), скорректировать КУ-7. **В:** прокси — хранить предстартовый пульс сидя в `daily_log` и считать тренд по нему | **А** |
|
||||||
|
| **Р2** | Идентификация клиентских сущностей: протокол sync требует `client_guid` для каждой записи, но у `exercise`, `program_version`, `athlete_profile` его нет; ключи — серверные `serial`, телефон офлайн не может узнать server id для ссылок (`workout_set.exercise_id`, `workout.program_version_id`) | **А:** добавить `client_guid UNIQUE` в эти таблицы + расширить ответ sync маппингом `{entity, client_guid, id}`. **Б:** UUID как PK всех клиентских сущностей. **В:** натуральные ключи (имя упражнения у атлета) | **А** (минимальная правка БД, идемпотентность сохраняется) |
|
||||||
|
| **Р3** | Safety-пороги применяются на телефоне офлайн (экран допуска, Ф-13.2), но определены только в серверном `appsettings.json`; канал доставки на телефон не задан | **А:** продублировать пороги в телефонном Preferences (умолчания — документ метрик); серверные `Safety.*` — для серверных правил/`red_flags`. **Б:** синхронизируемая сущность `settings` (сервер — истина; до первой синхронизации — умолчания телефона) | **А** для v1 (один владелец; расхождение источников задокументировать, общая сущность — кандидат v2) |
|
||||||
|
|
||||||
|
Если владелец не выбрал вариант — подготовить диффы по рекомендованному и
|
||||||
|
вынести на утверждение как предложение (самовольно вариант не менять).
|
||||||
|
|
||||||
|
## 2. Задания P1 (существенные)
|
||||||
|
|
||||||
|
### З-1. Интеграция данных правила 1 в v1 ⬜ *(после Р1; по Р1-А)*
|
||||||
|
|
||||||
|
1. `1-docs\1-reqs\requirements.md`:
|
||||||
|
- Ф-13.1 — дневник-минимум дополнить: пульс покоя (утро), самочувствие 1–5;
|
||||||
|
- Ф-13.6 — v2-перечень сузить до «талия, сон» (пульс покоя и самочувствие
|
||||||
|
переносятся в v1);
|
||||||
|
- Ф-12.5 — указать источник данных правила 1 (`daily_log`, тренд 2 дня).
|
||||||
|
2. `1-docs\2-db\src\tables.md`: `src.daily_log` — `hr_resting`, `wellbeing`
|
||||||
|
убрать из пометки «v2», описать как поля v1.
|
||||||
|
3. `1-docs\2-db\src\functions.md`: `daily_log_upsert` — параметры
|
||||||
|
`p_hr_resting`, `p_wellbeing`.
|
||||||
|
4. `1-docs\3-tech\tech-requirements.md`: п. 2.2 (`daily_log`) — поля v1;
|
||||||
|
чек-лист шага 7 не меняется.
|
||||||
|
|
||||||
|
### З-2. Актуализация архитектуры под Ф-13 ⬜
|
||||||
|
|
||||||
|
1. `1-docs\2-arch\architecture.md`:
|
||||||
|
- шапка: источники — vision **v1.3**, requirements v1.1; версия документа →
|
||||||
|
1.1 с примечанием «актуализация под Ф-13 (изменение vision 1.3)»;
|
||||||
|
- раздел 1.2 (телефон): в `WorkoutCore` добавить ответственность «предстартовый
|
||||||
|
допуск (пороги Safety, экран допуска) и дневник самоконтроля
|
||||||
|
(`daily_log`)»; в `TrainingUi` — экраны «Сегодня» и «Допуск»;
|
||||||
|
- раздел 2 (поток): шаг 0 перед «Тренировка» — допуск (пороги АД/пульса;
|
||||||
|
блокировка/лёгкое кардио; обход блокировки логируется);
|
||||||
|
- таблица компонентов: строка БД — добавить `daily_log` к перечню.
|
||||||
|
2. `1-docs\2-arch\hld.puml`: отразить допуск/дневник подписью в `WorkoutCore`
|
||||||
|
(без новых компонентов и связей — гранулярность схемы не меняется);
|
||||||
|
перерендерить `hld.svg` + `hld.png` навыком `std1\_skills\dgm-hld`
|
||||||
|
(`python std1\_skills\dgm-hld\render.py 1-docs\2-arch\hld.puml`), рендер
|
||||||
|
рядом с исходником (d-drg-11).
|
||||||
|
3. Утверждение — **Пользователь!**
|
||||||
|
|
||||||
|
### З-3. Синхронизация: `client_guid` и маппинг id ⬜ *(после Р2; по Р2-А)*
|
||||||
|
|
||||||
|
1. `1-docs\2-db\src\tables.md`: `src.exercise`, `src.program_version` —
|
||||||
|
колонка `client_guid uuid NOT NULL UNIQUE` (идемпотентность sync, Ф-7.4);
|
||||||
|
`src.athlete_profile` — upsert по `athlete_id` уже идемпотентен, решение
|
||||||
|
(без `client_guid`) зафиксировать явно в комментарии.
|
||||||
|
2. `1-docs\3-tech\tech-requirements.md`:
|
||||||
|
- п. 2.1 — ответ `POST /api/v1/sync`: помимо `accepted`, маппинг
|
||||||
|
`{entity, client_guid, id}` для созданных записей (телефон хранит
|
||||||
|
соответствие локальный id ↔ серверный);
|
||||||
|
- п. 2.2 — `exercise`, `program_version`: поле `client_guid`.
|
||||||
|
3. `1-docs\1-reqs\requirements.md`: Ф-7.2/Ф-7.3 — дополнить маппингом id
|
||||||
|
(одной формулировкой: «ответ содержит соответствие client_guid → серверный
|
||||||
|
id; телефон использует его для ссылок дочерних записей»).
|
||||||
|
|
||||||
|
### З-4. Safety-пороги телефона ⬜ *(после Р3; по Р3-А)*
|
||||||
|
|
||||||
|
1. `1-docs\3-tech\tech-requirements.md`, п. 4.1 (телефон): параметры
|
||||||
|
`Safety.BpCancelSys/Dias` (умолч. 150/90), `Safety.BpCardioSys/Dias`
|
||||||
|
(140/90), `Safety.RestingHrSitting` (90) с валидацией — как в п. 4.2;
|
||||||
|
примечание: умолчания из документа метрик; серверные `Safety.*` — источник
|
||||||
|
для серверных правил (`red_flags`), совпадение значений — ответственность
|
||||||
|
владельца конфигурации (ограничение v1 задокументировать, общая сущность —
|
||||||
|
кандидат v2).
|
||||||
|
2. `1-docs\1-reqs\requirements.md`: раздел 3 (телефонные настройки) —
|
||||||
|
дополнить теми же параметрами; Ф-13.5 — переформулировать: «пороги допуска
|
||||||
|
— конфигурируемые в настройках телефона; серверные `Safety.*` применяются
|
||||||
|
серверными правилами».
|
||||||
|
|
||||||
|
## 3. Задания P2
|
||||||
|
|
||||||
|
### З-5. `src.workout`: уникальность `fit_file_id` и `fit_workout_id` ⬜
|
||||||
|
|
||||||
|
`1-docs\2-db\src\tables.md`:
|
||||||
|
- у описания поля `fit_file_id` убрать «UNIQUE» — оставить составной
|
||||||
|
`UNIQUE(athlete_id, fit_file_id)` (изоляция атлетов);
|
||||||
|
- колонку `fit_workout_id` удалить: факты пишутся в ту же строку
|
||||||
|
(`facts_json`), отдельная строка «только .fit» создаётся с собственным
|
||||||
|
`client_guid` (сервер) — ссылочная колонка не используется.
|
||||||
|
|
||||||
|
### З-6. Sync-enum: фантом и пропуск ⬜
|
||||||
|
|
||||||
|
`1-docs\3-tech\tech-requirements.md`, п. 2.1: из перечня `entity` убрать
|
||||||
|
`set_note` (сущности нет ни в БД, ни в требованиях); добавить `daily_log`.
|
||||||
|
(Совместить с З-3.2 — одна правка п. 2.1.)
|
||||||
|
|
||||||
|
### З-7. Диапазон RPE ⬜
|
||||||
|
|
||||||
|
Согласовать: Ф-13.3 и tech-requirements п. 2.2 — «0–10»; `tables.md` —
|
||||||
|
`CHECK (rpe BETWEEN 1 AND 10)`. Рекомендация: единый диапазон **1–10**
|
||||||
|
(RPE 0 в документе метрик не используется; голос «РПЭ N» — N 1–10): в
|
||||||
|
Ф-13.3 «тапом 1–10», в tech-requirements 2.2 — «int? 1–10». При выборе
|
||||||
|
владельцем 0–10 — правится CHECK в tables.md.
|
||||||
|
|
||||||
|
### З-8. Грамматика Ф-1.2: команда «РПЭ N» ⬜
|
||||||
|
|
||||||
|
`1-docs\1-reqs\requirements.md`, Ф-1.2: добавить четвёртую команду
|
||||||
|
«РПЭ **N**» → RPE последнего подхода (N 1–10, по З-7); согласовать с Ф-13.3
|
||||||
|
и решением ОВ-2 в tech-requirements (грамматика уже включает «РПЭ»).
|
||||||
|
|
||||||
|
## 4. Задания P3 (гигиена)
|
||||||
|
|
||||||
|
| Код | Задание | Где |
|
||||||
|
|---|---|---|
|
||||||
|
| З-9 | Удалить мусорную строку «io header fix»; в Ф-12 перенумеровать второй «5.» (Офлайн-режим сервера) в «6.» | requirements.md:381–384 |
|
||||||
|
| З-10 | Исправить «.gp**х**» → «.gpx» (кириллическая буква) | requirements.md:267 |
|
||||||
|
| З-11 | Шапки-источники привести к vision **v1.3**: requirements (сейчас «v1.0»), tech-requirements (сейчас «v1.2»). Для architecture — в З-2 | requirements.md:4, tech-requirements.md:4 |
|
||||||
|
| З-12 | URL репозитория: `readme.md` — `VEU/VEU.WathBody.git`, `plan.md` — `VEU/WatchBody.git`. Сверить с фактическим `git remote -v` и привести оба файла к нему (сейчас remote, вероятно, не настроен — тогда принять `VEU/WatchBody.git` и исправить опечатку «WathBody») | readme.md:3–4, plan.md:3–4 |
|
||||||
|
| З-13 | Маркер «MM» в tables.md вне словаря d-db-2 (`CRUD/SELECT/NO/CUSTOM`): оставить как есть, в комментарий строки добавить «типовой набор связи ММ — d-db-3»; о необходимости маркера «MM» сообщить владельцу std1 (вне репозитория) | src/tables.md:14 |
|
||||||
|
| З-14 | Добавить в readme БД раздел «План миграции» (требование d-db-1): создание схем `src`/`ref`, вставка значений `ref.exercise_group`, порядок применения psql-файлов из `2-db\`, версионирование миграций | 1-docs/2-db/readme.md |
|
||||||
|
| З-15 | Сообщить владельцу std1 (вне репозитория): process.md шаг 6 указывает артефакты в `1-docs\d-db\`, противореча шагу 2 того же процесса и правилу d-db-1 (`1-docs\2-db\`); проект применил верный путь | — |
|
||||||
|
|
||||||
|
## 5. Порядок исполнения и версии
|
||||||
|
|
||||||
|
**Волна 1 — errata, выполняется сразу (З-5–З-14 без Р-зависимостей:**
|
||||||
|
З-5, З-6, З-9, З-10, З-11, З-12, З-13, З-14**).** Правки представляются
|
||||||
|
владельцу одним диффом → утверждение → коммит
|
||||||
|
«Ревью документации: errata (Ф-12 нумерация, .gpx, версии источников,
|
||||||
|
fit_file_id, sync-enum)». Версии: requirements → 1.2 (errata),
|
||||||
|
tables.md → новая редакция (дата), tech-requirements → 1.2, 2-db readme →
|
||||||
|
новая редакция.
|
||||||
|
|
||||||
|
**Волна 2 — после решений Р1–Р3 (З-1, З-2, З-3, З-4, З-8).** Все правки
|
||||||
|
одним пакетом «Актуализация по ревью: Ф-13 в архитектуре, данные правила 1,
|
||||||
|
client_guid/маппинг sync, Safety телефона» → рендер hld → утверждение
|
||||||
|
владельцем (одно утверждение на пакет) → коммит. Версии: requirements → 1.3,
|
||||||
|
architecture → 1.1, tech-requirements → 1.3, tables/functions → новая
|
||||||
|
редакция (число функций не меняется — меняются параметры `daily_log_upsert`
|
||||||
|
и колонки `client_guid`).
|
||||||
|
|
||||||
|
**После каждой волны — самопроверка (раздел 7) и отметки в разделе 6.**
|
||||||
|
|
||||||
|
## 6. Чек-лист
|
||||||
|
|
||||||
|
| Задание | P | Зависит от | Статус |
|
||||||
|
|---|---|---|---|
|
||||||
|
| Р1–Р3 решения владельца | — | — | ⬜ |
|
||||||
|
| З-1 правило 1: данные v1 | 1 | Р1 | ⬜ |
|
||||||
|
| З-2 архитектура + hld.puml + рендер | 1 | — (текст), рендер после правок | 🔄 (2026-10-17: Ф-13+Ф-14 внесены; черновик v1.1 — на утверждении) |
|
||||||
|
| З-3 client_guid + маппинг id | 1 | Р2 | ⬜ |
|
||||||
|
| З-4 Safety-пороги телефона | 1 | Р3 | ⬜ |
|
||||||
|
| З-5 fit_file_id / fit_workout_id | 2 | — | ✅ (2026-10-17) |
|
||||||
|
| З-6 sync-enum (set_note/daily_log) | 2 | — | ✅ (2026-10-17) |
|
||||||
|
| З-7 диапазон RPE | 2 | — | ⬜ |
|
||||||
|
| З-8 грамматика «РПЭ N» | 2 | З-7 | ⬜ |
|
||||||
|
| З-9 Ф-12: «io header fix», нумерация | 3 | — | ✅ (2026-10-17) |
|
||||||
|
| З-10 .gpх → .gpx | 3 | — | ✅ (2026-10-17) |
|
||||||
|
| З-11 шапки-источники → vision v1.3 | 3 | — | ✅ (2026-10-17, сразу v1.4) |
|
||||||
|
| З-12 URL репозитория | 3 | — | ✅ (2026-10-17, remote = VEU/VEU.WathBody.git, оба файла выверены) |
|
||||||
|
| З-13 маркер «MM» + письмо std1 | 3 | — | 🔄 (комментарий добавлен; письмо std1 — вне репо) |
|
||||||
|
| З-14 план миграции в 2-db readme | 3 | — | ✅ (2026-10-17) |
|
||||||
|
| З-15 сообщение владельцу std1 о process.md | 3 | — | ⬜ |
|
||||||
|
|
||||||
|
## 7. Самопроверка после правок
|
||||||
|
|
||||||
|
1. **requirements.md:** трассировка раздела 6 не нарушена (каждая Ф имеет БЦ/КУ);
|
||||||
|
ссылки на ОВ актуальны; нумерация Ф-12 сплошная; «РПЭ N» есть и в Ф-1.2,
|
||||||
|
и в Ф-13.3 с одним диапазоном.
|
||||||
|
2. **architecture.md / hld.puml:** шапка ссылается на vision v1.3 и
|
||||||
|
requirements текущей версии; Ф-13 присутствует в разделах 1.2, 2 и в таблице
|
||||||
|
компонентов; рендер (`hld.svg`/`hld.png`) свежее `.puml`; стиль — d-drg-3,
|
||||||
|
палитра и легенда — d-drg-4 (жёлтый — внешнее, серый — не в v1).
|
||||||
|
3. **tables.md / functions.md:** «Набор функций» в сводной таблице ↔ строки
|
||||||
|
«Списка функций» совпадают 1:1; словарь маркеров соблюдён; составной
|
||||||
|
`UNIQUE(athlete_id, fit_file_id)` — единственное описание уникальности;
|
||||||
|
`daily_log_upsert` содержит все поля v1.
|
||||||
|
4. **tech-requirements.md:** enum `entity` = перечень п. 2.2 без фантомов;
|
||||||
|
`Safety.*` есть в 4.1 и 4.2 с согласованными умолчаниями; ответ sync
|
||||||
|
описывает маппинг id.
|
||||||
|
5. **Общее:** git-статус чистый после коммитов; в логах/доках нет секретов;
|
||||||
|
push не выполнялся.
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# Функциональные требования: Феникс 6X v1
|
# Функциональные требования: Феникс 6X v1
|
||||||
|
|
||||||
> Шаг 3 процесса разработки (`std1\_process\process.md`).
|
> Шаг 3 процесса разработки (`std1\_process\process.md`).
|
||||||
> Источник: [vision.md](vision.md) (утверждён 2026-10-17, v1.0), разделы
|
> Источник: [vision.md](vision.md) (утверждён 2026-10-17, v1.3), разделы
|
||||||
> 1.3 (БЦ), 1.4 (КУ), 2.1–2.4; решения опросников 4.1–4.7; ТЗ
|
> 1.3 (БЦ), 1.4 (КУ), 2.1–2.4; решения опросников 4.1–4.7; ТЗ
|
||||||
> (`..\..\Техническое задание.md`), дизайн LLM-планирования (разд. 2–3,
|
> (`..\..\Техническое задание.md`), дизайн LLM-планирования (разд. 2–3,
|
||||||
> 6–8, 11 — шаг 1); изменение vision 1.1 (2026-10-17) — несколько
|
> 6–8, 11 — шаг 1); изменение vision 1.1 (2026-10-17) — несколько
|
||||||
|
|
@ -263,7 +263,7 @@ Garmin штатно — Ф-2.5, Ф-2.6). Код поля данных перен
|
||||||
результат — канонический JSON тренировки в `workout_facts`
|
результат — канонический JSON тренировки в `workout_facts`
|
||||||
(дизайн LLM-планирования, разд. 4).
|
(дизайн LLM-планирования, разд. 4).
|
||||||
3. Fallback-импорт (`--mode import`): файлы из `Import.Dir` (.fit, .tcx,
|
3. Fallback-импорт (`--mode import`): файлы из `Import.Dir` (.fit, .tcx,
|
||||||
.gpх — по документу форматов) парсятся тем же конвейером;
|
.gpx — по документу форматов) парсятся тем же конвейером;
|
||||||
обработанные перемещаются в `Import.ArchiveDir`; необработанные
|
обработанные перемещаются в `Import.ArchiveDir`; необработанные
|
||||||
остаются с записью в логе (код возврата 2).
|
остаются с записью в логе (код возврата 2).
|
||||||
4. Сопоставление факт ↔ голосовой учёт: тренировка .fit сопоставляется
|
4. Сопоставление факт ↔ голосовой учёт: тренировка .fit сопоставляется
|
||||||
|
|
@ -378,8 +378,7 @@ Garmin штатно — Ф-2.5, Ф-2.6). Код поля данных перен
|
||||||
- боль в колене ≥ 1 два занятия подряд → предложение замены
|
- боль в колене ≥ 1 два занятия подряд → предложение замены
|
||||||
упражнения из той же группы (пара-замена из атрибутов упражнения).
|
упражнения из той же группы (пара-замена из атрибутов упражнения).
|
||||||
|
|
||||||
io header fix
|
6. Офлайн-режим сервера: правила выполняются при следующем запуске
|
||||||
5. Офлайн-режим сервера: правила выполняются при следующем запуске
|
|
||||||
`serve`/`import` — телефон при этом полнофункционален (учёт и
|
`serve`/`import` — телефон при этом полнофункционален (учёт и
|
||||||
локальные планы работают без сервера).
|
локальные планы работают без сервера).
|
||||||
|
|
||||||
|
|
@ -414,6 +413,57 @@ io header fix
|
||||||
и правила координации 7–10 — v2; контрольные тесты — v3
|
и правила координации 7–10 — v2; контрольные тесты — v3
|
||||||
(документ метрик, п. 5).
|
(документ метрик, п. 5).
|
||||||
|
|
||||||
|
### Ф-14. Перерывы и возврат в режим (телефон + сервер; изменение 2)
|
||||||
|
|
||||||
|
Источник — документ `Перерывы_подводные_камни_и_рекомендации.md`
|
||||||
|
(МакРоберт, CDC «Staying on Track», Жижин гл. 5–6, Аттия). Модель:
|
||||||
|
`active → break → return → active`.
|
||||||
|
|
||||||
|
1. 🛡 **Break вычисляется автоматически:** пропущены все
|
||||||
|
запланированные сессии за 4 дня подряд → программа переводится
|
||||||
|
в статус `break` (Жижин гл. 6: эффект тает с 4-го дня). Ручного
|
||||||
|
включения break нет — только расчёт.
|
||||||
|
2. **Причина запрашивается у атлета:** при срабатывании автомат
|
||||||
|
показывает вопрос «Вы пропустили тренировки — что случилось?»
|
||||||
|
с выбором типа (болезнь / отпуск / аврал-недосып / травма /
|
||||||
|
другое) и предполагаемой даты возврата; до ответа тип —
|
||||||
|
«не указана» (правила 12–14 применяются после ответа). При типе
|
||||||
|
«болезнь с температурой» — минимум 3 дня после нормальной
|
||||||
|
температуры до первой сессии (правило 12). Атлет может объявить
|
||||||
|
break заранее («уезжаю в отпуск») — запланированный простой
|
||||||
|
попадает в тот же автомат.
|
||||||
|
3. **Формула возврата** (детерминированная, коэффициент от рабочего
|
||||||
|
веса, документ перерывов разд. 3.2):
|
||||||
|
|
||||||
|
| Простой | Коэффициент | Режим |
|
||||||
|
|---|---|---|
|
||||||
|
| 4–6 дней | 100 % | первая сессия: −1 подход, RPE-цель 5–6 |
|
||||||
|
| 7–13 дней | −10 % | 1–2 недели возврата |
|
||||||
|
| 14–27 дней | −15 % | 1 вводная неделя (техника, без отказа) |
|
||||||
|
| 28–59 дней | −25 % | 2 вводные недели |
|
||||||
|
| 60+ дней / болезнь с температурой / операция | −30…−40 % | перезапуск цикла, контроль АД первые 2 недели |
|
||||||
|
|
||||||
|
Кардио (зона 2) возвращается со 100 % длительности сразу
|
||||||
|
(митохондриальная пластичность); силу — по формуле.
|
||||||
|
4. **Return:** при первой сессии после break создаётся новая версия
|
||||||
|
программы с формульными весами (статус `draft`, `author=rules`,
|
||||||
|
`rationale` — причина снижения); подтверждение — по Ф-12.3. 🛡
|
||||||
|
Неизменяемость версий не нарушается.
|
||||||
|
5. **`session_kind`:** каждая тренировка помечается
|
||||||
|
`normal | return | deload | test` — снижение весов при возврате
|
||||||
|
не выглядит в истории как регресс.
|
||||||
|
6. **Домашний режим:** тип break «отпуск, зал недоступен» →
|
||||||
|
переключатель активирует заготовленный поддерживающий комплекс
|
||||||
|
(отжимания, приседания без веса, тяга резинки, планка, ходьба)
|
||||||
|
с пометкой «поддержание, не прогресс» (правило 14).
|
||||||
|
7. **Правила координации 12–17** (документ перерывов, разд. 3.3):
|
||||||
|
болезнь с температурой (12), аврал/недосып → средняя тренировка
|
||||||
|
вместо тяжёлой (13), домашний комплекс (14), break ≥ 14 дней →
|
||||||
|
ужесточение порогов АД на 2 недели (отмена при > 145/90) (15),
|
||||||
|
2+ перерыва ≥ 7 дней за месяц → план 2 дня/нед до adherence ≥ 80 %
|
||||||
|
(16), возврат после break ≥ 14 дней → тест-сессия при RPE ≤ 6 (17).
|
||||||
|
Считает `ProgressionRules` вместе с правилами 1–11.
|
||||||
|
|
||||||
### Логирование (телефон и сервер)
|
### Логирование (телефон и сервер)
|
||||||
|
|
||||||
1. `Info`: старт/остановка тренировки, каждая команда (Ф-1.5), пакеты
|
1. `Info`: старт/остановка тренировки, каждая команда (Ф-1.5), пакеты
|
||||||
|
|
@ -464,6 +514,7 @@ io header fix
|
||||||
| Ф-13 самоконтроль и допуск | БЦ-6 | КУ-7 | v1 |
|
| Ф-13 самоконтроль и допуск | БЦ-6 | КУ-7 | v1 |
|
||||||
| Ф-12 LLM-контур (еженедельно) | БЦ-3 | — | v2 |
|
| Ф-12 LLM-контур (еженедельно) | БЦ-3 | — | v2 |
|
||||||
| Ф-13 полная телеметрия, правила 7–10 | БЦ-6 | — | v2 |
|
| Ф-13 полная телеметрия, правила 7–10 | БЦ-6 | — | v2 |
|
||||||
|
| Ф-14 перерывы и возврат | БЦ-3, БЦ-6 | КУ-6, КУ-7 | v1 |
|
||||||
| Контрольные тесты | БЦ-6 | — | v3 |
|
| Контрольные тесты | БЦ-6 | — | v3 |
|
||||||
| Wake-word (Ф-1) | БЦ-1 | — | v2 |
|
| Wake-word (Ф-1) | БЦ-1 | — | v2 |
|
||||||
| iOS | БЦ-1, БЦ-2 | — | v2 |
|
| iOS | БЦ-1, БЦ-2 | — | v2 |
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# Vision: Феникс 6X — контроль силовых тренировок (телефон + Garmin Fenix 6 + личный сервер)
|
# Vision: Феникс 6X — контроль силовых тренировок (телефон + Garmin Fenix 6 + личный сервер)
|
||||||
|
|
||||||
> Версия 1.3 — **УТВЕРЖДЕНО** (2026-10-17; вопросы опросника 4.1–4.7
|
> Версия 1.4 — **УТВЕРЖДЕНО** (2026-10-17; вопросы опросника 4.1–4.7
|
||||||
> отвечены, ответы применены; утверждение — 2026-10-17; изменения
|
> отвечены, ответы применены; утверждение — 2026-10-17; изменения
|
||||||
> 1.1–1.3 — указания пользователя от 2026-10-17).
|
> 1.1–1.4 — указания пользователя от 2026-10-17).
|
||||||
> Изменение 1.1: серверная часть
|
> Изменение 1.1: серверная часть
|
||||||
> поддерживает нескольких атлетов — у каждого свои программы, профиль
|
> поддерживает нескольких атлетов — у каждого свои программы, профиль
|
||||||
> и данные, с собственных телефона и часов (пп. 2.2, 2.4, 3.1);
|
> и данные, с собственных телефона и часов (пп. 2.2, 2.4, 3.1);
|
||||||
|
|
@ -23,6 +23,12 @@
|
||||||
> (пороги АД/пульса), RPE и боль в колене по сетам; правила
|
> (пороги АД/пульса), RPE и боль в колене по сетам; правила
|
||||||
> координации Ф-12 расширены 11 детерминированными правилами по книгам
|
> координации Ф-12 расширены 11 детерминированными правилами по книгам
|
||||||
> (пп. 2.2, 2.3, 3.3).
|
> (пп. 2.2, 2.3, 3.3).
|
||||||
|
> Изменение 1.4 (документ «Перерывы_подводные_камни_и_рекомендации.md»,
|
||||||
|
> 2026-10-17): добавлена Ф-14 «Перерывы и возврат в режим» — автомат
|
||||||
|
> `active → break → return → active` (детекция по пропускам или метка
|
||||||
|
> пользователя), формула снижения весов по длительности простоя
|
||||||
|
> (−10 %…перезапуск цикла), метка `session_kind`, домашний
|
||||||
|
> поддерживающий комплекс, правила координации 12–17 (пп. 2.1, 2.2).
|
||||||
> Источник идеи: техническое задание
|
> Источник идеи: техническое задание
|
||||||
> «Феникс 6X» (Garmin Edition) от 17.10.2026
|
> «Феникс 6X» (Garmin Edition) от 17.10.2026
|
||||||
> ([Техническое задание.md](../../Техническое%20задание.md)); требование
|
> ([Техническое задание.md](../../Техническое%20задание.md)); требование
|
||||||
|
|
@ -325,6 +331,15 @@ Garmin, наш продукт фиксирует результаты без р
|
||||||
МакРоберт, CDC); состав v1 — MVP-приоритет документа (его п. 5):
|
МакРоберт, CDC); состав v1 — MVP-приоритет документа (его п. 5):
|
||||||
дневник-минимум + правила координации 1–6; утренняя телеметрия
|
дневник-минимум + правила координации 1–6; утренняя телеметрия
|
||||||
полностью и правила 7–10 — v2, контрольные тесты — v3.
|
полностью и правила 7–10 — v2, контрольные тесты — v3.
|
||||||
|
- **Ф-14. Перерывы и возврат в режим** (изменение 1.4) — конечный автомат
|
||||||
|
`active → break → return → active`: break вычисляется автоматически
|
||||||
|
(пропуск всех запланированных сессий 4 дня), причина запрашивается
|
||||||
|
у атлета (болезнь/отпуск/аврал/травма); при возврате программа переводится в режим
|
||||||
|
возврата по формуле длительности простоя (100 %…−40 %, вводные
|
||||||
|
недели), создаётся новая версия с `rationale`; тренировки помечаются
|
||||||
|
`session_kind` (normal/return/deload/test); «отпуск без зала» —
|
||||||
|
домашний поддерживающий комплекс; правила координации 12–17
|
||||||
|
(документ перерывов, разд. 3.2–3.3).
|
||||||
|
|
||||||
### 2.2. Объём первоначально запланированной версии
|
### 2.2. Объём первоначально запланированной версии
|
||||||
|
|
||||||
|
|
@ -332,8 +347,8 @@ Garmin, наш продукт фиксирует результаты без р
|
||||||
**v1.0 = полный MVP-цикл ТЗ (Ф-1–Ф-9) + программы: Ф-10, Ф-11 и правила
|
**v1.0 = полный MVP-цикл ТЗ (Ф-1–Ф-9) + программы: Ф-10, Ф-11 и правила
|
||||||
прогрессии/координации (основа Ф-12) — шаг 1 порядка внедрения
|
прогрессии/координации (основа Ф-12) — шаг 1 порядка внедрения
|
||||||
LLM-планирования, без LLM; Ф-13 в MVP-составе документа метрик
|
LLM-планирования, без LLM; Ф-13 в MVP-составе документа метрик
|
||||||
(дневник-минимум, допуск по АД/пульсу, правила 1–6); LLM-контур
|
(дневник-минимум, допуск по АД/пульсу, правила 1–6); Ф-14 — перерывы
|
||||||
Ф-12 — v2**.
|
и возврат (изменение 1.4); LLM-контур Ф-12 — v2**.
|
||||||
Разработка — в порядке перечня MVP ТЗ: часы → связь с телефоном → экран
|
Разработка — в порядке перечня MVP ТЗ: часы → связь с телефоном → экран
|
||||||
тренировки → голосовой ввод → локальная БД → сервер → забор .fit →
|
тренировки → голосовой ввод → локальная БД → сервер → забор .fit →
|
||||||
синхронизация → история и веб.
|
синхронизация → история и веб.
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,16 @@ vision 1.1); перечень моделей — открытый вопрос 8
|
||||||
### 1.2. Телефон атлета — **Phone.WatchBody** (Android, Kotlin)
|
### 1.2. Телефон атлета — **Phone.WatchBody** (Android, Kotlin)
|
||||||
|
|
||||||
- `TrainingUi` — экраны (Jetpack Compose — кандидат, фиксируется
|
- `TrainingUi` — экраны (Jetpack Compose — кандидат, фиксируется
|
||||||
шагом 5): активная тренировка, история, программы, профиль;
|
шагом 5): активная тренировка, история, программы, профиль,
|
||||||
тёмная тема, крупные зоны касания.
|
«Сегодня» (дневник) и «Допуск»; тёмная тема, крупные зоны касания.
|
||||||
- `VoiceInput` — офлайн-STT (движок — открытый вопрос 2) + грамматика
|
- `VoiceInput` — офлайн-STT (движок — открытый вопрос 2) + грамматика
|
||||||
команд (Ф-1.2) + TTS-подтверждения; журнал команд для сопоставления
|
команд (Ф-1.2) + TTS-подтверждения; журнал команд для сопоставления
|
||||||
с .fit.
|
с .fit.
|
||||||
- `WorkoutCore` — логика тренировки и программ: подходы, таймеры,
|
- `WorkoutCore` — логика тренировки и программ: подходы, таймеры,
|
||||||
план/факт, редактор программ; единственный писатель `LocalDb`.
|
план/факт, редактор программ; 🛡 предстартовый допуск (пороги
|
||||||
|
Safety, экран допуска) и дневник самоконтроля (`daily_log`);
|
||||||
|
автомат перерывов и формула возврата (Ф-14); единственный писатель
|
||||||
|
`LocalDb`.
|
||||||
- `LocalDb` — Room/SQLite: текущая тренировка, история, программы,
|
- `LocalDb` — Room/SQLite: текущая тренировка, история, программы,
|
||||||
библиотека, профиль, очередь.
|
библиотека, профиль, очередь.
|
||||||
- `SyncQueue` — исходящие записи с `client_guid`, пакеты ≤ 50,
|
- `SyncQueue` — исходящие записи с `client_guid`, пакеты ≤ 50,
|
||||||
|
|
@ -53,9 +56,9 @@ vision 1.1); перечень моделей — открытый вопрос 8
|
||||||
| `FitFetcher` | `Server.WatchBody.Fetch` | Клиент Garmin Connect (неофициальный, опросник 4.3); `--mode fetch`; дедупликация по `fit_file_id` |
|
| `FitFetcher` | `Server.WatchBody.Fetch` | Клиент Garmin Connect (неофициальный, опросник 4.3); `--mode fetch`; дедупликация по `fit_file_id` |
|
||||||
| `FitParser` | `Server.WatchBody.Import` | Garmin FIT SDK: Session/Lap/Record/Set → `workout_facts`; `--mode import` (fallback: .fit/.tcx/.gpx из папки) |
|
| `FitParser` | `Server.WatchBody.Import` | Garmin FIT SDK: Session/Lap/Record/Set → `workout_facts`; `--mode import` (fallback: .fit/.tcx/.gpx из папки) |
|
||||||
| `MetricsEngine` | `Server.WatchBody.Core` | adherence, тоннаж по группам, 1ПМ, пульс-метрики, красные флаги (АД/пульс/боль — документ метрик) → `workout_metrics` |
|
| `MetricsEngine` | `Server.WatchBody.Core` | adherence, тоннаж по группам, 1ПМ, пульс-метрики, красные флаги (АД/пульс/боль — документ метрик) → `workout_metrics` |
|
||||||
| `ProgressionRules` | `Server.WatchBody.Core` | Правила прогрессии, делоада и координации 1–6 (документ метрик) → draft-версии программ (`author=rules`) |
|
| `ProgressionRules` | `Server.WatchBody.Core` | Правила прогрессии, делоада и координации 1–11 (документ метрик) + 12–17 перерывы (документ перерывов): детекция `break` по пропускам, формула возврата → draft-версии (`author=rules`) |
|
||||||
| `ProgramStore` | `Server.WatchBody.Core` | Версионированный JSON программ; неизменяемость версий; `active` — ровно один на атлета |
|
| `ProgramStore` | `Server.WatchBody.Core` | Версионированный JSON программ; неизменяемость версий; `active` — ровно один на атлета |
|
||||||
| БД | схема `src` \| `ref` | PostgreSQL: атлеты, тренировки/факты, метрики, программы, журнал LLM (v2) |
|
| БД | схема `src` \| `ref` | PostgreSQL: атлеты, тренировки/факты + `session_kind`, дневник (`daily_log`), перерывы (`breaks`), метрики, программы, журнал LLM (v2) |
|
||||||
|
|
||||||
Общая библиотека — `Kit.Helpers` (`3-app\1-lib`, std1). Взаимодействие
|
Общая библиотека — `Kit.Helpers` (`3-app\1-lib`, std1). Взаимодействие
|
||||||
с LLM (v2, `LlmPlanner`) — по правилам std1 `c-llm`; в v1 компонент
|
с LLM (v2, `LlmPlanner`) — по правилам std1 `c-llm`; в v1 компонент
|
||||||
|
|
@ -69,6 +72,11 @@ vision 1.1); перечень моделей — открытый вопрос 8
|
||||||
|
|
||||||
## 2. Поток цикла обработки
|
## 2. Поток цикла обработки
|
||||||
|
|
||||||
|
0. **Допуск и перерывы.** Перед стартом — экран допуска (АД/пульс;
|
||||||
|
красные флаги блокируют или переводят в лёгкое кардио; обход
|
||||||
|
логируется); автомат перерывов ставит `break` по пропускам и
|
||||||
|
запрашивает причину у атлета; при возврате — формульная версия
|
||||||
|
(Ф-14).
|
||||||
1. **Тренировка.** Атлет запускает «Силовую» на часах (`FenixDataField`
|
1. **Тренировка.** Атлет запускает «Силовую» на часах (`FenixDataField`
|
||||||
показывает пульс/зоны/подходы) и активирует голосовой ввод на телефоне
|
показывает пульс/зоны/подходы) и активирует голосовой ввод на телефоне
|
||||||
(`VoiceInput` → команды → `WorkoutCore` → `LocalDb`). Часы и телефон
|
(`VoiceInput` → команды → `WorkoutCore` → `LocalDb`). Часы и телефон
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 176 KiB |
|
|
@ -31,7 +31,7 @@ node "Часы атлета\n(Garmin, Connect IQ)" as Watch {
|
||||||
node "Телефон атлета\n(Android, Kotlin)" as Phone {
|
node "Телефон атлета\n(Android, Kotlin)" as Phone {
|
||||||
component "VoiceInput\nофлайн-STT + грамматика команд" as VoiceInput
|
component "VoiceInput\nофлайн-STT + грамматика команд" as VoiceInput
|
||||||
component "TrainingUi\nэкран тренировки, таймеры, история" as TrainingUi
|
component "TrainingUi\nэкран тренировки, таймеры, история" as TrainingUi
|
||||||
component "WorkoutCore\nлогика тренировки и программ" as WorkoutCore
|
component "WorkoutCore\nлогика тренировки, допуск,\nдневник, перерывы" as WorkoutCore
|
||||||
component "LocalDb\nRoom/SQLite" as LocalDb
|
component "LocalDb\nRoom/SQLite" as LocalDb
|
||||||
component "SyncQueue\nочередь + идемпотентность" as SyncQueue
|
component "SyncQueue\nочередь + идемпотентность" as SyncQueue
|
||||||
component "WatchChannel\ncompanion-канал Connect IQ" as WatchChannel
|
component "WatchChannel\ncompanion-канал Connect IQ" as WatchChannel
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
|
@ -28,6 +28,24 @@
|
||||||
| [src\tables.md](src/tables.md) | таблицы слоя `src` |
|
| [src\tables.md](src/tables.md) | таблицы слоя `src` |
|
||||||
| `{слой}\functions.md` | списки функций (после утверждения таблиц) |
|
| `{слой}\functions.md` | списки функций (после утверждения таблиц) |
|
||||||
|
|
||||||
|
## План миграции (d-db-1)
|
||||||
|
|
||||||
|
1. Схемы: `CREATE SCHEMA IF NOT EXISTS src; CREATE SCHEMA IF NOT EXISTS ref;`
|
||||||
|
2. Справочники: `ref\exercise_group.psql` — таблица + вставка 5 значений
|
||||||
|
(идемпотентно, `ON CONFLICT (code) DO NOTHING`).
|
||||||
|
3. Таблицы `src`: порядок — `athlete` → `athlete_profile` → `exercise` →
|
||||||
|
`exercise_replacement` → `program` → `program_version` → `workout` →
|
||||||
|
`workout_set` → `command_log` → `daily_log` → `workout_metrics` →
|
||||||
|
`breaks` (FK-зависимости).
|
||||||
|
4. Функции: файлы `{слой}\функции.psql` по сущностям в том же порядке
|
||||||
|
(`CREATE OR REPLACE` — перезапуск безопасен).
|
||||||
|
5. Версионирование: каталог `2-db\migrations\` — `NNN_описание.sql`
|
||||||
|
по возрастанию; каждая миграция идемпотентна (IF NOT EXISTS /
|
||||||
|
OR REPLACE); факт применения — одна запись на файл в
|
||||||
|
`src.migration` (id, filename, applied_at).
|
||||||
|
6. Сборка: скрипт `2-dbuild.ps1` применяет миграции по номеру
|
||||||
|
(утилита `Server.WatchBody.Import --mode migrate`).
|
||||||
|
|
||||||
## Таблица `llm_calls` (v2)
|
## Таблица `llm_calls` (v2)
|
||||||
|
|
||||||
Журнал вызовов LLM-планировщика (дизайн LLM-планирования, разд. 8)
|
Журнал вызовов LLM-планировщика (дизайн LLM-планирования, разд. 8)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@
|
||||||
> они для сервисов владельца): изоляция атлетов.
|
> они для сервисов владельца): изоляция атлетов.
|
||||||
> Статусы: `PLAN` — только в списке (спецификаций и кода нет).
|
> Статусы: `PLAN` — только в списке (спецификаций и кода нет).
|
||||||
> **УТВЕРЖДЕНО** (2026-10-17) — список функций к реализации утверждён.
|
> **УТВЕРЖДЕНО** (2026-10-17) — список функций к реализации утверждён.
|
||||||
|
> Новая редакция (2026-10-17): + `breaks` (break_insert/update/select),
|
||||||
|
> `session_kind` в workout_insert/update — интеграция документа
|
||||||
|
> перерывов (Ф-14, изменение vision 1.4). Утверждение добавки —
|
||||||
|
> Пользователь!
|
||||||
|
|
||||||
## Список функций
|
## Список функций
|
||||||
|
|
||||||
|
|
@ -32,8 +36,8 @@
|
||||||
| program_version | program_version_update | PLAN | p_athlete_id, p_id, p_status | int — число строк | - | - | 🛡 меняется только статус; переходы draft→active→archived; активной становится ровно одна (сдвиг прежней в archived) |
|
| program_version | program_version_update | PLAN | p_athlete_id, p_id, p_status | int — число строк | - | - | 🛡 меняется только статус; переходы draft→active→archived; активной становится ровно одна (сдвиг прежней в archived) |
|
||||||
| program_version | program_version_select | PLAN | p_athlete_id, p_program_id, p_status, p_author | TABLE — строки (без body) | - | - | body — отдельным get (крупный jsonb) |
|
| program_version | program_version_select | PLAN | p_athlete_id, p_program_id, p_status, p_author | TABLE — строки (без body) | - | - | body — отдельным get (крупный jsonb) |
|
||||||
| program_version | program_version_get | PLAN | p_athlete_id, p_id | TABLE — одна строка с body | - | - | — |
|
| program_version | program_version_get | PLAN | p_athlete_id, p_id | TABLE — одна строка с body | - | - | — |
|
||||||
| workout | workout_insert | PLAN | p_athlete_id, p_client_guid, p_program_version_id, p_started_at | int — id | - | - | повтор `client_guid` возвращает существующий id (🛡 идемпотентность) |
|
| workout | workout_insert | PLAN | p_athlete_id, p_client_guid, p_program_version_id, p_started_at, p_session_kind | int — id | - | - | повтор `client_guid` возвращает существующий id (🛡 идемпотентность) |
|
||||||
| workout | workout_update | PLAN | p_athlete_id, p_id, p_ended_at, p_status, p_avg_hr, p_fit_workout_id, p_facts_json, p_fit_file_id, p_hr_recovery_s | int — число строк | - | - | факты .fit дописывает FitParser; клиент — только ended/status/avg_hr |
|
| workout | workout_update | PLAN | p_athlete_id, p_id, p_ended_at, p_status, p_session_kind, p_avg_hr, p_facts_json, p_fit_file_id, p_hr_recovery_s | int — число строк | - | - | факты .fit дописывает FitParser; клиент — только ended/status/session_kind/avg_hr |
|
||||||
| workout | workout_select | PLAN | p_athlete_id, p_status, p_date_from, p_date_to | TABLE — карточки + подходы (агрегат jsonb) | - | - | мультикурсор/агрегат: карточка + sets (d-db-6) |
|
| workout | workout_select | PLAN | p_athlete_id, p_status, p_date_from, p_date_to | TABLE — карточки + подходы (агрегат jsonb) | - | - | мультикурсор/агрегат: карточка + sets (d-db-6) |
|
||||||
| workout | workout_get | PLAN | p_athlete_id, p_id | TABLE — одна строка + sets + command_log | - | - | полная карточка (Ф-9.2) |
|
| workout | workout_get | PLAN | p_athlete_id, p_id | TABLE — одна строка + sets + command_log | - | - | полная карточка (Ф-9.2) |
|
||||||
| workout_set | workout_set_insert | PLAN | p_athlete_id, p_client_guid, p_workout_id, p_exercise_id, p_seq, p_weight_kg, p_reps, p_done_at, p_source, p_in_plan, p_rpe, p_knee_pain | int — id | - | - | идемпотентность по client_guid |
|
| workout_set | workout_set_insert | PLAN | p_athlete_id, p_client_guid, p_workout_id, p_exercise_id, p_seq, p_weight_kg, p_reps, p_done_at, p_source, p_in_plan, p_rpe, p_knee_pain | int — id | - | - | идемпотентность по client_guid |
|
||||||
|
|
@ -44,3 +48,6 @@
|
||||||
| daily_log | daily_log_select | PLAN | p_athlete_id, p_date_from, p_date_to | TABLE — строки | - | - | для сводки метрик и AdminWeb |
|
| daily_log | daily_log_select | PLAN | p_athlete_id, p_date_from, p_date_to | TABLE — строки | - | - | для сводки метрик и AdminWeb |
|
||||||
| workout_metrics | workout_metrics_upsert | PLAN | p_athlete_id, p_workout_id, p_adherence, p_tonnage, p_tonnage_by_group, p_e1pm_by_exercise, p_hr_metrics, p_red_flags | int — id | - | - | 1:1, пересчёт MetricsEngine |
|
| workout_metrics | workout_metrics_upsert | PLAN | p_athlete_id, p_workout_id, p_adherence, p_tonnage, p_tonnage_by_group, p_e1pm_by_exercise, p_hr_metrics, p_red_flags | int — id | - | - | 1:1, пересчёт MetricsEngine |
|
||||||
| workout_metrics | workout_metrics_select | PLAN | p_athlete_id, p_workout_id, p_date_from, p_date_to | TABLE — строки | - | - | графики AdminWeb (Ф-9.4) |
|
| workout_metrics | workout_metrics_select | PLAN | p_athlete_id, p_workout_id, p_date_from, p_date_to | TABLE — строки | - | - | графики AdminWeb (Ф-9.4) |
|
||||||
|
| breaks | break_insert | PLAN | p_athlete_id, p_client_guid, p_kind, p_source, p_started_on, p_note | int — id | - | - | auto-ставит сервер по пропускам; manual — телефон |
|
||||||
|
| breaks | break_update | PLAN | p_athlete_id, p_id, p_ended_on | int — число строк | - | - | закрытие break первой сессией после возврата |
|
||||||
|
| breaks | break_select | PLAN | p_athlete_id, p_kind, p_date_from, p_date_to | TABLE — строки | - | - | журнал перерывов; CSV-выгрузка (документ перерывов разд. 4) |
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
| `src.athlete` | сущность | athlete_insert, athlete_update, athlete_select, athlete_get | CUSTOM | без `_delete`: блокировка вместо удаления (`is_blocked`); запись/чтение — владелец и сервисы сервера, не атлет |
|
| `src.athlete` | сущность | athlete_insert, athlete_update, athlete_select, athlete_get | CUSTOM | без `_delete`: блокировка вместо удаления (`is_blocked`); запись/чтение — владелец и сервисы сервера, не атлет |
|
||||||
| `src.athlete_profile` | сущность | athlete_profile_upsert, athlete_profile_get | CUSTOM | 1:1 к `athlete`; upsert вместо insert/update (одна запись) |
|
| `src.athlete_profile` | сущность | athlete_profile_upsert, athlete_profile_get | CUSTOM | 1:1 к `athlete`; upsert вместо insert/update (одна запись) |
|
||||||
| `src.exercise` | сущность | exercise_insert, exercise_update, exercise_delete, exercise_select, exercise_get | CRUD | `_delete` — логический (`is_active=0`, requirements Ф-4.2); функции фильтруют `is_active` по умолчанию |
|
| `src.exercise` | сущность | exercise_insert, exercise_update, exercise_delete, exercise_select, exercise_get | CRUD | `_delete` — логический (`is_active=0`, requirements Ф-4.2); функции фильтруют `is_active` по умолчанию |
|
||||||
| `src.exercise_replacement` | связь ММ | exercise_replacement_insert, exercise_replacement_delete | MM | пара-замена для правила 6 (документ метрик); выборка — внутри `exercise_select` |
|
| `src.exercise_replacement` | связь ММ | exercise_replacement_insert, exercise_replacement_delete | MM | типовой набор связи ММ — d-db-3; пара-замена для правила 6 (документ метрик); выборка — внутри `exercise_select` |
|
||||||
| `src.program` | сущность | program_insert, program_select, program_get | CUSTOM | контейнер версий; без update/delete — жизненный цикл ведут версии |
|
| `src.program` | сущность | program_insert, program_select, program_get | CUSTOM | контейнер версий; без update/delete — жизненный цикл ведут версии |
|
||||||
| `src.program_version` | сущность | program_version_insert, program_version_update, program_version_select, program_version_get | CRUD | `body` jsonb (схема дизайна LLM-планирования разд. 2); 🛡 неизменяемость: `_update` меняет только `status` |
|
| `src.program_version` | сущность | program_version_insert, program_version_update, program_version_select, program_version_get | CRUD | `body` jsonb (схема дизайна LLM-планирования разд. 2); 🛡 неизменяемость: `_update` меняет только `status` |
|
||||||
| `src.workout` | сущность | workout_insert, workout_update, workout_select, workout_get | CRUD | `client_guid` UNIQUE — идемпотентность; `facts_json` — факты .fit |
|
| `src.workout` | сущность | workout_insert, workout_update, workout_select, workout_get | CRUD | `client_guid` UNIQUE — идемпотентность; `facts_json` — факты .fit |
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
| `src.command_log` | сущность | command_log_insert, command_log_select | CUSTOM | журнал голосовых команд (Ф-1.5, 🛡 не редактируется); update/delete нет |
|
| `src.command_log` | сущность | command_log_insert, command_log_select | CUSTOM | журнал голосовых команд (Ф-1.5, 🛡 не редактируется); update/delete нет |
|
||||||
| `src.daily_log` | сущность | daily_log_upsert, daily_log_select | CUSTOM | день уникален для атлета (`UNIQUE(athlete_id, date)`) — upsert |
|
| `src.daily_log` | сущность | daily_log_upsert, daily_log_select | CUSTOM | день уникален для атлета (`UNIQUE(athlete_id, date)`) — upsert |
|
||||||
| `src.workout_metrics` | сущность | workout_metrics_upsert, workout_metrics_select | CUSTOM | 1:1 к `workout`, считает сервер (MetricsEngine) — телефон только читает; upsert (пересчёт) |
|
| `src.workout_metrics` | сущность | workout_metrics_upsert, workout_metrics_select | CUSTOM | 1:1 к `workout`, считает сервер (MetricsEngine) — телефон только читает; upsert (пересчёт) |
|
||||||
|
| `src.breaks` | сущность | break_insert, break_update, break_select | CUSTOM | перерывы (Ф-14); закрытие = update (`ended_at`); delete нет — журнал |
|
||||||
|
|
||||||
## Описания
|
## Описания
|
||||||
|
|
||||||
|
|
@ -99,13 +100,13 @@
|
||||||
| `started_at` | timestamptz NOT NULL | начало (UTC) |
|
| `started_at` | timestamptz NOT NULL | начало (UTC) |
|
||||||
| `ended_at` | timestamptz NULL | конец |
|
| `ended_at` | timestamptz NULL | конец |
|
||||||
| `status` | text NOT NULL DEFAULT 'active' | `active` \| `finished` \| `cancelled` (Ф-3.5) |
|
| `status` | text NOT NULL DEFAULT 'active' | `active` \| `finished` \| `cancelled` (Ф-3.5) |
|
||||||
|
| `session_kind` | text NOT NULL DEFAULT 'normal' | `normal` \| `return` \| `deload` \| `test` — интерпретация снижения весов (Ф-14.5) |
|
||||||
| `avg_hr` | int NULL | средний пульс |
|
| `avg_hr` | int NULL | средний пульс |
|
||||||
| `fit_workout_id` | int NULL | сопоставленная тренировка .fit — см. ниже |
|
|
||||||
| `facts_json` | jsonb NULL | канонический факт из .fit (`workout-facts/1`, tech-requirements 2.3); заполняет FitParser |
|
| `facts_json` | jsonb NULL | канонический факт из .fit (`workout-facts/1`, tech-requirements 2.3); заполняет FitParser |
|
||||||
| `fit_file_id` | text NULL UNIQUE | дедупликация fetch (Ф-8.1) |
|
| `fit_file_id` | text NULL | дедупликация fetch (Ф-8.1); уникальность — составная `UNIQUE(athlete_id, fit_file_id)` |
|
||||||
| `hr_recovery_s` | int NULL | возврат пульса к <90 (Ф-13.4, из .fit) |
|
| `hr_recovery_s` | int NULL | возврат пульса к <90 (Ф-13.4, из .fit) |
|
||||||
|
|
||||||
`UNIQUE(athlete_id, fit_file_id)`; сопоставление телефон ↔ .fit — окно
|
`UNIQUE(athlete_id, fit_file_id)` — единственная уникальность `fit_file_id`; сопоставление телефон ↔ .fit — окно
|
||||||
±15 минут по `started_at` (Ф-8.4): факты пишутся в ту же строку
|
±15 минут по `started_at` (Ф-8.4): факты пишутся в ту же строку
|
||||||
(`facts_json`), либо создается строка «только .fit» без `client_guid`
|
(`facts_json`), либо создается строка «только .fit» без `client_guid`
|
||||||
пары — тогда `client_guid` генерирует сервер.
|
пары — тогда `client_guid` генерирует сервер.
|
||||||
|
|
@ -156,6 +157,19 @@
|
||||||
| `wellbeing` | int NULL CHECK (1–5) | самочувствие (v2) |
|
| `wellbeing` | int NULL CHECK (1–5) | самочувствие (v2) |
|
||||||
| `client_guid` | uuid NOT NULL UNIQUE | идемпотентность |
|
| `client_guid` | uuid NOT NULL UNIQUE | идемпотентность |
|
||||||
|
|
||||||
|
### `src.breaks` — перерывы (Ф-14)
|
||||||
|
|
||||||
|
| Поле | Тип | Описание |
|
||||||
|
|---|---|---|
|
||||||
|
| `id` | serial PK | — |
|
||||||
|
| `athlete_id` | int NOT NULL | → `src.athlete.id` |
|
||||||
|
| `kind` | text NULL | ответ атлета: `illness` \| `vacation` \| `workload` \| `injury` \| `other`; NULL — ещё не отвечен (правила 12–14 ждут ответа) |
|
||||||
|
| `source` | text NOT NULL DEFAULT 'auto' | 🛡 всегда `auto` — break вычисляется по пропускам (Ф-14.1) |
|
||||||
|
| `started_on` | date NOT NULL | первый пропущенный день |
|
||||||
|
| `ended_on` | date NULL | возврат (заполняется первой сессией после break) |
|
||||||
|
| `note` | text | причина-текст пользователя |
|
||||||
|
| `client_guid` | uuid NOT NULL UNIQUE | идемпотентность (для manual) |
|
||||||
|
|
||||||
### `src.workout_metrics` — метрики тренировки (MetricsEngine, 1:1)
|
### `src.workout_metrics` — метрики тренировки (MetricsEngine, 1:1)
|
||||||
|
|
||||||
| Поле | Тип | Описание |
|
| Поле | Тип | Описание |
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
# Технические требования: WatchBody («Феникс 6X») v1
|
# Технические требования: WatchBody («Феникс 6X») v1
|
||||||
|
|
||||||
> Шаг 5 процесса разработки (`std1\_process\process.md`).
|
> Шаг 5 процесса разработки (`std1\_process\process.md`).
|
||||||
> Источники: [vision.md](../1-reqs/vision.md) v1.2,
|
> Источники: [vision.md](../1-reqs/vision.md) v1.4,
|
||||||
> [requirements.md](../1-reqs/requirements.md) (утверждён, раздел 7 —
|
> [requirements.md](../1-reqs/requirements.md) (утверждён, раздел 7 —
|
||||||
> открытые вопросы), [architecture.md](../2-arch/architecture.md)
|
> открытые вопросы), [architecture.md](../2-arch/architecture.md)
|
||||||
> (утверждена), дизайн LLM-планирования, документ форматов.
|
> (утверждена), дизайн LLM-планирования, документ форматов.
|
||||||
> Версия 1.1 — **УТВЕРЖДЕНО** (2026-10-17; интеграция документа метрик —
|
> Версия 1.1 — **УТВЕРЖДЕНО** (2026-10-17; интеграция документа метрик —
|
||||||
> Ф-13, Safety-пороги, daily_log — утверждена вместе с документом).
|
> Ф-13, Safety-пороги, daily_log — утверждена вместе с документом).
|
||||||
|
> Версия 1.2 — черновик (2026-10-17): errata ревью (З-6, З-11) +
|
||||||
|
> интеграция документа перерывов (Ф-14: сущность `break`,
|
||||||
|
> `session_kind`). Утверждение — Пользователь!
|
||||||
|
|
||||||
## 1. Решения открытых вопросов (закрытие раздела 7 requirements)
|
## 1. Решения открытых вопросов (закрытие раздела 7 requirements)
|
||||||
|
|
||||||
|
|
@ -31,7 +34,7 @@
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"client_guid": "uuid-v4",
|
"client_guid": "uuid-v4",
|
||||||
"entity": "workout | exercise | program_version | profile | workout_set | set_note",
|
"entity": "workout | workout_set | exercise | program_version | profile | daily_log | break",
|
||||||
"op": "upsert",
|
"op": "upsert",
|
||||||
"data": { ...схема сущности... }
|
"data": { ...схема сущности... }
|
||||||
}
|
}
|
||||||
|
|
@ -47,12 +50,16 @@
|
||||||
- `exercise`: `exercise_id` (uuid), `name`, `group` (push|pull|legs|core|…),
|
- `exercise`: `exercise_id` (uuid), `name`, `group` (push|pull|legs|core|…),
|
||||||
`is_base` (bool), `is_active` (bool);
|
`is_base` (bool), `is_active` (bool);
|
||||||
- `workout`: `workout_id` (uuid), `started_at`/`ended_at` (UTC ISO 8601),
|
- `workout`: `workout_id` (uuid), `started_at`/`ended_at` (UTC ISO 8601),
|
||||||
`status` (active|finished|cancelled), `program_version_id` (nullable),
|
`status` (active|finished|cancelled), `session_kind`
|
||||||
|
(normal|return|deload|test — Ф-14.5), `program_version_id` (nullable),
|
||||||
`avg_hr`;
|
`avg_hr`;
|
||||||
- `workout_set`: `workout_id`, `exercise_id`, `seq`, `weight_kg`, `reps`,
|
- `workout_set`: `workout_id`, `exercise_id`, `seq`, `weight_kg`, `reps`,
|
||||||
`done_at`, `source` (voice|watch|edit), `in_plan` (bool), `rpe` (int? 0–10),
|
`done_at`, `source` (voice|watch|edit), `in_plan` (bool), `rpe` (int? 0–10),
|
||||||
`knee_pain` (int? 0–10, только группа «ноги»);
|
`knee_pain` (int? 0–10, только группа «ноги»);
|
||||||
- `profile`: `sex`, `birth_year`, `weight_kg`, `hr_max` (nullable);
|
- `profile`: `sex`, `birth_year`, `weight_kg`, `hr_max` (nullable);
|
||||||
|
- `break`: `kind` (NULL до ответа атлета), `started_on`, `note`,
|
||||||
|
`planned_return` — break ставится автоматически (детекция по
|
||||||
|
пропускам ≥ 4 дней), причина запрашивается у атлета (Ф-14.1–2);
|
||||||
- `daily_log`: `date` (YYYY-MM-DD), `bp_sys`, `bp_dias`, `weight_kg`
|
- `daily_log`: `date` (YYYY-MM-DD), `bp_sys`, `bp_dias`, `weight_kg`
|
||||||
(Ф-13.1; v2 добавит `hr_resting`, `waist_cm`, `sleep_h`, `wellbeing`);
|
(Ф-13.1; v2 добавит `hr_resting`, `waist_cm`, `sleep_h`, `wellbeing`);
|
||||||
- `program_version`: JSON-схема программы из дизайна LLM-планирования
|
- `program_version`: JSON-схема программы из дизайна LLM-планирования
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
# Перерывы в тренировках и «подводные камни»: правила из книг + рекомендации для программного комплекса
|
||||||
|
|
||||||
|
> Дата: 2026-10-17. Источники: МакРоберт «Думай! 2» (циклирование, болезнь, авралы), CDC/Tufts «Growing Stronger» (гл. «Staying on Track»: отпуск/болезнь/срывы), Жижин (гл. 5–6: перерывы, переутомление), Аттия «Пережить» (обратимость адаптации), «10 ошибок начинающих».
|
||||||
|
> Связано: `program-trenirovok.json` (v4), `Метрики_тренировок_и_самоконтроля.md`, `Архитектура_LLM_планирования_тренировок.md`.
|
||||||
|
|
||||||
|
## 1. Что говорят книги о простоях
|
||||||
|
|
||||||
|
| Ситуация | Правило | Источник |
|
||||||
|
|---|---|---|
|
||||||
|
| Перерыв **4+ дня** между тренировками | «сводит тренировочный эффект к нулю» — нельзя допускать регулярно | Жижин гл. 6 |
|
||||||
|
| Простуда (1–2 пропущенные тренировки) | Пропустить; при возврате **сбросить 5–10 кг** со штанги, 1–2 недели на возврат к прежним весам. Но если силы сохранились — можно продолжить с прежними: «опыт подскажет» | МакРоберт, гл. о циклах |
|
||||||
|
| Аврал на работе, недосып, пропущенная неделя | Возобновить **с меньшими весами**, 2 недели на возврат к прежнему уровню | МакРоберт |
|
||||||
|
| Плановый отдых между циклами | 7–10 дней; после — «фаза разгона»: веса **−10–15%** от освоенных, упор на технику, 1–2 «вводные» недели | МакРоберт (также «Руки титана»: 10-дневные паузы между фазами) |
|
||||||
|
| Отпуск/болезнь/семья/работа — **1–2+ недели** | «Не чувствовать вины. Вернуться к тренировкам как можно быстрее. Вернуться туда же, где остановился, **может и не получиться — чуть снизить веса**. Потерянное вернётся» | CDC «Staying on Track» |
|
||||||
|
| Врач запретил нагрузки (болезнь/операция) | Тренировки не начинать до разрешения (PAR-Q — входной скрининг) | CDC (PAR-Q) |
|
||||||
|
| Митохондриальная форма (зона 2) | «Не используете — теряете», но митохондрии пластичны: регулярный возврат восстанавливает их быстрее, чем набиралось с нуля | Аттия гл. 10 |
|
||||||
|
| Регулярность как принцип | «Тренироваться ровно и стабильно, без перерывов» — но жизнь вносит перерывы, поэтому их надо **циклировать по науке**, а не героически пересиливать | МакРоберт |
|
||||||
|
|
||||||
|
**Вывод из книг:** перерыв — это не провал, а штатная часть цикла. Система координации должна не «прощать» пропуски, а **автоматически переводить программу в режим возврата** с заведомо заниженными весами.
|
||||||
|
|
||||||
|
## 2. Смежные «подводные камни» (из тех же книг)
|
||||||
|
|
||||||
|
1. **Перетренированность** (Жижин гл. 5–6; МакРоберт): ухудшение настроения, раздражительность, сбитый сон, нежелание тренироваться, утренний пульс +8–10, застой результатов. Лечение — не «пробить», а отдых/лёгкая неделя. У 45+ с гипертонией перетр = прямая угроза АД.
|
||||||
|
2. **Застой (плато)** (МакРоберт): не добавлять упражнения, а менять число рабочих сетов (1↔2↔3), пересмотреть отдых/сон/еду, при необходимости — полный перерыв на неделю и новый цикл.
|
||||||
|
3. **Недосып и стресс на работе** (МакРоберт): «нет смысла тренироваться тяжело, если вас преследуют стрессы» — тяжёлая тренировка при <7 ч сна урезается по интенсивности.
|
||||||
|
4. **Тренировка через боль** («10 ошибок» №4; Шварценеггер кн. 5): острая боль = стоп; боль, проходящая после разминки, — тоже сигнал; колено: 2 занятия подряд с болью → замена упражнения.
|
||||||
|
_Психологические эффекты (чувство вины после пропуска, «растерянность» после возврата) — осознаваемы пользователем и в автоматическую координацию не тащим; учитываются только в тоне сообщений UI. Ниже — измеримые проблемы._
|
||||||
|
|
||||||
|
5. **Возврат «с места в карьер»** (МакРоберт, CDC): типовая травма возвращенца — старт с прежних весов после 2+ недель пропуска. Измеримо: `break_days ≥14` → формульное снижение весов (раздел 3.2).
|
||||||
|
6. **Праздники/отпуск = еда** (Аттия, Жижин гл. 7): вес за отпуск уходит вверх. Измеримо: тренд веса тела — корректируется дефицит по правилу 8–9 из файла метрик.
|
||||||
|
7. **Длительная мышечная боль** (МакРоберт): боль дольше недели. Измеримо: флаг боли ≥1 два занятия подряд → облегчённая вторая тренировка (60–70%, 2–3 сета).
|
||||||
|
8. **Замена упражнений при отсутствии зала** (командировка, отпуск): измеримо по метке типа break = vacation/no_gym → домашний поддерживающий комплекс с ожиданием «поддержание, не прогресс» (Жижин).
|
||||||
|
|
||||||
|
## 3. Рекомендации для программного комплекса «Феникс 6X»
|
||||||
|
|
||||||
|
### 3.1. Модель состояний пользователя
|
||||||
|
|
||||||
|
Ввести конечный автомат поверх программы: `active → break → return → active`.
|
||||||
|
|
||||||
|
- **`break`** — ставится автоматически: пропущены все запланированные сессии за N дней (N = 4 по Жижину для «эффект начинает таять»; 10–14 дней — «полноценный простой»), либо вручную пользователем («болею», «отпуск», «аврал», «травма») с указанием типа и предполагаемой даты возврата.
|
||||||
|
- **`return`** — при первой сессии после break; программа на 1–2 недели (или по формуле ниже) переводится в режим возврата.
|
||||||
|
|
||||||
|
### 3.2. Формула снижения при возврате (детерминированная, для валидатора)
|
||||||
|
|
||||||
|
`коэффициент весов = f(дней простоя)`, от рабочего веса:
|
||||||
|
|
||||||
|
| Простой | Коэффициент | Комментарий |
|
||||||
|
|---|---|---|
|
||||||
|
| 4–6 дней | 100%, но первая сессия −1 подход в упражнении и −RPE (цель 5–6) | «опыт подскажет»: если всё легко — сразу к прежним (МакРоберт) |
|
||||||
|
| 7–13 дней | −10% | простойуд + простуда-граница (МакРоберт: −5–10 кг ≈ −10%) |
|
||||||
|
| 14–27 дней | −15%, и 1 неделя «вводная» (техника, без отказа) | «фаза разгона» МакРоберта |
|
||||||
|
| 28–59 дней | −25%, 2 вводные недели | консервативная экстраполяция + CDC «снизить веса» |
|
||||||
|
| 60+ дней / после болезни с температурой / после операции | перезапуск цикла: −30…−40%, возврат к вводному комплексу месяца 1, обязательный контроль АД первые 2 недели | новый цикл (МакРоберт), CDC: «restart slowly» |
|
||||||
|
|
||||||
|
Отдельно: **кардио-зона 2 восстанавливается быстрее силы** (Аттия, митохондриальная пластичность) — возвращать кардио можно с 100% длительности сразу, силу — по формуле.
|
||||||
|
|
||||||
|
### 3.3. Правила координации (добавка к 11 правилам из файла метрик)
|
||||||
|
|
||||||
|
12. `тип break = болезнь с температурой` → минимум 3 полных дня после нормальной температуры до первой сессии; первая сессия — 50% объёма.
|
||||||
|
13. `тип break = аврал/недосып` (без пропуска всех сессий) → на этой неделе вместо «большой» тренировки ставится «средняя»: тяжёлые подходы −1, RPE-цель −1 (МакРоберт).
|
||||||
|
14. `тип break = отпуск с залом недоступен` → выдаётся домашний поддерживающий комплекс (отжимания, приседания без веса/до стула, тяга резинки, планка, ходьба) с пометкой «поддержание, не прогресс» (Жижин: домашний тренинг слабее — ожидания занижаем).
|
||||||
|
15. `break ≥14 дней` → при возврате контрольные пороги АД ужесточаются на 2 недели (отмена при >145/90 вместо 150/90) — возврат после простоя при гипертонии контролируем строже (Жижин гл. 3).
|
||||||
|
16. `2+ перерыва ≥7 дней за месяц` → план сокращается структурно: 2 дня/нед вместо 3 (CDC: устойчивость важнее объёма), пока adherence не вернётся к 80%+.
|
||||||
|
17. `возврат после break ≥14 дней` → тест-сессия: работаем по RPE ≤6, вес = формула, по факту пульса/АД решение о следующей.
|
||||||
|
|
||||||
|
### 3.4. UX-рекомендации
|
||||||
|
|
||||||
|
- При отметке «болею/отпуск» — сразу показать рассчитанный план возврата (тип, дата, коэффициент весов).
|
||||||
|
- После break в `rationale` новой версии программы фиксируется причина снижения (журнал изменений) — это же получает LLM-планировщик в сводке.
|
||||||
|
- «Домашний режим» — заготовленный мини-план, активируется одним переключателем.
|
||||||
|
- Возврат после травмы (мениск!) — через чек-лист боли (0–10 по упражнениям с ногами) на первой тест-сессии.
|
||||||
|
|
||||||
|
### 3.5. Что фиксировать в БД
|
||||||
|
|
||||||
|
- Таблица `breaks`: тип (illness/vacation/workload/injury/manual), дата начала/конца, источник (auto/manual), причина-текст.
|
||||||
|
- В `sessions` — флаг `session_kind: normal | return | deload | test`, чтобы история весов интерпретировалась правильно (снижение при возврате ≠ регресс).
|
||||||
|
- Связь выполненных сессий с версией программы остаётся (архитектура), но при `return` создаётся **новая версия** программы с формульными весами — неизменяемость версий не нарушается.
|
||||||
|
|
||||||
|
## 4. Возможности форматов планов: где это живёт
|
||||||
|
|
||||||
|
| Формат | Поддержка простоев/возврата | Вывод |
|
||||||
|
|---|---|---|
|
||||||
|
| **Свой JSON программы** (`program-trenirovok.json`) | **Полная.** Поля: `status: break/return` у версии, `session_kind: normal/return/deload/test` у сессии, `weight_factor` у SetPlan, таблица `breaks` в БД. Коэффициенты возврата (3.2) — просто SetPlan с пересчитанными весами в новой версии: неизменяемость версий не нарушается | Основное место логики |
|
||||||
|
| **FIT (activity)** — запись тренировки | Понятия «перерыв» нет: файл = одна выполненная активность. Метка `return`/`deload` — в имени/notes сессии; факт привязывается к `program_version` на сервере | Хранит факт, не план |
|
||||||
|
| **FIT (workout)** — план на часы | Один файл = одна тренировка (шаги/повторы/отдых). Расписание недель держит Garmin Connect, но «неделя возврата −15%» не выражается — только готовые workout-файлы с уже пересчитанными весами в шагах | Экспорт сессии `return` возможен: вес зашит в шаги; семантика «это возврат» остаётся в JSON |
|
||||||
|
| **ZWO / ERG / MRC** | Только интервальные шаги мощность/пульс; силовых данных и циклирования нет | Не подходит |
|
||||||
|
| **CSV (отчёты)** | Выгрузка журнала `breaks` + adherence | Отчётность |
|
||||||
|
|
||||||
|
**Итог:** вся логика простоев — сущность прикладного слоя (JSON + БД + валидатор). Внешние форматы получают только следствие — конкретную сессию с пересчитанными весами; это соответствует п. 5.3 «Форматы_тренировок_и_рекомендации.md» (внутренний формат — JSON, FIT — канал доставки на Garmin).
|
||||||
|
|
||||||
|
## 5. Резюме одной строкой
|
||||||
|
|
||||||
|
Простой — штатная фаза цикла: система сама детектирует его по пропускам или меткам пользователя, сама считает сниженные веса по длительности простоя (−10%…перезапуск), сама ужесточает контроль АД на возврате; логика живёт в собственном JSON и БД, в форматы Garmin уходит уже готовая сессия.
|
||||||
Loading…
Reference in New Issue