Региональные цены: UAH/BYN/VND/UZS + обобщённый список по валюте

plan_prices уже поддерживал мультивалютность (USD/RUB/CNY/TRY/IRR) — просто
добавляю ещё 4 по аналогии, по локалям уже сделанным в этой сессии
(uk/be/vi/uz). Цифры — прикидка (~45% от рыночной конвертации, тот же
порядок, что уже неявно в RUB/CNY/TRY), не сверено с реальными
конкурентами по каждому рынку — легко поправить UPDATE'ом по этой же
таблице.

list_active_plans_by_currency — обобщённая версия list_active_plans_usd,
нужна для мультивалютного /plans и бота.
This commit is contained in:
2026-07-11 00:54:48 +07:00
parent a84d5dc820
commit a89721fbee
2 changed files with 99 additions and 0 deletions
+25
View File
@@ -124,6 +124,15 @@ pub trait AppRepository: Send + Sync {
/// `0001_init.sql`), а не потому что CryptoBot требует именно её.
async fn list_active_plans_usd(&self) -> Result<Vec<(String, i64)>, sqlx::Error>;
/// Обобщённая версия `list_active_plans_usd` — тарифы в произвольной
/// валюте (см. `modules::geoip` — валюта определяется по IP/языку).
/// Пустой Vec, если для этой валюты нет ни одной активной строки в
/// `plan_prices` (вызывающая сторона должна фолбэкнуться на USD).
async fn list_active_plans_by_currency(
&self,
currency: &str,
) -> Result<Vec<(String, i64)>, sqlx::Error>;
async fn create_invoice(
&self,
user_id: Uuid,
@@ -728,6 +737,22 @@ impl AppRepository for PgRepository {
.await
}
#[instrument(skip(self))]
async fn list_active_plans_by_currency(
&self,
currency: &str,
) -> Result<Vec<(String, i64)>, sqlx::Error> {
sqlx::query_as(
"SELECT pp.plan_name, pp.amount FROM plan_prices pp \
JOIN plans p ON p.name = pp.plan_name \
WHERE pp.currency = $1 AND pp.is_active = TRUE AND p.is_active = TRUE \
ORDER BY pp.amount ASC",
)
.bind(currency)
.fetch_all(&self.pool)
.await
}
#[instrument(skip(self))]
async fn create_invoice(
&self,