d91aef012e
- modules::geoip — DB-IP Lite (.mmdb, без регистрации/ключа, в отличие от MaxMind) для страны по IP, X4BNet lists_vpn для грубой VPN/датацентр- эвристики. Обе базы скачиваются в рантайме, обновление — фоновая задача в tasks.rs (раз в сутки по умолчанию, GEOIP_REFRESH_INTERVAL). - GET /api/v1/billing/plans (public_router, без auth_guard) — цены в валюте, определённой по IP посетителя (X-Real-IP/X-Forwarded-For, см. nginx-конфиги). VPN/датацентр IP -> всегда базовый USD, чтобы обход региона через любой публичный VPN не обесценивал скидки. - Бот: Bot API не отдаёт IP пользователя вообще — валюта определяется по Telegram language_code. Показ цены — в валюте региона, САМА оплата через CryptoBot остаётся в USD/USDT (провайдер биллит 1:1 к USD-цене тарифа, менять валюту списания нельзя, не меняя сам провайдер).
57 lines
2.2 KiB
TOML
57 lines
2.2 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"] }
|
|
maxminddb = "0.24"
|
|
ipnet = "2.10"
|
|
flate2 = "1.0"
|
|
|
|
[profile.release]
|
|
opt-level = 3
|
|
lto = "thin"
|
|
codegen-units = 16
|
|
# НЕ panic="abort": по умолчанию tokio ловит панику отдельной задачи (одного
|
|
# запроса) через catch_unwind на границе задачи и превращает её в JoinError —
|
|
# остальные соединения продолжают жить. panic="abort" эту изоляцию отключает:
|
|
# любая паника где угодно в обработчике одного запроса мгновенно убивает весь
|
|
# процесс и рвёт всех подключённых пользователей разом.
|
|
strip = true
|