2.4 KiB
2.4 KiB
Спецификация 03: тренировки и CSV (AdminWorkoutsController)
Источники: Ф-9.2, tech-req 2.4 (CSV), m04 (workout_metrics), m06 (facts_json workout-facts/1).
1. Список
GET /api/admin/workouts?athleteId&dateFrom&dateTo&limit&offset
(Bearer) → {"total":N,"items":[карточки]}; карточка:
workoutId, athleteId, athleteName, startedAt, endedAt, durationMin, status, sessionKind, avgHr, setsCount, exercisesCount, adherence
(adherence — из workout_metrics; нет строки → null). Все атлеты;
athleteId опционален; limit ≤ 100 (default 50), offset ≥ 0.
2. Карточка
GET /api/admin/workouts/{id} → карточка списка +:
sets[]: seq, exerciseName, weightKg, reps, inPlan, rpe, kneePain (из workout_select-агрегата m01; имя — по exercise_id из библиотеки атлета);planFact: по каждому упражнению — план (активная версия: вес × повторы по сетам дня недели) против факта (подходы); план дня не сопоставился → только факт (как в m04 adherence fallback);timeline[]: изfacts_json.laps[]+records[]— по каждому подходу:startOffsetS, durationS, avgHr, peakHr, restAfterS(отдых = старт следующего lap − конец этого);hrCurve[]:[{t,hr}]из records (прореживание: не более 600 точек, шагduration/600). facts_json нет →timeline/hrCurveпустые.
3. CSV (КУ-4)
GET /api/admin/workouts.csv?athleteId&dateFrom&dateTo — та же
выборка (без пагинации, лимит 10 000):
- разделитель
;, UTF-8 c BOM, заголовок:athlete;date;duration_min;avg_hr;sets;exercises;adherence_pct; - строка — тренировка: имя атлета; дата YYYY-MM-DD; длительность (мин, из ended−started; нет — пустая ячейка); avg_hr; число подходов; число упражнений; adherence (нет — пустая);
Content-Type: text/csv; charset=utf-8,Content-Disposition: attachment; filename="workouts.csv".
4. Ошибки
401 без токена; 404 чужой/несуществующий id. 🛡3: только чтение.