# Netrunner Control Plane Бэкенд VPN-сервиса «Netrunner»: авторизация (Telegram / анонимный «Ghost Protocol»), биллинг подписок через TON, реферальная программа, оркестрация VPN-нод по SSH, Telegram-бот как второй канал входа и встроенная раздача SPA-фронтенда. Стек: Rust (axum, sqlx/Postgres, teloxide, tokio) + React/TypeScript (Vite) фронтенд, собранные в единый Docker-образ. ## Структура репозитория | Путь | Что там | Подробнее | |---|---|---| | [`src/`](src) | Rust-бэкенд (control plane) | см. ниже | | [`src/modules/`](src/modules/README.md) | Бизнес-модули (auth, billing, nodes, referrals, users) | [README](src/modules/README.md) | | [`src/db/`](src/db/README.md) | Модели и репозиторий (доступ к Postgres) | [README](src/db/README.md) | | [`frontend/`](frontend/README.md) | React/Vite SPA (личный кабинет, игра, админка нод) | [README](frontend/README.md) | | [`migrations/`](migrations) | SQL-миграции (sqlx) | — | | [`templates/init_node.sh`](templates/init_node.sh) | Bash-скрипт инициализации новой VPN-ноды, исполняется по SSH | — | | [`tests/`](tests) | Интеграционные тесты репозитория (`sqlx::test`, требуют Postgres) | — | Инфраструктура и процесс деплоя подробно описаны в [`DEPLOYMENT.md`](DEPLOYMENT.md); список закрытых и остаточных угроз безопасности — в [`SECURITY_AUDIT.md`](SECURITY_AUDIT.md). Неструктурированный бэклог идей и задач — в [`things.txt`](things.txt). ## Архитектура бэкенда Слоями, сверху вниз: 1. **`main.rs`** — точка входа: поднимает пул Postgres, собирает `ApiState` (репозиторий + сервисы всех модулей) и параллельно запускает HTTP API, Telegram-бота и фоновые задачи биллинга до общего сигнала остановки (Ctrl+C / SIGTERM). 2. **`api.rs`** — сборка axum-роутера: монтирует контроллеры модулей, rate-limiting (`tower_governor`), CORS, Prometheus-метрики (`/metrics`), health-пробы (`/health`, `/health/ready`) и раздачу статики фронтенда как SPA-фолбэк. 3. **`modules/*/controller.rs`** — HTTP-контракты (axum-роуты, JSON DTO), тонкий слой без бизнес-логики. 4. **`modules/*/service.rs`** — бизнес-логика модуля. 5. **`db::repository::AppRepository`** — трейт доступа к БД; единственная реализация — `PgRepository` (Postgres/sqlx). Сервисы знают только о трейте, поэтому теоретически подменяемы в тестах без реальной БД. 6. **`bot.rs`** — Telegram-бот (teloxide), использует те же сервисы, что и HTTP API. 7. **`tasks.rs`** — фоновый цикл: сброс просроченных подписок и сверка блокчейна на предмет потерянных платежей. 8. **`error.rs`** — единый `AppError` с `IntoResponse`: маппинг в HTTP-статус, безопасное сообщение наружу и подробности только в логи/метрики. ## Быстрый старт (локальная разработка) ```bash cp .env.example .env # заполнить секреты (JWT_SECRET, ARGON_SALT, TELOXIDE_TOKEN, ...) make dev # docker compose: db + redis + app с hot-reload (cargo watch) ``` Приложение поднимется на `http://localhost:8080` (`/health`, `/health/ready`). Остальные команды — `make help`. ## Известные незавершённые места (недоделки) Ниже — то, что явно недоделано или является временной заглушкой в текущем коде. В самих файлах эти места помечены комментариями `// TODO:` — см. также [`SECURITY_AUDIT.md`](SECURITY_AUDIT.md) для рисков безопасности отдельно. - **Cyberhack без анти-чита.** `POST /users/hack/result` принимает `score` от клиента и лишь клампит его в `0..=500` — сервер не проверяет, что игра реально была сыграна честно. Пока не эксплуатируемо (баланс E$ нигде не тратится), но станет дырой, как только появится трата баланса. См. `src/modules/users/controller.rs`. - **`GET /nodes/routing` возвращает неполный конфиг.** Отдаёт только `ip/port/region/supported_protocols` (последнее — статичная заглушка). Реальному VPN-клиенту нужны ещё `tunnel_*`-поля (уже есть в модели `VpnNode`, но не сериализуются), `public_key`/`sni_domain` (их нет даже в схеме БД) и одноразовый session-токен. См. `src/modules/nodes/controller.rs`. - **`GET /nodes/stats` отдаёт фейковый `uptime: "99.9%"`** для всех нод — не реальная метрика. - **Нет health-check воркера для VPN-нод.** Статус ноды в БД не переоценивается сам: если физический сервер лёг, control plane продолжит считать его `online` и выдавать клиентам. См. `src/tasks.rs`. - **Провижининг ноды — синхронный.** `POST /admin/nodes` держит HTTP-запрос открытым на всё время SSH-провижининга (может занимать минуты) вместо немедленного `202 Accepted` + фоновой задачи. См. `src/modules/nodes/service.rs`. - **Курс TON запрашивается синхронно на каждый инвойс** (`BillingService::initiate_payment`) — не кешируется, хотя Redis в проекте уже подключён. - **Таблица `auth_sessions`** объявлена в миграции, но нигде не используется — заброшенный черновик флоу авторизации через Magic Link из бота. Либо доделать, либо убрать из схемы. - **Telegram-бот: разделы «Тарифы» и «Синдикат»** в inline-меню — заглушка «В разработке...» (`src/bot.rs`, `handle_callbacks`). - **Фронтенд, `AdminDashboard.tsx`:** кнопка «Force Restart» ничего не делает (нет `onClick`); UI для удаления ноды тоже отсутствует, хотя бэкенд уже умеет `DELETE /api/v1/admin/nodes/{id}`. - **Фронтенд, `Auth.tsx`:** искусственные задержки (`setTimeout` 800мс/6000мс) чисто ради вида терминала; при генерации Ghost-seed нет кнопки «скачать ключ» — если юзер не успеет скопировать seed за 6 секунд до авто-редиректа, доступ к анонимному аккаунту теряется безвозвратно (seed невосстановим). - **`frontend/README.md`** был шаблоном Vite по умолчанию (сейчас заменён на специфичный для проекта).