errors fix
This commit is contained in:
+88
-1
@@ -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,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user