51 lines
3.7 KiB
Markdown
51 lines
3.7 KiB
Markdown
# Спецификация: 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` |
|