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 display_name: Option, pub bio: Option, pub location: Option, pub custom_data: Option, pub status: String, pub created_at: DateTime, pub updated_at: DateTime, } #[derive(Debug, Serialize, Deserialize)] pub struct UpsertPhotographerProfilePayload { pub display_name: Option, pub bio: Option, pub location: Option, pub custom_data: Option, } pub struct PhotographerRepository; impl PhotographerRepository { pub async fn get_by_user_id(pool: &PgPool, user_id: Uuid) -> Result, sqlx::Error> { sqlx::query_as!( PhotographerProfile, r#"SELECT id, user_id, display_name, bio, location, custom_data as "custom_data: Option", status, created_at, updated_at FROM photographer_profiles WHERE user_id = $1"#, user_id ).fetch_optional(pool).await } pub async fn upsert(pool: &PgPool, user_id: Uuid, p: UpsertPhotographerProfilePayload) -> Result { sqlx::query_as!( PhotographerProfile, r#"INSERT INTO photographer_profiles (user_id, display_name, bio, location, custom_data) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (user_id) DO UPDATE SET display_name = COALESCE(EXCLUDED.display_name, photographer_profiles.display_name), bio = EXCLUDED.bio, location = EXCLUDED.location, custom_data = EXCLUDED.custom_data, updated_at = NOW() RETURNING id, user_id, display_name, bio, location, custom_data as "custom_data: Option", status, created_at, updated_at"#, user_id, p.display_name, p.bio, p.location, p.custom_data ).fetch_one(pool).await } }