Ревью №3 утверждено: Ф-13.7 источник не программа (З-30), импорт пакета программы ОВ-11 + program-import-format.md + src.program.external_id (З-31, О-4-Б), backspace в 2-db readme (З-33), косметика (З-34)
This commit is contained in:
parent
0e8e3a6ad6
commit
a1b4969f57
|
|
@ -11,7 +11,9 @@
|
|||
> `program-trenirovok.md`), UI/UX-рекомендациями
|
||||
> (`3-tech\ui-ux-recommendations.md`) и внутренними противоречиями.
|
||||
> **Уточнение владельца (чат, 2026-10-17):** якорные часы — **Fenix 6X**
|
||||
> (280×280 MIP). В ТЗ указан «Fenix 6, 260×260» — считать опиской исходника,
|
||||
> (280×280 MIP). Примечание (ревью №3, З-30): `program-trenirovok.*` —
|
||||
> импортируемый пакет эксплуатации; формулировка источника в Ф-13.7
|
||||
> скорректирована по З-30 — не копировать прежнюю. В ТЗ указан «Fenix 6, 260×260» — считать опиской исходника,
|
||||
> документы разработки приводятся к Fenix 6X (З-18).
|
||||
> **Состояние репозитория на момент проверки:** коммит `e674318`, ветка
|
||||
> `main`, статус чистый; ссылки на строки — по нему, после правок
|
||||
|
|
@ -219,7 +221,7 @@ requirements → 1.4, tech-requirements → 1.4, tables/functions → новая
|
|||
| З-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 не подтвердилась — путь верен) |
|
||||
| З-25 migrate-режим, src.migration, опечатка | 3 | — | ✅ (2026-10-17; опечатка подтвердилась — байт 0x08, исправлена по З-33 ревью №3) |
|
||||
| З-26 дробные веса | 3 | О-2 | ✅ (2026-10-17, по О-2-Б) |
|
||||
| З-27 шаг изоляции | 3 | О-3 | ✅ (2026-10-17, по О-3-А) |
|
||||
| З-28 ui-ux-recommendations v1.1 | 3 | — | ✅ (2026-10-17) |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,224 @@
|
|||
# Ревью документации №3 от 2026-10-17 — задания к исполнению
|
||||
|
||||
> **Исполнитель:** агент сопровождения документации WatchBody.
|
||||
> **Источник:** третья архитектурная проверка документации шагов 1–6
|
||||
> (после исполнения ревью №2, З-16…З-29, коммит `e674318` + рабочая
|
||||
> копия): сверка с исходной задачей (`Техническое задание.md`,
|
||||
> `Требование.md`), документами-рекомендациями и внутренняя
|
||||
> согласованность (requirements ↔ vision ↔ architecture ↔ tech-req ↔
|
||||
> tables ↔ functions ↔ readme/plan).
|
||||
> **Уточнение владельца (чат, 2026-10-17):** программа тренировок
|
||||
> (`program-trenirovok.md` / `program-trenirovok.json`) — **импортируемый
|
||||
> пакет процесса эксплуатации**, назначается атлету индивидуально и
|
||||
> **не может быть нормативным источником документации разработки**.
|
||||
> В документах разработки на неё допустимы ссылки только как на
|
||||
> импортируемые данные атлета (формат/пример).
|
||||
> **Состояние репозитория на момент проверки:** коммит `e674318`,
|
||||
> ветка `main`; правки ревью №2 в рабочей копии, **не закоммичены**
|
||||
> (12 изменённых файлов; чек-лист ревью №2 «push выполнен после каждой
|
||||
> волны» — не соответствует факту, см. раздел 8). Также в рабочей
|
||||
> копии изменены корневые `program-trenirovok.md`/`.json` (v4→v5) и
|
||||
> добавлен `program-import.json` — это эксплуатационные данные, в
|
||||
> документационный коммит не включать; правку v4→v5 подтвердить у
|
||||
> владельца.
|
||||
> **Статусная модель заданий:** ⬜ не начато → 🔄 в работе → ✅ готово
|
||||
> (утверждено владельцем). Отметки — в разделе 6 по мере работы.
|
||||
> **Общие правила исполнения:**
|
||||
> 1. Правки вносятся в черновые версии текущей волны ревью №2 (они ещё
|
||||
> не утверждены): vision 1.5 (черновик), requirements 1.4,
|
||||
> tech-requirements 1.4, architecture 1.2, tables/functions —
|
||||
> новая редакция. Утверждение — одно на весь пакет
|
||||
> **Пользователь!** (d-dev-4).
|
||||
> 2. Содержание утверждённых документов меняется только в объёме
|
||||
> заданий; инварианты 🛡 не ослабляются; трассировка
|
||||
> «Ф → БЦ → КУ → версия» (раздел 6 requirements) сохраняется.
|
||||
> 3. Задание, зависящее от решения О-4 (раздел 1), не вносится до
|
||||
> выбора владельцем; остальные можно выполнять сразу. Если владелец
|
||||
> не выбрал — подготовить дифф по рекомендованному варианту и
|
||||
> вынести на утверждение.
|
||||
> 4. Код (`3-app\`, `2-db\`) не трогается — задание касается только
|
||||
> `1-docs\` и корневых `readme.md`/`plan.md`-упоминаний.
|
||||
> 5. Коммит и push — после утверждения пакета владельцем, **только
|
||||
> файлы `1-docs\` и корневой `readme.md`**; корневые
|
||||
> `program-trenirovok.*` и `program-import.json` в коммит не
|
||||
> включать (эксплуатационные данные).
|
||||
> 6. Исходные документы задачи в корне (`Техническое задание.md`,
|
||||
> документы-рекомендации, `program-trenirovok.*`) не редактируются
|
||||
> — это вход/эксплуатационные данные, а не документация разработки.
|
||||
|
||||
## 0. Сводка ревью №3
|
||||
|
||||
Исполнение ревью №2 подтверждено полностью: все задания З-16…З-29
|
||||
проверены по содержанию и внесены (uuid-FK и типы возврата; контур break
|
||||
`planned_return`/`source auto|manual`/`break_update`; якорь Fenix 6X
|
||||
единообразно в vision/requirements/tech-req/architecture/readme/plan;
|
||||
ОВ-10 закрыт по О-1-А; `Safety.HrStrengthMax` в Ф-13.7 и обеих таблицах
|
||||
разд. 3; fetch 15 мин ↔ БЦ-5; migrate-режим и `src.migration`;
|
||||
перечень `LocalDb`; ui-ux 1.1; чек-лист ревью №1). Трассировка
|
||||
Ф → БЦ → КУ не нарушена; противоречий requirements ↔ vision по
|
||||
MVP-составу, правилам 1–17, ограничениям 45+/гипертония/мениск не
|
||||
найдено. Документация в целом соответствует исходной задаче,
|
||||
рекомендациям и ограничениям.
|
||||
|
||||
С учётом уточнения владельца о программе тренировок найдено:
|
||||
**2 существенных дефекта (P1)** — Ф-13.7 называет программу тренировок
|
||||
нормативным источником и контур импорта пакета программы отсутствует в
|
||||
документации разработки; **1 средний (P2)** — рассинхрон шапок
|
||||
(architecture ↔ vision/requirements, снимается утверждением волны);
|
||||
**4 мелких (P3, гигиена)**, включая не соответствующий факту статус
|
||||
З-25 в чек-листе ревью №2.
|
||||
|
||||
## 1. Решения владельца (блокируют часть заданий)
|
||||
|
||||
| Код | Вопрос | Варианты | Рекомендация ревью |
|
||||
|---|---|---|---|
|
||||
| **О-4** | Контур импорта пакета программы (`program-import.json`) в v1 не предусмотрен: `--mode import` принимает только .fit/.tcx/.gpx (Ф-8.3); формат пакета нигде не зафиксирован; `program_id` пакета — строка (`prg_2026_10_health_start`) против `src.program.id` serial; секция `profile.limitations` пакета не отражена в `program_version.body` | **А:** v1 без импорта пакета — программа заводится редактором телефона (Ф-4/Ф-5) и версионируется консолью владельца (Ф-10.2); в requirements (разд. 7) и tech-req явно записать «импорт пакета программы в v1 не предусмотрен — кандидат v2». **Б:** импорт пакета в v1 — расширение `--mode import` (формат `program-import.json`), маппинг на `src.program`/`src.program_version.body`; `program_id` строки — внешний идентификатор пакета (колонка `external_id UNIQUE`); `profile.limitations` — Safety-порогами НЕ управляет (только конфиг `Safety.*`), v1 секцию игнорирует | **Б** (следует из уточнения владельца: пакет — механизм эксплуатации; иначе путь доставки программы атлету в v1 не закрыт). Формат зафиксировать отдельным документом `3-tech\program-import-format.md` |
|
||||
|
||||
## 2. Задания P1 (существенные, блокируют шаг 7)
|
||||
|
||||
### З-30. Ф-13.7: программа тренировок — не нормативный источник ⬜
|
||||
|
||||
Противоречие: Ф-13.7 (`requirements.md`, раздел 5, Ф-13, п. 7) —
|
||||
«Источник — программа тренировок и документ метрик (п. 2.3)». По
|
||||
уточнению владельца программа — импортируемые данные атлета, нормативом
|
||||
для разработки быть не может; иначе порог пульса силовой части зависит
|
||||
от содержимого эксплуатационного пакета, а не от требований.
|
||||
|
||||
1. `1-docs\1-reqs\requirements.md`, Ф-13.7 — заменить последнюю фразу:
|
||||
«Источник — документ метрик (п. 2.3); значение перенесено в параметр
|
||||
конфигурации `Safety.HrStrengthMax` (разд. 3, умолчание 120).
|
||||
Программа тренировок — импортируемые данные атлета (см. О-4);
|
||||
нормативным источником требований не является».
|
||||
2. `1-docs\0-mng\review-2026-10-17-2.md`, задание З-20 (и шапка, строка
|
||||
11) — добавить примечание «уточнение владельца 2026-10-17 (ревью
|
||||
№3): `program-trenirovok.*` — импортируемый пакет эксплуатации;
|
||||
формулировка источника в Ф-13.7 скорректирована по З-30», чтобы
|
||||
формулировку не скопировали повторно.
|
||||
3. Самопроверка: grep по `1-docs` — не осталось мест, где
|
||||
`program-trenirovok` или «программа тренировок» названа
|
||||
источником/нормативом требования (описание функциональности —
|
||||
«программы тренировок формируются/редактируются» — допустимо).
|
||||
|
||||
### З-31. Контур импорта пакета программы (после О-4) ⬜
|
||||
|
||||
Пакет программы — заявленный механизм эксплуатации, но путь его
|
||||
попадания в систему не документирован; формат не зафиксирован; схема БД
|
||||
не согласована с пакетом.
|
||||
|
||||
По **О-4-Б** (рекомендовано):
|
||||
1. `1-docs\3-tech\tech-requirements.md` — п. 2.1: сущность `program`
|
||||
дополнить `external_id` (строка, UNIQUE — идентификатор пакета);
|
||||
решение в разд. 1: «Импорт пакета программы — `--mode import`,
|
||||
формат `program-import.json` (см. `program-import-format.md`);
|
||||
повторный импорт пакета с тем же `external_id` — новая версия
|
||||
`program_version`». §5/§6 — при необходимости.
|
||||
2. Новый документ `1-docs\3-tech\program-import-format.md` — формат
|
||||
пакета: структура недель → тренировок → упражнений → подходов;
|
||||
`program_id` (строка), `profile` (v1 игнорируется, поля
|
||||
задокументированы); коды возврата — как у import (requirements 2.3).
|
||||
3. `1-docs\2-db\src\tables.md` — `src.program`: колонка
|
||||
`external_id | text UNIQUE NULL | идентификатор пакета
|
||||
(program-import.json)`; `program_version.body` — примечание:
|
||||
секция `profile` пакета в body не переносится (v1).
|
||||
4. `1-docs\2-db\src\functions.md` — `program_insert`/`program_version_insert`:
|
||||
параметры/комментарии под `external_id` (список функций не меняется).
|
||||
5. `1-docs\1-reqs\requirements.md` — Ф-8.3: источник импорта пополняется
|
||||
«пакет программы (`program-import.json`)»; раздел 7 — новый закрытый
|
||||
вопрос со ссылкой на tech-req.
|
||||
По **О-4-А**: только п. 5 в усечённом виде — «импорт пакета программы в
|
||||
v1 не предусмотрен (программа — редактор телефона/консоль владельца);
|
||||
кандидат v2» + закрытый вопрос в разд. 7; п. 1–4 не выполнять.
|
||||
6. Трассировку раздела 6 не менять (Ф-8 уже привязан).
|
||||
|
||||
## 3. Задания P2
|
||||
|
||||
### З-32. Рассинхрон шапок (снимается утверждением волны) ⬜
|
||||
|
||||
- `1-docs\2-arch\architecture.md`, шапка (стр. 4–8): «vision.md
|
||||
(v1.4, изменения 1.1–1.4)» → v1.5 (изменения 1.1–1.5);
|
||||
«requirements.md v1.4 (черновик, ревью №2)» → актуальная версия по
|
||||
факту утверждения пакета.
|
||||
- `1-docs\1-reqs\requirements.md`, шапка: «vision.md (утверждён
|
||||
2026-10-17, v1.5)» — статус «утверждён» корректен только после
|
||||
утверждения vision 1.5 владельцем; привести к факту при утверждении.
|
||||
- Выполняется **в момент утверждения пакета** (одним диффом с
|
||||
проставлением статусов УТВЕРЖДЕНО в шапках vision 1.5, requirements,
|
||||
tech-req, architecture 1.2, tables/functions).
|
||||
|
||||
## 4. Задания P3 (гигиена)
|
||||
|
||||
### З-33. Байт backspace в `2-db\readme.md` + статус З-25 ⬜
|
||||
|
||||
1. `1-docs\2-db\readme.md:47` — физический байт backspace (0x08):
|
||||
текст «2-db\<BS>uild.ps1» (визуально «2-dbuild.ps1») → заменить на
|
||||
корректный «2-db\build.ps1» (проверка: `od -c` не должен показывать
|
||||
`\b`).
|
||||
2. `1-docs\0-mng\review-2026-10-17-2.md`, чек-лист, З-25 — статусная
|
||||
формулировка «опечатка в readme не подтвердилась — путь верен» **не
|
||||
соответствует факту**: исправить на «опечатка подтвердилась (байт
|
||||
0x08), исправлена по З-33».
|
||||
|
||||
### З-34. Косметика tables/functions/ui-ux ⬜
|
||||
|
||||
1. `1-docs\2-db\src\functions.md` (exercise_delete, стр. 30) и
|
||||
`src\tables.md` (комментарий `is_active`): «`is_active=0`» →
|
||||
«`is_active=false`» (колонка boolean).
|
||||
2. `1-docs\2-db\src\functions.md` (workout_insert, стр. 42): комментарий
|
||||
«повтор `client_guid`» → «повтор `p_id` (uuid — PK клиентской
|
||||
сущности, генерирует телефон)» — терминология уровней sync/БД.
|
||||
3. `1-docs\3-tech\ui-ux-recommendations.md`, §6.2 (стр. 76): остаток
|
||||
«ввод RPE/боли — задача часов» пометить как неприменимое к форме
|
||||
«поле данных» (так же, как на стр. 81: кнопки обрабатывает Garmin,
|
||||
Ф-2.5–2.6; ввод RPE/боли — телефон, Ф-13.3).
|
||||
|
||||
## 5. Порядок исполнения и версии
|
||||
|
||||
**Один пакет:** З-30, З-32, З-33, З-34 сразу; З-31 после О-4 (по
|
||||
рекомендации — О-4-Б). Все правки — в текущие черновые версии волны
|
||||
ревью №2 (vision 1.5, requirements 1.4, tech-req 1.4, architecture 1.2,
|
||||
tables/functions новая редакция, 2-db readme новая редакция, новый
|
||||
`program-import-format.md`). При утверждении пакета — З-32 (шапки,
|
||||
статусы УТВЕРЖДЕНО) → одно утверждение владельцем → коммит и push
|
||||
(только `1-docs\` + корневой `readme.md`; `program-trenirovok.*` и
|
||||
`program-import.json` — отдельно по решению владельца) → **шаг 7**.
|
||||
|
||||
## 6. Чек-лист
|
||||
|
||||
| Задание | P | Зависит от | Статус |
|
||||
|---|---|---|---|
|
||||
| О-4 решение владельца (импорт пакета программы) | — | — | ✅ О-4-Б (2026-10-17) |
|
||||
| З-30 Ф-13.7 источник (не программа) | 1 | — | ✅ (2026-10-17) |
|
||||
| З-31 контур импорта пакета программы | 1 | О-4 | ✅ (2026-10-17, по О-4-Б) |
|
||||
| З-32 шапки architecture/requirements | 2 | утверждение пакета | ✅ (2026-10-17, утверждено) |
|
||||
| З-33 backspace 2-db\readme.md + статус З-25 | 3 | — | ✅ (2026-10-17) |
|
||||
| З-34 косметика (is_active=false, p_id, ui-ux 6.2) | 3 | — | ✅ (2026-10-17) |
|
||||
| Коммит и push (только 1-docs + readme) | — | утверждение | ✅ (2026-10-17) |
|
||||
| Подтверждение владельцем правки program-trenirovok v4→v5 | — | — | ⬜ |
|
||||
|
||||
## 7. Самопроверка после правок
|
||||
|
||||
1. **requirements.md:** Ф-13.7 — источник «документ метрик +
|
||||
`Safety.HrStrengthMax`», программа названа импортируемыми данными;
|
||||
Ф-8.3 согласован с решением О-4; трассировка раздела 6 не изменена.
|
||||
2. **Grep по `1-docs`:** нет упоминаний `program-trenirovok` /
|
||||
«программа тренировок» как источника требования; термин
|
||||
«пакет программы» (`program-import.json`) присутствует по О-4-Б
|
||||
(tech-req, requirements, tables/functions, format-документ).
|
||||
3. **tables/functions:** `src.program.external_id` есть, функции
|
||||
согласованы, перечень таблиц ↔ функций 1:1 сохранён.
|
||||
4. **2-db\readme.md:** `od -c` строки 47 без `\b`; путь
|
||||
«2-db\build.ps1» корректен.
|
||||
5. **Шапки:** architecture ↔ vision v1.5 ↔ requirements ↔ tech-req —
|
||||
версии и статусы совпадают с фактом утверждения.
|
||||
6. **Git:** в коммит вошли только `1-docs\` и корневой `readme.md`;
|
||||
push выполнен; `git status` по `1-docs\` чистый.
|
||||
|
||||
## 8. Отмечено при проверке (не задания)
|
||||
|
||||
- Чек-лист ревью №2 («push выполнен после каждой волны») не
|
||||
соответствовал факту: правки волны в рабочей копии не закоммичены.
|
||||
Коммит/пуш выполняется по п. 5 настоящего файла — после утверждения.
|
||||
- Изменение корневых `program-trenirovok.md`/`.json` (v4→v5) и новый
|
||||
`program-import.json` — эксплуатационные данные, правилами ревью не
|
||||
регулируются; в документационный коммит не включать; авторство правки
|
||||
подтвердить у владельца.
|
||||
|
|
@ -26,7 +26,9 @@
|
|||
> (З-18, изменение vision 1.5), ОВ-10 закрыт (З-19, решение владельца),
|
||||
> `Safety.HrStrengthMax` (З-20), грамматика «…с половиной» (З-26, решение
|
||||
> владельца О-2-Б), `Progression.IsoStepKg` (З-27, решение владельца
|
||||
> О-3-А), режим `--mode migrate` (З-25).
|
||||
> О-3-А), режим `--mode migrate` (З-25). Правки ревью №3
|
||||
> (`0-mng\review-2026-10-17-3.md`): Ф-13.7 — источник не программа
|
||||
> (З-30), Ф-8.3 — импорт пакета программы (З-31, О-4-Б), вопрос 12.
|
||||
|
||||
## 1. Назначение и границы
|
||||
|
||||
|
|
@ -298,10 +300,17 @@ Garmin штатно — Ф-2.5, Ф-2.6). Код поля данных перен
|
|||
`Record` (дискретный пульс), `Set` (повторения/вес, если есть);
|
||||
результат — канонический JSON тренировки в `workout_facts`
|
||||
(дизайн LLM-планирования, разд. 4).
|
||||
3. Fallback-импорт (`--mode import`): файлы из `Import.Dir` (.fit, .tcx,
|
||||
.gpx — по документу форматов) парсятся тем же конвейером;
|
||||
обработанные перемещаются в `Import.ArchiveDir`; необработанные
|
||||
остаются с записью в логе (код возврата 2).
|
||||
3. Импорт (`--mode import`): файлы из `Import.Dir` — .fit, .tcx,
|
||||
.gpx (по документу форматов) и пакет программы
|
||||
`program-import.json` (формат — `3-tech\program-import-format.md`,
|
||||
закрытый вопрос 12): пакет маппится на `src.program`/
|
||||
`src.program_version.body` по `external_id`; повторный импорт
|
||||
пакета с тем же `external_id` — новая версия `program_version`.
|
||||
Файлы и пакеты парсятся тем же конвейером; обработанные
|
||||
перемещаются в `Import.ArchiveDir`; необработанные остаются
|
||||
с записью в логе (код возврата 2). Секция `profile` пакета
|
||||
в v1 не переносится (Safety-порогами управляет только конфиг
|
||||
`Safety.*`).
|
||||
4. Сопоставление факт ↔ голосовой учёт: тренировка .fit сопоставляется
|
||||
с тренировкой телефона по времени начала (± 15 минут) —
|
||||
сопоставлённая пара связывается; несопоставленные остаются
|
||||
|
|
@ -455,8 +464,12 @@ Garmin штатно — Ф-2.5, Ф-2.6). Код поля данных перен
|
|||
7. **Во время силовой части:** пульс > `Safety.HrStrengthMax`
|
||||
(умолчание 120) → предупреждение на телефоне (баннер + вибро,
|
||||
спокойная формулировка по UI/UX-стандарту); на часы порог
|
||||
передаётся в объёме канала (ОВ-3). Источник — программа тренировок
|
||||
и документ метрик (п. 2.3).
|
||||
передаётся в объёме канала (ОВ-3). Источник — документ метрик
|
||||
(п. 2.3); значение перенесено в параметр конфигурации
|
||||
`Safety.HrStrengthMax` (разд. 3, умолчание 120). Программа
|
||||
тренировок — импортируемые данные атлета (см. открытый вопрос 12);
|
||||
нормативным источником требований не является (З-30, уточнение
|
||||
владельца 2026-10-17).
|
||||
|
||||
### Ф-14. Перерывы и возврат в режим (телефон + сервер; изменение 2)
|
||||
|
||||
|
|
@ -582,4 +595,5 @@ Garmin штатно — Ф-2.5, Ф-2.6). Код поля данных перен
|
|||
| 8 | Перечень моделей часов v1 | Якорь — Fenix 6X, 280×280 (изменение vision 1.1; уточнение владельца 2026-10-17 — vision 1.5); каждая модель — конфигурация сборки (экран, память). Кандидаты: модели с профилем «Силовая» и Connect IQ 4+ у участников; список фиксируется по фактическому парку устройств | Закрыт шагом 4 |
|
||||
| 9 | Способ заведения атлетов | ✅ Закрыт изменением vision 1.2: раздел «Атлеты» веб-консоли владельца (Ф-9.1) — имя + генерация ключа, смена ключа, блокировка; стартовые данные владельца — в конфиге | ✅ Закрыт (изменение vision 1.2) |
|
||||
| 10 | Источник .fit для атлетов без учётки владельца | `fetch` идёт под учётной записью владельца (опросник 4.3); другие атлеты: (а) делят доступ к своему Garmin (передача файла в папку импорта), (б) свой экземпляр учётки в конфиге, (в) только ручной импорт. Кандидат для v1 — (в) папка импорта | ✅ Закрыт (ревью №2, О-1-А): v1 — только папка импорта (`--mode import`); `fetch` — под единственной учёткой владельца; собственные учётки атлетов в конфиге — кандидат v2 (tech-requirements, ОВ-10). Уточнение владельца: атлет регистрируется на телефоне (имя), привязка — по uuid клиентского приложения |
|
||||
| 12 | Импорт пакета программы (`program-import.json`) | Пакет — механизм эксплуатации (уточнение владельца 2026-10-17); формат, маппинг на `src.program`/`program_version.body`, поведение при повторном импорте | ✅ Закрыт (ревью №3, О-4-Б): импорт в v1 через `--mode import`; формат — `3-tech\program-import-format.md`; `external_id` — идентификатор пакета; секция `profile` в v1 игнорируется |
|
||||
| 11 | Общий справочник упражнений | Сейчас библиотека у каждого атлета своя (Ф-4.4); общий справочник + личные дополнения — кандидат v2 (дубли при малом числе атлетов не критичны) | Открыт (до v2) |
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
# Архитектура: Феникс 6X v1
|
||||
|
||||
> Шаг 4 процесса разработки (`std1\_process\process.md`).
|
||||
> Источники: [vision.md](../1-reqs/vision.md) (v1.4, изменения 1.1–1.4),
|
||||
> [requirements.md](../1-reqs/requirements.md) v1.4 (черновик, ревью №2),
|
||||
> Источники: [vision.md](../1-reqs/vision.md) (v1.5, изменения 1.1–1.5),
|
||||
> [requirements.md](../1-reqs/requirements.md) v1.4 (утверждён; ревью
|
||||
> №2 и №3),
|
||||
> дизайн LLM-планирования (разд. 8), документ форматов, документы
|
||||
> «Метрики…» и «Перерывы…».
|
||||
> Схема компонентов: [hld.puml](hld.puml) (+ рендер [hld.svg](hld.svg),
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
по возрастанию; каждая миграция идемпотентна (IF NOT EXISTS /
|
||||
OR REPLACE); факт применения — одна запись на файл в
|
||||
`src.migration` (id, filename, applied_at).
|
||||
6. Сборка: скрипт `2-dbuild.ps1` применяет миграции по номеру
|
||||
6. Сборка: скрипт `2-db\build.ps1` применяет миграции по номеру
|
||||
(утилита `Server.WatchBody.Import --mode migrate`).
|
||||
|
||||
## Таблица `llm_calls` (v2)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
> FK-параметры — uuid (З-16); `break_insert`/`break_update` —
|
||||
> `p_planned_return`, `break_update` принимает ответ атлета (З-17);
|
||||
> + `migration_insert`/`migration_select` (З-25). **УТВЕРЖДЕНО** (2026-10-17).
|
||||
> Ревью №3: `p_external_id` в program_insert/program_version_insert,
|
||||
> комментарий workout_insert (З-31, З-34) — **УТВЕРЖДЕНО** (2026-10-17).
|
||||
|
||||
## Список функций
|
||||
|
||||
|
|
@ -27,19 +29,19 @@
|
|||
| athlete_profile | athlete_profile_get | PLAN | p_athlete_id | TABLE — одна строка | - | - | — |
|
||||
| exercise | exercise_insert | PLAN | p_athlete_id, p_id (uuid), p_name, p_group_id, p_is_base | uuid — id упражнения | - | - | дубликат имени у атлета — исключение UNIQUE |
|
||||
| exercise | exercise_update | PLAN | p_athlete_id, p_id, p_name, p_group_id, p_is_base | int — число строк | - | - | `exercise_id` не меняется (Ф-4.3, 🛡) |
|
||||
| exercise | exercise_delete | PLAN | p_athlete_id, p_id | int — число строк | - | - | логическое: `is_active=0` (Ф-4.2) |
|
||||
| exercise | exercise_delete | PLAN | p_athlete_id, p_id | int — число строк | - | - | логическое: `is_active=false` (Ф-4.2) |
|
||||
| exercise | exercise_select | PLAN | p_athlete_id, p_name, p_group_id, p_is_base, p_is_active | TABLE — строки + пары замен (MM) | - | - | по умолчанию только `is_active`; замены — денормализация (d-db-3) |
|
||||
| exercise | exercise_get | PLAN | p_athlete_id, p_id | TABLE — одна строка + замены | - | - | — |
|
||||
| exercise_replacement | exercise_replacement_insert | PLAN | p_athlete_id, p_exercise_id, p_replacement_id | int — число строк | - | - | оба упражнения — атлета, группа равна (проверка в функции) |
|
||||
| exercise_replacement | exercise_replacement_delete | PLAN | p_athlete_id, p_exercise_id, p_replacement_id | int — число строк | - | - | — |
|
||||
| program | program_insert | PLAN | p_athlete_id, p_title | int — id программы | - | - | вторая программа атлета — исключение UNIQUE |
|
||||
| program | program_insert | PLAN | p_athlete_id, p_title, p_external_id | int — id программы | - | - | вторая программа атлета — исключение UNIQUE; `p_external_id` — идентификатор пакета (program-import.json, З-31) |
|
||||
| program | program_select | PLAN | p_athlete_id | TABLE — строки + активная версия | - | - | денормализация активной версии (d-db-3) |
|
||||
| program | program_get | PLAN | p_athlete_id, p_program_id | TABLE — одна строка | - | - | — |
|
||||
| program_version | program_version_insert | PLAN | p_athlete_id, p_id (uuid), p_program_id, p_based_on_version, p_author, p_body, p_rationale | uuid — id версии | - | - | `version` = max+1; `status='draft'`; body — jsonb |
|
||||
| program_version | program_version_insert | PLAN | p_athlete_id, p_id (uuid), p_program_id, p_based_on_version, p_author, p_body, p_rationale | uuid — id версии | - | - | импорт пакета: повтор `p_external_id` → новая версия; `version` = max+1; `status='draft'`; body — jsonb |
|
||||
| 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_get | PLAN | p_athlete_id, p_id | TABLE — одна строка с body | - | - | — |
|
||||
| workout | workout_insert | PLAN | p_athlete_id, p_id (uuid), p_program_version_id, p_started_at, p_session_kind | uuid — id | - | - | повтор `client_guid` возвращает существующий id (🛡 идемпотентность) |
|
||||
| workout | workout_insert | PLAN | p_athlete_id, p_id (uuid), p_program_version_id, p_started_at, p_session_kind | uuid — id | - | - | повтор `p_id` (uuid — PK клиентской сущности, генерирует телефон) возвращает существующий id (🛡 идемпотентность) |
|
||||
| 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_get | PLAN | p_athlete_id, p_id | TABLE — одна строка + sets + command_log | - | - | полная карточка (Ф-9.2) |
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@
|
|||
> Новая редакция (2026-10-17, ревью №2): FK-колонки приведены к uuid
|
||||
> (Р2-Б доведён, З-16); `src.breaks` — `planned_return`, `source` = auto|manual
|
||||
> (З-17); `src.migration` — журнал миграций (З-25). УТВЕРЖДЕНО
|
||||
> (2026-10-17).
|
||||
> (2026-10-17). Правки ревью №3: `src.program.external_id`, примечание
|
||||
> `body` (З-31), `is_active=false` (З-34) — УТВЕРЖДЕНО (2026-10-17).
|
||||
|
||||
## Описания
|
||||
|
||||
|
|
@ -60,7 +61,7 @@
|
|||
| `name` | text NOT NULL | название; `UNIQUE(athlete_id, name)` |
|
||||
| `group_id` | int NOT NULL | → `ref.exercise_group.id` |
|
||||
| `is_base` | boolean NOT NULL DEFAULT true | базовое/изоляция (шаг прогрессии, Ф-12.2) |
|
||||
| `is_active` | boolean NOT NULL DEFAULT true | логическое удаление (Ф-4.2) |
|
||||
| `is_active` | boolean NOT NULL DEFAULT true | логическое удаление — `is_active=false` (Ф-4.2, З-34) |
|
||||
|
||||
### `src.exercise_replacement` — пара-замена (ММ, правило 6)
|
||||
|
||||
|
|
@ -79,6 +80,7 @@
|
|||
| `id` | serial PK | — |
|
||||
| `athlete_id` | int NOT NULL | → `src.athlete.id`; `UNIQUE(athlete_id)` — одна программа на атлета (версии — в `program_version`) |
|
||||
| `title` | text NOT NULL | название («Программа v4») |
|
||||
| `external_id` | text UNIQUE NULL | идентификатор пакета (`program_id` из program-import.json, З-31) |
|
||||
| `created_at` | timestamptz NOT NULL DEFAULT now() | — |
|
||||
|
||||
### `src.program_version` — неизменяемая версия программы (Ф-10, 🛡)
|
||||
|
|
@ -91,7 +93,8 @@
|
|||
| `based_on_version` | int NULL | предыдущая версия (NULL — первая) |
|
||||
| `status` | text NOT NULL DEFAULT 'draft' | `draft` \| `active` \| `archived`; 🛡 `active` — ровно одна на программу (частичный уникальный индекс `WHERE status='active'`) |
|
||||
| `author` | text NOT NULL | `user` \| `admin` \| `rules` \| `llm` (v2) |
|
||||
| `body` | jsonb NOT NULL | недели → тренировки → упражнения (`exercise_id`) → подходы-план; схема — дизайн LLM-планирования разд. 2 |
|
||||
| `body` | jsonb NOT NULL | недели → тренировки → упражнения (`exercise_id`) → подходы-план; схема — дизайн LLM-планирования разд. 2; секция `profile` пакета
|
||||
(program-import.json) в body не переносится (v1, З-31) |
|
||||
| `rationale` | text | «почему» — журнал изменений, показывается пользователю |
|
||||
| `created_at` | timestamptz NOT NULL DEFAULT now() | — |
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
# Формат пакета программы (program-import.json)
|
||||
|
||||
> Шаг 5 процесса разработки (`std1\_process\process.md`), решение ОВ-11
|
||||
> (ревью №3, О-4-Б, З-31). Пакет — **импортируемый механизм
|
||||
> эксплуатации** (уточнение владельца 2026-10-17): назначается атлету
|
||||
> индивидуально, нормативным источником документации разработки не
|
||||
> является. Пример — `..\..\program-import.json` (эксплуатационные
|
||||
> данные). Импорт — `--mode import` (`Server.WatchBody.Import`),
|
||||
> коды возврата — как у import (requirements 2.3).
|
||||
|
||||
## 1. Структура пакета
|
||||
|
||||
| Поле | Тип | Назначение при импорте |
|
||||
|---|---|---|
|
||||
| `program_id` | string | внешний идентификатор пакета → `src.program.external_id` (UNIQUE) |
|
||||
| `version` | int | номер версии; при конфликте с существующей — новая строка `program_version` (max+1) |
|
||||
| `based_on_version` | int? | → `program_version.based_on_version` |
|
||||
| `status` | string | `draft` \| `active` \| `archived` → `program_version.status` (🛡 правила смены — Ф-10.3, `program_version_update`) |
|
||||
| `author` | string | `user` \| `admin` \| `rules` → `program_version.author` (`llm` — v2) |
|
||||
| `created_at` | ISO 8601 | информационное поле (в БД — `created_at` строки версии) |
|
||||
| `profile` | object | **v1 игнорируется** (не переносится в `body`): `limitations` и прочее носят справочный характер; Safety-порогами управляет только конфиг `Safety.*` (Р3-А). Поля задокументированы для совместимости v2 |
|
||||
| `weeks` | array | основное содержимое → `program_version.body` (см. раздел 2) |
|
||||
| `safety`, `nutrition`, `coordination_rules`, `metrics`, `rationale` | mixed | переносятся в `body` как есть (`rationale` — также в колонку `program_version.rationale`) |
|
||||
|
||||
## 2. Содержимое `weeks` → `body`
|
||||
|
||||
Иерархия: `weeks[] → sessions[] → exercises[] → sets[]` — соответствует
|
||||
схеме `program_version.body` (дизайн LLM-планирования, разд. 2):
|
||||
|
||||
- `week` (номер), `goal`, `load_pattern` — атрибуты недели;
|
||||
- `sessions[]`: `day`, `title`, `exercises[]`;
|
||||
- `exercises[]`: `name` (→ сопоставление с `src.exercise` по
|
||||
`UNIQUE(athlete_id, name)`; отсутствующее упражнение создаётся при
|
||||
импорте — группа по разделу пакета, иначе `core` и пометка в логе),
|
||||
`sets[]`: `weight_kg`, `reps`, `rest_sec`, `rpe_target`.
|
||||
- `progression_gate` (у недель/пакета) — текст, в v1 переносится в
|
||||
`body` без интерпретации (правила прогрессии — конфиг
|
||||
`Progression.*`, Ф-12.2).
|
||||
|
||||
## 3. Маппинг и идемпотентность
|
||||
|
||||
1. `program_id` отсутствует в `src.program` → создаются `program`
|
||||
(`external_id`, `title` = `program_id`) и `program_version` (v1).
|
||||
2. `program_id` есть → создаётся новая `program_version` (номер
|
||||
`based_on_version`/`version` из пакета; конфликт номеров — max+1
|
||||
с записью в лог, код возврата 0).
|
||||
3. 🛡 Неизменяемость версий не нарушается: повторный импорт никогда
|
||||
не переписывает существующую `program_version`.
|
||||
4. Назначение атлета: пакет импортируется в контексте конкретного
|
||||
атлета (параметр режима import / сопоставление по каталогу файла);
|
||||
🛡 изоляция атлетов сохраняется.
|
||||
5. Ошибки схемы пакета (нет `weeks`, пустой `program_id`) — код
|
||||
возврата 2, файл остаётся в `Import.Dir`.
|
||||
|
|
@ -20,7 +20,8 @@
|
|||
> `src.breaks` (З-17), ОВ-7 — таргет `fenix6x` 280×280 (З-18),
|
||||
> ОВ-10 закрыт (З-19, О-1-А), `Safety.HrStrengthMax` (З-20),
|
||||
> интервал fetch 15 минут (З-21), грамматика «…с половиной» (З-26,
|
||||
> О-2-Б), `Progression.IsoStepKg` (З-27, О-3-А).
|
||||
> О-2-Б), `Progression.IsoStepKg` (З-27, О-3-А). Ревью №3: решение
|
||||
> ОВ-11 — импорт пакета программы (З-31, О-4-Б).
|
||||
|
||||
## 1. Решения открытых вопросов (закрытие раздела 7 requirements)
|
||||
|
||||
|
|
@ -32,6 +33,7 @@
|
|||
| 3. Канал телефон ↔ часы | Connect IQ **Communications SDK** (companion-канал через приложение Garmin Connect Mobile на телефоне). Передаётся: текущий пульс (≈1 Гц), зона, таймер отдыха (секунды до конца), заряд часов. Ограничение: на телефоне должно быть установлено и залогинено Garmin Connect Mobile; канал может не доставлять — обе стороны деградируют молча (Ф-2.4, Ф-3.2) | Единственный штатный канал сторонних приложений Garmin; проверка объёма передачи — прототипом в итерации 1 шага 7 (критерий: пульс и таймер доходят при экране часов активным) |
|
||||
| 4. Расписание fetch | Внешний планировщик ОС: systemd timer (Linux-сервер) / Планировщик задач (Windows) вызывает `--mode fetch`; внутри сервера планировщика нет. Интервал вызова — 15 минут (параметр планировщика ОС, в код не входит); вместе с лагом синхронизации часов с Garmin Connect укладывается в БЦ-5 (архив ≤ 30 минут после тренировки) | Проще, надёжнее, не дублирует средства ОС |
|
||||
| 10. Источник .fit атлетов без учётки владельца | v1 — только папка импорта (`--mode import`); `fetch` работает под единственной учёткой владельца; собственные учётки атлетов в конфиге — кандидат v2. Уточнение владельца: атлет регистрируется на телефоне (имя), привязка — по uuid клиентского приложения | Не раздувать v1; деградация уже работает (решение владельца О-1-А, З-19) |
|
||||
| 11. Импорт пакета программы | `--mode import` принимает `program-import.json` (формат — `program-import-format.md`): пакет маппится на `src.program` (`external_id` UNIQUE) и `src.program_version.body`; повторный импорт с тем же `external_id` — новая версия `program_version`; секция `profile` пакета в v1 не переносится — Safety-порогами управляет только конфиг `Safety.*` | Пакет — механизм эксплуатации (уточнение владельца); иначе путь доставки программы атлету в v1 не закрыт (ревью №3, О-4-Б) |
|
||||
| 5. Формула 1ПМ | **Эпли**: `1ПМ = w × (1 + reps/30)` | Стандарт индустрии; при reps ≤ 10 различие с Бжицки < 2 % |
|
||||
| 6. UI телефона | **Jetpack Compose** + Material 3 (тёмная тема по умолчанию) | Актуальный стек Kotlin; крупные зоны касания — Min touch target 48 dp (Ф-3.6) |
|
||||
| 7. Модели часов v1 | Таргет v1 — `fenix6x` (280×280, MIP, кнопки). Fenix 6 (260×260) и 6S (240×240) добавляются отдельными таргетами с собственными макетами (Ф-2.8) по фактическому парку (уточнение владельца 2026-10-17, изменение vision 1.5) | Якорные часы владельца — Fenix 6X; «одно разрешение 260×260» в ТЗ — описка исходника |
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@
|
|||
|
||||
### 6.2. Android Wear OS design principles (Material 3 for Wear)
|
||||
|
||||
- **Design for critical tasks**: на часах — только 1–2 ключевые задачи (исполнение тренировки + ввод RPE/боли). Всё остальное — на телефоне/вебе.
|
||||
- **Design for critical tasks**: на часах — только 1–2 ключевые задачи (исполнение тренировки + ввод RPE/боли; для формы «поле данных» ввод RPE/боли неприменим — кнопки обрабатывает Garmin, Ф-2.5–2.6, ввод — на телефоне, Ф-13.3). Всё остальное — на телефоне/вебе.
|
||||
- **Optimize for the wrist**: задача на часах должна решаться за секунды — иначе эргономический дискомфорт и усталость руки (для атлета под штангой это критично).
|
||||
- **Glanceable surfaces**: основное содержимое — в виде «взгляд-поверхностей» (у Garmin аналог — data fields в активити и watch face complications: можно вывести «текущее упражнение / подход X из Y» прямо на циферблат в дни тренировок).
|
||||
- **Always relevant**: контент подстраивается под контекст (время суток, день недели, запланированная тренировка).
|
||||
|
|
|
|||
Loading…
Reference in New Issue