VEU.WathBody/1-docs/4-modules/m08-admin-web
virus-home d61499025c Этап 7, итерация 3 завершена: m08-admin-web (консоль владельца)
Backend (Server.WatchBody.Web): AdminAuthService — PBKDF2
(pbkdf2$100000$salt$hash) → in-memory Bearer-сессии TTL 8 ч
(Admin.Login пуст → консоль отключена); 6 контроллеров /api/admin/*:
login/logout; атлеты (создание — ключ wb-… возвращается один раз,
смена ключа, блокировка → 401 на /api/v1); тренировки всех атлетов
(фильтры/пагинация, карточка план/факт + таймлайн Lap/пульс +
пульсограмма ≤600 точек), CSV (;/BOM, tech-req 2.4); программы
(версии/body, активация draft, применение rules-предложения через
author=admin-копию — неизменяемость версий); метрики (+weekly
ISO-агрегат); план/факт (PlanSummaryService: недели от понедельника
создания active-версии, performed — только плановые дни).

Errata m02: ApiKeyMiddleware сужен до /api/v1/* (перехватывал статику);
Kit.Routes — роут на блок AddController (NeedHttpPost_All не чейнится).

Flutter Web UI (3-app\3-web\admin-web, SDK 3.47.7): Material 3 тёмная
тема, NavigationRail, 6 экранов, токен sessionStorage, 401 → логин,
CSV через Bearer+Blob, графики CustomPaint; без внешних pub-пакетов;
build.ps1 → wwwroot\admin (сборка в .gitignore — артефакт).

Тесты: Web 105/105 (m08 — 7), Core 56/56; flutter analyze 0
ошибок/варнингов; HTTP-смок хостинга/логина пройден. Эксплуатационные
файлы в коммит не включены.
2026-10-19 01:31:45 +05:00
..
api_specs Этап 7, итерация 3 завершена: m08-admin-web (консоль владельца) 2026-10-19 01:31:45 +05:00
SKILL.md Этап 7, итерация 3 завершена: m08-admin-web (консоль владельца) 2026-10-19 01:31:45 +05:00
module_reqs.md Этап 7, итерация 3 завершена: m08-admin-web (консоль владельца) 2026-10-19 01:31:45 +05:00
readme.md Этап 7, итерация 3 завершена: m08-admin-web (консоль владельца) 2026-10-19 01:31:45 +05:00

readme.md

m08-admin-web — план работ (d-dev)

Модуль: admin REST API /api/admin/* в Server.WatchBody.Web (бэкенд консоли владельца, Ф-9; UI — Flutter Web, отдельный этап). Алгоритм: std1\_rules\d\d-dev.md. Требования: module_reqs.md. Зависимости: m01 (репозитории, DONE), m02 (Web/маршруты/middleware, DONE), m03 (ProgramStore, DONE), m04 (workout_metrics, DONE).

Шаг Что делаем Статус
0 Модульные документы: module_reqs.md / readme.md / SKILL.md ✅ 2026-10-18
1 Список единиц (классы/методы/конфиг/тесты) ✅ 2026-10-18
1.3 Пользователь! утверждение списка ⬜
2 Спецификации: api_specs (auth, athletes, workouts+CSV, programs, metrics, plan, UI) ✅ 2026-10-19
2.4 Пользователь! утверждение спецификаций ⬜
3 Реализация + тесты ✅ 2026-10-19 (Web 105/105, из них m08 — 7; Core 56/56; flutter analyze 0 ошибок; build web → wwwrootdmin; HTTP-смок хостинга/логина пройден)
3.4 Пользователь! утверждение реализации (закрытие модуля) ✅ 2026-10-19
4 Завершение: план, примечания ✅ 2026-10-19 — Модуль завершён (2026-10-19). Итерация 3 завершена. Следующий по плану этапа 7 — m09-phone-core (итерация 4, Android).

Статусы: ⬜ не начат · 🔄 в работе · ✅ готов.

Примечания по ходу работ

  1. Kit.Helpers.Routes: NeedHttpPost_All нельзя чейнить на несколько роутов одного блока AddController (RouteFluent — дубль ключа httpMethod) — каждый admin-эндпоинт в отдельном блоке.
  2. ApiKeyMiddleware сужен до /api/v1/* (errata m02): раньше перехватывал вообще все пути — статика консоли /admin и прочее получали 401. /api/admin — Bearer-контур, /health — открыт; поведение /api/v1/* не изменилось (тесты зелёные).
  3. workout_select без «всех атлетов» — admin-список собирается обходом атлетов (v1: атлетов немного; кандидат — функция БД в v2).
  4. Request.Body в Kestrel не seekable — чтение тела один раз, без Position = 0 (иначе 500).
  5. workout_insert не пишет ended_at (errata m02/m06): тесты дозакрывают через Update.
  6. Flutter: SDK 3.47.7 (C: ools lutter, PATH в каждом вызове); без внешних pub-пакетов (только SDK) — dart:html для HTTP/Blob (deprecation-info осознанно, web-only v1); сборка 41 МБ (canvaskit) — wwwrootdmin в .gitignore (артефакт, собирается build.ps1); analyze — 0 ошибок/варнингов, 4 info (dart:html ×2, use_build_context ×2 — ложные срабатывания при guard mounted).
  7. Смоки: HTTP (curl) — статика 200, /health 200, /api/v1 без ключа 401, login 401/200, athletes/plan с Bearer — данные; браузерный прогон UI — за владельцем (чек-лист spec 06 §4).