166 lines
5.2 KiB
Rust
166 lines
5.2 KiB
Rust
use anyhow::Context;
|
|
use app_error::AppError;
|
|
use database::collab::upsert_collab_member_with_txn;
|
|
use database::pg_row::{AFWorkspaceMemberRow, AFWorkspaceRow};
|
|
use database::user::select_uid_from_email;
|
|
use database::workspace::{
|
|
delete_from_workspace, delete_workspace_members, insert_user_workspace,
|
|
insert_workspace_member_with_txn, select_all_user_workspaces, select_workspace,
|
|
select_workspace_member_list, update_updated_at_of_workspace, upsert_workspace_member,
|
|
};
|
|
use database_entity::dto::{AFAccessLevel, AFRole, AFWorkspace};
|
|
use shared_entity::dto::workspace_dto::{CreateWorkspaceMember, WorkspaceMemberChangeset};
|
|
use shared_entity::response::AppResponseError;
|
|
use sqlx::{types::uuid, PgPool};
|
|
use std::collections::HashMap;
|
|
use std::ops::DerefMut;
|
|
use tracing::instrument;
|
|
use uuid::Uuid;
|
|
|
|
pub async fn delete_workspace_for_user(
|
|
pg_pool: &PgPool,
|
|
workspace_id: &Uuid,
|
|
) -> Result<(), AppResponseError> {
|
|
delete_from_workspace(pg_pool, workspace_id).await?;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn create_workspace_for_user(
|
|
pg_pool: &PgPool,
|
|
user_uuid: &Uuid,
|
|
workspace_name: &str,
|
|
) -> Result<AFWorkspace, AppResponseError> {
|
|
let new_workspace_row = insert_user_workspace(pg_pool, user_uuid, workspace_name).await?;
|
|
let new_workspace = AFWorkspace::try_from(new_workspace_row)?;
|
|
Ok(new_workspace)
|
|
}
|
|
|
|
pub async fn get_all_user_workspaces(
|
|
pg_pool: &PgPool,
|
|
user_uuid: &Uuid,
|
|
) -> Result<Vec<AFWorkspaceRow>, AppResponseError> {
|
|
let workspaces = select_all_user_workspaces(pg_pool, user_uuid).await?;
|
|
Ok(workspaces)
|
|
}
|
|
|
|
/// Returns the workspace with the given workspace_id and update the updated_at field of the
|
|
/// workspace.
|
|
pub async fn open_workspace(
|
|
pg_pool: &PgPool,
|
|
user_uuid: &Uuid,
|
|
workspace_id: &Uuid,
|
|
) -> Result<AFWorkspace, AppResponseError> {
|
|
let mut txn = pg_pool
|
|
.begin()
|
|
.await
|
|
.context("Begin transaction to open workspace")?;
|
|
let row = select_workspace(txn.deref_mut(), workspace_id).await?;
|
|
update_updated_at_of_workspace(txn.deref_mut(), user_uuid, workspace_id).await?;
|
|
txn
|
|
.commit()
|
|
.await
|
|
.context("Commit transaction to open workspace")?;
|
|
let workspace = AFWorkspace::try_from(row)?;
|
|
|
|
Ok(workspace)
|
|
}
|
|
|
|
/// Returns the list of uid of members that are added to the workspace.
|
|
/// Adds members to a workspace.
|
|
///
|
|
/// This function is responsible for adding a list of members to a specified workspace.
|
|
/// Each member is associated with a role, which determines their access level within the workspace.
|
|
/// The function performs the following operations:
|
|
/// 1. Begins a database transaction.
|
|
/// 2. For each member:
|
|
/// - Determines the access level based on the member's role.
|
|
/// - If the member exists (based on their email), inserts them into the workspace and updates their collaboration access level.
|
|
/// 3. Commits the database transaction.
|
|
///
|
|
/// # Returns
|
|
/// - A `Result` containing a `HashMap` where the key is the user ID (`uid`) and the value is the role (`AFRole`) assigned to the user in the workspace.
|
|
/// If there's an error during the operation, an `AppError` is returned.
|
|
///
|
|
#[instrument(level = "debug", skip_all, err)]
|
|
pub async fn add_workspace_members(
|
|
pg_pool: &PgPool,
|
|
_user_uuid: &Uuid,
|
|
workspace_id: &Uuid,
|
|
members: Vec<CreateWorkspaceMember>,
|
|
) -> Result<HashMap<i64, AFRole>, AppError> {
|
|
let mut txn = pg_pool
|
|
.begin()
|
|
.await
|
|
.context("Begin transaction to insert workspace members")?;
|
|
|
|
let mut role_by_uid = HashMap::new();
|
|
for member in members.into_iter() {
|
|
let access_level = match &member.role {
|
|
AFRole::Owner => AFAccessLevel::FullAccess,
|
|
AFRole::Member => AFAccessLevel::ReadAndWrite,
|
|
AFRole::Guest => AFAccessLevel::ReadOnly,
|
|
};
|
|
|
|
let uid = select_uid_from_email(txn.deref_mut(), &member.email).await?;
|
|
// .context(format!(
|
|
// "Failed to get uid from email {} when adding workspace members",
|
|
// member.email
|
|
// ))?;
|
|
insert_workspace_member_with_txn(&mut txn, workspace_id, &member.email, member.role.clone())
|
|
.await?;
|
|
upsert_collab_member_with_txn(uid, workspace_id.to_string(), &access_level, &mut txn).await?;
|
|
role_by_uid.insert(uid, member.role);
|
|
}
|
|
|
|
txn
|
|
.commit()
|
|
.await
|
|
.context("Commit transaction to insert workspace members")?;
|
|
Ok(role_by_uid)
|
|
}
|
|
|
|
pub async fn remove_workspace_members(
|
|
user_uuid: &Uuid,
|
|
pg_pool: &PgPool,
|
|
workspace_id: &Uuid,
|
|
member_emails: &[String],
|
|
) -> Result<(), AppResponseError> {
|
|
let mut txn = pg_pool
|
|
.begin()
|
|
.await
|
|
.context("Begin transaction to delete workspace members")?;
|
|
|
|
for email in member_emails {
|
|
delete_workspace_members(user_uuid, &mut txn, workspace_id, email.as_str()).await?;
|
|
}
|
|
|
|
txn
|
|
.commit()
|
|
.await
|
|
.context("Commit transaction to delete workspace members")?;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn get_workspace_members(
|
|
pg_pool: &PgPool,
|
|
_user_uuid: &Uuid,
|
|
workspace_id: &Uuid,
|
|
) -> Result<Vec<AFWorkspaceMemberRow>, AppResponseError> {
|
|
Ok(select_workspace_member_list(pg_pool, workspace_id).await?)
|
|
}
|
|
|
|
pub async fn update_workspace_member(
|
|
pg_pool: &PgPool,
|
|
workspace_id: &Uuid,
|
|
changeset: &WorkspaceMemberChangeset,
|
|
) -> Result<(), AppError> {
|
|
upsert_workspace_member(
|
|
pg_pool,
|
|
workspace_id,
|
|
&changeset.email,
|
|
changeset.role.clone(),
|
|
)
|
|
.await?;
|
|
Ok(())
|
|
}
|