63 lines
4.3 KiB
Markdown
63 lines
4.3 KiB
Markdown
# Спецификация 01: каркас приложения (shell)
|
||
|
||
Источники: архитектура 1.2 (TrainingUi), Ф-3.6, Ф-7.3/7.5,
|
||
tech-req 4.1/6, ui-ux разд. 3. Единица 1 (каркас) + баннеры (10).
|
||
|
||
## 1. Каркас
|
||
|
||
- `WatchBodyApp` (Application) — ручной DI-контейнер (без Hilt в v1):
|
||
`AppDatabase` (m09 build), `WorkoutCore`, `SettingsRepository`,
|
||
ленивый `ApiClient` (создаётся по актуальным настройкам);
|
||
- `MainActivity` — единственная activity; `WatchBodyTheme` — тёмная
|
||
colorScheme Material 3, типографика ≥ 16 sp;
|
||
- нижняя навигация `NavigationBar` — 5 вкладок: Сегодня / Тренировка
|
||
/ История / Программы / Профиль; состояние — один `NavController`
|
||
(compose-navigation), вкладки — `popUpTo(start) saveState/restore`;
|
||
- «Библиотека» и «Настройки» — экраны-переходы (иконки в appbar
|
||
«Сегодня» и «Профиля»); системный Back — к вкладке.
|
||
|
||
## 2. Первый запуск
|
||
|
||
Если `baseUrl` или `apiKey` пусты — поверх вкладок показывается
|
||
экран «Настройки» (без него остальное неактивно); после сохранения
|
||
валидных значений — возврат на «Сегодня». Повторно гейт не срабатывает.
|
||
|
||
## 3. Баннеры синхронизации (Ф-7.3/7.5)
|
||
|
||
Источник состояния: `WorkManager.getWorkInfosForUniqueWorkFlow("sync")`
|
||
+ `SyncDao.count()` (Flow). Правила отображения (верх экрана, тихий
|
||
цветовой код + текст — цвет дублируется текстом 🛡):
|
||
|
||
| Состояние | Баннер |
|
||
|---|---|
|
||
| очередь > 0, work нет/не RUNNING | «В очереди на отправку: N» |
|
||
| work RUNNING | «Синхронизация…» |
|
||
| SUCCEEDED и очередь стала 0 | «Данные успешно синхронизированы» (скрывается через ~5 с, показ однократно на смену состояния) |
|
||
| FAILED флаг `authError` (401) | «Ключ API неверен — проверьте настройки» (постоянно до успешной синхронизации) |
|
||
| FAILED флаг `conflict` (409) | «Конфликт версии программы — обратитесь к владельцу» |
|
||
| FAILED прочее (ретрай/сеть) | «Синхронизация временно недоступна — повторим автоматически» |
|
||
|
||
Индикатор сети в статус-строке тренировки: `ConnectivityManager`
|
||
(онлайн/офлайн) — информационный, ничего не блокирует (офлайн-first).
|
||
|
||
## 4. Расписание отправки
|
||
|
||
- после каждого действия пользователя через `WorkoutCore`
|
||
(дневник/подход/старт/финиш/профиль/упражнение/перерыв) —
|
||
`SyncWorker.schedule(context, wifiOnly)` (m09, unique KEEP —
|
||
повторные вызовы не плодят работы);
|
||
- кнопка «Синхронизировать сейчас» (Настройки) — новый
|
||
`SyncWorker.scheduleNow(context)`: те же worker/имя/ретраи,
|
||
ограничение только CONNECTED (явное действие — Wi-Fi-ограничение
|
||
не применяется; расширение m09, readme m09 п. 6).
|
||
|
||
## 5. Правила
|
||
|
||
- 🛡 UI не обращается к DAO/Api напрямую — только `WorkoutCore`,
|
||
`SettingsRepository`, DAO-чтения (Flow) для списков истории/
|
||
очереди (чтение напрямую разрешено — единственный писатель
|
||
WorkoutCore, m09);
|
||
- ViewModels — `ViewModel` + viewModelFactory из контейнера;
|
||
состояние экранов — `StateFlow`;
|
||
- строковые ресурсы — ru (локализация одного языка в v1).
|