VEU.WathBody/1-docs/4-modules/m08-admin-web/module_reqs.md

86 lines
6.5 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.

# Требования к модулю: m08-admin-web
> Модуль — административная консоль владельца (Ф-9, решение владельца
> 2026-10-17): бэкенд — admin REST API `/api/admin/*` в
> `Server.WatchBody.Web`; UI — Flutter Web-приложение
> `3-app\3-web\admin-web` (SDK 3.47.7 — `C:\tools\flutter`), сборка
> отдаётся сервером из `wwwroot\admin\`. Аутентификация владельца —
> логин/пароль (`Admin.Login` / `Admin.PasswordHash`, PBKDF2) →
> Bearer-токен сессии; атлеты к консоли доступа не имеют (🛡
> изменение vision 1.2). Самодостаточная копия требований (d-dev-6).
## 1. Назначение и границы
**В границах модуля (backend REST):**
- аутентификация: `POST /api/admin/login` (логин+пароль →
`pbkdf2$...`-проверка → Bearer-токен, in-memory сессия, TTL 8 ч);
все `/api/admin/*` кроме login — только с валидным токеном (401);
- атлеты (Ф-9.1): список; создание (имя → сервер генерирует API-ключ,
возвращается один раз, в БД — только хэш); смена ключа; блокировка/
разблокировка (заблокированный ключ → 401 на API телефонов);
- тренировки (Ф-9.2): таблица по всем атлетам (фильтр атлет/дата,
пагинация); карточка (подходы, план/факт, `facts_json`: таймлайн
Lap + пульс Record, средний/пиковый пульс подхода, отдых);
CSV-выгрузка текущей выборки (КУ-4, формат tech-req 2.4: `;`,
UTF-8 BOM, `athlete;date;duration_min;avg_hr;sets;exercises;
adherence_pct`);
- программы (Ф-9.3): версии атлета (статусы/автор/даты/body);
активация draft (ProgramStore.Activate); применение предложения
правил из консоли — новая версия `author=admin` с телом rules-draft,
затем активация (🛡 неизменяемость версений, Ф-9.3);
- метрики (Ф-9.4): выборка `workout_metrics` атлета за период;
- планы тренировок (Ф-9.5): сводка план/факт по неделям активной
версии (запланировано сессий / выполнено / пропущено; доля);
- отдача статики Flutter-сборки `wwwroot\admin\` (если каталог есть) —
UI хостится тем же Kestrel.
**Вне границ модуля:** Flutter Web UI `3-app\3-web\admin-web`
(отдельный этап — требует Flutter SDK, решение гейта 1.3), редактор
body версий (v1: просмотр + активация; правка — телефон m09/импорт
m06), LLM-контур (v2), выгрузка АД-журнала CSV (v3).
## 2. Сессии и токены
- пароль проверяется по `Admin.PasswordHash` (PBKDF2 100k, соль в
хэше, префикс `pbkdf2$`; формат — `<login>-salt` || PBKDF2-SHA256);
несовпадение → 401 без указания, что именно неверно;
- токен: 256-bit random (base64url), in-memory словарь
`token → (expiresAt)`; перезапуск сервера — сессии сбрасываются
(владелец входит заново); TTL 8 ч; logout — удаление из словаря;
- 🛡 токены/пароли в логи не пишутся; `Admin.PasswordHash` не
возвращается никаким эндпоинтом.
## 3. Инварианты (🛡 — нарушять запрещено)
1. **Только владелец** — `/api/admin/*` недоступен атлетам: их
`X-Api-Key` не принимается, изолированный контур (`/api/v1/*`
не меняется).
2. **Тайны** — API-ключ атлета возвращается только при создании/смене;
хэши, пароли, токены — не возвращаются и не логируются.
3. **Запись только управляющая** — admin API не пишет факт-данные
(тренировки/подходы/метрики): только атлеты (create/block/key),
статусы версий программ и author=admin-копии предложений.
4. **Неизменяемость версий** — активация через ProgramStore;
author=admin-копия создаётся CreateDraft, оригинал rules-draft
не меняется.
5. **Формат CSV** — точно tech-req 2.4 (разделитель `;`, UTF-8 BOM).
## 4. Критерии приёмки модуля
1. Логин: верный пароль → токен (последующие запросы с Bearer — 200);
неверный → 401; без токена/с токеном атлета (X-Api-Key) → 401.
2. Атлеты: создание возвращает ключ (в БД только хэш, повторный
запрос ключ не отдаёт); смена ключа; блокировка → sync телефона
с тем ключом получает 401; разблокировка → снова 200.
3. Тренировки: список всех атлетов с фильтрами/пагинацией; карточка
с подходами и план/факт; CSV выборки соответствует формату.
4. Программы: версии атлета; активация draft меняет active (прежняя —
archived); применение rules-предложения → активна версия
author=admin с телом предложения.
5. Метрики и план/факт: выборка метрик за период; сводка недель
(запланировано/выполнено/пропущено) сходится с фактическими
тренировками.
6. Тесты интеграционные против docker `watchbody-pg` — зелёные;
сборка решения без ошибок.