use crate::{ db::Pool, error::{AppError, AppResult}, models::club::Club, }; use chrono::Utc; const CLUB_SELECT: &str = "SELECT id, profile_id, name, coins, level, created_at, updated_at, manager_name \ FROM clubs"; pub async fn get_club_by_profile(pool: &Pool, profile_id: &str) -> AppResult { sqlx::query_as::<_, Club>(&format!("{CLUB_SELECT} WHERE profile_id = ? LIMIT 1")) .bind(profile_id) .fetch_optional(pool) .await? .ok_or_else(|| AppError::NotFound("club not found".into())) } pub async fn get_club_by_id(pool: &Pool, club_id: &str) -> AppResult { sqlx::query_as::<_, Club>(&format!("{CLUB_SELECT} WHERE id = ? LIMIT 1")) .bind(club_id) .fetch_optional(pool) .await? .ok_or_else(|| AppError::NotFound("club not found".into())) } pub async fn create_club(pool: &Pool, club: &Club) -> AppResult<()> { sqlx::query( "INSERT INTO clubs (id, profile_id, name, coins, level, created_at, updated_at, manager_name) \ VALUES (?, ?, ?, ?, ?, ?, ?, ?)", ) .bind(&club.id) .bind(&club.profile_id) .bind(&club.name) .bind(club.coins) .bind(club.level) .bind(club.created_at) .bind(club.updated_at) .bind(&club.manager_name) .execute(pool) .await?; Ok(()) } pub async fn update_club( pool: &Pool, club_id: &str, name: Option<&str>, manager_name: Option<&str>, ) -> AppResult { let now = Utc::now(); if let Some(n) = name { sqlx::query("UPDATE clubs SET name = ?, updated_at = ? WHERE id = ?") .bind(n) .bind(now) .bind(club_id) .execute(pool) .await?; } if let Some(m) = manager_name { sqlx::query("UPDATE clubs SET manager_name = ?, updated_at = ? WHERE id = ?") .bind(m) .bind(now) .bind(club_id) .execute(pool) .await?; } get_club_by_id(pool, club_id).await } pub async fn add_coins(pool: &Pool, club_id: &str, amount: i64) -> AppResult { let now = Utc::now(); sqlx::query("UPDATE clubs SET coins = coins + ?, updated_at = ? WHERE id = ?") .bind(amount) .bind(now) .bind(club_id) .execute(pool) .await?; let new_balance = sqlx::query_scalar::<_, i64>("SELECT coins FROM clubs WHERE id = ?") .bind(club_id) .fetch_one(pool) .await?; Ok(new_balance) } pub async fn spend_coins(pool: &Pool, club_id: &str, amount: i64) -> AppResult { let balance = sqlx::query_scalar::<_, i64>("SELECT coins FROM clubs WHERE id = ?") .bind(club_id) .fetch_one(pool) .await?; if balance < amount { return Err(AppError::BadRequest(format!( "insufficient coins: have {balance}, need {amount}" ))); } let now = Utc::now(); sqlx::query("UPDATE clubs SET coins = coins - ?, updated_at = ? WHERE id = ?") .bind(amount) .bind(now) .bind(club_id) .execute(pool) .await?; Ok(balance - amount) }