use crate::domain::events::role::{ RoleCreatedEvent, RoleDeletedEvent, RoleUpdatedEvent, RoleUserCreatedEvent, RoleUserDeletedEvent, }; use crate::models::{role, role_user}; use crate::services::ServicesContext; use sea_orm::{ActiveModelTrait, EntityTrait, TransactionTrait}; use std::sync::Arc; use uuid::Uuid; #[derive(Debug, Clone)] pub struct RoleService { service_context: Arc, } impl RoleService { pub fn new(service_context: Arc) -> Self { Self { service_context } } pub async fn create_role( &self, active: role::ActiveModel, ) -> Result { let db = &self.service_context.repositories.server.context.db; let event_bus = &self.service_context.event_bus; let txn = db.begin().await?; let role = active.insert(&txn).await?; txn.commit().await?; event_bus.emit(RoleCreatedEvent { role: role.clone() }); Ok(role) } pub async fn update_role( &self, active: role::ActiveModel, ) -> Result { let db = &self.service_context.repositories.server.context.db; let event_bus = &self.service_context.event_bus; let txn = db.begin().await?; let role = active.update(&txn).await?; txn.commit().await?; event_bus.emit(RoleUpdatedEvent { role: role.clone() }); Ok(role) } pub async fn delete_role(&self, id: Uuid) -> Result { let db = &self.service_context.repositories.server.context.db; let event_bus = &self.service_context.event_bus; let txn = db.begin().await?; let existing = role::Entity::find_by_id(id).one(&txn).await?; let res = role::Entity::delete_by_id(id).exec(&txn).await?; let deleted = res.rows_affected > 0; txn.commit().await?; if let Some(role) = existing.filter(|_| deleted) { event_bus.emit(RoleDeletedEvent { role }); } Ok(deleted) } pub async fn add_member( &self, role_id: Uuid, user_id: Uuid, server_id: Uuid, ) -> Result { let added = self .service_context .repositories .role .add_member(role_id, user_id) .await?; if added { let role_user = role_user::Entity::find_by_id((role_id, user_id)) .one(&self.service_context.repositories.server.context.db) .await? .ok_or_else(|| anyhow::anyhow!("Role membership not found"))?; self.service_context.event_bus.emit(RoleUserCreatedEvent { role_user, server_id, }); } Ok(added) } pub async fn remove_member( &self, role_id: Uuid, user_id: Uuid, server_id: Uuid, ) -> Result { let existing = role_user::Entity::find_by_id((role_id, user_id)) .one(&self.service_context.repositories.server.context.db) .await?; let removed = self .service_context .repositories .role .remove_member(role_id, user_id) .await?; if let Some(role_user) = existing.filter(|_| removed) { self.service_context.event_bus.emit(RoleUserDeletedEvent { role_user, server_id, }); } Ok(removed) } }