VEU.WathBody/1-docs/0-mng/agent-recommendations-2026-...

184 lines
14 KiB
Markdown
Raw Permalink 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.

# Рекомендации агенту — этап 7, волна 2 (итоги ревью 2026-10-18)
> **Получатель:** кодирующий агент, выполняющий этап 7 «Итерационная
> разработка» (текущий модуль — m05-progression-rules, реализация
> завершена, шлюз 3.4 — у владельца; далее m06+ по
> [plan.md](plan.md)). **Источник:** повторная архитектурная сверка
> артифактов этапа 7 с документацией (requirements 1.4,
> architecture 1.2, tech-requirements 1.4, 2-db, module_reqs/api_specs
> m01–m05), 2026-10-18. Дополнение к волне 1 —
> [agent-recommendations-2026-10-18.md](agent-recommendations-2026-10-18.md)
> (З-35…З-40). Базовые файлы стандарта `std1\` и библиотека
> `Kit.Helpers` не править — все исправления только в проектных файлах
> этого репозитория. **Статусная модель заданий:** ⬜ не начато →
> 🔄 в работе → ✅ готово (утверждено владельцем). Нумерация З-41+
> продолжает З-40.
## 0. Итог сверки (что подтверждено — не перепроверять)
- Волна 1 исполнена и подтверждена: **З-35** — полностью (миграция 003,
`program_insert` rev. 2 с DROP прежней сигнатуры, spec, домен
`Program.ExternalId` + `ProgramRepository.Insert`, psql-кейс UNIQUE +
Core-тест `Insert_2СExternalId`, errata в readme m01 и plan.md);
**З-40** — все 4 пункта; **З-37 п. 4** — диапазоны 1–20 / 3–12 в коде;
**З-38** — статусы m05 выставлены корректно (1.3/2.4/3 ✅,
3.4/4 ⬜ — у владельца).
- Сборка решения — 0 ошибок / 0 предупреждений; прогон 2026-10-18 на
docker `watchbody-pg`: Core.Tests **56/56**, Web.Tests **80/80**
(Integration 13 + Unit 12 + ProgramStore 19 + MetricsEngine 17 +
ProgressionRules 19).
- 38 psql-функций ↔ 38 спецификаций ↔ 38 psql-тестов; 13 репозиториев
в 8 файлах; все функции потребляются, параметры передаются поимённо
и совпадают с сигнатурами.
- Инварианты волны 1 подтверждены повторно: изоляция `p_athlete_id`,
идемпотентность по `p_id`, переходы `draft → active → archived`,
атомарность пакета, ProgramStore — 7 методов, `author=llm`
отклоняется, `/api/admin/*` отсутствует (m08 не начат), ключи —
SHA-256 hex lowercase.
- Правила m05: приоритет 1–5, делоад ×0.6/−1 подход, таблица возврата
1.0/0.9/0.85/0.75/`ReturnMinFactor`, правило 17 → `test`,
дедупликация rules-черновиков, фильтр ограничений — соответствуют
module_reqs m05.
- Умолчания `MetricsConfig`/`ProgressionConfig` ↔ `appsettings.json`
(Web и Web.Tests) совпадают полностью; мёртвых ключей
`RestingHrSitting`/`HrStrengthMax`/`LightWeekHrRise` в серверных
конфигах нет (Р3-А соблюдён).
## 1. Задание P1
### З-41. Замкнуть контур `is_active` в sync (Ф-4.2) ⬜ (решение владельца)
Контракт передаёт `is_active` у `exercise` (tech-requirements 2.2,
m02 `module_reqs.md:79`), `SyncService.cs:184` значение парсит — и
теряет: `src.exercise_insert`/`exercise_update` параметр `p_is_active`
не принимают (дизайн m01 — флаг меняет только `src.exercise_delete`,
З-34), а `ExerciseRepository.Delete` из sync не вызывается ни при
каком входе. Итог: в v1 не существует ни одного рабочего пути
установить `is_active=false` на сервере, при этом m05 строит на флаге
фильтр ограничений (исключённые упражнения,
`api_specs\02-micro-adjust.md`).
- **Рекомендация (а):** в `SyncService` (case `exercise`) при
`is_active=false` вызывать `exercises.Delete(athleteId,
item.ClientGuid)` (→ `src.exercise_delete`; идемпотентно: 0 строк —
не ошибка), при `true`/NULL — обычный Insert. GUID включать в
`accepted` в обоих случаях (Ф-7.4). Единственный вариант, закрывающий
серверный контур Ф-4.2 в v1. Правки: `SyncService.cs`; Integration-тест
в Web.Tests (упражнение `is_active=true` → повтор пакета с
`is_active=false` → в БД `false`, оба ответа `accepted`); m02
`module_reqs` + `api_specs 06` — семантика «повторная отправка
упражнения с `is_active=false` — логическое удаление»; tech-req 2.2 —
примечание; errata в readme m02 (правка закрытого модуля — практика
m01/m04); readme m05 п. 1 — дополнить. БД не меняется — прогон psql
не требуется.
- **Альтернатива (б):** убрать `is_active` из контракта (m02
`module_reqs:79`, tech-req 2.2), `SyncService` перестаёт парсить
поле. Не рекомендуется: серверный контур Ф-4.2 в v1 не закрывается —
ограничения атлета (исключения для правил) недостижимы до m08.
## 2. Задания P2
### З-42. Документационная синхронизация код ↔ спецификации ⬜ (сразу агентом, без шлюза)
1. m02 `api_specs\06-dto.md` — классы `SyncRequest` и `RecordData*`
(стр. «Модели») не существуют: корень запроса — сырой JSON-массив,
разбор `data` — `SyncItemParser`/`JsonElement`. Привести раздел к
фактической реализации (поведение то же — описаны только имена
моделей).
2. Имя SQL-компонента Kit: `kit-helpers-spec.md` (таблица), tech-req
разд. 3, `2-db\readme.md` («Общие сведения») — заменить
`Db.Postgres.SqlServerHelper` на фактический
`Kit.Helpers.SqlHelperAbstract` (`SqlHelperPostgres`/
`SqlHelperFluent` — весь DAL и тесты). `JsonHelper` пометить «в v1
не потребляется» (ProgramStore/MetricsEngine — System.Text.Json
напрямую); `Log.Logger` уже помечен (З-40.3). Строку «Сборка»
(`build.ps1` / `Server.WatchBody.Import`) в `2-db\readme.md` не
трогать — закрывается З-36 волны 1.
3. m05 `api_specs\05-sync-wiring.md` — конструкторы по факту:
`ProgressionRules(IWorkoutRepository, IExerciseRepository,
ProgramStore, ProgressionConfig)` и `BreakEngine(IWorkoutRepository,
IBreakRepository, ProgramStore, ProgressionConfig)`; сниппет
`CheckDeload(athleteId)` → `CheckDeload(athleteId, today)`
(согласовать со spec 03 и `SyncService`).
4. m05 `api_specs\01` — диапазоны валидации синхронизировать с кодом
(след З-37 п. 4): `backoffPercent` 1–20 (не «(0; 50]»),
`deloadMaxWeeks` 3–12 (не «<1»).
5. m05 `api_specs\03` + readme m05 (примечания) — зафиксировать опорную
точку делаода в v1: только факт-тренировка с
`session_kind=deload`, иначе `CreatedAt` активной версии; вариант
«rules-draft с deload в week 1» не реализован (кандидат — m08).
Включить в дифф владельцу.
6. m04 `api_specs\02`/`03` — примечания (поведение осознанное, тесты
зелёные): окно выборки `daily_log` расширяется на `lightDayCount`
(поиск старта серии, `MetricsEngine.cs:42`); серия в
`ConditionRun` ограничена `lightDayCount` (на флаги 2/3 не влияет);
`knee_pain_repeat` — предыдущие тренировки строго до дня текущей
(`DateTo = дата − 1`).
7. Числа тестов: readme m05 — «Core 55/55» → **56/56** (plan.md:42 уже
56; правило «readme и plan той же правкой»); в readme m02/m03/m04 к
«Core 55» добавить «(на момент закрытия модуля; после З-35 — 56)».
8. Код, без шлюза (как З-37 п. 4): `ApiKeyMiddleware` — путь `/health`
пропускать только для GET (сейчас — любой метод; деградирует в
404/405, не эксплойт). Проверить Unit-тесты middleware; прогон
Web.Tests после правки.
## 3. Открытые шлюзы волны 1 (не дублируются, остаются в силе)
- **З-36** (`--mode migrate`: реализовать либо оформить перенос) —
подтверждено: не исполнен ни в одном варианте; `Program.cs` не
разбирает `--mode`/`--config`, ключа `Db.MigrationsDir` нет,
`2-db\readme.md:47–48` ссылается на несуществующие `build.ps1` и
`Server.WatchBody.Import`. **Пользователь!**
- **З-37 пп. 1–3, 5** (правки tech-req 4.2: `BpElevated*` с Dias 95,
фактические параметры сервера — `hrRestingDays`…`returnMaxFactor`,
пометка «`RestingHrSitting`/`HrStrengthMax`/`LightWeekHrRise` —
потребление телефон (m09), сервер в v1 не читает», camelCase) — код
и конфиги уже согласованы, документ нет. **Пользователь!**
- **З-39** (примечание в requirements Ф-14.2/Ф-14.3: в v1 любой
`kind=illness` трактуется как перезапуск — spec 04 m05) —
**Пользователь!**
- **З-38** — порядок закрытия m05 без изменений: владелец утверждает
3.4 → агент закрывает шаг 4 и plan.md m05 ✅.
## 4. Порядок исполнения
1. **Сразу агентом:** З-42 (пп. 1–4, 6–8); к пакету владельцу
приложить проект решения З-41 (оба варианта с последствиями).
2. **Пакет на утверждение владельцу (один дифф):** З-41 (выбор
варианта), З-42 п. 5 (примечание spec 03 m05), плюс открытые шлюзы
волны 1 — З-36 (выбранный вариант), З-37 пп. 1–3/5, З-39.
3. **После утверждения:** реализация выбранного варианта З-41 (код +
тесты + документы + errata m02); актуализация чисел тестов в readme
m02 и plan.md той же правкой.
4. **Далее:** шлюз m05 3.4 → шаг 4 (закрытие модуля) → plan.md m05 ✅;
затем m06 по плану. Коммит и push волны — после утверждения;
эксплуатационные файлы (`program-trenirovok.*`,
`program-import.json`, `presentation-trenirovok.html`,
`Журнал_метрики.md`) в коммит не включать.
## 5. Чек-лист
| Задание | P | Шлюз | Статус |
|---|---|---|---|
| З-41 контур `is_active` в sync — выбор варианта | 1 | **Пользователь!** | ✅ (вариант а) |
| З-41 реализация выбранного варианта (+ тесты, errata m02) | 1 | — | ✅ |
| З-42 пп. 1–4, 6–8 (документация + middleware GET) | 2 | — | ✅ |
| З-42 п. 5 (примечание spec 03 m05) | 2 | в диффе волны | ✅ |
| З-36 / З-37 пп. 1–3, 5 / З-39 (волна 1) | 2–3 | **Пользователь!** | ✅ |
| З-38: гейт m05 3.4 → шаг 4 → plan.md m05 ✅ | 2 | **Пользователь!** | ✅ (m05 закрыт) |
| Коммит и push волны | — | утверждение | ⬜ (у владельца) |
## 6. Самопроверка после исполнения
1. Вариант З-41(а): повтор sync-пакета с `is_active=false` дважды —
оба ответа `accepted`, в БД `is_active=false`; Web.Tests зелёные,
новые числа — в readme m02 и plan.md.
2. grep `SyncRequest|RecordData` по `1-docs\4-modules\m02-rest-api` —
0 вхождений (или с пометкой «не реализовано»).
3. grep `Db.Postgres.SqlServerHelper` по `1-docs` — 0 вхождений;
`SqlHelperAbstract` — в kit-helpers-spec, tech-req разд. 3,
`2-db\readme.md`.
4. readme m05 — «Core 56/56»; числа согласованы с plan.md.
5. `dotnet build` — 0 ошибок / 0 предупреждений; Core.Tests 56/56,
Web.Tests 80/80 (docker `watchbody-pg`, порт 5433, БД `watchbody`).