fix: incorrect requester avatar url and workspace member count (#847)

This commit is contained in:
Khor Shu Heng 2024-09-29 11:03:08 +08:00 committed by GitHub
parent 47a1aae75c
commit 757d0e5380
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 115 additions and 57 deletions

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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,

View File

@ -55,6 +55,49 @@ impl TryFrom<AFWorkspaceRow> for AFWorkspace {
}
}
#[derive(Debug, Clone, FromRow, Serialize, Deserialize, sqlx::Type)]
pub struct AFWorkspaceWithMemberCountRow {
pub workspace_id: Uuid,
pub database_storage_id: Option<Uuid>,
pub owner_uid: Option<i64>,
pub owner_name: Option<String>,
pub created_at: Option<DateTime<Utc>>,
pub workspace_type: i32,
pub deleted_at: Option<DateTime<Utc>>,
pub workspace_name: Option<String>,
pub icon: Option<String>,
pub member_count: i64,
}
impl TryFrom<AFWorkspaceWithMemberCountRow> for AFWorkspace {
type Error = AppError;
fn try_from(value: AFWorkspaceWithMemberCountRow) -> Result<Self, Self::Error> {
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<AFAccessRequestMinimalColumn> 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,

View File

@ -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