# Рекомендации агенту — этап 7 (итоги архитектурного ревью 2026-10-18) > **Получатель:** кодирующий агент, выполняющий этап 7 «Итерационная > разработка» (текущий модуль — m05-progression-rules; далее 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. > Базовые файлы стандарта `std1\` и библиотека `Kit.Helpers` не править — > все исправления только в проектных файлах этого репозитория. > **Статусная модель заданий:** ⬜ не начато → 🔄 в работе → ✅ готово > (утверждено владельцем). Нумерация З-35+ продолжает З-34 > (ревью №3, [review-2026-10-17-3.md](review-2026-10-17-3.md)). ## 0. Итог сверки (что подтверждено — не перепроверять) - Сборка решения — 0 ошибок / 0 предупреждений; тесты: Core.Tests **55/55**, Web.Tests **80/80** (Integration 13 + Unit 12 + ProgramStore 19 + MetricsEngine 17 + ProgressionRules 19), psql-проверок **122** — все числа в readme модулей и plan.md совпадают с фактом. - Структура DAL — 13 репозиториев в 8 файлах, 7 фильтров; доступ к БД — только хранимые функции через Kit.Helpers. - 38 psql-функций ↔ 38 тестов ↔ 38 спецификаций, статусы `DONE`. - 🛡-инварианты серверного кода соблюдены: изоляция `p_athlete_id` (включая явные проверки в `workout_insert`, `program_version_update`, `workout_metrics_upsert`), идемпотентность по `p_id`, статусные переходы `draft → active → archived` со сдвигом прежней `active`, логическое `exercise_delete`, отказ `break.source=auto` из sync, атомарность пакета `TransactionScope` (чтения — до транзакции), сбой метрик/правил не ломает sync, ProgramStore — 7 методов, авторы `user/admin/rules` (llm отклоняется), авто-смены активной версии нет. - Sync-валидация полного состава: пакет ≤ 50, `op=upsert`, диапазоны `rpe` 1–10 / `wellbeing` 1–5 / `knee_pain` 0–10, 409 по spec 03 m02. - Правила m05: 1–5 по порядку, делоад ×0.6/−1 подход, формула возврата по таблице (1.0/0.9/0.85/0.75/ReturnMinFactor), правило 17 → `test`, дедупликация rules-черновиков. ## 1. Задание P1 ### З-35. Довести З-31 (`src.program.external_id`) до артефактов БД и DAL ⬜ Решение О-4-Б утверждено и внесено в документацию (`2-db\src\tables.md:83` — колонка `external_id`; `2-db\src\functions.md`, `program_insert` — параметр `p_external_id`), но в коде отсутствует полностью (grep по `2-db\` и `3-app\` — 0 вхождений): миграция 002, `program_insert.psql`, `func_specs\program_insert.md`, `ProgramRepository.Insert`. Контракт импорта пакета программы (Ф-8.3, tech-req ОВ-11) на текущей схеме нереализуем — блокер m06. 1. `2-db\migrations\003_program_external_id.sql` — новая миграция (001–002 уже применены на `watchbody-pg`, журнал не трогать): `ALTER TABLE src.program ADD COLUMN IF NOT EXISTS external_id text;` + `CREATE UNIQUE INDEX IF NOT EXISTS uq_program_external_id ON src.program (external_id);` (идемпотентно; NULL не ограничивается — программа из sync создаётся без пакета). 2. `2-db\src\functions\program_insert.psql` — параметр `p_external_id text DEFAULT NULL`, включить в INSERT. 3. `1-docs\2-db\src\func_specs\program_insert.md` — синхронизировать (параметр + тест-кейс «повтор того же `external_id` → исключение UNIQUE»; новая версия при повторе пакета — путь импорта, m06). 4. `Server.WatchBody.Core`: `Program.ExternalId` (string?) в домен, `ProgramRepository.Insert` — параметр `p_external_id` (`AddParameterNullable`); `SyncService.CreateProgram` не меняется (NULL по умолчанию). 5. Тесты: psql `test_program_insert` — кейс UNIQUE-повтора; Core.Tests `ProgramRepositoryTests` — кейс вставки с `external_id`; прогон на docker `watchbody-pg`. 6. `readme.md` m01 — errata-примечание (практика модуля): «З-31 не был доведён до SQL/DAL-артефактов, вскрыто ревью этапа 7 (2026-10-18), исправлено по З-35»; числа тестов в readme m01 и plan.md (строка m01) актуализировать после добавления кейсов. ## 2. Задания P2 ### З-36. Режим `--mode migrate` — реализовать либо оформить перенос ⬜ (решение владельца) `requirements` 2.3 и `module_reqs` m01 (разд. 1, критерий приёмки 1) требуют CLI `--mode serve|import|fetch|migrate`; `plan.md` (строка m01) включает его в закрытый модуль. Фактически `Program.cs` аргументы не разбирает; `2-db\readme.md` ссылается на несуществующий `build.ps1`. - **Рекомендация (реализовать):** разбор `--mode`/`--config` в `Program.cs`; для `migrate` — применение файлов `2-db\migrations\` по возрастанию, журнал через `MigrationRepository` (уже готов), транзакция на файл, откат при сбое, коды возврата 0/1 (как import); путь миграций — новый ключ конфига `Db.MigrationsDir` (умолчание — `migrations` рядом с исполняемым файлом). Внесение ключа — правка tech-req 4.2 → шлюз «**Пользователь!**». - **Альтернатива (перенести в m06):** в `plan.md` (строки m01/m06), `module_reqs` m01 и `2-db\readme.md` зафиксировать «`--mode migrate` входит в `Server.WatchBody.Import` (m06)»; m01 в plan.md — примечание. ### З-37. Конфигурация `Safety.*`/`Progression.*` ↔ tech-req 4.2 ⬜ (правка утверждённого документа — шлюз) Расхождения (код — `MetricsConfig.cs`, `ProgressionConfig.cs`, `appsettings.json`): 1. `bpElevatedSys/Dias` (умолчание 140/**95**) против tech-req `BpCardioSys/Dias` (140/90, «≤ BpCancel») — с умолчаниями документа невыполнимо; отказ от проверки задокументирован в m04. Рекомендация: tech-req 4.2 переименовать в `BpElevated*`, умолчание Dias 95, примечание «проверка ≤ BpCancel не применяется (коридоры АД перекрываются, spec 01 m04)». 2. В tech-req 4.2 отсутствуют фактические параметры сервера: `hrRestingDays`, `wellbeingDays`, `lightDayCount`, `kneePainMin`, `kneeRepeatSessions`, `hrBaselineDays`, `hrBaselineMin`, `missDaysForBreak`, `returnMinFactor/MaxFactor` — дополнить таблицу. 3. `RestingHrSitting`, `HrStrengthMax`, `LightWeekHrRise` в серверной конфигурации не читаются (пороги допуска — телефон по Р3-А; Ф-13.7). Рекомендация: в tech-req 4.2 пометить «потребление — телефон (m09); сервер в v1 не читает» — без мёртвых ключей в appsettings. 4. Диапазоны валидации сузить в коде до утверждённых: `backoffPercent` → 1–20 (`ProgressionConfig.cs:44`), `deloadMaxWeeks` → 3–12 (`ProgressionConfig.cs:45`) — это правка кода без шлюза. 5. Регистр имён в tech-req 4.2 привести к фактическим camelCase. ### З-38. Шлюзы и статусы m05 ⬜ (шлюз — владелец, остальное — агент) По [m05 readme](../4-modules/m05-progression-rules/readme.md) шаг 1.3 («**Пользователь!**» — утверждение списка единиц) — ⬜ при выполненных шагах 2/2.4/3; в [plan.md](plan.md) m05 — ⬜. Проект решения гейта — `module_reqs` разд. 2.4. Порядок: владелец утверждает 1.3 → агент проставляет 1.3 ✅ и m05 🔄 в plan.md → шлюз 3.4 (утверждение реализации) → шаг 4 (закрытие модуля), plan.md m05 ✅. ## 3. Задания P3 ### З-39. Трассировка Ф-14.3: «болезнь с температурой» vs `kind=illness` ⬜ (шлюз) Spec 04 m05 (утверждён) применяет коэффициент перезапуска 0.6 к любому `kind=illness` («любой длительности»), requirements Ф-14.3 — только к «болезни с температурой». Признака «с температурой» в данных `breaks` нет, поэтому рекомендуется примечание в requirements Ф-14.2/Ф-14.3: «в v1 любой break `kind=illness` трактуется как перезапуск (spec 04 m05); различение „с температурой“ — кандидат v2». Утверждение — владелец. ### З-40. Косметика и примечания ⬜ (сразу, без шлюза) 1. `2-db\src\functions\exercise_delete.psql:1` — заголовок «is_active = 0» → «is_active = false» (терминология З-34). 2. `m02 api_specs\04-workouts-get.md` — примечание «пагинация в памяти (выборка атлета целиком) — известное ограничение v1». 3. `tech-requirements` разд. 3 — примечание «в sync-контуре v1 используется `ILogger`; `Log.Logger` — файловые логи последующих модулей (errata m04 №4)». 4. `m05 api_specs\02-micro-adjust.md` — примечание: «та же группа» пары-замены гарантируется `exercise_replacement_insert` (проверка на вставке пары); runtime-проверка в `ApplyExclusion` не дублируется. ## 4. Порядок исполнения 1. **Сразу агентом:** З-35 (код + БД + тесты, прогон на docker `watchbody-pg`), З-40; в З-37 — п. 4 (диапазоны кода). 2. **Пакет на утверждение владельцу (один дифф):** З-36 (выбранный вариант), З-37 (пп. 1–3, 5 — правки tech-req 4.2), З-39. 3. **После утверждения:** З-38 — закрытие шлюзов m05, синхронизация статусов (readme m05, plan.md); далее продолжение этапа 7 — закрытие m05 (3.4 → 4) и m06 по plan.md. 4. Коммит и push — после утверждения волны владельцем; эксплуатационные файлы (`program-trenirovok.*`, `program-import.json`, `presentation-trenirovok.html`) в коммит не включать. ## 5. Чек-лист | Задание | P | Шлюз | Статус | |---|---|---|---| | З-35 external_id: миграция 003 + функция + spec + DAL + тесты | 1 | — | ✅ | | З-36 `--mode migrate`: реализация или перенос (по выбору) | 2 | **Пользователь!** | ✅ (реализовано) | | З-37 Safety/Progression ↔ tech-req 4.2 (пп. 1–3, 5) | 2 | **Пользователь!** | ✅ | | З-37 п. 4 — диапазоны валидации в коде | 2 | — | ✅ | | З-38 шлюзы/статусы m05 (1.3 → 🔄 → 3.4 → 4) | 2 | **Пользователь!** | ✅ (m05 закрыт) | | З-39 примечание Ф-14.3 (illness → перезапуск) | 3 | **Пользователь!** | ✅ | | З-40 косметика (4 пункта) | 3 | — | ✅ | | Коммит и push волны | — | утверждение | ⬜ (у владельца) | ## 6. Как продолжать работу после заданий - Точка входа — первый незакрытый шаг/шлюз в readme текущего модуля; шлюзы «**Пользователь!**» (d-dev-4) без явного утверждения не переходить. - Новые сущности, функции БД, эндпоинты и параметры конфига не вводить без правки `module_reqs.md` модуля (состав зафиксирован шагами d-dev). - Прогон тестов — PostgreSQL 17 в docker `watchbody-pg` (порт 5433, БД `watchbody`); изменения чисел тестов актуализировать в readme модуля и `plan.md` той же правкой. - Errata интеграций фиксировать в readme модуля-обнаружителя (практика m01/m02/m04 — сохранить). ## 7. Самопроверка после З-35 1. `\i 2-db\migrations\003_program_external_id.sql` дважды — без ошибок (идемпотентность); `src.program` содержит колонку и уникальный индекс. 2. `SELECT src.program_insert(1, 'Т', 'pkg_1')` дважды — второй вызов — исключение UNIQUE; psql-тест `test_program_insert` — PASS. 3. Core.Tests и Web.Tests — зелёные; новые числа внесены в readme m01 и plan.md. 4. grep `external_id` по `2-db\` и `Server.WatchBody.Core` — вхождения в миграции, функции, спецификации, домене и репозитории.