128 lines
11 KiB
Markdown
128 lines
11 KiB
Markdown
# Hermes Hub — редизайн по утверждённому макету B5
|
||
|
||
Дата: 2026-08-21
|
||
|
||
Ветка: `codex/mockup-redesign`
|
||
|
||
BASE_SHA: `69cbefcab6d566929d99b7ad7dc1b6b9824bfb2b` (`origin/main`, обновлён перед финальной интеграцией)
|
||
|
||
FINAL_SHA: `git rev-parse codex/mockup-redesign` в момент handoff. Точный SHA указан в итоговом сообщении, поскольку commit не может содержать собственный SHA.
|
||
|
||
## Реализовано
|
||
|
||
- Один утверждённый layout для трёх схем: `dark`, `hybrid`, `light`.
|
||
- Все палитры находятся в `theme.py`, имеют одинаковый набор токенов и меняют всё окно после сохранения настройки.
|
||
- Выбор темы сохраняется в `hub_settings.json`; приложение применяет его при следующем запуске.
|
||
- Общий каркас соответствует макету: брендовая левая панель, прокручиваемая навигация, пользователь и версия снизу, глобальная верхняя строка с состоянием, `Ctrl + K`, добавлением аккаунта и служебными действиями.
|
||
- Dashboard: пять компактных KPI, провайдеры → оркестратор → роли, правая панель состояния, реальные события снизу.
|
||
- Второй визуальный проход заменил прямоугольный центр круглым брендированным оркестратором, добавил плавные связи со стрелками и реальными подписями, provider logos, quota-bars, sparklines и табличную ленту событий.
|
||
- Подключён утверждённый пользователем `logo_approved.png`; боковое меню и кнопки header используют единый рисуемый контурный набор иконок вместо разнородных Unicode-глифов.
|
||
- После обновления контракта подключены реальные доли/число вызовов и P50 по провайдерам, вызовы по ролям, active calls и локальные CPU/RAM/disk/network.
|
||
- Добавлены отдельные вкладки «Квоты и лимиты» и «Аналитика» на данных `HubSnapshot`/`TelemetryService`.
|
||
- Журнал получает реальные события через action layer приложения, поддерживает поиск и фильтр уровня.
|
||
- На «Аккаунты» возвращены `test`, `set_main`, `set_orchestrator`, `assign_role`; механический и фактический UI-тесты проверяют все четыре триггера.
|
||
- Сохранена keyed-дельта карточек и квотных корзин.
|
||
- Цветовые литералы вне `theme.py` удалены; отдельный тест запрещает их повторное появление.
|
||
|
||
## Изменённые файлы
|
||
|
||
- `src/antigravity_provider/router/hermes_hub_app.py`
|
||
- `src/antigravity_provider/router/ui/theme.py`
|
||
- `src/antigravity_provider/router/ui/components.py`
|
||
- `src/antigravity_provider/router/ui/assets.py`
|
||
- `src/antigravity_provider/router/ui/add_account_wizard.py`
|
||
- `assets/branding/logo/logo_approved.png`
|
||
- `src/antigravity_provider/router/ui/views/dashboard_view.py`
|
||
- `src/antigravity_provider/router/ui/views/logs_view.py`
|
||
- `src/antigravity_provider/router/ui/views/settings_view.py`
|
||
- `src/antigravity_provider/router/ui/views/team_view.py`
|
||
- `src/antigravity_provider/router/ui/views/analytics_view.py`
|
||
- `src/antigravity_provider/router/ui/views/quotas_view.py`
|
||
- `tests/test_ui_mockup_redesign.py`
|
||
- `tests/test_ui_screenshot_harness.py`
|
||
- `artifacts/mockup-redesign/*.png`
|
||
- `CODEX_MOCKUP_REDESIGN_REPORT.md`
|
||
|
||
Backend/state/adapters, installer, scripts, config, legacy и чужие тесты не изменялись.
|
||
|
||
## Проверка размеров и scaling
|
||
|
||
Проверены `1280×720`, `1366×768`, `1920×1080`. На наименьшем размере дополнительно проверены 100%, 125% и 150% widget scaling. Правая граница поиска и кнопки добавления оставалась внутри верхней строки:
|
||
|
||
```text
|
||
scale 1.00: search_right=539, add_right=1074, header_width=1090
|
||
scale 1.25: search_right=661, add_right=1023, header_width=1043
|
||
scale 1.50: search_right=781, add_right=971, header_width=995
|
||
```
|
||
|
||
Навигация помещена в прокручиваемую область, поэтому нижние разделы доступны при 150%.
|
||
|
||
## Скриншоты — все вкладки и темы
|
||
|
||
| Вкладка | Тёмная | Гибрид | Светлая |
|
||
|---|---|---|---|
|
||
| Обзор | [dark](artifacts/mockup-redesign/overview-dark.png) | [hybrid](artifacts/mockup-redesign/overview-hybrid.png) | [light](artifacts/mockup-redesign/overview-light.png) |
|
||
| Команда | [dark](artifacts/mockup-redesign/team-dark.png) | [hybrid](artifacts/mockup-redesign/team-hybrid.png) | [light](artifacts/mockup-redesign/team-light.png) |
|
||
| Аккаунты | [dark](artifacts/mockup-redesign/accounts-dark.png) | [hybrid](artifacts/mockup-redesign/accounts-hybrid.png) | [light](artifacts/mockup-redesign/accounts-light.png) |
|
||
| Маршрутизация | [dark](artifacts/mockup-redesign/routing-dark.png) | [hybrid](artifacts/mockup-redesign/routing-hybrid.png) | [light](artifacts/mockup-redesign/routing-light.png) |
|
||
| Провайдеры | [dark](artifacts/mockup-redesign/providers-dark.png) | [hybrid](artifacts/mockup-redesign/providers-hybrid.png) | [light](artifacts/mockup-redesign/providers-light.png) |
|
||
| Квоты | [dark](artifacts/mockup-redesign/quotas-dark.png) | [hybrid](artifacts/mockup-redesign/quotas-hybrid.png) | [light](artifacts/mockup-redesign/quotas-light.png) |
|
||
| Аналитика | [dark](artifacts/mockup-redesign/analytics-dark.png) | [hybrid](artifacts/mockup-redesign/analytics-hybrid.png) | [light](artifacts/mockup-redesign/analytics-light.png) |
|
||
| Состояние | [dark](artifacts/mockup-redesign/health-dark.png) | [hybrid](artifacts/mockup-redesign/health-hybrid.png) | [light](artifacts/mockup-redesign/health-light.png) |
|
||
| Журнал | [dark](artifacts/mockup-redesign/logs-dark.png) | [hybrid](artifacts/mockup-redesign/logs-hybrid.png) | [light](artifacts/mockup-redesign/logs-light.png) |
|
||
| Настройки | [dark](artifacts/mockup-redesign/settings-dark.png) | [hybrid](artifacts/mockup-redesign/settings-hybrid.png) | [light](artifacts/mockup-redesign/settings-light.png) |
|
||
| О программе | [dark](artifacts/mockup-redesign/about-dark.png) | [hybrid](artifacts/mockup-redesign/about-hybrid.png) | [light](artifacts/mockup-redesign/about-light.png) |
|
||
|
||
## Расхождения с макетом
|
||
|
||
| Элемент макета | Реализация и причина |
|
||
|---|---|
|
||
| «Квота сегодня 78%» | Показано `Н/Д`, пока нет хотя бы одной реально измеренной корзины. Baseline `None` не превращается в процент. |
|
||
| «Активные задачи 24» | Заменено на реальные вызовы роутера из telemetry. Подсистемы задач/очередей нет. |
|
||
| «Окно обслуживания 09:00–21:00» | Заменено количеством реальных failover-переключений. Понятия окна обслуживания нет. |
|
||
| Доли провайдеров 45/35/20% и 128/74/56 запросов по ролям | Показываются только из реального `metrics.telemetry.by_provider/by_role`; без вызовов отображаются online/`Н/Д`, а не цифры макета. |
|
||
| Латентность каждого провайдера | Показывается реальный P50 из `by_provider`; без измерений значение скрыто. |
|
||
| CPU, память, диск, сеть | Показываются реальные локальные измерения `psutil`; при недоступном `psutil` — `Н/Д`. |
|
||
| Очереди задач | Блок исключён: подсистемы очередей в продукте нет. |
|
||
| Раздел «Инциденты» | Не создан: вместо него используется реальный журнал с фильтром ошибок. |
|
||
| Кривые соединения | Реализованы адаптивные сглаженные линии со стрелками и подписями реальной доли/числа вызовов; при отсутствии telemetry показывается `Н/Д`. |
|
||
| Версия `2.8.1` на макете | Показывается реальная версия пакета `0.1.1`. |
|
||
|
||
## Проверки
|
||
|
||
### Headless без UI-зависимостей
|
||
|
||
```powershell
|
||
uv run --isolated --no-project --with pytest --with pyyaml --with pydantic --with requests --with httpx --with psutil python -m pytest -q
|
||
```
|
||
|
||
Результат: `193 passed, 26 skipped, 3 deselected in 14.32s`.
|
||
|
||
### UI-enabled
|
||
|
||
Из-за известной повторной инициализации Tcl/Tk набор выполнен в трёх свежих процессах:
|
||
|
||
```powershell
|
||
uv run --extra dev python -m pytest -q --ignore=tests/test_ui_phase2_6.py --deselect=tests/test_oauth_lifecycle.py::test_f_copy_before_open_browser
|
||
uv run --extra dev python -m pytest -q tests/test_ui_phase2_6.py
|
||
uv run --extra dev python -m pytest -q tests/test_oauth_lifecycle.py::test_f_copy_before_open_browser
|
||
```
|
||
|
||
Результаты: `244 passed, 2 skipped, 4 deselected`; `4 passed`; `1 passed`. Итог уникального набора: `249 passed, 2 skipped, 3 deselected`, ошибок нет.
|
||
|
||
### Статика и release gate
|
||
|
||
```powershell
|
||
uv run ruff check .
|
||
uv run --extra dev python scripts/release_gate.py
|
||
```
|
||
|
||
Результат: Ruff — `All checks passed!`; release gate — `PASSED`, публичный package и hash подтверждены.
|
||
|
||
## Backend gaps
|
||
|
||
1. Внешние provider RPS/SLA, task queues и maintenance windows отсутствуют в продукте; UI их не синтезирует.
|
||
2. Baseline-квоты остаются `None`; реальное число появляется только из provider claim/runtime event.
|
||
3. `HubSnapshot` не содержит журнал событий; app action layer передаёт в views безопасные presentation-объекты из `EventLogService`, сами views backend не читают.
|
||
4. Network contract содержит накопительные bytes с момента загрузки ОС, а не мгновенную скорость; UI показывает объём, не выдуманный Мбит/с.
|
||
5. Тег `v0.1.1`, release и manifest не создавались и не изменялись.
|