platform: modularize api/gui, add docs-tests-web foundation, and refresh root config

This commit is contained in:
beckline
2026-03-26 22:40:54 +03:00
parent 0e2d7f61ea
commit 6a56d734c2
562 changed files with 70151 additions and 16423 deletions

View File

@@ -0,0 +1,101 @@
# E4.4 Multi-Interface GUI Design (Desktop-first)
Дата: 2026-03-15
Статус: planned (design approved)
Владелец: Engineering
## 1) Ответ на ключевой вопрос
- Да, это общий мультиинтерфейсный контур на всё приложение.
- Источник истины: Go-ядро (`transport interfaces/policies/owners/owner-locks`).
- GUI/Web/Mobile только рисуют состояние и вызывают API.
## 2) Границы
- `AdGuardVPN` остаётся отдельным engine-контуром (autoloop/tun0) и не смешивается с transport policy ownership.
- Мультиинтерфейс (`iface_id`, `routing_table`, owner-locks) относится к transport-движкам (`singbox`, далее `dnstt`, `phoenix`).
- Дизайн делаем универсальным, без жёсткой привязки к одному протоколу.
## 3) UI-композиция (вкладка/модуль Transport)
### A. Interface Summary (верхний блок)
- Карточки по `iface_id`:
- `iface_id`,
- `routing_table`,
- количество клиентов на интерфейсе,
- количество rule/intents.
- Источники:
- `GET /api/v1/transport/interfaces`,
- `GET /api/v1/transport/policies`.
### B. Clients Grid (карточки подключений)
- Карточки клиентов остаются, но группируются по `iface_id`.
- На карточке:
- `client name/id`,
- `protocol/transport/security`,
- `status/latency`,
- `egress ip/country` (если доступно).
- Источник:
- `GET /api/v1/transport/clients`,
- `GET /api/v1/egress/identity?scope=transport:<client_id>`.
### C. Ownership & Locks Panel (новый блок)
- Вкладки внутри панели:
- `Ownership`:
- данные из `GET /api/v1/transport/owners`,
- поля: selector, owner client, iface, `owner_status`, `lock_active`.
- `Destination locks`:
- данные из `GET /api/v1/transport/owner-locks`,
- поля: destination ip, owner client, mark, proto, updated_at.
- Назначение:
- быстро понять, почему блокируется owner-switch.
### D. Safe Lock Recovery (точечная очистка lock)
- Кнопка: `Clear selected lock(s)` в `Destination locks`.
- Только точечный режим:
- по `client_id`,
- по `destination_ip`/`destination_ips`.
- Полный clear без фильтра запрещён.
## 4) UX-flow clear owner-lock (двухшаговый)
1. Пользователь выбирает фильтры и нажимает `Clear`.
2. GUI вызывает `POST /api/v1/transport/owner-locks/clear` без `confirm_token`.
3. Backend отвечает:
- `OWNER_LOCK_CLEAR_CONFIRM_REQUIRED`,
- `confirm_token`,
- список matched lock.
4. GUI показывает confirm-диалог с последствиями (что удалится).
5. При подтверждении GUI повторяет запрос с `confirm_token`.
6. Успех:
- перечитать `owner-locks`,
- обновить `owners`,
- показать `cleared_count`.
## 5) Правила безопасности UI
- Нельзя отправить clear-запрос без фильтра.
- Нельзя кешировать `confirm_token` между сессиями.
- При `*_REVISION_MISMATCH` GUI обязан перечитать `owner-locks` и повторить выбор.
- Все mutating-кнопки блокируются на время in-flight запроса.
## 6) События/обновление данных
- В приоритете SSE refresh от уже существующих transport-событий.
- На `transport_policy_applied`:
- перечитать `owners`,
- если включён sticky-режим, перечитать `owner-locks`.
- После clear:
- локально optimistic update запрещён, только re-fetch из API.
## 7) Контракт API для GUI (фикс)
- `GET /api/v1/transport/interfaces`
- `GET /api/v1/transport/clients`
- `GET /api/v1/transport/policies`
- `GET /api/v1/transport/owners`
- `GET /api/v1/transport/owner-locks`
- `POST /api/v1/transport/owner-locks/clear`
- `POST /api/v1/transport/policies/validate`
- `POST /api/v1/transport/policies/apply`
## 8) Порядок внедрения GUI
1. Добавить read-only `Ownership & Locks Panel`.
2. Подключить фильтры и таблицу `Destination locks`.
3. Подключить двухшаговый clear-flow с confirm-диалогом.
4. Встроить обновление после validate/apply и transport refresh.
5. После desktop-стабилизации переиспользовать UI-контракт в web/mobile.