post services integrations
This commit is contained in:
@@ -0,0 +1,263 @@
|
||||
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 std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ChannelService {
|
||||
service_context: Arc<ServicesContext>,
|
||||
}
|
||||
|
||||
impl ChannelService {
|
||||
pub fn new(service_context: Arc<ServicesContext>) -> Self {
|
||||
Self { service_context }
|
||||
}
|
||||
|
||||
pub async fn create_channel(
|
||||
&self,
|
||||
payload: CreateChannelRequest,
|
||||
) -> Result<channel::Model, anyhow::Error> {
|
||||
let db = &self.service_context.repositories.server.context.db;
|
||||
let event_bus = &self.service_context.event_bus;
|
||||
|
||||
// Start transaction
|
||||
let txn = db.begin().await?;
|
||||
|
||||
// 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?;
|
||||
|
||||
// 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 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?;
|
||||
}
|
||||
|
||||
// Commit transaction
|
||||
txn.commit().await?;
|
||||
|
||||
// Post-commit event emission
|
||||
event_bus.emit("channel_created", channel.clone());
|
||||
|
||||
Ok(channel)
|
||||
}
|
||||
|
||||
pub async fn update_channel(
|
||||
&self,
|
||||
id: Uuid,
|
||||
payload: UpdateChannelRequest,
|
||||
) -> Result<channel::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 existing = channel::Entity::find_by_id(id)
|
||||
.one(&txn)
|
||||
.await?
|
||||
.ok_or_else(|| anyhow::anyhow!("Channel not found"))?;
|
||||
|
||||
let mut active: channel::ActiveModel = existing.into();
|
||||
active.server_id = Set(payload.server_id);
|
||||
active.category_id = Set(payload.category_id);
|
||||
active.channel_type = Set(payload.channel_type);
|
||||
active.name = Set(payload.name);
|
||||
|
||||
let channel = active.update(&txn).await?;
|
||||
|
||||
// Update server_item_order parent_category_id or server_id if needed
|
||||
if let Some(server_id) = channel.server_id {
|
||||
crate::models::server_item_order::Entity::update_many()
|
||||
.set(crate::models::server_item_order::ActiveModel {
|
||||
parent_category_id: Set(channel.category_id),
|
||||
..Default::default()
|
||||
})
|
||||
.filter(crate::models::server_item_order::Column::ResourceId.eq(channel.id))
|
||||
.exec(&txn)
|
||||
.await?;
|
||||
}
|
||||
|
||||
txn.commit().await?;
|
||||
|
||||
event_bus.emit("channel_updated", channel.clone());
|
||||
|
||||
Ok(channel)
|
||||
}
|
||||
|
||||
pub async fn delete_channel(&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?;
|
||||
|
||||
// Delete associated order records
|
||||
crate::models::server_item_order::Entity::delete_many()
|
||||
.filter(crate::models::server_item_order::Column::ResourceId.eq(id))
|
||||
.exec(&txn)
|
||||
.await?;
|
||||
|
||||
let res = channel::Entity::delete_by_id(id)
|
||||
.exec(&txn)
|
||||
.await?;
|
||||
|
||||
let deleted = res.rows_affected > 0;
|
||||
|
||||
txn.commit().await?;
|
||||
|
||||
if deleted {
|
||||
event_bus.emit("channel_deleted", id);
|
||||
}
|
||||
|
||||
Ok(deleted)
|
||||
}
|
||||
|
||||
pub async fn set_user_permission(
|
||||
&self,
|
||||
channel_id: Uuid,
|
||||
user_id: Uuid,
|
||||
permissions: u64,
|
||||
) -> Result<(), 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 permission = crate::models::channel_user_permission::ActiveModel {
|
||||
channel_id: Set(channel_id),
|
||||
user_id: Set(user_id),
|
||||
permissions: Set(permissions as i64),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
crate::models::channel_user_permission::Entity::insert(permission)
|
||||
.on_conflict(
|
||||
sea_orm::sea_query::OnConflict::columns([
|
||||
crate::models::channel_user_permission::Column::ChannelId,
|
||||
crate::models::channel_user_permission::Column::UserId,
|
||||
])
|
||||
.update_columns([crate::models::channel_user_permission::Column::Permissions])
|
||||
.to_owned(),
|
||||
)
|
||||
.exec(&txn)
|
||||
.await?;
|
||||
|
||||
txn.commit().await?;
|
||||
|
||||
event_bus.emit("channel_user_permission_created", (channel_id, user_id, permissions));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn remove_user_permission(
|
||||
&self,
|
||||
channel_id: Uuid,
|
||||
user_id: Uuid,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let db = &self.service_context.repositories.server.context.db;
|
||||
let event_bus = &self.service_context.event_bus;
|
||||
|
||||
let txn = db.begin().await?;
|
||||
|
||||
crate::models::channel_user_permission::Entity::delete_many()
|
||||
.filter(crate::models::channel_user_permission::Column::ChannelId.eq(channel_id))
|
||||
.filter(crate::models::channel_user_permission::Column::UserId.eq(user_id))
|
||||
.exec(&txn)
|
||||
.await?;
|
||||
|
||||
txn.commit().await?;
|
||||
|
||||
event_bus.emit("channel_user_permission_deleted", (channel_id, user_id));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn set_role_permission(
|
||||
&self,
|
||||
channel_id: Uuid,
|
||||
role_id: Uuid,
|
||||
permissions: u64,
|
||||
) -> Result<(), 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 permission = crate::models::channel_role_permission::ActiveModel {
|
||||
channel_id: Set(channel_id),
|
||||
role_id: Set(role_id),
|
||||
permissions: Set(permissions as i64),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
crate::models::channel_role_permission::Entity::insert(permission)
|
||||
.on_conflict(
|
||||
sea_orm::sea_query::OnConflict::columns([
|
||||
crate::models::channel_role_permission::Column::ChannelId,
|
||||
crate::models::channel_role_permission::Column::RoleId,
|
||||
])
|
||||
.update_columns([crate::models::channel_role_permission::Column::Permissions])
|
||||
.to_owned(),
|
||||
)
|
||||
.exec(&txn)
|
||||
.await?;
|
||||
|
||||
txn.commit().await?;
|
||||
|
||||
event_bus.emit("channel_role_permission_created", (channel_id, role_id, permissions));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn remove_role_permission(
|
||||
&self,
|
||||
channel_id: Uuid,
|
||||
role_id: Uuid,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let db = &self.service_context.repositories.server.context.db;
|
||||
let event_bus = &self.service_context.event_bus;
|
||||
|
||||
let txn = db.begin().await?;
|
||||
|
||||
crate::models::channel_role_permission::Entity::delete_many()
|
||||
.filter(crate::models::channel_role_permission::Column::ChannelId.eq(channel_id))
|
||||
.filter(crate::models::channel_role_permission::Column::RoleId.eq(role_id))
|
||||
.exec(&txn)
|
||||
.await?;
|
||||
|
||||
txn.commit().await?;
|
||||
|
||||
event_bus.emit("channel_role_permission_deleted", (channel_id, role_id));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user