This commit is contained in:
2026-08-01 14:11:19 +02:00
parent 22b0bc36bb
commit b946cfd866
13 changed files with 689 additions and 152 deletions
+84 -45
View File
@@ -1,9 +1,11 @@
use crate::repositories::Repositories;
use crate::services::ServicesContext;
use crate::domain::dto::channel::{CreateChannelRequest, UpdateChannelRequest};
use crate::models::channel;
use event_bus::Scope;
use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, QuerySelect, QueryOrder, TransactionTrait, Set, PaginatorTrait};
use crate::models::{channel, role};
use crate::permissions::PermissionSet;
use crate::services::ServicesContext;
use crate::services::permission::PermissionService;
use sea_orm::{
ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, QuerySelect, Set, TransactionTrait,
};
use std::sync::Arc;
use uuid::Uuid;
@@ -24,47 +26,80 @@ impl ChannelService {
let db = &self.service_context.repositories.server.context.db;
let event_bus = &self.service_context.event_bus;
// Start transaction
let txn = db.begin().await?;
let channel = db
.transaction::<_, channel::Model, anyhow::Error>(|txn| {
Box::pin(async move {
// 1. Insertion du canal
let active_model = channel::ActiveModel {
server_id: Set(payload.server_id),
category_id: Set(payload.category_id),
channel_type: Set(payload.channel_type),
name: Set(payload.name),
..Default::default()
};
// 1. Insert channel within transaction
let active_model = channel::ActiveModel {
server_id: Set(payload.server_id),
category_id: Set(payload.category_id),
channel_type: Set(payload.channel_type),
name: Set(payload.name),
..Default::default()
};
let channel = active_model.insert(txn).await?;
let channel = active_model.insert(&txn).await?;
// 2. Si server_id est présent, enregistrement de l'ordre d'affichage
if let Some(server_id) = payload.server_id {
let max_order: Option<i64> =
crate::models::server_item_order::Entity::find()
.filter(
crate::models::server_item_order::Column::ServerId
.eq(server_id),
)
.select_only()
.column_as(
crate::models::server_item_order::Column::OrderKey.max(),
"max_key",
)
.into_tuple::<Option<i64>>()
.one(txn)
.await?
.flatten();
// 2. If server_id is present, insert into server_item_order within transaction
if let Some(server_id) = payload.server_id {
// Get max order key or determine order key
let max_order: Option<i64> = crate::models::server_item_order::Entity::find()
.filter(crate::models::server_item_order::Column::ServerId.eq(server_id))
.select_only()
.column_as(crate::models::server_item_order::Column::OrderKey.max(), "max_key")
.into_tuple::<Option<i64>>()
.one(&txn)
.await?
.flatten();
let next_order = max_order.unwrap_or(0) + 1;
let next_order = max_order.unwrap_or(0) + 1;
let order_item = crate::models::server_item_order::ActiveModel {
server_id: Set(server_id),
resource_id: Set(channel.id),
resource_type: Set(
crate::models::server_item_order::OrderedResourceType::Channel,
),
parent_category_id: Set(payload.category_id),
order_key: Set(next_order),
..Default::default()
};
order_item.insert(txn).await?;
let order_item = crate::models::server_item_order::ActiveModel {
server_id: Set(server_id),
resource_id: Set(channel.id),
resource_type: Set(crate::models::server_item_order::OrderedResourceType::Channel),
parent_category_id: Set(payload.category_id),
order_key: Set(next_order),
..Default::default()
};
order_item.insert(&txn).await?;
}
// 3. Attribution des permissions par défaut au rôle par défaut
if let Some(default_role) = role::Entity::find()
.filter(role::Column::ServerId.eq(server_id))
.filter(role::Column::IsDefault.eq(true))
.one(txn)
.await?
{
let default_channel_permissions =
PermissionSet::DEFAULT.channel.bits() as i64;
// Commit transaction
txn.commit().await?;
let role_perm = crate::models::channel_role_permission::ActiveModel {
channel_id: Set(channel.id),
role_id: Set(default_role.id),
permissions: Set(default_channel_permissions),
..Default::default()
};
role_perm.insert(txn).await?;
}
// 4. Refresh des permissions (Global pour l'instant)
// TODO: Cibler/focaliser le spectre du recalcul (ex: uniquement les membres impactés ou le canal spécifique)
PermissionService::sync_server_with_db(txn, server_id).await?;
}
Ok(channel)
})
})
.await?;
// Post-commit event emission
event_bus.emit("channel_created", channel.clone());
@@ -126,9 +161,7 @@ impl ChannelService {
.exec(&txn)
.await?;
let res = channel::Entity::delete_by_id(id)
.exec(&txn)
.await?;
let res = channel::Entity::delete_by_id(id).exec(&txn).await?;
let deleted = res.rows_affected > 0;
@@ -173,7 +206,10 @@ impl ChannelService {
txn.commit().await?;
event_bus.emit("channel_user_permission_created", (channel_id, user_id, permissions));
event_bus.emit(
"channel_user_permission_created",
(channel_id, user_id, permissions),
);
Ok(())
}
@@ -233,7 +269,10 @@ impl ChannelService {
txn.commit().await?;
event_bus.emit("channel_role_permission_created", (channel_id, role_id, permissions));
event_bus.emit(
"channel_role_permission_created",
(channel_id, role_id, permissions),
);
Ok(())
}