4.3 KiB
4.3 KiB
Спецификация 04: перерывы — BreakEngine (Ф-14, документ перерывов 3.1–3.3)
1. Сигнатуры
public bool DetectBreak(int athleteId, DateOnly today); // true — break открыт
public ProgramVersion? CloseOnReturn(int athleteId, Guid workoutId, DateOnly today);
(today — явный параметр для тестируемости; sync передаёт текущую
дату UTC. CloseOnReturn сам читает тренировку по id — в sync есть
только идентификатор.)
Вызов из sync (spec 05): DetectBreak — до записи пакета не нужен;
вызывается после коммита пакета вместе с правилами. CloseOnReturn —
когда пакет содержит workout (первая сессия после break).
2. DetectBreak — авто-детект (Ф-14.1)
- Открытый break есть (
BreakRepository.Select,ended_on = NULL, последний поstarted_on) → false. - Активной версии нет → false.
- Окно
[today − MissDaysForBreak + 1 .. today](умолчание 4 дня). Плановые дни недели в окне — поbody.weeks[].sessions[].day(v1 все недели одинаковы). День плановый и по нему нет тренировки (workoutс датойstarted_at::date= день) — пропуск. - Пропущены все плановые дни окна →
BreakRepository.Insert(source=auto, kind=NULL, started_on = первый пропущенный день, note «авто: пропущены все сессии за N дней»). → true. - Есть хотя бы одна тренировка в окне → false.
Атлет может объявить break заранее — телефон вставляет
source=manual (m09); авто-детект видит открытый manual и не дублирует.
3. CloseOnReturn — закрытие и формула возврата (Ф-14.3–14.5, правило 17)
Первый workout в пакете при открытом break:
break_update:ended_on= дата тренировки (kind/note не трогаем — ответ атлета придёт отдельным каналом, m08/m09).- Длительность простоя
days = ended_on − started_on; коэффициент по таблице документа перерывов (разд. 3.2), фактор зажат конфигом[ReturnMinFactor; ReturnMaxFactor]:
| Простой | Коэффициент | Режим |
|---|---|---|
| kind=illness (любой длительности) | 0.6 (нижняя граница) | перезапуск, rationale «болезнь» |
| 4–6 дней | 1.0 (веса без снижения) | первая сессия: подходы −1, target_rpe 5 |
| 7–13 | 0.9 | возврат 1–2 недели |
| 14–27 | 0.85 | 1 вводная неделя |
| 28–59 | 0.75 | 2 вводные недели |
| 60+ | ReturnMinFactor (0.6) | перезапуск цикла |
- Draft-версия возврата (одна на break; повторный вызов того же
break — дедупликация по rules-draft на активную версию, как в
spec 02/03): deep-copy body, week 1:
- веса
× коэффициент, округление к 0.5 кг; весnullне трогаем; session_kind:days < 14→"return",days ≥ 14→"test"(правило 17), для illness →"return";- simple 4–6 дней: подходы
−1(мин 1),target_rpe= 5; cardio_after_minне меняется (кардио возвращается со 100 %, Аттия);- rationale — «возврат после break N дней (тип T): веса ×K».
- веса
SessionKinds(domain Workout) — константы normal/return/deload/test; в body week 1 sessions пишется"session_kind"; телефон при старте тренировки проставитworkout.session_kindиз активной версии.
🛡 Версии неизменяемы; активация — только человеком (Ф-14.4).