375b333978
Ролевая система вместо привязки к 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>
50 lines
1.6 KiB
TOML
50 lines
1.6 KiB
TOML
[package]
|
|
name = "netrunner-control-plane"
|
|
version = "0.2.0"
|
|
edition = "2021"
|
|
|
|
[dependencies]
|
|
tokio = { version = "1.40", features = ["full"] }
|
|
axum = { version = "0.8.9", features = ["macros"] }
|
|
tower = "0.5.3"
|
|
tower-http = { version = "0.6.8", features = ["fs", "trace", "cors"] }
|
|
tower_governor = "0.8"
|
|
teloxide = { version = "0.17", features = ["macros", "rustls"] }
|
|
|
|
# 🔥 ИСПРАВЛЕНО: Включаем "migrate" для автоматического создания баз в тестах
|
|
sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "postgres", "uuid", "chrono", "migrate", "rust_decimal"] }
|
|
redis = { version = "1.2.0", features = ["tokio-comp", "aio", "connection-manager"] }
|
|
|
|
serde = { version = "1.0", features = ["derive"] }
|
|
serde_json = "1.0"
|
|
uuid = { version = "1.10", features = ["v4", "serde"] }
|
|
chrono = { version = "0.4", features = ["serde"] }
|
|
thiserror = "2.0.18"
|
|
async-trait = "0.1"
|
|
tokio-util = { version = "0.7", features = ["rt"] }
|
|
|
|
jsonwebtoken = { version = "10.3", default-features = false, features = ["use_pem", "rust_crypto"] }
|
|
hmac = "0.13.0"
|
|
sha2 = "0.11.0"
|
|
hex = "0.4"
|
|
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
|
|
metrics = "0.24.3"
|
|
metrics-exporter-prometheus = "0.18.1"
|
|
dotenvy = "0.15"
|
|
clap = { version = "4.6.1", features = ["derive"] }
|
|
ssh2 = "0.9.5"
|
|
rand = "0.8"
|
|
argon2 = "0.5"
|
|
rpassword = "7.5"
|
|
rust_decimal = { version = "1.42.0", features = ["serde"] }
|
|
reqwest = { version = "0.11", features = ["json"] }
|
|
|
|
[profile.release]
|
|
opt-level = 3
|
|
lto = "thin"
|
|
codegen-units = 16
|
|
panic = "abort"
|
|
strip = true
|