use crate::models::category; use crate::models::server_item_order::OrderedResourceType; use crate::services::ServicesContext; use sea_orm::{ActiveModelTrait, EntityTrait, Set, TransactionTrait}; use std::sync::Arc; use uuid::Uuid; #[derive(Debug, Clone)] pub struct CategoryService { service_context: Arc, } impl CategoryService { pub fn new(service_context: Arc) -> Self { Self { service_context } } pub async fn create_category( &self, server_id: Uuid, name: String, ) -> Result { let db = &self.service_context.repositories.server.context.db; let event_bus = &self.service_context.event_bus; let server_order = self .service_context .services .get() .expect("services initialized") .server_order .clone(); let cat = db .transaction::<_, category::Model, anyhow::Error>(|txn| { Box::pin(async move { let active = category::ActiveModel { server_id: Set(server_id), name: Set(name), ..Default::default() }; let cat = active.insert(txn).await?; server_order .append(txn, server_id, cat.id, OrderedResourceType::Category, None) .await?; Ok(cat) }) }) .await?; event_bus.emit("category_created", cat.clone()); Ok(cat) } pub async fn update_category( &self, id: Uuid, name: String, ) -> 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 = category::Entity::find_by_id(id) .one(&txn) .await? .ok_or_else(|| anyhow::anyhow!("Category not found"))?; let mut active: category::ActiveModel = existing.into(); active.name = Set(name); let cat = active.update(&txn).await?; txn.commit().await?; event_bus.emit("category_updated", cat.clone()); Ok(cat) } pub async fn delete_category(&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 = category::Entity::find_by_id(id) .one(&txn) .await? .ok_or_else(|| anyhow::anyhow!("Category not found"))?; self.service_context .services .get() .expect("services initialized") .server_order .remove(&txn, id, OrderedResourceType::Category) .await?; let res = category::Entity::delete_by_id(id).exec(&txn).await?; let deleted = res.rows_affected > 0; txn.commit().await?; if deleted { event_bus.emit("category_deleted", existing); } Ok(deleted) } }