nxtgauge-backend-rust/crates/db/src/models/user_role_profile.rs
2026-04-18 18:30:56 +02:00

237 lines
7.9 KiB
Rust

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::{FromRow, PgPool};
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct UserRoleProfile {
pub id: Uuid,
pub user_id: Uuid,
pub role_key: String,
pub display_name: Option<String>,
pub bio: Option<String>,
pub location: Option<String>,
pub avatar_url: Option<String>,
pub phone: Option<String>,
pub email: Option<String>,
pub status: String,
pub verification_status: String,
pub approval_status: String,
pub rejection_reason: Option<String>,
pub approved_at: Option<DateTime<Utc>>,
pub verified_at: Option<DateTime<Utc>>,
pub is_profile_public: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserRoleProfileWithExtension<T> {
#[serde(flatten)]
pub profile: UserRoleProfile,
#[serde(flatten)]
pub extension: T,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RoleKey {
Photographer,
Tutor,
MakeupArtist,
Developer,
VideoEditor,
GraphicDesigner,
SocialMediaManager,
FitnessTrainer,
CateringService,
UgcContentCreator,
Company,
Customer,
Candidate,
}
impl RoleKey {
pub fn as_str(&self) -> &'static str {
match self {
RoleKey::Photographer => "photographer",
RoleKey::Tutor => "tutor",
RoleKey::MakeupArtist => "makeup_artist",
RoleKey::Developer => "developer",
RoleKey::VideoEditor => "video_editor",
RoleKey::GraphicDesigner => "graphic_designer",
RoleKey::SocialMediaManager => "social_media_manager",
RoleKey::FitnessTrainer => "fitness_trainer",
RoleKey::CateringService => "catering_service",
RoleKey::UgcContentCreator => "ugc_content_creator",
RoleKey::Company => "company",
RoleKey::Customer => "customer",
RoleKey::Candidate => "candidate",
}
}
}
pub struct UserRoleProfileRepository;
impl UserRoleProfileRepository {
pub async fn get_by_user_and_role(
pool: &PgPool,
user_id: Uuid,
role_key: &str,
) -> Result<Option<UserRoleProfile>, sqlx::Error> {
sqlx::query_as::<_, UserRoleProfile>(
r#"SELECT id, user_id, role_key, display_name, bio, location,
avatar_url, phone, email, status,
verification_status, approval_status, rejection_reason,
approved_at, verified_at, is_profile_public,
created_at, updated_at
FROM user_role_profiles
WHERE user_id = $1 AND role_key = $2"#,
)
.bind(user_id)
.bind(role_key)
.fetch_optional(pool)
.await
}
pub async fn get_by_id(
pool: &PgPool,
id: Uuid,
) -> Result<Option<UserRoleProfile>, sqlx::Error> {
sqlx::query_as::<_, UserRoleProfile>(
r#"SELECT id, user_id, role_key, display_name, bio, location,
avatar_url, phone, email, status,
verification_status, approval_status, rejection_reason,
approved_at, verified_at, is_profile_public,
created_at, updated_at
FROM user_role_profiles
WHERE id = $1"#,
)
.bind(id)
.fetch_optional(pool)
.await
}
pub async fn get_all_by_user(
pool: &PgPool,
user_id: Uuid,
) -> Result<Vec<UserRoleProfile>, sqlx::Error> {
sqlx::query_as::<_, UserRoleProfile>(
r#"SELECT id, user_id, role_key, display_name, bio, location,
avatar_url, phone, email, status,
verification_status, approval_status, rejection_reason,
approved_at, verified_at, is_profile_public,
created_at, updated_at
FROM user_role_profiles
WHERE user_id = $1"#,
)
.bind(user_id)
.fetch_all(pool)
.await
}
pub async fn create(
pool: &PgPool,
user_id: Uuid,
role_key: &str,
) -> Result<UserRoleProfile, sqlx::Error> {
sqlx::query_as::<_, UserRoleProfile>(
r#"INSERT INTO user_role_profiles (user_id, role_key)
VALUES ($1, $2)
ON CONFLICT (user_id, role_key) DO UPDATE SET user_id = EXCLUDED.user_id
RETURNING id, user_id, role_key, display_name, bio, location,
avatar_url, phone, email, status,
verification_status, approval_status, rejection_reason,
approved_at, verified_at, is_profile_public,
created_at, updated_at"#,
)
.bind(user_id)
.bind(role_key)
.fetch_one(pool)
.await
}
pub async fn update(
pool: &PgPool,
id: Uuid,
display_name: Option<String>,
bio: Option<String>,
location: Option<String>,
avatar_url: Option<String>,
phone: Option<String>,
email: Option<String>,
is_profile_public: bool,
) -> Result<UserRoleProfile, sqlx::Error> {
sqlx::query_as::<_, UserRoleProfile>(
r#"UPDATE user_role_profiles SET
display_name = COALESCE($2, display_name),
bio = COALESCE($3, bio),
location = COALESCE($4, location),
avatar_url = COALESCE($5, avatar_url),
phone = COALESCE($6, phone),
email = COALESCE($7, email),
is_profile_public = $8,
updated_at = NOW()
WHERE id = $1
RETURNING id, user_id, role_key, display_name, bio, location,
avatar_url, phone, email, status,
verification_status, approval_status, rejection_reason,
approved_at, verified_at, is_profile_public,
created_at, updated_at"#,
)
.bind(id)
.bind(display_name)
.bind(bio)
.bind(location)
.bind(avatar_url)
.bind(phone)
.bind(email)
.bind(is_profile_public)
.fetch_one(pool)
.await
}
pub async fn approve(
pool: &PgPool,
id: Uuid,
_approved_by: Uuid,
) -> Result<UserRoleProfile, sqlx::Error> {
sqlx::query_as::<_, UserRoleProfile>(
r#"UPDATE user_role_profiles SET
approval_status = 'APPROVED',
approved_at = NOW(),
updated_at = NOW()
WHERE id = $1
RETURNING id, user_id, role_key, display_name, bio, location,
avatar_url, phone, email, status,
verification_status, approval_status, rejection_reason,
approved_at, verified_at, is_profile_public,
created_at, updated_at"#,
)
.bind(id)
.fetch_one(pool)
.await
}
pub async fn reject(
pool: &PgPool,
id: Uuid,
rejection_reason: &str,
) -> Result<UserRoleProfile, sqlx::Error> {
sqlx::query_as::<_, UserRoleProfile>(
r#"UPDATE user_role_profiles SET
approval_status = 'REJECTED',
rejection_reason = $2,
updated_at = NOW()
WHERE id = $1
RETURNING id, user_id, role_key, display_name, bio, location,
avatar_url, phone, email, status,
verification_status, approval_status, rejection_reason,
approved_at, verified_at, is_profile_public,
created_at, updated_at"#,
)
.bind(id)
.bind(rejection_reason)
.fetch_one(pool)
.await
}
}