errors fix

This commit is contained in:
2026-04-24 17:01:57 +07:00
parent 0dc6562dd2
commit 17a4980329
6 changed files with 203 additions and 82 deletions
+88 -1
View File
@@ -1,6 +1,7 @@
use async_trait::async_trait;
use chrono::{DateTime, Utc};
use sqlx::{Executor, FromRow, PgPool};
use serde::{Deserialize, Serialize};
use sqlx::{types::Json, Executor, FromRow, PgPool};
use uuid::Uuid;
#[derive(Debug, Clone, FromRow, serde::Serialize)]
@@ -44,6 +45,28 @@ pub struct CreateNodePayload {
pub port: i32,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct SubscriptionData {
pub status: String,
pub expires_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ReferralData {
pub user_id: Uuid,
pub reward: i64,
}
#[derive(Debug, Serialize)]
pub struct ProfileData {
pub id: Uuid,
pub username: Option<String>,
pub balance: i64,
pub game_tickets: i32,
pub subscription: Option<SubscriptionData>,
pub referrals: Vec<ReferralData>,
}
#[async_trait]
pub trait AppRepository: Send + Sync {
async fn upsert_user(&self, tg_id: i64, username: Option<String>) -> Result<User, sqlx::Error>;
@@ -69,6 +92,10 @@ pub trait AppRepository: Send + Sync {
// 🔥 ДОБАВЛЕНО: Новые методы для профиля
async fn get_subscription(&self, user_id: Uuid) -> Result<Option<Subscription>, sqlx::Error>;
async fn get_referral_stats(&self, user_id: Uuid) -> Result<(i64, i64), sqlx::Error>;
async fn get_aggregated_profile(
&self,
user_id: Uuid,
) -> Result<Option<ProfileData>, sqlx::Error>;
}
pub struct PgRepository {
@@ -213,4 +240,64 @@ impl AppRepository for PgRepository {
.await?;
Ok((row.0.unwrap_or(0), row.1.unwrap_or(0)))
}
async fn get_aggregated_profile(
&self,
user_id: Uuid,
) -> Result<Option<ProfileData>, sqlx::Error> {
#[derive(FromRow)]
struct RawProfile {
id: Uuid,
tg_username: Option<String>,
balance: i64,
game_tickets: i32,
subscription: Option<Json<SubscriptionData>>,
referrals: Json<Vec<ReferralData>>,
}
let query = r#"
SELECT
u.id,
u.tg_username,
u.balance,
u.game_tickets,
(
SELECT jsonb_build_object(
'status', s.plan_name,
'expires_at', s.expires_at
)
FROM public.subscriptions s
WHERE s.user_id = u.id
LIMIT 1
) AS "subscription",
COALESCE(
(
SELECT jsonb_agg(
jsonb_build_object(
'user_id', r.referred_id,
'reward', r.earned_bonus
)
)
FROM public.referrals r
WHERE r.referrer_id = u.id
), '[]'::jsonb
) AS "referrals"
FROM public.users u
WHERE u.id = $1
"#;
let raw: Option<RawProfile> = sqlx::query_as::<_, RawProfile>(query)
.bind(user_id)
.fetch_optional(&self.pool)
.await?;
Ok(raw.map(|r| ProfileData {
id: r.id,
username: r.tg_username,
balance: r.balance,
game_tickets: r.game_tickets,
subscription: r.subscription.map(|json| json.0),
referrals: r.referrals.0,
}))
}
}