Add profiles table

This commit is contained in:
2025-02-07 02:32:31 +00:00
parent 124b1cf484
commit cf18044b95
27 changed files with 1194 additions and 150 deletions

View File

@@ -1,8 +1,10 @@
use std::fmt::Display;
use profile_repository::ProfileRepository;
use staff_role_repository::StaffRoleRepository;
use user_repository::UserRepository;
pub mod profile_repository;
pub mod staff_role_repository;
pub mod user_repository;
@@ -19,6 +21,7 @@ pub trait RepositoryProvider {
pub trait Repository
where
Self: ProfileRepository<BackendError = <Self as Repository>::BackendError>,
Self: StaffRoleRepository<BackendError = <Self as Repository>::BackendError>,
Self: UserRepository<BackendError = <Self as Repository>::BackendError>,
{

View File

@@ -0,0 +1,165 @@
use chrono::DateTime;
use chrono::Utc;
use super::RepositoryError;
/// A repository trait for managing user profiles, supporting asynchronous operations.
///
/// This trait defines the required operations for interacting with user profiles,
/// including creation, retrieval, history management, and version rollback. It is
/// designed to be implemented for various backends, such as databases, using Diesel or Diesel Async.
///
/// # Type Parameters
/// - `BackendError`: Represents the error type returned by the underlying backend implementation.
///
/// # Errors
/// All methods return a `RepositoryError<Self::BackendError>`, which encapsulates
/// errors specific to the backend implementation.
#[async_trait::async_trait]
pub trait ProfileRepository {
/// The associated error type returned by backend operations.
type BackendError: std::error::Error;
/// Inserts a new profile into the repository and marks it as the active profile for the user it belongs to.
///
/// # Arguments
/// * `new_profile` - The profile data to insert.
///
/// # Returns
/// * `Ok(Profile)` - The inserted profile with its assigned ID.
/// * `Err(RepositoryError<Self::BackendError>)` - If the operation fails.
async fn insert_profile(&mut self, new_profile: NewProfile) -> Result<Profile, RepositoryError<Self::BackendError>>;
/// Retrieves a profile by its unique ID.
///
/// # Arguments
/// * `id` - The unique profile ID.
///
/// # Returns
/// * `Ok(Some(Profile))` - If a profile with the given ID exists.
/// * `Ok(None)` - If no profile is found.
/// * `Err(RepositoryError<Self::BackendError>)` - If an error occurs.
async fn profile(&mut self, id: i32) -> Result<Option<Profile>, RepositoryError<Self::BackendError>>;
/// Retrieves the active profile associated with a given user ID.
///
/// # Arguments
/// * `user_id` - The ID of the user whose profile is being retrieved.
///
/// # Returns
/// * `Ok(Some(Profile))` - The users active profile for the user if it exists.
/// * `Ok(None)` - If no active profile is found for the user.
/// * `Err(RepositoryError<Self::BackendError>)` - If an error occurs.
async fn active_profile(&mut self, user_id: i32) -> Result<Option<Profile>, RepositoryError<Self::BackendError>>;
/// Retrieves the active profile associated with a given Discord user ID.
///
/// # Arguments
/// * `discord_user_id` - The Discord user's unique identifier.
///
/// # Returns
/// * `Ok(Some(Profile))` - The users active profile for the user if it exists.
/// * `Ok(None)` - If no active profile is found for the user.
/// * `Err(RepositoryError<Self::BackendError>)` - If an error occurs.
async fn active_profile_by_discord_id(&mut self, discord_user_id: u64) -> Result<Option<Profile>, RepositoryError<Self::BackendError>>;
/// Retrieves the full profile history for a given user.
///
/// # Arguments
/// * `user_id` - The ID of the user whose profile history is being retrieved.
///
/// # Returns
/// * `Ok(Vec<Profile>)` - A list of all past versions of the user's profile.
/// * `Err(RepositoryError<Self::BackendError>)` - If an error occurs.
async fn profiles_by_user_id(&mut self, user_id: i32) -> Result<Vec<Profile>, RepositoryError<Self::BackendError>>;
/// Retrieves the full profile history for a given Discord user.
///
/// # Arguments
/// * `discord_user_id` - The Discord user's unique identifier.
///
/// # Returns
/// * `Ok(Vec<Profile>)` - A list of all past versions of the user's profile.
/// * `Err(RepositoryError<Self::BackendError>)` - If an error occurs.
async fn profiles_by_discord_id(&mut self, discord_user_id: u64) -> Result<Vec<Profile>, RepositoryError<Self::BackendError>>;
/// Sets an profile version as active.
///
/// This function marks `profile_id` as the active profile
/// and deactivates all other profiles for the user.
///
/// # Arguments
/// * `user_id` - The ID of the user.
/// * `profile_id` - The profile ID to mark as active.
///
/// # Returns
/// * `Ok(false)` - If the specified profile does not exist.
/// * `Ok(true)` - If the operation was successful.
/// * `Err(RepositoryError<Self::BackendError>)` - If the operation fails.
async fn set_active_profile(&mut self, user_id: i32, profile_id: i32) -> Result<bool, RepositoryError<Self::BackendError>>;
}
pub struct Profile {
pub id: i32,
pub user_id: i32,
pub thumbnail_url: Option<String>,
pub image_url: Option<String>,
pub trainer_class: Option<String>,
pub nature: Option<String>,
pub partner_pokemon: Option<String>,
pub starting_region: Option<String>,
pub favourite_food: Option<String>,
pub likes: Option<String>,
pub quotes: Option<String>,
pub pokemon_go_code: Option<String>,
pub pokemon_pocket_code: Option<String>,
pub switch_code: Option<String>,
pub created_at: DateTime<Utc>,
pub is_active: bool,
}
pub struct NewProfile {
pub user_id: i32,
pub thumbnail_url: Option<String>,
pub image_url: Option<String>,
pub trainer_class: Option<String>,
pub nature: Option<String>,
pub partner_pokemon: Option<String>,
pub starting_region: Option<String>,
pub favourite_food: Option<String>,
pub likes: Option<String>,
pub quotes: Option<String>,
pub pokemon_go_code: Option<String>,
pub pokemon_pocket_code: Option<String>,
pub switch_code: Option<String>,
}
impl Profile {
pub fn into_new(self) -> NewProfile {
NewProfile {
user_id: self.user_id,
thumbnail_url: self.thumbnail_url,
image_url: self.image_url,
trainer_class: self.trainer_class,
nature: self.nature,
partner_pokemon: self.partner_pokemon,
starting_region: self.starting_region,
favourite_food: self.favourite_food,
likes: self.likes,
quotes: self.quotes,
pokemon_go_code: self.pokemon_go_code,
pokemon_pocket_code: self.pokemon_pocket_code,
switch_code: self.switch_code,
}
}
}

View File

@@ -11,21 +11,13 @@ pub trait UserRepository {
async fn insert_user(&mut self, new_user: NewUser) -> Result<User, RepositoryError<Self::BackendError>>;
async fn update_user(&mut self, user: User) -> Result<Option<User>, RepositoryError<Self::BackendError>>;
async fn remove_user(&mut self, id: i32) -> Result<Option<User>, RepositoryError<Self::BackendError>>;
}
pub struct User {
pub id: i32,
pub discord_user_id: u64,
pub pokemon_go_code: Option<String>,
pub pokemon_pocket_code: Option<String>,
pub switch_code: Option<String>,
}
pub struct NewUser {
pub discord_user_id: u64,
pub pokemon_go_code: Option<String>,
pub pokemon_pocket_code: Option<String>,
pub switch_code: Option<String>,
}