VEU.WathBody/1-docs/4-modules/m02-rest-api/api_specs/06-dto.md

51 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Спецификация: DTO пакета sync и ответов (единица 7)
## Назначение
C#-модели запроса/ответа REST API (проект `Server.WatchBody.Web`,
каталог `Dto\`); сериализация — System.Text.Json, camelCase,
регистронезависимая десериализация. Это транспортные модели — доменные
объекты m01 (`Server.WatchBody.Core`) в API наружу не выдаются.
Примечание (З-42): корень запроса — **сырой JSON-массив** (обёртки
`SyncRequest` нет); разбор поля `data` — не strongly-typed модели, а
`SyncItemParser` над `JsonElement` (проверка обязательных полей при
разборе, лишние игнорируются, недостающие обязательные → 400).
Модели `SyncRequest`/`RecordData*` из ранней редакции спецификации
не реализованы.
## Модели
| Класс | Поля | Комментарий |
|---|---|---|
| `SyncItem` | `Guid ClientGuid`, `string Entity`, `string Op`, `JsonElement Data` | элемент массива-корня; `Data` — сырой JSON, разбирается по `Entity` (`SyncItemParser`) |
| `SyncResponse` | `List<Guid> Accepted` | `{"accepted": [...]}` |
| `ErrorResponse` | `string Error` | `{"error": "..."}` для 400/401/404/409 |
| `WorkoutListResponse` | `List<WorkoutDto> Items`, `int Total` | список тренировок |
| `WorkoutDto` | `Guid WorkoutId`, `DateTime? StartedAt/EndedAt`, `string Status`, `string SessionKind`, `int? AvgHr`, `List<WorkoutSetDto> Sets` | `sets` — из агрегата `workout_select` |
| `WorkoutSetDto` | `Guid SetId`, `Guid? ExerciseId`, `int Seq`, `decimal WeightKg`, `int Reps`, `DateTime DoneAt`, `string Source`, `bool InPlan`, `int? Rpe`, `int? KneePain` | — |
| `CommandLogDto` | `Guid Id`, `int TOffsetS`, `string RecognizedText`, `JsonElement Semantics`, `bool Accepted` | `semantics` — jsonb как есть |
| `ActiveProgramResponse` | `int ProgramId`, `Guid VersionId`, `int Version`, `int? BasedOnVersion`, `string Author`, `string Status`, `JsonElement Body`, `string? Rationale`, `DateTime CreatedAt` | `body` — jsonb как есть |
## Правила
0. `exercise` с `is_active=false` — логическое удаление через
`src.exercise_delete` (З-41(а), Ф-4.2); повторное `true` после
удаления не восстанавливает (путь восстановления — m08, v1 нет).
1. Даты: `started_at`/`ended_at`/`done_at` — UTC ISO 8601
(`DateTimeKind.Utc`); `date` (daily_log), `started_on`/
`planned_return` (break) — `DateOnly` (YYYY-MM-DD).
2. Числа с фиксированной точкой (`weight_kg`) — `decimal`.
3. Валидация диапазонов (`rpe` 1–10, `knee_pain` 0–10, `wellbeing` 1–5,
пакет ≤ 50) — до открытия транзакции; нарушение → 400.
4. Названия полей — camelCase в JSON, PascalCase в C#.
## Тесты
| # | Проверка | Ожидание |
|---|---|---|
| 1 | Десериализация конверта (все 7 `entity`) | поля заполнены, `Data` сохранён |
| 2 | Отсутствие обязательного поля (`workout` без `started_at`) | ошибка валидации → 400 |
| 3 | Сериализация ответов — camelCase, `null`-поля опущены | соответствует примерам спецификаций |
| 4 | Дата без времени (`date: "2026-10-17"`) | разбирается в `DateOnly` |