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, status, created_at, updated_at FROM photographer_profiles WHERE user_id = $1"#, ) .bind(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, status, created_at, updated_at"#, ) .bind(user_id) .bind(p.display_name) .bind(p.bio) .bind(p.location) .bind(p.custom_data) .fetch_one(pool) .await } }