use crate::AppService; use crate::error::AppError; use chrono::Utc; use models::workspaces::{WorkspaceRole, workspace}; use sea_orm::*; use serde::{Deserialize, Serialize}; use session::Session; #[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)] pub struct WorkspaceUpdateParams { pub name: Option, pub description: Option, pub avatar_url: Option, pub billing_email: Option, } impl AppService { pub async fn workspace_update( &self, ctx: &Session, workspace_slug: String, params: WorkspaceUpdateParams, ) -> Result { let user_uid = ctx.user().ok_or(AppError::Unauthorized)?; let ws = self .utils_find_workspace_by_slug(workspace_slug.clone()) .await?; self.utils_check_workspace_permission(ws.id, user_uid, &[WorkspaceRole::Admin]) .await?; let mut m: workspace::ActiveModel = ws.into(); if let Some(name) = params.name { // Check name uniqueness if workspace::Entity::find() .filter(workspace::Column::Name.eq(&name)) .filter(workspace::Column::DeletedAt.is_null()) .filter(workspace::Column::Id.ne(m.id.clone().unwrap())) .one(&self.db) .await? .is_some() { return Err(AppError::WorkspaceNameAlreadyExists); } m.name = Set(name); } if let Some(description) = params.description { m.description = Set(Some(description)); } if let Some(avatar_url) = params.avatar_url { m.avatar_url = Set(Some(avatar_url)); } if let Some(billing_email) = params.billing_email { m.billing_email = Set(Some(billing_email)); } m.updated_at = Set(Utc::now()); m.update(&self.db).await.map_err(Into::into) } /// Soft-delete a workspace. Only owner can delete. pub async fn workspace_delete( &self, ctx: &Session, workspace_slug: String, ) -> Result<(), AppError> { let user_uid = ctx.user().ok_or(AppError::Unauthorized)?; let ws = self.utils_find_workspace_by_slug(workspace_slug).await?; self.utils_check_workspace_permission(ws.id, user_uid, &[WorkspaceRole::Owner]) .await?; let mut m: workspace::ActiveModel = ws.into(); m.deleted_at = Set(Some(Utc::now())); m.updated_at = Set(Utc::now()); m.update(&self.db).await?; Ok(()) } }