# Спецификация 01: LocalDb (Room) — схема Источники: архитектура 1.2 (LocalDb), 2-db src-таблицы (зеркала), tech-req SyncQueue, Р2-Б (UUID-PK генерирует телефон). ## 1. База `AppDatabase` (Room, version = 1): один атлет на устройство (athlete_id на сервер подставляет ключ — Ф-7.2). Все PK — UUID (String) кроме отмеченного. Timestamps — epoch millis (Long); даты (daily_log/breaks) — ISO `yyyy-MM-dd` (String). ## 2. Таблицы | Entity | Колонки (ключевые) | Примечание | |---|---|---| | `exercise` | id PK, name (UNIQUE), group_code, is_base, is_active | справочник атлета (Ф-4) | | `program_version` | id PK, version, status, author, based_on_version?, body JSON, rationale, created_at | локальная копия (с сервера + локальные draft) | | `workout` | id PK, program_version_id?, started_at, ended_at?, status (active/finished/cancelled), session_kind, avg_hr? | | | `workout_set` | id PK, workout_id FK→workout(cascade), exercise_id?, seq, weight_kg, reps, done_at, source (voice/watch/edit), in_plan, rpe?, knee_pain? | | | `command_log` | id PK, workout_id FK, t_offset_s, recognized_text, semantics JSON, accepted | голос m11; в m09 — ручная заготовка | | `daily_log` | date PK (yyyy-MM-dd), **guid** (стабильный UUID записи), bp_sys?, bp_dias?, weight_kg?, hr_resting?, wellbeing? | день уникален (Ф-13.1); guid — client_guid для sync (errata 2026-10-19: сервер требует UUID у всех сущностей) | | `breaks` | id PK, kind?, source (manual), started_on, planned_return?, ended_on?, note | Ф-14.2 | | `profile` | singleton (id=0), **guid** (стабильный UUID записи), sex?, birth_year?, weight_kg?, hr_max? | Ф-6; guid — client_guid для sync (errata 2026-10-19) | | `sync_pending` | client_guid PK, entity, payload JSON, created_at | очередь (spec 03) | Индексы: `workout_set.workout_id`, `sync_pending.created_at`, `exercise.name`. ## 3. DAO (по одному на группу) - `WorkoutDao`: активная тренировка (status=active), upsert, список истории (finished/cancelled по убыванию started_at), подходы тренировки; - `ExerciseDao` / `ProgramDao` / `DailyLogDao` / `BreakDao` / `ProfileDao` — upsert/select; - `SyncDao`: `pending(limit)` по возрастанию created_at, `deleteAll(guids)`, `count()`. ## 4. Правила - 🛡 Пишет только `WorkoutCore` (и `SyncQueue` — свой статус); - миграции: version 1, `fallbackToDestructiveMigration` запрещён после первого релиза (сейчас допустим — до m10); - body/semantics/payload — строки JSON (kotlinx-serialization).