use super::{AnyResult, RepositoryContext}; use crate::models::{role, server, server_role_permission, server_user, server_user_permission, }; use sea_orm::prelude::*; use sea_orm::{ActiveModelTrait, QuerySelect, Set}; use sea_orm::sea_query::OnConflict; use std::sync::Arc; use uuid::Uuid; #[derive(Clone, Debug)] pub struct ServerRepository { pub context: Arc, } impl ServerRepository { pub async fn get_all(&self) -> AnyResult> { Ok(server::Entity::find().all(&self.context.db).await?) } pub async fn get_by_id(&self, id: Uuid) -> AnyResult> { Ok(server::Entity::find_by_id(id).one(&self.context.db).await?) } pub async fn get_default(&self) -> AnyResult> { Ok(server::Entity::find() .filter(server::Column::IsDefault.eq(true)) .one(&self.context.db) .await?) } pub async fn update(&self, active: server::ActiveModel) -> AnyResult { let server = active.update(&self.context.db).await?; Ok(server) } pub async fn create(&self, active: server::ActiveModel) -> AnyResult { let server = active.insert(&self.context.db).await?; // Créer le groupe par défaut pour le serveur let default_group = role::ActiveModel { server_id: Set(server.id), name: Set("Member".to_string()), is_default: Set(true), ..Default::default() }; default_group.insert(&self.context.db).await?; Ok(server) } pub async fn create_with_args( &self, name: String, is_default: bool, ) -> AnyResult { let active = server::ActiveModel { name: Set(name), is_default: Set(is_default), ..Default::default() }; self.create(active).await } pub async fn add_user(&self, server_id: Uuid, user_id: Uuid) -> AnyResult { server_user::ActiveModel { server_id: Set(server_id), user_id: Set(user_id), ..Default::default() } .insert(&self.context.db) .await?; let role_id: Uuid = role::Entity::find() .filter(role::Column::ServerId.eq(server_id)) .filter(role::Column::IsDefault.eq(true)) .select_only() .column(role::Column::Id) .into_tuple::() .one(&self.context.db) .await? .ok_or_else(|| anyhow::anyhow!("Rôle par défaut introuvable"))?; Ok(true) } pub async fn delete(&self, id: Uuid) -> AnyResult { let res = server::Entity::delete_by_id(id) .exec(&self.context.db) .await?; Ok(res.rows_affected > 0) } pub async fn count(&self) -> AnyResult { let res = server::Entity::find().count(&self.context.db).await?; Ok(res as usize) } pub async fn get_user_permission( &self, server_id: Uuid, user_id: Uuid, ) -> AnyResult> { Ok(server_user_permission::Entity::find() .filter(server_user_permission::Column::ServerId.eq(server_id)) .filter(server_user_permission::Column::UserId.eq(user_id)) .one(&self.context.db) .await?) } pub async fn set_user_permission( &self, server_id: Uuid, user_id: Uuid, permissions: u64, ) -> AnyResult<()> { let permission = server_user_permission::ActiveModel { server_id: Set(server_id), user_id: Set(user_id), permissions: Set(permissions as i64), ..Default::default() }; server_user_permission::Entity::insert(permission) .on_conflict( OnConflict::columns([ server_user_permission::Column::ServerId, server_user_permission::Column::UserId, ]) .update_columns([server_user_permission::Column::Permissions]) .to_owned(), ) .exec(&self.context.db) .await?; Ok(()) } pub async fn remove_user_permission(&self, server_id: Uuid, user_id: Uuid) -> AnyResult<()> { server_user_permission::Entity::delete_many() .filter(server_user_permission::Column::ServerId.eq(server_id)) .filter(server_user_permission::Column::UserId.eq(user_id)) .exec(&self.context.db) .await?; Ok(()) } pub async fn get_role_permission( &self, server_id: Uuid, role_id: Uuid, ) -> AnyResult> { Ok(server_role_permission::Entity::find() .filter(server_role_permission::Column::ServerId.eq(server_id)) .filter(server_role_permission::Column::RoleId.eq(role_id)) .one(&self.context.db) .await?) } pub async fn set_role_permission( &self, server_id: Uuid, role_id: Uuid, permissions: u64, ) -> AnyResult<()> { let permission = server_role_permission::ActiveModel { server_id: Set(server_id), role_id: Set(role_id), permissions: Set(permissions as i64), ..Default::default() }; let result = server_role_permission::Entity::insert(permission) .on_conflict( OnConflict::columns([ server_role_permission::Column::ServerId, server_role_permission::Column::RoleId, ]) .update_columns([server_role_permission::Column::Permissions]) .to_owned(), ) .exec(&self.context.db) .await?; Ok(()) } pub async fn remove_role_permission(&self, server_id: Uuid, role_id: Uuid) -> AnyResult<()> { server_role_permission::Entity::delete_many() .filter(server_role_permission::Column::ServerId.eq(server_id)) .filter(server_role_permission::Column::RoleId.eq(role_id)) .exec(&self.context.db) .await?; Ok(()) } } // Helpers // impl ServerRepository { // pub async fn get_tree(&self, server_id: Uuid) -> AnyResult { // // 1. Récupération des catégories avec leurs channels // let categories_with_channels = category::Entity::find() // .filter(category::Column::ServerId.eq(server_id)) // .find_with_related(channel::Entity) // .all(&self.context.db) // .await?; // // // 2. Récupération des channels orphelins (sans catégorie) // let orphan_channels = channel::Entity::find() // .filter(channel::Column::ServerId.eq(server_id)) // .filter(channel::Column::CategoryId.is_null()) // .all(&self.context.db) // .await?; // // // 3. Transformation et tri des enfants // let mut items: Vec = Vec::new(); // // for (cat, mut channels) in categories_with_channels { // // On trie les channels internes (obligatoire car SQL ne garantit aucun ordre ici) // channels.sort_by(|a, b| { // a.position // .cmp(&b.position) // .then(a.created_at.cmp(&b.created_at)) // }); // items.push(ServerExplorerItem::Category(cat, channels)); // } // // for chan in orphan_channels { // items.push(ServerExplorerItem::Channel(chan)); // } // // // 4. Tri final de la liste globale (Mélange catégories et orphelins) // items.sort_by(|a, b| { // let pos_cmp = a.position().cmp(&b.position()); // // if pos_cmp == std::cmp::Ordering::Equal { // // Départage par date si position identique // let date_a = match a { // ServerExplorerItem::Category(c, _) => c.created_at, // ServerExplorerItem::Channel(c) => c.created_at, // }; // let date_b = match b { // ServerExplorerItem::Category(c, _) => c.created_at, // ServerExplorerItem::Channel(c) => c.created_at, // }; // date_a.cmp(&date_b) // } else { // pos_cmp // } // }); // // Ok(ServerTree { items }) // } // }