72 lines
5.5 KiB
Markdown
72 lines
5.5 KiB
Markdown
# m09-phone-core — план работ (d-dev)
|
||
|
||
> Модуль: Phone.WatchBody — ядро телефона (Room LocalDb, WorkoutCore,
|
||
> SyncQueue, ApiClient); UI — m10.
|
||
> Алгоритм: `std1\_rules\d\d-dev.md`. Требования:
|
||
> [module_reqs.md](module_reqs.md).
|
||
> Зависимости: m02 (REST sync-контракт, DONE), m03/m04/m05 (серверные
|
||
> вычисления — телефон только пишет/читает).
|
||
|
||
| Шаг | Что делаем | Статус |
|
||
|---|---|---|
|
||
| 0 | Модульные документы: module_reqs.md / readme.md / SKILL.md | ✅ 2026-10-19 |
|
||
| 1 | Список единиц (классы/методы/конфиг/тесты) | ✅ 2026-10-19 |
|
||
| 1.3 | **Пользователь!** утверждение списка (+ решение по SDK) | ✅ 2026-10-19 |
|
||
| 2 | Спецификации: api_specs (LocalDb-схема, WorkoutCore, SyncQueue, контракт) | ✅ 2026-10-19 |
|
||
| 2.4 | **Пользователь!** утверждение спецификаций | ✅ 2026-10-19 |
|
||
| 3 | Реализация + тесты | ✅ 2026-10-19 |
|
||
| 3.4 | **Пользователь!** утверждение реализации (закрытие модуля) | ✅ 2026-10-19 |
|
||
| 4 | Завершение: план, примечания | ✅ 2026-10-19 |
|
||
|
||
Статусы: ⬜ не начат · 🔄 в работе · ✅ готов.
|
||
|
||
## Примечания по ходу работ
|
||
|
||
1. **Toolchain** (установлен агентом 2026-10-19 в `C:\tools`): JDK 21
|
||
(Temurin), Android SDK (platforms;android-36, build-tools 36.0.0),
|
||
Gradle — wrapper 8.11.1 в проекте. Сборка:
|
||
`JAVA_HOME`/`ANDROID_HOME` + `./gradlew :app:assembleDebug
|
||
:app:testDebugUnitTest`. Итог: BUILD SUCCESSFUL, APK 4,2 МБ,
|
||
unit-тесты **18/18** (CoreLogicTest 10 + SyncPayloadTest 8).
|
||
2. **local.properties**: `sdk.dir` — только прямые слэши
|
||
(`C:/tools/android-sdk`); экранированные бэкслэши дают IOException
|
||
«Синтаксическая ошибка в имени файла» в SdkLocator (Windows).
|
||
3. **Room**: snake_case-имена колонок — через `@ColumnInfo`
|
||
(31 аннотация, включая PK `sync_pending.client_guid`); Kotlin-поля
|
||
camelCase, индексы/FK ссылаются на snake_case.
|
||
4. **Errata контракта (смок 2026-10-19 против живого сервера,
|
||
порт 5000, тест-ключ test-key-ivan-0001)**: сервер требует
|
||
`client_guid`-UUID у ВСЕХ сущностей — daily_log («2026-10-19») и
|
||
profile («profile») отвергнуты («client_guid отсутствует или не
|
||
uuid»). Фикс: стабильные `guid`-колонки daily_log/profile
|
||
(WorkoutCore хранит существующий guid при правках, в конверт идёт
|
||
он); specs 01/04 синхронизированы, фикстуры тестов обновлены.
|
||
5. **Смок итог**: пакет 5 сущностей (exercise/workout/workout_set/
|
||
daily_log/break manual) → `accepted` все 5; повтор того же пакета —
|
||
идемпотентен (workout_set — 1 строка, daily_log — upsert по дате с
|
||
заменой id на guid); все строки проверены в docker-БД `watchbody-pg`
|
||
(метрики workout посчитаны: тоннаж 640). Попутно: `break.kind` —
|
||
только illness/vacation/workload/injury/other («rest» отклонён
|
||
400); `break.ended_on` сервер не разбирает — локальное закрытие
|
||
перерыва в v1 не синхронизируется (возврат выводит серверный
|
||
BreakEngine), кандидат v2 (spec 04).
|
||
6. **Расширение модулем m10** (решение гейта 1.3 m10, утверждено
|
||
2026-10-19): `AppSettings`/`SettingsRepository` дополняются ключами
|
||
`hrMaxBpm` (Hr.MaxBpm) и `hrStrengthMax` (Safety.HrStrengthMax) —
|
||
оба из tech-req 4.1, в m09 не были заведены; в `SyncWorker`
|
||
добавляется `scheduleNow(context)` (немедленная отправка без
|
||
ограничения Wi-Fi — кнопка «Синхронизировать сейчас»; уникальное
|
||
имя work и ретраи не меняются). Поведение ядра m09 не меняется.
|
||
По ходу шага 3 m10 добавлены: DAO-чтения для UI
|
||
(`activeWorkoutFlow`/`setsFlow`/`lastSetForExercise`/
|
||
`exercisesFlow`/`activeProgramFlow`/`versions`/`dailyLogFlow`/
|
||
`profileFlow`/`countFlow` — чтение напрямую UI разрешено, писатель
|
||
один); `logSet` — параметр `source` (форма m10 = `edit`, было
|
||
зашито `voice`); `renameExercise(id, newName)` (🛡 UUID не меняется,
|
||
Ф-4.3); **errata контракта** — `PayloadFactory.programVersion`
|
||
переписана под m02 spec 03: поля программы на верхнем уровне data
|
||
(вложенного `body` нет) + обязательное числовое `version`
|
||
(значение считает БД); зафиксировано `profile.sex ∈ m|f` (валидатор
|
||
m02). Живой смок m10 подтвердил оба исправления (accepted +
|
||
GET active с `weeks` на верхнем уровне).
|