# Roadmap Порядок реализации по этапам (milestones). Каждый этап — работоспособный инкремент. ## M0 — Каркас и инфраструктура - Solution + 4 проекта (Domain/Application/Infrastructure/Api), ссылки по Clean Architecture. - `Directory.Build.props`, `.editorconfig`, nullable + анализаторы, `dotnet format` в CI. - EF Core + Npgsql, первая миграция. - Scaffolding фронта: Vite + React + TS + Tailwind + shadcn/ui + TanStack Query/Router; **тема light/dark/system** (провайдер + переключатель); i18n (RU/EN); dev-прокси `/api`,`/hubs` на бэк. - **Единый контейнер**: multi-stage Dockerfile (node → dotnet publish → aspnet), Api раздаёт SPA из `wwwroot` (fallback на `index.html`); docker-compose `app` + `db` (PostgreSQL); `ForwardedHeaders` (TLS — внешним прокси); авто-применение миграций на старте. - Health-check `/health`, Serilog, OpenAPI + Scalar. - **CI (GitHub Actions)**: `dotnet build/test` + `pnpm build/lint/typecheck` (без деплоя). - **Готово, когда**: единый образ поднимается в docker-compose рядом с postgres, отдаёт заглушку SPA и `/health`, есть базовая миграция, CI зелёный. ## M1 — Аутентификация и сидинг - ASP.NET Core Identity (`AppUser`/`AppRole` c `MaxConfigs`); `DbInitializer`: системные роли `admin`/`user` и учётка админа + Telegram id админов из env ([`.env.example`](../.env.example)). - **Вход по username** (email не используется); JWT access + refresh (httpOnly cookie, ротация, хранение хэшей), CSRF на refresh, Identity lockout, rate-limit на `/auth/*`; смена пароля. - Регистрация: новый пользователь → роль `user`, `IsActivated = false`. - Фронт: страницы login/register (username), стор авторизации, refresh-flow, guard-маршруты. - **Готово, когда**: регистрация/вход/refresh/logout по username работают, админ засидан, новый юзер неактивен. ## M2 — Роли и активация - Домен: динамические роли (CRUD `admin`, квота `MaxConfigs`), `ActivationRequest`. - Команды/запросы: CreateRole/UpdateRole/DeleteRole, ChangeUserRole (одна роль), RequestActivation (с комментарием), ApproveActivation/RejectActivation. - Эндпоинты активации (user + admin) и ролей; policy `RequireActivated`. - Фронт: экран «запросить активацию» (с комментарием), админ-очередь запросов, управление ролями/назначением. - **Готово, когда**: юзер запрашивает активацию с комментарием, админ на сайте активирует; роли с квотами работают. ## M3 — Ноды и публикация inbounds (по ролям) - Домен `Node`/`Inbound` (+ `AllowedRoles`, `DisplayName`); порт `IXuiPanelGateway` + `XuiPanelGateway` (per-node клиент, ThreeXui.Net); шифрование секретов нод (`ISecretProtector`). - Команды/запросы: RegisterNode, SyncNode, Probe, ListNodes, ListInbounds, PublishInbound (с выбором ролей). - Админка нод/инбаундов на фронте (публикация с `displayName` и `allowedRoleIds`). - **Готово, когда**: админ подключает реальную 3x-ui и публикует inbound «Германия (Trojan)» для выбранных ролей. ## M4 — Конфиги пользователя (ядро продукта) - Домен `VpnConfig` (создание, отзыв, ротация, статусы; инварианты: активирован + квота роли (грандфазеринг) + доступ роли к инбаунду; проверка квоты в транзакции; схема `ClientEmail`). - CreateVpnConfig (с `label`/`deviceLimit`→`limitIp`), EditVpnConfig, RotateVpnConfig, RevokeVpnConfig, GetMyConfigs, GetConfigLink, ListAvailableInbounds; connection string + QR. - Подписка: агрегированная `/sub/{userToken}` (все конфиги) + по конфигу `/sub/{configToken}`; заголовки `Subscription-Userinfo` / `profile-update-interval`. - Самоудаление аккаунта (`DELETE /api/auth/me`): отзыв всех конфигов + удаление данных. - Каталог приложений `ClientApp` (домен + `GET /api/apps` по ОС; сид из `seed/client-apps.json`) + **страница инструкций** на фронте. - Фронт: дашборд (метки, лимит устройств), создание/редактирование, страница инструкций, копирование, QR, отзыв, перевыпуск, настройки аккаунта. - **Готово, когда**: активированный юзер создаёт рабочий конфиг в доступном инбаунде в пределах квоты; работает агрегированная подписка. ## M5 — Синхронизация трафика и realtime - `TrafficSyncService` (обход нод, обновление трафика/статусов, `TrafficSample`); реконсиляция дрейфа с 3x-ui. - `NodeHealthCheckService`; `TrafficRetentionService` (TTL-чистка истории). - SignalR `PanelHub` + `IRealtimeNotifier`; события трафика/статусов/нод/активации. - Фронт: живые прогресс-бары трафика, статусы онлайн, реакция на превышение лимита/срока. - **Готово, когда**: трафик и статусы обновляются в UI без перезагрузки. ## M6 — Админ-статистика, управление пользователями, аудит - ListUsers, BlockUser (→ отключение конфигов в 3x-ui) / UnblockUser, ChangeUserRole, ResetUserPassword (без привязки TG), GetUserConfigs, force-revoke, GetStats. - `AuditLog`: запись значимых действий (Web/Telegram/System) + эндпоинт `/api/admin/audit`. - Каталог приложений: админ-CRUD `ClientApp` (`/api/admin/apps`) — название, ссылка, ОС, порядок, вкл/выкл. - Фронт: таблицы пользователей/конфигов/ролей, журнал аудита, графики трафика (Recharts), сводки. - **Готово, когда**: админ видит статистику и журнал, управляет пользователями/ролями/конфигами; блокировка гасит VPN. ## M7 — Telegram-бот ✅ - Библиотека Telegram.Bot, `TelegramBotHostedService` (long polling) в процессе Api, `IOptions`. - Домен: поля Telegram у `AppUser`, `TelegramLinkToken`, `TelegramLoginRequest`. - Флоу привязки (`LinkTelegramCommand`) + эндпоинт `link-token`/`unlink`. - Passwordless-вход: `login-request` + подтверждение в боте (`ApproveTelegramLoginCommand`) → выпуск JWT; поллинг завершения на фронте (`GET /api/auth/telegram/login-request/{id}`). - Команды бота: `/start`, меню, «Мои конфиги» (`GetMyConfigsQuery`), `/login`, `/unlink`, `/requests`, `/help`. - **Админ в боте**: уведомления о запросах активации + inline «Активировать/Отклонить», `/requests` (по Telegram id из env). - **DM-уведомления юзеру**: активация (`ApproveActivationCommandHandler`), блокировка (`BlockUserCommandHandler`), принудительный отзыв конфига админом (`ForceRevokeConfigCommandHandler`) — если Telegram привязан. Бот — read-only по конфигам. - **Готово, когда**: юзер привязывает Telegram, входит без пароля, видит конфиги; админ активирует запросы прямо в боте. ✅ Достигнуто. - **Перенесено в backlog** (не реализовано в MVP): восстановление пароля через бота (`/resetpassword` с одноразовой ссылкой) — сейчас сброс пароля только через админа (`ResetUserPasswordCommand`); QR прямо в сообщениях бота; фронтовые кнопки «Войти через Telegram»/«Привязать Telegram» (бэкенд-контракт готов, фронт не реализовывался в эту итерацию). ## M8 — Закалка (hardening) ✅ - Тесты: `PnvPanel.Domain.Tests` (54, чистые unit-тесты инвариантов сущностей), `PnvPanel.Application.Tests` (71, CQRS-хендлеры на EF Core InMemory + NSubstitute-моки портов), `PnvPanel.IntegrationTests` (Testcontainers.PostgreSql + `WebApplicationFactory` — реальный HTTP-контракт, включая проверку `pg_advisory_xact_lock` под параллельной нагрузкой на квоту конфигов). - Rate-limiting, аудит-лог, единообразные `ProblemDetails`, ретеншн `TrafficSample` — сделаны в M5/M6. - CI (`.github/workflows/ci.yml`): `dotnet build/test` (backend, включая интеграционные — на `ubuntu-latest` Docker доступен) + `pnpm lint/typecheck/build` (frontend), без деплоя. - Прод-`docker-compose.yml`: `env_file: .env` прокидывает все секреты в контейнер `app`, том `dp_keys` для key-ring Data Protection (переживает пересоздание контейнера), healthcheck `app` через `GET /health` (curl добавлен в runtime-образ). TLS — внешним прокси (без изменений). - **Готово, когда**: зелёный CI, покрытие ключевых сценариев, готовность к деплою. ✅ Достигнуто (интеграционные тесты не запускались локально — Docker Desktop недоступен на машине разработки; зависят от Docker в CI для первого реального прогона). ## Backlog (после MVP) - Полное самообслуживание в боте (создание/ротация/отзыв конфигов) — в MVP бот read-only. - Полная регистрация аккаунта через Telegram (в MVP — только привязка); Telegram Login Widget как альтернатива. - Тарифы/биллинг/платежи, автопродление, промокоды. - Реферальная программа; расширенные уведомления (через Telegram/веб — email в проекте не используется). - Балансировка/выбор оптимальной ноды, автоскейл. - OpenTelemetry-трейсинг, метрики, дашборды. - Вынос фоновых задач в Hangfire/Quartz; TimescaleDB для истории трафика. - Мультиязычность (RU/EN и далее).