From 757d0e53807a1df8b69a1d2a3d8d758dd80cbc6a Mon Sep 17 00:00:00 2001 From: Khor Shu Heng <32997938+khorshuheng@users.noreply.github.com> Date: Sun, 29 Sep 2024 11:03:08 +0800 Subject: [PATCH] fix: incorrect requester avatar url and workspace member count (#847) --- ...8f28e239a30fab8891497a28d6b079141f7bf.json | 52 ------------------- ...d8de543c15f2aa0318dac2d10c5f1ef0f0232.json | 52 +++++++++++++++++++ libs/database/src/access_request.rs | 19 +++++-- libs/database/src/pg_row.rs | 45 +++++++++++++++- tests/workspace/access_request.rs | 4 ++ 5 files changed, 115 insertions(+), 57 deletions(-) delete mode 100644 .sqlx/query-222344980faea1b159256d6d5128f28e239a30fab8891497a28d6b079141f7bf.json create mode 100644 .sqlx/query-343cdf36e68c8333ecc6b778789d8de543c15f2aa0318dac2d10c5f1ef0f0232.json diff --git a/.sqlx/query-222344980faea1b159256d6d5128f28e239a30fab8891497a28d6b079141f7bf.json b/.sqlx/query-222344980faea1b159256d6d5128f28e239a30fab8891497a28d6b079141f7bf.json deleted file mode 100644 index e063855ea..000000000 --- a/.sqlx/query-222344980faea1b159256d6d5128f28e239a30fab8891497a28d6b079141f7bf.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n request_id,\n view_id,\n (\n workspace_id,\n af_workspace.database_storage_id,\n af_workspace.owner_uid,\n owner_profile.name,\n af_workspace.created_at,\n af_workspace.workspace_type,\n af_workspace.deleted_at,\n af_workspace.workspace_name,\n af_workspace.icon\n ) AS \"workspace!: AFWorkspaceRow\",\n (\n af_user.uuid,\n af_user.name,\n af_user.email,\n af_user.metadata ->> 'avatar'\n ) AS \"requester!: AFAccessRequesterColumn\",\n status AS \"status: AFAccessRequestStatusColumn\",\n af_access_request.created_at AS created_at\n FROM af_access_request\n JOIN af_user USING (uid)\n JOIN af_workspace USING (workspace_id)\n JOIN af_user AS owner_profile ON af_workspace.owner_uid = owner_profile.uid\n WHERE request_id = $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "request_id", - "type_info": "Uuid" - }, - { - "ordinal": 1, - "name": "view_id", - "type_info": "Uuid" - }, - { - "ordinal": 2, - "name": "workspace!: AFWorkspaceRow", - "type_info": "Record" - }, - { - "ordinal": 3, - "name": "requester!: AFAccessRequesterColumn", - "type_info": "Record" - }, - { - "ordinal": 4, - "name": "status: AFAccessRequestStatusColumn", - "type_info": "Int4" - }, - { - "ordinal": 5, - "name": "created_at", - "type_info": "Timestamptz" - } - ], - "parameters": { - "Left": [ - "Uuid" - ] - }, - "nullable": [ - false, - false, - null, - null, - false, - false - ] - }, - "hash": "222344980faea1b159256d6d5128f28e239a30fab8891497a28d6b079141f7bf" -} diff --git a/.sqlx/query-343cdf36e68c8333ecc6b778789d8de543c15f2aa0318dac2d10c5f1ef0f0232.json b/.sqlx/query-343cdf36e68c8333ecc6b778789d8de543c15f2aa0318dac2d10c5f1ef0f0232.json new file mode 100644 index 000000000..c86517cab --- /dev/null +++ b/.sqlx/query-343cdf36e68c8333ecc6b778789d8de543c15f2aa0318dac2d10c5f1ef0f0232.json @@ -0,0 +1,52 @@ +{ + "db_name": "PostgreSQL", + "query": "\n WITH request_id_workspace_member_count AS (\n SELECT\n request_id,\n COUNT(*) AS member_count\n FROM af_access_request\n JOIN af_workspace_member USING (workspace_id)\n WHERE request_id = $1\n GROUP BY request_id\n )\n SELECT\n request_id,\n view_id,\n (\n workspace_id,\n af_workspace.database_storage_id,\n af_workspace.owner_uid,\n owner_profile.name,\n af_workspace.created_at,\n af_workspace.workspace_type,\n af_workspace.deleted_at,\n af_workspace.workspace_name,\n af_workspace.icon,\n request_id_workspace_member_count.member_count\n ) AS \"workspace!: AFWorkspaceWithMemberCountRow\",\n (\n af_user.uuid,\n af_user.name,\n af_user.email,\n af_user.metadata ->> 'icon_url'\n ) AS \"requester!: AFAccessRequesterColumn\",\n status AS \"status: AFAccessRequestStatusColumn\",\n af_access_request.created_at AS created_at\n FROM af_access_request\n JOIN af_user USING (uid)\n JOIN af_workspace USING (workspace_id)\n JOIN af_user AS owner_profile ON af_workspace.owner_uid = owner_profile.uid\n JOIN request_id_workspace_member_count USING (request_id)\n WHERE request_id = $1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "request_id", + "type_info": "Uuid" + }, + { + "ordinal": 1, + "name": "view_id", + "type_info": "Uuid" + }, + { + "ordinal": 2, + "name": "workspace!: AFWorkspaceWithMemberCountRow", + "type_info": "Record" + }, + { + "ordinal": 3, + "name": "requester!: AFAccessRequesterColumn", + "type_info": "Record" + }, + { + "ordinal": 4, + "name": "status: AFAccessRequestStatusColumn", + "type_info": "Int4" + }, + { + "ordinal": 5, + "name": "created_at", + "type_info": "Timestamptz" + } + ], + "parameters": { + "Left": [ + "Uuid" + ] + }, + "nullable": [ + false, + false, + null, + null, + false, + false + ] + }, + "hash": "343cdf36e68c8333ecc6b778789d8de543c15f2aa0318dac2d10c5f1ef0f0232" +} diff --git a/libs/database/src/access_request.rs b/libs/database/src/access_request.rs index f5d69702e..4650fd1e6 100644 --- a/libs/database/src/access_request.rs +++ b/libs/database/src/access_request.rs @@ -1,6 +1,6 @@ use crate::pg_row::{ AFAccessRequestStatusColumn, AFAccessRequestWithViewIdColumn, AFAccessRequesterColumn, - AFWorkspaceRow, + AFWorkspaceWithMemberCountRow, }; use app_error::AppError; use database_entity::dto::AccessRequestWithViewId; @@ -54,6 +54,15 @@ pub async fn select_access_request_by_request_id<'a, E: Executor<'a, Database = let access_request = sqlx::query_as!( AFAccessRequestWithViewIdColumn, r#" + WITH request_id_workspace_member_count AS ( + SELECT + request_id, + COUNT(*) AS member_count + FROM af_access_request + JOIN af_workspace_member USING (workspace_id) + WHERE request_id = $1 + GROUP BY request_id + ) SELECT request_id, view_id, @@ -66,13 +75,14 @@ pub async fn select_access_request_by_request_id<'a, E: Executor<'a, Database = af_workspace.workspace_type, af_workspace.deleted_at, af_workspace.workspace_name, - af_workspace.icon - ) AS "workspace!: AFWorkspaceRow", + af_workspace.icon, + request_id_workspace_member_count.member_count + ) AS "workspace!: AFWorkspaceWithMemberCountRow", ( af_user.uuid, af_user.name, af_user.email, - af_user.metadata ->> 'avatar' + af_user.metadata ->> 'icon_url' ) AS "requester!: AFAccessRequesterColumn", status AS "status: AFAccessRequestStatusColumn", af_access_request.created_at AS created_at @@ -80,6 +90,7 @@ pub async fn select_access_request_by_request_id<'a, E: Executor<'a, Database = JOIN af_user USING (uid) JOIN af_workspace USING (workspace_id) JOIN af_user AS owner_profile ON af_workspace.owner_uid = owner_profile.uid + JOIN request_id_workspace_member_count USING (request_id) WHERE request_id = $1 "#, request_id, diff --git a/libs/database/src/pg_row.rs b/libs/database/src/pg_row.rs index 70b3d8024..357bd2b2d 100644 --- a/libs/database/src/pg_row.rs +++ b/libs/database/src/pg_row.rs @@ -55,6 +55,49 @@ impl TryFrom for AFWorkspace { } } +#[derive(Debug, Clone, FromRow, Serialize, Deserialize, sqlx::Type)] +pub struct AFWorkspaceWithMemberCountRow { + pub workspace_id: Uuid, + pub database_storage_id: Option, + pub owner_uid: Option, + pub owner_name: Option, + pub created_at: Option>, + pub workspace_type: i32, + pub deleted_at: Option>, + pub workspace_name: Option, + pub icon: Option, + pub member_count: i64, +} + +impl TryFrom for AFWorkspace { + type Error = AppError; + + fn try_from(value: AFWorkspaceWithMemberCountRow) -> Result { + let owner_uid = value + .owner_uid + .ok_or(AppError::Internal(anyhow!("Unexpected empty owner_uid")))?; + let database_storage_id = value + .database_storage_id + .ok_or(AppError::Internal(anyhow!("Unexpected empty workspace_id")))?; + + let workspace_name = value.workspace_name.unwrap_or_default(); + let created_at = value.created_at.unwrap_or_else(Utc::now); + let icon = value.icon.unwrap_or_default(); + + Ok(Self { + workspace_id: value.workspace_id, + database_storage_id, + owner_uid, + owner_name: value.owner_name.unwrap_or_default(), + workspace_type: value.workspace_type, + workspace_name, + created_at, + icon, + member_count: Some(value.member_count), + }) + } +} + /// Represent the row of the af_user table #[derive(Debug, FromRow, Deserialize, Serialize, Clone)] pub struct AFUserRow { @@ -563,7 +606,7 @@ impl From for AccessRequestMinimal { #[derive(Serialize, Deserialize, Debug)] pub struct AFAccessRequestWithViewIdColumn { pub request_id: Uuid, - pub workspace: AFWorkspaceRow, + pub workspace: AFWorkspaceWithMemberCountRow, pub requester: AccessRequesterInfo, pub view_id: Uuid, pub status: AFAccessRequestStatusColumn, diff --git a/tests/workspace/access_request.rs b/tests/workspace/access_request.rs index 816132891..92d3c8a02 100644 --- a/tests/workspace/access_request.rs +++ b/tests/workspace/access_request.rs @@ -58,6 +58,10 @@ async fn access_request_test() { access_request_to_be_approved.workspace.workspace_id, workspace_id ); + assert_eq!( + access_request_to_be_approved.workspace.member_count, + Some(1) + ); owner_client .approve_access_request(access_request_id) .await