57 lines
4.2 KiB
Markdown
57 lines
4.2 KiB
Markdown
# Спецификация: красные флаги (red_flags)
|
||
|
||
> v1 — документ метрик, правила 1 и 6; пороги — `MetricsConfig`
|
||
> ([01-metrics-config.md](01-metrics-config.md)). Выход — массив
|
||
> объектов в `workout_metrics.red_flags` (jsonb).
|
||
|
||
## 1. Формат
|
||
|
||
```json
|
||
"red_flags": [
|
||
{"flag": "bp_over_150_90", "date": "2026-10-17"},
|
||
{"flag": "hr_resting_up", "dates": ["2026-10-16", "2026-10-17"]}
|
||
]
|
||
```
|
||
|
||
Поле `date(s)` — даты, на которых условие выполнено; пороги в
|
||
`red_flags` не дублируются. Порядок — как в таблице ниже; пусто → `[]`.
|
||
|
||
## 2. Флаги
|
||
|
||
| # | flag | Условие | Данные |
|
||
|---|---|---|---|
|
||
| 1 | `bp_over_150_90` | у дня тренировки `bp_sys > BpCancelSys` **или** `bp_dias > BpCancelDias` | `daily_log` дня тренировки (нет записи или нет АД → флага нет) |
|
||
| 2 | `bp_elevated` | не сработал #1 И `bp_sys ≥ BpElevatedSys` или `bp_dias ≥ BpElevatedDias` | там же |
|
||
| 3 | `hr_resting_up` | `hr_resting ≥ базовый + HrRestingRise` в `HrRestingDays` дней, **включая день тренировки**, подряд (без дыр по календарю: сравниваются имеющиеся значения подряд идущих дат с записями) | `daily_log` окна; базовый = среднее `hr_resting` за `HrBaselineDays` **до** первого дня серии, значений < `HrBaselineMin` → флаг не ставится |
|
||
| 4 | `wellbeing_low` | `wellbeing ≤ WellbeingLow` в `WellbeingDays` дней подряд (как #3, без базового) | `daily_log` окна |
|
||
| 5 | `cancel_recommendation` | #3 или #4 держится ≥ `LightDayCount` дней подряд | следствие #3/#4 |
|
||
| 6 | `knee_pain_repeat` | в `KneeRepeatSessions` последних занятиях подряд (текущая + предыдущая по `started_at`) есть подход группы «ноги» с `knee_pain ≥ KneePainMin` | `workout_set.knee_pain` |
|
||
|
||
Пояснения:
|
||
|
||
- «группа ноги» — код группы упражнения == `legs` (справочник групп,
|
||
m01).
|
||
- Предыдущее занятие для #6 — ближайшая по `started_at` тренировка
|
||
атлета раньше текущей (статус любой).
|
||
- #3: серия считается по фактическим записям `daily_log`: идём от дня
|
||
тренировки назад; каждая запись с условием продлевает серию, запись
|
||
с `hr_resting` без условия её рвёт, день без записи её не рвёт
|
||
(пропуск ввода не карается), но и не удлиняет.
|
||
- #5: если серия #3/#4 ≥ `LightDayCount` — добавляется один флаг
|
||
`cancel_recommendation` с общим списком дат.
|
||
- Примечания (З-42 п. 6; поведение осознанное, тесты зелёные):
|
||
(а) серия в `ConditionRun` ограничена `lightDayCount` датами —
|
||
флаги #3/#4 (порог 2 дня) и #5 (порог 3 дня) это не искажает;
|
||
(б) `knee_pain_repeat` — предыдущие тренировки строго **до дня**
|
||
текущей (`DateTo = дата − 1`): две сессии в один день не считаются
|
||
«двумя занятиями подряд».
|
||
|
||
## 3. Семантика потребителям
|
||
|
||
- m05 (правила прогрессии) и телефон: `hr_resting_up`/`wellbeing_low`
|
||
без #5 → следующая тренировка помечается лёгкой (60–70 % весов,
|
||
2 сета); с #5 → предложение отмены + совет к врачу (Ф-12.5).
|
||
- `knee_pain_repeat` → предложение замены упражнения из пары-замены
|
||
(Ф-12.5; атрибуты упражнения).
|
||
- m04 только фиксирует флаги; никаких записей в план (🛡3).
|