52 lines
3.5 KiB
Markdown
52 lines
3.5 KiB
Markdown
# m04-metrics-engine — план работ (d-dev)
|
||
|
||
> Модуль: MetricsEngine — расчёт метрик тренировки в
|
||
> `Server.WatchBody.Core` → `src.workout_metrics`.
|
||
> Алгоритм: `std1\_rules\d\d-dev.md` (итерационная разработка по
|
||
> модулям). Требования: [module_reqs.md](module_reqs.md).
|
||
> Зависимости: m01 (репозитории, DONE), m02 (sync — точка вызова, DONE),
|
||
> m03 (ProgramStore — активная версия для adherence, DONE).
|
||
|
||
| Шаг | Что делаем | Статус |
|
||
|---|---|---|
|
||
| 0 | Модульные документы: module_reqs.md / readme.md / SKILL.md | ✅ 2026-10-18 |
|
||
| 1 | Список единиц (классы/методы/конфиг/тесты) | ✅ 2026-10-18 |
|
||
| 1.3 | **Пользователь!** утверждение списка | ✅ 2026-10-18 |
|
||
| 2 | Спецификации: api_specs (контракт расчёта, пороги, флаги) | ✅ 2026-10-18 |
|
||
| 2.4 | **Пользователь!** утверждение спецификаций | ✅ 2026-10-18 |
|
||
| 3 | Реализация + тесты | ✅ 2026-10-18 (тесты Web 61/61 + Core 55/55 на момент закрытия модуля; после З-35 — 56/56) |
|
||
| 3.4 | **Пользователь!** утверждение реализации (закрытие модуля) | ✅ 2026-10-18 |
|
||
| 4 | Завершение: план, примечания | ✅ 2026-10-18 — **Модуль завершён** (2026-10-18). Следующий по плану этапа 7 — m05-progression-rules (итерация 2). |
|
||
|
||
Статусы: ⬜ не начат · 🔄 в работе · ✅ готов.
|
||
|
||
## Примечания по ходу работ
|
||
|
||
Errata m01 (найдено тестами m04, исправлено):
|
||
|
||
1. **`DailyLogRepository`** (и break-часть файла): Npgsql возвращает
|
||
колонки `date` как `DateOnly`, а не `DateTime` — каст через
|
||
`Convert<DateTime>` падал `InvalidCastException`. Заменено на
|
||
`DailyLogRepository.AsDate(object)`.
|
||
2. **`WorkoutRepository.ParseSets`**: ключи агрегата `workout_select`
|
||
— snake_case (`in_plan`, `weight_kg`); без
|
||
`JsonNamingPolicy.SnakeCaseLower` поля `WorkoutSet` молча не
|
||
заполнялись (case-insensitive подчёркивания не игнорирует).
|
||
|
||
Errata m02 (интеграция метрик в sync):
|
||
|
||
3. **TransactionScope живёт до конца метода**: пересчёт метрик внутри
|
||
`using var scope` падал «TransactionScope is already complete»
|
||
(соединения пристраиваются к завершённой ambient-транзакции).
|
||
Запись пакета вынесена в `ApplyAll` — scope закрывается до
|
||
пересчёта.
|
||
4. **Kit.Helpers.Log.Logger не настроен** (`_pathLogFolder = null` →
|
||
`Path.Combine` бросает) — в `SyncService` использован стандартный
|
||
`ILogger<SyncService>`.
|
||
5. В DI добавлены `IWorkoutMetricsRepository`, `ProgramStore`,
|
||
`MetricsEngine`, `MetricsConfig` (секция `Safety` в appsettings).
|
||
|
||
Решение по порогам АД: коридоры документа метрик перекрываются
|
||
(отмена >150/**90**, «только кардио» 140–150/**90–95**) — проверка
|
||
валидации `bpElevatedDias ≤ bpCancelDias` не применяется (spec 01).
|