use crate::services::ServicesContext; use crate::models::{role, user}; use crate::auth::password; use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, TransactionTrait, Set}; use std::sync::Arc; use uuid::Uuid; #[derive(Debug, Clone)] pub struct UserService { service_context: Arc, } impl UserService { pub fn new(service_context: Arc) -> Self { Self { service_context } } pub async fn create_user( &self, active: user::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 usr = active.insert(&txn).await?; txn.commit().await?; event_bus.emit("user_created", usr.clone()); Ok(usr) } pub async fn update_user( &self, active: user::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 usr = active.update(&txn).await?; txn.commit().await?; event_bus.emit("user_updated", usr.clone()); Ok(usr) } pub async fn set_password(&self, id: Uuid, password_str: String) -> 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 user_model = user::Entity::find_by_id(id) .one(&txn) .await? .ok_or_else(|| anyhow::anyhow!("User not found"))?; let mut active = user_model.into_active_model(); let password_to_hash = password_str.clone(); let hashed = tokio::task::spawn_blocking(move || password::hash_password(&password_to_hash)) .await .map_err(|e| anyhow::anyhow!("Join error: {}", e))? .map_err(|e| anyhow::anyhow!("Password hashing failed: {}", e))?; active.password = Set(hashed); let usr = active.update(&txn).await?; txn.commit().await?; event_bus.emit("user_changed", usr); Ok(()) } pub async fn delete_user(&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 res = user::Entity::delete_by_id(id) .exec(&txn) .await?; let deleted = res.rows_affected > 0; txn.commit().await?; if deleted { event_bus.emit("user_deleted", id); } Ok(deleted) } }