# 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`