VEU.WathBody/1-docs/4-modules/m04-metrics-engine/module_reqs.md

7.5 KiB
Raw Permalink Blame History

Требования к модулю: m04-metrics-engine

Модуль — сервис MetricsEngine в Server.WatchBody.Core: детерминированный расчёт метрик тренировки (adherence, тоннаж, оценочный 1ПМ, пульс-метрики, красные флаги) после каждой синхронизированной тренировки → src.workout_metrics (1:1, upsert). Источники: Ф-12.1/Ф-12.5, Ф-13.5, документ метрик (..\..\..\Метрики_тренировок_и_самоконтроля.md, п. 2.5, правила 1–6), архитектура (строка MetricsEngine), дизайн LLM-планирования разд. 4. Самодостаточная копия требований (d-dev-6).

1. Назначение и границы

В границах модуля:

  • класс MetricsEngine (Server.WatchBody.Core, каталог Metrics\): расчёт метрик одной тренировки атлета по его данным и запись в workout_metrics (upsert — пересчёт разрешён);
  • вызов из m02: после успешного коммита пакета sync MetricsEngine пересчитывает затронутые тренировки (Ф-12.1 «после каждой синхронизированной тренировки»); сбой расчёта не откатывает sync (метрики — производные данные, пересчитываются повторно);
  • пороги красных флагов — из конфигурации Safety.* сервера (Р3-А; умолчания — документ метрик, Ф-13.5);
  • тесты сервиса (интеграционные, docker watchbody-pg).

Вне границ модуля: правила прогрессии/делоада и создание draft-версий (m05 — читает workout_metrics и workout_set); парсинг .fit (m06 — кладёт факты в workout.facts_json/avg_hr/ hr_recovery_s до расчёта); отображение метрик (телефон m09/m10, AdminWeb m08 — читают workout_metrics_select); расчёт adherence «за период» и еженедельные сводки (п. 2.5 документа метрик, не названные в v1) — по потребности m05/m08; перерывы auto по пропускам (Ф-14.1 — отдельная логика, не метрика).

2. Состав метрик (контракт документа метрик, v1)

Поле workout_metrics Расчёт (детерминированно)
adherence % подходов «по плану» (workout_set.in_plan) от планового числа подходов сессии в активной версии программы (body, схема дизайна LLM-планирования разд. 2); план/сессию не удалось сопоставить → % in_plan среди подходов тренировки
tonnage Σ (weight_kg × reps) по всем подходам с weight>0, reps>0
tonnage_by_group тот же Σ по группам упражнений (exercise.group), код группы → кг
e1pm_by_exercise формула Эпли (ОВ-7): w × (1 + reps/30) по лучшему (максимальному весу) подходу каждого упражнения
hr_metrics из workout.facts_json (.fit, если уже импортирован): средний/пиковый пульс, отдых между подходами; нет фактов → {avg_hr, hr_recovery_s} из workout (то, что прислал телефон/.fit-импорт)
red_flags сработавшие красные флаги (см. разд. 3)

3. Красные флаги (v1 — документ метрик, правила 1, 6; Ф-12.5)

Флаг Условие Источник данных
bp_over_150_90 АД дня тренировки > 150/90 (пороги Safety.BpCancelSys/Dias) daily_log дня тренировки
bp_elevated АД в коридоре 140–150/90–95 daily_log дня тренировки
hr_resting_up пульс покоя ≥ базового +8 уд/мин (Safety.HrRestingRise) 2 дня подряд daily_log (тренд за 2 дня до дня тренировки; базовый = среднее за предыдущие 14 дней, при <3 значениях базового флаг не ставится)
wellbeing_low самочувствие ≤ 2 (Safety.WellbeingLow) 2 дня подряд daily_log
cancel_recommendation hr_resting_up/wellbeing_low держится 3+ дня → предложение отмены и совет к врачу daily_log
knee_pain_repeat боль в колене ≥ 1 (Safety.KneePainMin) в двух занятиях подряд (сеты группы «ноги») workout_set.knee_pain предыдущей и текущей тренировки

Флаги — накопленный список фактов сработавших условий с датами; значения порогов в red_flags не дублируются. 🛡 Пороги — только из конфигурации, в коде не хардкодятся (Р3-А).

4. Инварианты (🛡 — нарушать запрещено)

  1. Изоляция атлета — расчёт только по данным одного athleteId; все входные выборки — по нему (репозитории m01).
  2. Метрики — производные данные — upsert разрешён всегда (пересчёт); sync атлета не может «сломать» метрики другого.
  3. Без побочных эффектов на план — MetricsEngine ничего не пишет в workout/workout_set/program_version (это m05); только workout_metrics.
  4. Сбой расчёта не ломает sync — исключение расчёта метрик логируется, пакет sync остаётся принятым.
  5. Детерминированность — тот же вход → тот же выход; никакого LLM.

5. Критерии приёмки модуля

  1. После sync тренировки с подходами workout_metrics заполнен: adherence/tonnage/tonnage_by_group/e1pm (Эпли проверяется вручную посчитанным значением)/hr_metrics.
  2. Повторный расчёт (повторный sync того же пакета) не создаёт вторую строку (upsert 1:1).
  3. Красные флаги: сценарии АД>150/90, пульс покоя +8 два дня, самочувствие ≤2, колено ≥1 два занятия — флаги ставятся; чистые данные — red_flags пустой.
  4. Изоляция: расчёт атлета А не видит данные атлета Б.
  5. Сбой расчёта метрик не мешает принятию пакета sync.
  6. Тесты интеграционные против docker watchbody-pg — зелёные; сборка решения без ошибок.