VEU.WathBody/1-docs/0-mng/review-2026-10-17-2.md

252 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ревью документации №2 от 2026-10-17 — задания к исполнению
> **Исполнитель:** агент сопровождения документации WatchBody.
> **Источник:** вторая архитектурная проверка документации шагов 1–6
> (после выполнения волн 1–2 ревью №1, коммит `e674318`): сверка с исходной
> задачей (`Техническое задание.md`, `Требование.md`), документами-
> рекомендациями (`Метрики_тренировок_и_самоконтроля.md`,
> `Перерывы_подводные_камни_и_рекомендации.md`,
> `Форматы_тренировок_и_рекомендации.md`,
> `Архитектура_LLM_планирования_тренировок.md`,
> `program-trenirovok.md`), UI/UX-рекомендациями
> (`3-tech\ui-ux-recommendations.md`) и внутренними противоречиями.
> **Уточнение владельца (чат, 2026-10-17):** якорные часы — **Fenix 6X**
> (280×280 MIP). В ТЗ указан «Fenix 6, 260×260» — считать опиской исходника,
> документы разработки приводятся к Fenix 6X (З-18).
> **Состояние репозитория на момент проверки:** коммит `e674318`, ветка
> `main`, статус чистый; ссылки на строки — по нему, после правок
> ориентироваться по разделам.
> **Статусная модель заданий:** ⬜ не начато → 🔄 в работе → ✅ готово
> (утверждено владельцем). Отметки — в разделе 6 по мере работы.
> **Общие правила исполнения:**
> 1. Правки вносятся новыми версиями утверждённых документов (перечень —
> раздел 5). Каждая новая версия — точка утверждения **Пользователь!**
> (d-dev-4).
> 2. Содержание утверждённых документов меняется только в объёме заданий;
> инварианты 🛡 не ослабляются; трассировка «Ф → БЦ → КУ → версия»
> (раздел 6 requirements) сохраняется.
> 3. Задания, зависящие от решений О-1…О-3 (раздел 1), не вносятся до выбора
> владельцем; остальные можно выполнять сразу. Если владелец не выбрал —
> подготовить дифф по рекомендованному варианту и вынести на утверждение.
> 4. Код (`3-app\`, `2-db\`) не трогается — задание касается только `1-docs\`
> и корневых `readme.md`/`plan.md`-упоминаний.
> 5. Коммиты пушатся после каждой волны (credentials настроены).
> 6. Исходные документы задачи в корне (`Техническое задание.md`, документы-
> рекомендации, `program-trenirovok.*`) **не редактируются** — это вход,
> а не документация разработки.
## 0. Сводка ревью №2
Соответствие исходной задаче и рекомендациям в целом подтверждено: все 9
позиций MVP ТЗ покрыты (Ф-1–Ф-9), стеки соответствуют `Требование.md`
(C#/.NET 10 + PostgreSQL по std1, Kotlin, Monkey C), решения ревью №1
(Р1-А/Р2-Б/Р3-А, З-1…З-8) внесены в документы, правила книг перенесены
(допуск АД/пульс, правила 1–6 в v1 / 7–10 в v2, формула возврата и правила
12–17 дословно, FIT/JSON/CSV, шаг 1 LLM-дизайна в v1, UI/UX-стандарт).
Найдено: **2 существенных дефекта (P1)** — Р2-Б доведён не до конца
(FK-колонки и типы возврата остались `int` при uuid-PK) и контур break не
имеет пути записи ответа атлета; **4 средних (P2)**; **8 мелких (P3,
гигиена)**, включая неактуализированный чек-лист ревью №1.
## 1. Решения владельца (блокируют часть заданий)
| Код | Вопрос | Варианты | Рекомендация ревью |
|---|---|---|---|
| **О-1** | ОВ-10 requirements (источник .fit для атлетов без учётки владельца) помечен «закрыт шагом 5», но решения в tech-requirements нет | **А:** v1 — только папка импорта `--mode import` для таких атлетов; собственные учётки в конфиге — кандидат v2. **Б:** список учётных записей Garmin в `appsettings.json` (по атлету) уже в v1 | **А** (не раздувать v1; деградация уже работает) |
| **О-2** | П-2 (vision) «вес — целые числа» противоречит пикеру шага 2,5 кг (Ф-3.6): голос не введёт 22,5 кг — запишет 22 (искажение план/факт и тоннажа) | **А:** зафиксировать ограничение: голос — целые кг, дробные — правка тапом (примечание в Ф-1.2 и П-2). **Б:** расширить грамматику: «…с половиной» → +0,5 кг (словарь Vosk + постобработка, tech-req §5) | **А** для v1 (просто и предсказуемо); **Б** — кандидат v2 |
| **О-3** | Шаг прогрессии изоляции `BaseStepKg/2` = 1,25 кг (при умолчании 2,5) выходит из коридора метрик «руки +0,5–1 кг» (правило 4) | **А:** отдельный параметр `Progression.IsoStepKg` (умолчание 1,0; валидация 0,25–5). **Б:** оставить 1,25 с примечанием «осознанное решение владельца» | **А** (коридор метрик соблюдается без ручной подгонки) |
## 2. Задания P1 (существенные, блокируют шаг 7)
### З-16. Доведение Р2-Б: uuid-FK и типы возврата функций ⬜
1. `1-docs\2-db\src\tables.md` — колонки-ссылки на uuid-PK сменить `int` →
`uuid NOT NULL` (или NULL по смыслу):
- `src.workout.program_version_id`: `uuid NULL → src.program_version.id`;
- `src.workout_set.exercise_id`: `uuid NULL → src.exercise.id`;
- `src.exercise_replacement.exercise_id`, `replacement_id`:
`uuid → src.exercise.id`.
2. `1-docs\2-db\src\functions.md` — тип возврата для uuid-сущностей
«int — id» → «uuid — id»: `exercise_insert`,
`program_version_insert`, `workout_insert`, `workout_set_insert`,
`command_log_insert`, `break_insert`. Для `exercise_replacement_insert`
(ММ, составной PK, id нет) — «int — число строк».
3. Самопроверка: в tables.md не осталось ссылок `int →` на таблицы с
`uuid PK`; каждой функции вставки uuid-сущности соответствует возврат
`uuid`.
### З-17. Контур break: путь записи ответа атлета ⬜
Противоречие: Ф-14.2 собирает причину и дату возврата, sync-сущность
`break` передаёт `planned_return`, но в `src.breaks` колонки нет,
`source` объявлен «🛡 всегда auto», а `break_update` принимает только
`p_ended_on` — ответу атлета некуда и нечем записаться; правила 12–14 без
`kind` не работают.
1. `1-docs\2-db\src\tables.md`, `src.breaks`:
- добавить колонку `planned_return | date NULL | предполагаемая дата
возврата (Ф-14.2)`;
- `source` — снять пометку «🛡 всегда auto», описать:
`auto` — сервер по пропускам (Ф-14.1); `manual` — запланированный
простой, объявленный атлетом заранее (Ф-14.2). Значение из sync —
только `manual`; `auto` проставляет сервер.
2. `1-docs\2-db\src\functions.md`:
- `break_insert` — параметры `p_kind, p_source, p_started_on,
p_planned_return, p_note`; комментарий: «auto — сервер по пропускам;
manual — телефон (объявление заранее)»;
- `break_update` — параметры `p_kind, p_note, p_planned_return,
p_ended_on`; комментарий: «ответ атлета на вопрос о причине
(Ф-14.2) + закрытие первой сессией после возврата».
3. `1-docs\1-reqs\requirements.md`, Ф-14.1 — снять натяжку «Ручного
включения break нет» против Ф-14.2: переформулировать «Break ставится
автоматически по пропускам (основной путь); атлет может объявить
перерыв заранее (Ф-14.2) — такой break создаётся с `source=manual`;
произвольного ручного включения без объявления нет».
4. `1-docs\3-tech\tech-requirements.md`, п. 2.1, сущность `break` —
привести к таблице: `kind` (NULL до ответа), `source` (телефон
передаёт `manual`), `started_on`, `planned_return`, `note`;
`ended_on` проставляет сервер первой сессией после возврата.
## 3. Задания P2
### З-18. Якорные часы — Fenix 6X (уточнение владельца от 2026-10-17) ⬜
Заменить «Fenix 6 (260×260)» → «Fenix 6X (280×280)» и убрать ложное
«одно разрешение для 6/6S/6X» (фактически: 6S — 240×240, 6 — 260×260,
6X — 280×280):
1. `1-docs\1-reqs\vision.md`: «Что уже есть» (Fenix 6, 260×260 MIP →
Fenix 6X, 280×280 MIP); БР-3 («якорное устройство — Fenix 6»);
З-3 п. 1.7 («якорь — Fenix 6»); п. 2.4 («якорное устройство v1 —
Fenix 6 (260×260 MIP, кнопки)»). Оформить как **изменение 1.5**
(уточнение владельца 2026-10-17: якорь — Fenix 6X; в ТЗ указан
Fenix 6/260×260 — описка исходника) → версия vision **1.5**.
2. `1-docs\1-reqs\requirements.md`: раздел 2.1 («Якорное устройство —
Fenix 6») + примечание об уточнении владельца; открытый вопрос 8
(«Якорь — Fenix 6»).
3. `1-docs\3-tech\tech-requirements.md`, решение ОВ-7 — переписать:
«Таргет v1 — `fenix6x` (280×280, MIP, кнопки). Fenix 6 (260×260) и
6S (240×240) добавляются отдельными таргетами с собственными макетами
(Ф-2.8) по фактическому парку». Утверждение — Пользователь!
4. Корневой `readme.md` («часы Garmin Fenix 6», состав системы) и
`1-docs\0-mng\plan.md` (строка версий, «Fenix 6 (Monkey C…)») —
привести к Fenix 6X.
5. `1-docs\3-tech\ui-ux-recommendations.md` не трогать: там Fenix 6X /
280×280 указаны верно.
6. ТЗ (`..\..\Техническое задание.md`) не редактировать (вход).
### З-19. Закрытие ОВ-10 (после О-1; по О-1-А) ⬜
`1-docs\3-tech\tech-requirements.md`, раздел 1 — добавить строку ОВ-10:
«Источник .fit атлетов без учётки владельца — только папка импорта
(`--mode import`); `fetch` работает под единственной учёткой владельца;
собственные учётки атлетов в конфиге — кандидат v2». В requirements
раздел 7 (ОВ-10) — проставить финальное решение со ссылкой на
tech-requirements.
### З-20. Порог пульса силовой части (`Safety.HrStrengthMax`) ⬜
Ограничение профиля «пульс при силовой ≤ 110–120 уд/мин»
(`program-trenirovok.md`, документ метрик п. 2.3) в требованиях не
отражено; зоны 50/70/85 % дают жёлтый от ~123 и красный от ~150
(Танака, 45 лет) — для гипертоника 45+ ключевой порог не контролируется.
1. `1-docs\1-reqs\requirements.md`:
- раздел 3, таблица телефона: `Safety.HrStrengthMax` — «порог пульса
в силовой части (предупреждение)», умолчание `120`; та же строка —
в серверной таблице (для `red_flags`);
- Ф-13 — новый пункт 7 (без перенумерации 4–6, на них есть ссылки):
«Во время силовой части: пульс > `Safety.HrStrengthMax` →
предупреждение на телефоне (баннер + вибро, спокойная формулировка
по UI/UX-стандарту); на часы порог передаётся в объёме канала
(ОВ-3). Источник — программа тренировок и документ метрик (п. 2.3)».
2. `1-docs\3-tech\tech-requirements.md`: п. 4.1 и 4.2 — строка
`Safety.HrStrengthMax | int | 100–180 (умолчание 120)`.
3. Трассировку раздела 6 не менять (Ф-13 уже привязан к БЦ-6/КУ-7).
### З-21. Период запуска `fetch` (проверяемость БЦ-5) ⬜
БЦ-5 требует «архив на сервере ≤ 30 минут после тренировки», решение
ОВ-4 — внешний планировщик — интервал не задан нигде, критерий
непроверяем.
`1-docs\3-tech\tech-requirements.md`, решение ОВ-4 — дополнить: «Интервал
вызова — 15 минут (параметр планировщика ОС, в код не входит); вместе с
лагом синхронизации часов с Garmin Connect укладывается в БЦ-5 (≤ 30 мин)».
## 4. Задания P3 (гигиена)
| Код | Задание | Где |
|---|---|---|
| З-22 | Шапка-источник: «vision v1.3» → «vision v1.4»; в разделе 2.3 («--mode fetch») «открытый вопрос 5» → «открытый вопрос 4» | requirements.md:4, :85 |
| З-23 | URL репозитория → `https://git.mind01.ru/VEU/VEU.WathBody.git` (как в readme, по фактическому remote; З-12 ревью №1 был закрыт ошибочно); в «Составе версий» указать: v1.0 включает Ф-13 (MVP-состав документа метрик) и Ф-14 (vision 2.2) | plan.md:3–4, раздел «Состав версий» |
| З-24 | Чек-лист ревью №1 актуализировать по факту: Р1-А/Р2-Б/Р3-А — решены; З-1, З-3, З-4, З-7, З-8 — ✅; З-2 — ✅ (architecture v1.1 утверждена); З-12 — частично переоткрыт (plan.md, см. З-23); З-13 🔄 и З-15 ⬜ остаются | review-2026-10-17.md, раздел 6 |
| З-25 | Опечатка «2-dbuild.ps1» → «2-db\build.ps1»; режим `--mode migrate` добавить в таблицу режимов requirements 2.3 (семантика: применение миграций из `2-db\migrations\`; коды возврата — как у import); таблицу `src.migration` (id serial PK, filename UNIQUE, applied_at; функции migration_insert/migration_select, CUSTOM) добавить в перечень и описания tables.md | 2-db\readme.md:47–48, requirements 2.3, 2-db\src\tables.md |
| З-26 | Дробные веса (после О-2): по А — примечание в Ф-1.2 («голос — целые кг; дробные (шаг 2,5) — правка тапом, Ф-1.6») и уточнение П-2 в vision; по Б — грамматика «…с половиной» → +0,5 кг в Ф-1.2 и словарь/постобработка в tech-req §5 (VoiceInput) | requirements Ф-1.2, vision П-2, tech-req §5 |
| З-27 | Шаг прогрессии изоляции (после О-3): по А — параметр `Progression.IsoStepKg` (умолчание 1,0; валидация 0,25–5) в раздел 3 и п. 4.2, Ф-12.2 — «+ `IsoStepKg` (изоляция)»; по Б — примечание в Ф-12.2 «умолчание даёт 1,25 кг — выше коридора метрик 0,5–1 кг, решение владельца» | requirements 3, Ф-12.2; tech-req 4.2 |
| З-28 | UI/UX-рекомендации → версия 1.1: §3 и §6.3 — «id-mapping» заменить на «UUID PK клиентских сущностей (Р2-Б)»; §2.2 и §6.2 — пометить «ввод RPE/боли на часах» как неприменимое к форме «поле данных» (кнопки обрабатывает Garmin, Ф-2.5–2.6; ввод RPE/боли — телефон, Ф-13.3); §2.1/§8 (Fenix 6X, 280×280) — верно, не менять | 3-tech\ui-ux-recommendations.md |
| З-29 | Перечень `LocalDb` в архитектуре дополнить: дневник самоконтроля (`daily_log`) и перерывы (`breaks`); версия architecture → 1.2 (мелкая правка перечня) | architecture.md, раздел 1.2 |
## 5. Порядок исполнения и версии
**Волна 1 — P1 + P2 (З-16, З-17, З-18, З-20, З-21 сразу; З-19 после О-1).**
Один пакет «Ревью №2: uuid-FK (Р2-Б доведён), контур break, якорь Fenix 6X,
ОВ-10, Safety.HrStrengthMax, период fetch» → утверждение владельцем (одно
утверждение на пакет) → коммит и push. Версии: vision → 1.5 (изменение 1.5),
requirements → 1.4, tech-requirements → 1.4, tables/functions → новая
редакция (число функций не меняется — меняются типы/параметры), 2-db readme
→ новая редакция.
**Волна 2 — P3 errata (З-22, З-23, З-24, З-25, З-29 сразу; З-26, З-27
после О-2/О-3; З-28 сразу).** Пакет «Ревью №2: errata (шапки, plan.md,
чек-лист ревью №1, migrate-mode, ui-ux v1.1, LocalDb)» → утверждение →
коммит и push. Версии: ui-ux-recommendations → 1.1, architecture → 1.2;
остальные правки — внутри версий волны 1.
**После каждой волны — самопроверка (раздел 7) и отметки в разделе 6.**
## 6. Чек-лист
| Задание | P | Зависит от | Статус |
|---|---|---|---|
| О-1…О-3 решения владельца | — | — | ✅ О-1 — ответ владельца: атлеты саморегистрируются на телефоне (имя), привязка — по uuid клиентского приложения (для .fit применён О-1-А — папка импорта); О-2-Б; О-3-А (2026-10-17) |
| З-16 uuid-FK + типы возврата | 1 | — | ✅ (2026-10-17) |
| З-17 контур break (planned_return, source, update) | 1 | — | ✅ (2026-10-17) |
| З-18 якорь Fenix 6X (vision 1.5, requirements, tech-req, readme, plan) | 2 | — (уточнение владельца дано) | ✅ (2026-10-17) |
| З-19 закрытие ОВ-10 | 2 | О-1 | ✅ (2026-10-17, О-1-А + уточнение владельца о регистрации) |
| З-20 Safety.HrStrengthMax | 2 | — | ✅ (2026-10-17) |
| З-21 период fetch (БЦ-5) | 2 | — | ✅ (2026-10-17, интервал 15 мин) |
| З-22 шапка requirements, ОВ-нумерация | 3 | — | ✅ (2026-10-17, сразу vision v1.5) |
| З-23 plan.md URL + состав версий | 3 | — | ✅ (2026-10-17) |
| З-24 чек-лист ревью №1 | 3 | — | ✅ (2026-10-17) |
| З-25 migrate-режим, src.migration, опечатка | 3 | — | ✅ (2026-10-17; опечатка в readme не подтвердилась — путь верен) |
| З-26 дробные веса | 3 | О-2 | ✅ (2026-10-17, по О-2-Б) |
| З-27 шаг изоляции | 3 | О-3 | ✅ (2026-10-17, по О-3-А) |
| З-28 ui-ux-recommendations v1.1 | 3 | — | ✅ (2026-10-17) |
| З-29 LocalDb перечень (architecture 1.2) | 3 | — | ✅ (2026-10-17) |
## 7. Самопроверка после правок
1. **tables.md / functions.md:** нет ссылок `int →` на uuid-PK; возвраты
insert-функций uuid-сущностей — `uuid`; у `src.breaks` есть
`planned_return`, `source` описан как `auto|manual`; перечень таблиц
↔ список функций совпадают 1:1 (включая `src.migration`).
2. **requirements.md:** Ф-14.1 согласован с Ф-14.2; Ф-13.7 ссылается на
`Safety.HrStrengthMax`; строки раздела 3 (телефон и сервер) содержат
`Safety.HrStrengthMax`; шапка — vision v1.4 (после волны 1 — v1.5);
трассировка раздела 6 не нарушена; Ф-13.4/Ф-13.5/Ф-13.6 сохранили
номера.
3. **tech-requirements.md:** ОВ-7 — таргет `fenix6x` (280×280); ОВ-4 —
интервал 15 минут; ОВ-10 присутствует и закрыт по О-1; п. 4.1/4.2
содержат `Safety.HrStrengthMax` с одинаковой валидацией; сущность
`break` (п. 2.1) совпадает с `src.breaks` по полям.
4. **vision.md:** изменение 1.5 добавлено в шапку; упоминания «Fenix 6 /
260×260» в п. 1.1, БР-3, З-3, п. 2.4 заменены на Fenix 6X / 280×280.
5. **Согласованность устройств:** «Fenix 6X / 280×280» единообразно в
vision, requirements, tech-requirements, architecture (если
упоминается), корневом readme.md, plan.md; в ui-ux-recommendations
не изменено (уже верно).
6. **Общее:** git-статус чистый после коммитов; исходники задачи в корне
не редактировались; в логах/доках нет секретов; push выполнен после
каждой волны.