Files
oxspeak_server/src/services/role.rs
T
2026-09-23 10:36:14 +02:00

126 lines
3.5 KiB
Rust

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<ServicesContext>,
}
impl RoleService {
pub fn new(service_context: Arc<ServicesContext>) -> Self {
Self { service_context }
}
pub async fn create_role(
&self,
active: role::ActiveModel,
) -> Result<role::Model, anyhow::Error> {
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<role::Model, anyhow::Error> {
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<bool, anyhow::Error> {
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<bool, anyhow::Error> {
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<bool, anyhow::Error> {
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)
}
}