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,144 @@
# A1 Аудит API и HTTP-маршрутов
Дата: 2026-02-27
Статус: draft
Владелец: Engineering
## 1) Цель
- Подтвердить, что все пользовательские сценарии (статусы, смена режимов, управление маршрутами, DNS, VPN, SmartDNS, trace) реализованы в Go-ядре и доступны через единую REST-SSE оболочку.
- Зафиксировать текущую структуру `/api/v1/*`, SSE `/api/v1/events/stream` и CLI-режимов (`routes-update`, `routes-clear`, `autoloop`) как основу для будущего веб-интерфейса.
## 1.1) Факт по коду (точный baseline)
- Источник: `selective-vpn-api/app/server.go`.
- Зарегистрировано `61` `mux.HandleFunc(...)`.
- Из них:
- `60` endpoint под `/api/v1/*`.
- `1` сервисный endpoint `/healthz`.
- CLI режимы в `Run()`: `routes-update`, `routes-clear`, `autoloop`.
- Изменение от 2026-03-07: в transport добавлены `8` base route (`/api/v1/transport/*`) и action-subpath `GET /api/v1/transport/clients/{id}/metrics`.
## 2) Критерии завершения
- Таблица endpoint → handler-файл / CLI mode составлена и вынесена в документ (см. Phase A).
- Подтверждено, что GUI не содержит альтернативных реализаций бизнес-логики (всё идет через Go API).
- Описаны ответы (CmdResult, dataclasses) и форматы, которые нужно сохранять для веба.
## 3) Задачи
- Выписать все маршруты из `selective-vpn-api/app/server.go` и сопоставить их с файлами-обработчиками (`routes_handlers.go`, `traffic_mode.go`, `dns_settings.go`, `vpn_handlers.go`, `smartdns_runtime.go`, `trace_handlers.go`, `traffic_appmarks.go` и др.).
- Отметить CLI-флаги и специальные пути (`/routes/update`, `/routes/timer`, `/routes/rollback`, trace, SmartDNS, VPN login) и их привязку к Go-механикам.
- Проверить `selective-vpn-gui/api_client.py` на факт наличия всех URL/методов/форматов и зафиксировать зависимости.
- Подготовить краткое описание (для фазы A) о том, какие маршруты уже готовы к прямому вызову чере веб (без правок).
## 4) Состояние (черновик таблицы)
| Endpoint | HTTP | Handler file | Краткая логика | Требования |
| --- | --- | --- | --- | --- |
| `/api/v1/status`, `/api/v1/routes/status` | GET | `routes_handlers.go` | Чтение `status.json`, вычисление policy-route через nftables | Файл `status.json`, доступ к nftables |
| `/api/v1/routes/service[*]` | POST | `routes_handlers.go` | `systemctl start|stop|restart` service unit | systemd unit name, root или capability |
| `/api/v1/routes/update` | POST | `routes_handlers.go``routes_update.go` | Сообщает о ручном апдейте через Go-реализацию вместо bash → обновляет set и policy | NFT/state dirs, `stateDir`, `preferredIface` |
| `/api/v1/routes/timer`, `/routes/timer/toggle` | GET/POST | `routes_handlers.go` | Чтение/запись enable flag для таймера, использует `runRoutesTimerSet` | Файл таймера, systemd |
| `/api/v1/traffic/mode`, `/traffic/mode/test` | GET/POST | `traffic_mode.go` | Переключает режимы Selective/Full/Direct, включает auto bypass, проверка `TrafficModeState` | Состояние в `stateDir`, доступ к nftables/systemd |
| `/api/v1/dns-upstreams`, `/api/v1/dns/mode`, `/api/v1/dns/benchmark` | GET/POST | `dns_settings.go` | Управление DNS upstreams, режимом и benchmark (проверка резольвера) | `resolv.conf`, `dnsmaestro`, `SmartDNS` |
| `/api/v1/vpn/status`, `/api/v1/vpn/autoloop*` | GET/POST | `vpn_handlers.go` | Статусы VPN, управление autoloop/autoconnect (через AdGuard VPN API) | Доступ к AdGuard VPN API, PTY |
| `/api/v1/events/stream` | GET SSE | `events_handlers.go` / `events_bus.go` | SSE-поток статусов и логов для GUI | Доступ к event bus, `ctx` |
| `/api/v1/trace`, `/api/v1/trace-json`, `/api/v1/trace/append` | GET/POST | `trace_handlers.go` | tail/JSON/append лог-файла `trace.log` | Доступ к `trace.log`, root |
| `/api/v1/traffic/advanced/reset` | POST | `traffic_mode.go` | Сброс расширенных bypass-опций (auto-local, ingress) | Доступ к traffic state |
| `/api/v1/traffic/interfaces` | GET | `traffic_mode.go` | Список интерфейсов и предпочитаемый iface | Просмотр `iproute2` interfaces |
| `/api/v1/traffic/candidates` | GET | `traffic_candidates.go` | Выборка потенциальных подсетей для bypass | `nft`/routing discovery |
| `/api/v1/traffic/appmarks` | POST | `traffic_appmarks.go` | Управление cgroup mark (vpn/direct) | `cgroup v2`, systemd scopes |
| `/api/v1/traffic/appmarks/items` | GET | `traffic_appmarks.go` | Список runtime marks для UI | `cgroup v2` info |
| `/api/v1/traffic/app-profiles` | GET/POST/DELETE | `traffic_app_profiles.go` | CRUD профилей запуска приложений | Хранение в `stateDir` |
| `/api/v1/traffic/audit` | GET | `traffic_audit.go` | Проверки консистентности nft/route | Доступ к nft\logs |
| `/api/v1/vpn/autoloop-status` | GET | `vpn_handlers.go` | Статус autoloop watcher | AdGuard VPN API |
| `/api/v1/vpn/status` | GET | `vpn_handlers.go` | Общий статус VPN/traffic | AdGuard VPN API |
| `/api/v1/vpn/autoconnect` | POST | `vpn_handlers.go` | Переключение autoconnect | AdGuard VPN API |
| `/api/v1/vpn/locations` | GET | `vpn_handlers.go` | Список стран/регионов | AdGuard VPN API (locations) |
| `/api/v1/vpn/location` | POST | `vpn_handlers.go` | Установка нового location | AdGuard VPN API |
| `/api/v1/vpn/login/session/*` | POST/GET | `vpn_login_session.go` | Установка интерактивной PTY сессии, проверки, действия | PTY, systemd user session |
| `/api/v1/vpn/logout` | POST | `vpn_handlers.go` | Выход VPN | AdGuard VPN API |
| `/api/v1/dns/upstream-pool` | GET/POST | `dns_settings.go` | pool upstreams (итоги) | `dns_upstreams` state |
| `/api/v1/dns/status` | GET | `dns_settings.go` | Текущий upstreams и режим | `resolver` состояние |
| `/api/v1/dns/smartdns-service` | POST | `dns_settings.go` | Старт/стоп SmartDNS сервис | `smartdns` бинарь, systemd unit |
| `/api/v1/smartdns/service` | POST | `smartdns_runtime.go` | Управление SmartDNS runtime | systemd + config |
| `/api/v1/smartdns/runtime` | GET | `smartdns_runtime.go` | Получение runtime stats | СмартДНС статус |
| `/api/v1/smartdns/prewarm` | POST | `smartdns_runtime.go` | Прогрев wildcard-базы | smartdns runtime |
| `/api/v1/domains/table` | GET/POST | `domains_handlers.go` | Загрузка/сохранение таблицы доменов | Файл доменов |
| `/api/v1/domains/file` | GET | `domains_handlers.go` | Скачать raw файл доменов | Доступ к `domains.json` |
| `/api/v1/smartdns/wildcards` | GET/POST | `smartdns_wildcards_store.go` | CRUD wildcard-списка | `wildcards.json` |
Это рабочая матрица для ключевых сценариев. Полный реестр endpointов из `server.go` приведён ниже.
## 5) GUI → API
- `selective-vpn-gui/api_client.py` инкапсулирует все URL/методы/JSON-форматы (например, `TrafficModeStatus`, `TrafficAppMarkItem`, `CmdResult`), поэтому при замене фронта достаточно реализовать аналогичные dataclasses в новой веб-части.
- `dashboard_controller.py` использует эти модели, подписывается на SSE и отображает текущий статус/trace. Нужно подтвердить, что в GUI нет logic-branch (например, расчёт маршрутов), которая должна перейти в веб отдельно.
- Задача анализа: пробежать по `api_client.py` и `dashboard_controller.py` и отметить все вызовы; в Phase D перенести их в колонку “UI usage” для проверки совместимости.
## 6) CLI-режимы и API parity
- `routes-update` / `selective-vpn-api routes-update` — запускает ту же логику, что и `POST /api/v1/routes/update`, но без HTTP-запросов; используется для cron/автообновления.
- `routes-clear` / `/api/v1/routes/rollback` — очищает nftables/statestatus; веб должен предоставить rollback-кнопку, чтобы совпадал функционал CLI.
- `autoloop` — опрашивает AdGuard VPN API и пишет `autoloop.log`; веб потребляет статус через `/api/v1/vpn/autoloop-status` и SSE события watchers.
## 7) Полный реестр endpoint (из `server.go`)
- `/healthz`
- `/api/v1/events/stream`
- `/api/v1/status`
- `/api/v1/routes/status`
- `/api/v1/vpn/login-state`
- `/api/v1/systemd/state`
- `/api/v1/routes/service/start`
- `/api/v1/routes/service/stop`
- `/api/v1/routes/service/restart`
- `/api/v1/routes/service`
- `/api/v1/routes/update`
- `/api/v1/routes/timer`
- `/api/v1/routes/timer/toggle`
- `/api/v1/routes/rollback`
- `/api/v1/routes/clear`
- `/api/v1/routes/cache/restore`
- `/api/v1/routes/precheck/debug`
- `/api/v1/routes/fix-policy-route`
- `/api/v1/routes/fix-policy`
- `/api/v1/traffic/mode`
- `/api/v1/traffic/mode/test`
- `/api/v1/traffic/advanced/reset`
- `/api/v1/traffic/interfaces`
- `/api/v1/traffic/candidates`
- `/api/v1/traffic/appmarks`
- `/api/v1/traffic/appmarks/items`
- `/api/v1/traffic/app-profiles`
- `/api/v1/traffic/audit`
- `/api/v1/trace`
- `/api/v1/trace-json`
- `/api/v1/trace/append`
- `/api/v1/dns-upstreams`
- `/api/v1/dns/upstream-pool`
- `/api/v1/dns/status`
- `/api/v1/dns/mode`
- `/api/v1/dns/benchmark`
- `/api/v1/dns/smartdns-service`
- `/api/v1/smartdns/service`
- `/api/v1/smartdns/runtime`
- `/api/v1/smartdns/prewarm`
- `/api/v1/domains/table`
- `/api/v1/domains/file`
- `/api/v1/smartdns/wildcards`
- `/api/v1/vpn/autoloop-status`
- `/api/v1/vpn/status`
- `/api/v1/vpn/autoconnect`
- `/api/v1/vpn/locations`
- `/api/v1/vpn/location`
- `/api/v1/vpn/login/session/start`
- `/api/v1/vpn/login/session/state`
- `/api/v1/vpn/login/session/action`
- `/api/v1/vpn/login/session/stop`
- `/api/v1/vpn/logout`
- `/api/v1/transport/clients`
- `/api/v1/transport/clients/{id}`
- `/api/v1/transport/clients/{id}/start`
- `/api/v1/transport/clients/{id}/stop`
- `/api/v1/transport/clients/{id}/restart`
- `/api/v1/transport/clients/{id}/health`
- `/api/v1/transport/policies`
- `/api/v1/transport/policies/validate`
- `/api/v1/transport/policies/apply`
- `/api/v1/transport/policies/rollback`
- `/api/v1/transport/conflicts`
- `/api/v1/transport/capabilities`