use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use sqlx::{FromRow, PgPool}; use uuid::Uuid; #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct PhotographerProfile { pub id: Uuid, pub user_id: Uuid, pub portfolio_url: Option, pub equipment_list: Option, pub years_of_experience: Option, pub hourly_rate: Option, pub specialties: Option>, pub created_at: DateTime, pub updated_at: DateTime, } #[derive(Debug, Serialize, Deserialize)] pub struct UpsertPhotographerProfilePayload { pub portfolio_url: Option, pub equipment_list: Option, pub years_of_experience: Option, pub hourly_rate: Option, pub specialties: Option>, } pub struct PhotographerRepository; impl PhotographerRepository { pub async fn get_by_user_id( pool: &PgPool, user_id: Uuid, ) -> Result, sqlx::Error> { let profile = sqlx::query_as!( PhotographerProfile, r#" SELECT id, user_id, portfolio_url, equipment_list, years_of_experience, hourly_rate, specialties, created_at, updated_at FROM photographer_profiles WHERE user_id = $1 "#, user_id ) .fetch_optional(pool) .await?; Ok(profile) } pub async fn upsert( pool: &PgPool, user_id: Uuid, payload: UpsertPhotographerProfilePayload, ) -> Result { let hourly_rate_bd = payload.hourly_rate.map(|v| sqlx::types::BigDecimal::try_from(v).unwrap_or_default()); let profile = sqlx::query_as!( PhotographerProfile, r#" INSERT INTO photographer_profiles ( user_id, portfolio_url, equipment_list, years_of_experience, hourly_rate, specialties ) VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT (user_id) DO UPDATE SET portfolio_url = EXCLUDED.portfolio_url, equipment_list = EXCLUDED.equipment_list, years_of_experience = EXCLUDED.years_of_experience, hourly_rate = EXCLUDED.hourly_rate, specialties = EXCLUDED.specialties, updated_at = NOW() RETURNING id, user_id, portfolio_url, equipment_list, years_of_experience, hourly_rate, specialties, created_at, updated_at "#, user_id, payload.portfolio_url, payload.equipment_list, payload.years_of_experience, hourly_rate_bd, payload.specialties.as_deref() ) .fetch_one(pool) .await?; Ok(profile) } }