Prometheus/Loki/Grafana больше не живут внутри backend-стека — единый
стек теперь на VPS с данными (netrunner-data), т.к. ему нужно видеть
ещё лендинг и все прокси-ноды, не только бэкенд. Отсюда только тонкий
promtail, пушащий логи по сети (LOKI_PUSH_URL).
Новые бизнес-метрики поверх уже существующих generic HTTP-метрик:
payments_total{provider,status}, nodes_online/nodes_total,
support_tickets_total{status}, referral_signups_total,
partner_commission_total{currency} — тем же макросом metrics::counter!/
gauge!, что уже был в api.rs/error.rs.
Новый гейт-эндпоинт GET /api/v1/admin/observability/check (только
Owner/Moderator) — для Caddy forward_auth перед Grafana (см.
netrunner-data/observability/Caddyfile), встройка в админку через
GRAFANA_PUBLIC_URL в GET /api/v1/config.
templates/init_node.sh — добавляет --metrics-port 9093 в провижининг
новых прокси-нод.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ролевая система вместо привязки к Telegram
----------------------------------------
Раньше единственный способ получить админ-доступ — admin_guard, пускавший
по ADMIN_TG_ID или role=="admin" (без сеттера для роли). Заменяет на
Owner/Moderator/Partner:
- migrations/0005_roles_and_partners.sql — username/password_hash на users
(NULL у обычных Ghost/Telegram-юзеров, тот же паттерн, что и у seed_hash/
tg_id), can_manage_nodes, commission_percent, partner_code,
referred_by_partner_id; новые таблицы partner_commissions и
withdrawal_requests.
- auth/guard.rs — admin_guard заменён на owner_guard/staff_guard/
node_manage_guard/partner_guard; ADMIN_TG_ID убран из ApiState и main.rs.
- auth/service.rs — hash_password/login_staff со случайной Argon2-солью на
каждого юзера (не общий фиксированный ARGON_SALT, который годится для
высокоэнтропийных seed-логинов, но не для человеческих паролей).
- POST /api/v1/auth/admin/login — вход модератора/партнёра/овнера паролем,
переиспользует существующий issue_session().
- --create-owner CLI-флаг (main.rs) со скрытым вводом пароля (rpassword) —
вместо ручного SQL для создания первого владельца с VPS-консоли.
- src/modules/staff/ — эндпоинты создания модераторов/партнёров, переключения
can_manage_nodes, списка заявок на вывод и их approve/reject/paid.
- Комиссия партнёра начисляется в BillingService::confirm_payment отдельным
шагом после существующей рефералки, пересчитывается через
get_plan_price(invoice.plan_name, invoice.currency) — НЕ через
invoice.amount напрямую, потому что у провайдеров разная внутренняя
единица (TON — nanoTON+2% буфер, CryptoBot — фиатные центы напрямую).
- bot.rs — /start p_XXXXXX привязывает покупателя к партнёру по коду
(first-wins, до существующих веток numeric-tg_id-рефералки и кода входа).
- frontend/ — AdminLogin/AdminLayout/StaffPage/WithdrawalsPage/EarningsPage
поверх существующего Vite-админ-фронта (без отдельного проекта).
Оплата через @CryptoBot
------------------------
- modules/billing/providers/cryptobot.rs — новый PaymentProvider (Crypto Pay
API), плюс попутно исправлены два реальных бага в существующем коде:
confirm_payment был жёстко завязан на TON-провайдера при любом инвойсе, и
InvoiceRecord не хранил currency, из-за чего TON-курс молча применялся ко
всем провайдерам вместо родной валюты инвойса.
- bot.rs — экран выбора способа оплаты для CryptoBot-инвойсов.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>