From 11cdc862f2b4b57983fb19fdfaaa44c673d0fd36 Mon Sep 17 00:00:00 2001 From: Zack Fu Zi Xiang Date: Fri, 13 Sep 2024 17:43:10 +0800 Subject: [PATCH] feat: additional fields for workspace invitation --- ...44ac932ee88c6326ecaf9b4b4c7f690eff41c.json | 59 -------------- ...6965553938838c83085273f68f687c976767a.json | 77 +++++++++++++++++++ ...e111d06e327edd9f3a98a4b0636bfe8fd6319.json | 59 -------------- ...a14b5ae2fd15b3c5d2b84d5dd5a551954ecde.json | 77 +++++++++++++++++++ libs/database-entity/src/dto.rs | 3 + libs/database/src/workspace.rs | 69 +++++++++++------ tests/workspace/invitation_crud.rs | 9 +++ 7 files changed, 210 insertions(+), 143 deletions(-) delete mode 100644 .sqlx/query-2c1152b8867bebcb63b637820eb44ac932ee88c6326ecaf9b4b4c7f690eff41c.json create mode 100644 .sqlx/query-2ee385e58e042071290226289646965553938838c83085273f68f687c976767a.json delete mode 100644 .sqlx/query-6dd7f6db2d364cc37b1b46c611fe111d06e327edd9f3a98a4b0636bfe8fd6319.json create mode 100644 .sqlx/query-de595bd6554d8e1f58c9c4bb94ea14b5ae2fd15b3c5d2b84d5dd5a551954ecde.json diff --git a/.sqlx/query-2c1152b8867bebcb63b637820eb44ac932ee88c6326ecaf9b4b4c7f690eff41c.json b/.sqlx/query-2c1152b8867bebcb63b637820eb44ac932ee88c6326ecaf9b4b4c7f690eff41c.json deleted file mode 100644 index c62ab8d1..00000000 --- a/.sqlx/query-2c1152b8867bebcb63b637820eb44ac932ee88c6326ecaf9b4b4c7f690eff41c.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n id AS invite_id,\n workspace_id,\n (SELECT workspace_name FROM public.af_workspace WHERE workspace_id = af_workspace_invitation.workspace_id),\n (SELECT email FROM public.af_user WHERE uid = af_workspace_invitation.inviter) AS inviter_email,\n (SELECT name FROM public.af_user WHERE uid = af_workspace_invitation.inviter) AS inviter_name,\n status,\n updated_at\n FROM\n public.af_workspace_invitation\n WHERE af_workspace_invitation.invitee_email = (SELECT email FROM public.af_user WHERE uuid = $1)\n AND ($2::SMALLINT IS NULL OR status = $2)\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "invite_id", - "type_info": "Uuid" - }, - { - "ordinal": 1, - "name": "workspace_id", - "type_info": "Uuid" - }, - { - "ordinal": 2, - "name": "workspace_name", - "type_info": "Text" - }, - { - "ordinal": 3, - "name": "inviter_email", - "type_info": "Text" - }, - { - "ordinal": 4, - "name": "inviter_name", - "type_info": "Text" - }, - { - "ordinal": 5, - "name": "status", - "type_info": "Int2" - }, - { - "ordinal": 6, - "name": "updated_at", - "type_info": "Timestamptz" - } - ], - "parameters": { - "Left": [ - "Uuid", - "Int2" - ] - }, - "nullable": [ - false, - false, - null, - null, - null, - false, - false - ] - }, - "hash": "2c1152b8867bebcb63b637820eb44ac932ee88c6326ecaf9b4b4c7f690eff41c" -} diff --git a/.sqlx/query-2ee385e58e042071290226289646965553938838c83085273f68f687c976767a.json b/.sqlx/query-2ee385e58e042071290226289646965553938838c83085273f68f687c976767a.json new file mode 100644 index 00000000..c11d4afc --- /dev/null +++ b/.sqlx/query-2ee385e58e042071290226289646965553938838c83085273f68f687c976767a.json @@ -0,0 +1,77 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n i.id AS invite_id,\n i.workspace_id,\n w.workspace_name,\n u_inviter.email AS inviter_email,\n u_inviter.name AS inviter_name,\n i.status,\n i.updated_at,\n u_inviter.metadata->>'icon_url' AS inviter_icon,\n w.icon AS workspace_icon,\n (SELECT COUNT(*) FROM public.af_workspace_member m WHERE m.workspace_id = i.workspace_id) AS member_count\n FROM\n public.af_workspace_invitation i\n JOIN public.af_workspace w ON i.workspace_id = w.workspace_id\n JOIN public.af_user u_inviter ON i.inviter = u_inviter.uid\n JOIN public.af_user u_invitee ON u_invitee.uuid = $1\n WHERE\n i.invitee_email = u_invitee.email\n AND i.id = $2;\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "invite_id", + "type_info": "Uuid" + }, + { + "ordinal": 1, + "name": "workspace_id", + "type_info": "Uuid" + }, + { + "ordinal": 2, + "name": "workspace_name", + "type_info": "Text" + }, + { + "ordinal": 3, + "name": "inviter_email", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "inviter_name", + "type_info": "Text" + }, + { + "ordinal": 5, + "name": "status", + "type_info": "Int2" + }, + { + "ordinal": 6, + "name": "updated_at", + "type_info": "Timestamptz" + }, + { + "ordinal": 7, + "name": "inviter_icon", + "type_info": "Text" + }, + { + "ordinal": 8, + "name": "workspace_icon", + "type_info": "Text" + }, + { + "ordinal": 9, + "name": "member_count", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Uuid", + "Uuid" + ] + }, + "nullable": [ + false, + false, + true, + false, + false, + false, + false, + null, + false, + null + ] + }, + "hash": "2ee385e58e042071290226289646965553938838c83085273f68f687c976767a" +} diff --git a/.sqlx/query-6dd7f6db2d364cc37b1b46c611fe111d06e327edd9f3a98a4b0636bfe8fd6319.json b/.sqlx/query-6dd7f6db2d364cc37b1b46c611fe111d06e327edd9f3a98a4b0636bfe8fd6319.json deleted file mode 100644 index 6c269e95..00000000 --- a/.sqlx/query-6dd7f6db2d364cc37b1b46c611fe111d06e327edd9f3a98a4b0636bfe8fd6319.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n id AS invite_id,\n workspace_id,\n (SELECT workspace_name FROM public.af_workspace WHERE workspace_id = af_workspace_invitation.workspace_id),\n (SELECT email FROM public.af_user WHERE uid = af_workspace_invitation.inviter) AS inviter_email,\n (SELECT name FROM public.af_user WHERE uid = af_workspace_invitation.inviter) AS inviter_name,\n status,\n updated_at\n FROM public.af_workspace_invitation\n WHERE af_workspace_invitation.invitee_email = (SELECT email FROM public.af_user WHERE uuid = $1)\n AND id = $2\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "invite_id", - "type_info": "Uuid" - }, - { - "ordinal": 1, - "name": "workspace_id", - "type_info": "Uuid" - }, - { - "ordinal": 2, - "name": "workspace_name", - "type_info": "Text" - }, - { - "ordinal": 3, - "name": "inviter_email", - "type_info": "Text" - }, - { - "ordinal": 4, - "name": "inviter_name", - "type_info": "Text" - }, - { - "ordinal": 5, - "name": "status", - "type_info": "Int2" - }, - { - "ordinal": 6, - "name": "updated_at", - "type_info": "Timestamptz" - } - ], - "parameters": { - "Left": [ - "Uuid", - "Uuid" - ] - }, - "nullable": [ - false, - false, - null, - null, - null, - false, - false - ] - }, - "hash": "6dd7f6db2d364cc37b1b46c611fe111d06e327edd9f3a98a4b0636bfe8fd6319" -} diff --git a/.sqlx/query-de595bd6554d8e1f58c9c4bb94ea14b5ae2fd15b3c5d2b84d5dd5a551954ecde.json b/.sqlx/query-de595bd6554d8e1f58c9c4bb94ea14b5ae2fd15b3c5d2b84d5dd5a551954ecde.json new file mode 100644 index 00000000..0dc790db --- /dev/null +++ b/.sqlx/query-de595bd6554d8e1f58c9c4bb94ea14b5ae2fd15b3c5d2b84d5dd5a551954ecde.json @@ -0,0 +1,77 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n i.id AS invite_id,\n i.workspace_id,\n w.workspace_name,\n u_inviter.email AS inviter_email,\n u_inviter.name AS inviter_name,\n i.status,\n i.updated_at,\n u_inviter.metadata->>'icon_url' AS inviter_icon,\n w.icon AS workspace_icon,\n (SELECT COUNT(*) FROM public.af_workspace_member m WHERE m.workspace_id = i.workspace_id) AS member_count\n FROM\n public.af_workspace_invitation i\n JOIN public.af_workspace w ON i.workspace_id = w.workspace_id\n JOIN public.af_user u_inviter ON i.inviter = u_inviter.uid\n JOIN public.af_user u_invitee ON u_invitee.uuid = $1\n WHERE\n i.invitee_email = u_invitee.email\n AND ($2::SMALLINT IS NULL OR i.status = $2);\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "invite_id", + "type_info": "Uuid" + }, + { + "ordinal": 1, + "name": "workspace_id", + "type_info": "Uuid" + }, + { + "ordinal": 2, + "name": "workspace_name", + "type_info": "Text" + }, + { + "ordinal": 3, + "name": "inviter_email", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "inviter_name", + "type_info": "Text" + }, + { + "ordinal": 5, + "name": "status", + "type_info": "Int2" + }, + { + "ordinal": 6, + "name": "updated_at", + "type_info": "Timestamptz" + }, + { + "ordinal": 7, + "name": "inviter_icon", + "type_info": "Text" + }, + { + "ordinal": 8, + "name": "workspace_icon", + "type_info": "Text" + }, + { + "ordinal": 9, + "name": "member_count", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Uuid", + "Int2" + ] + }, + "nullable": [ + false, + false, + true, + false, + false, + false, + false, + null, + false, + null + ] + }, + "hash": "de595bd6554d8e1f58c9c4bb94ea14b5ae2fd15b3c5d2b84d5dd5a551954ecde" +} diff --git a/libs/database-entity/src/dto.rs b/libs/database-entity/src/dto.rs index e197ef98..38744f89 100644 --- a/libs/database-entity/src/dto.rs +++ b/libs/database-entity/src/dto.rs @@ -601,6 +601,9 @@ pub struct AFWorkspaceInvitation { pub inviter_name: Option, pub status: AFWorkspaceInvitationStatus, pub updated_at: DateTime, + pub inviter_icon: Option, + pub workspace_icon: String, + pub member_count: Option, // use unwrap_or(0) to get the value } #[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)] diff --git a/libs/database/src/workspace.rs b/libs/database/src/workspace.rs index 85d2e692..354ac035 100644 --- a/libs/database/src/workspace.rs +++ b/libs/database/src/workspace.rs @@ -409,22 +409,31 @@ pub async fn select_workspace_invitations_for_user( let res = sqlx::query_as!( AFWorkspaceInvitation, r#" - SELECT - id AS invite_id, - workspace_id, - (SELECT workspace_name FROM public.af_workspace WHERE workspace_id = af_workspace_invitation.workspace_id), - (SELECT email FROM public.af_user WHERE uid = af_workspace_invitation.inviter) AS inviter_email, - (SELECT name FROM public.af_user WHERE uid = af_workspace_invitation.inviter) AS inviter_name, - status, - updated_at - FROM - public.af_workspace_invitation - WHERE af_workspace_invitation.invitee_email = (SELECT email FROM public.af_user WHERE uuid = $1) - AND ($2::SMALLINT IS NULL OR status = $2) + SELECT + i.id AS invite_id, + i.workspace_id, + w.workspace_name, + u_inviter.email AS inviter_email, + u_inviter.name AS inviter_name, + i.status, + i.updated_at, + u_inviter.metadata->>'icon_url' AS inviter_icon, + w.icon AS workspace_icon, + (SELECT COUNT(*) FROM public.af_workspace_member m WHERE m.workspace_id = i.workspace_id) AS member_count + FROM + public.af_workspace_invitation i + JOIN public.af_workspace w ON i.workspace_id = w.workspace_id + JOIN public.af_user u_inviter ON i.inviter = u_inviter.uid + JOIN public.af_user u_invitee ON u_invitee.uuid = $1 + WHERE + i.invitee_email = u_invitee.email + AND ($2::SMALLINT IS NULL OR i.status = $2); "#, invitee_uuid, status_filter.map(|s| s as i16) - ).fetch_all(pg_pool).await?; + ) + .fetch_all(pg_pool) + .await?; Ok(res) } @@ -437,21 +446,31 @@ pub async fn select_workspace_invitation_for_user( let res = sqlx::query_as!( AFWorkspaceInvitation, r#" - SELECT - id AS invite_id, - workspace_id, - (SELECT workspace_name FROM public.af_workspace WHERE workspace_id = af_workspace_invitation.workspace_id), - (SELECT email FROM public.af_user WHERE uid = af_workspace_invitation.inviter) AS inviter_email, - (SELECT name FROM public.af_user WHERE uid = af_workspace_invitation.inviter) AS inviter_name, - status, - updated_at - FROM public.af_workspace_invitation - WHERE af_workspace_invitation.invitee_email = (SELECT email FROM public.af_user WHERE uuid = $1) - AND id = $2 + SELECT + i.id AS invite_id, + i.workspace_id, + w.workspace_name, + u_inviter.email AS inviter_email, + u_inviter.name AS inviter_name, + i.status, + i.updated_at, + u_inviter.metadata->>'icon_url' AS inviter_icon, + w.icon AS workspace_icon, + (SELECT COUNT(*) FROM public.af_workspace_member m WHERE m.workspace_id = i.workspace_id) AS member_count + FROM + public.af_workspace_invitation i + JOIN public.af_workspace w ON i.workspace_id = w.workspace_id + JOIN public.af_user u_inviter ON i.inviter = u_inviter.uid + JOIN public.af_user u_invitee ON u_invitee.uuid = $1 + WHERE + i.invitee_email = u_invitee.email + AND i.id = $2; "#, invitee_uuid, invite_id, - ).fetch_one(pg_pool).await?; + ) + .fetch_one(pg_pool) + .await?; Ok(res) } diff --git a/tests/workspace/invitation_crud.rs b/tests/workspace/invitation_crud.rs index e84cc655..1a59f2f8 100644 --- a/tests/workspace/invitation_crud.rs +++ b/tests/workspace/invitation_crud.rs @@ -59,12 +59,21 @@ async fn invite_workspace_crud() { assert_eq!(invitation.inviter_email, Some(alice.email)); assert_eq!(invitation.status, AFWorkspaceInvitationStatus::Pending); + assert_eq!(invitation.member_count.unwrap_or(0), 1); bob_client .accept_workspace_invitation(&invite_id) .await .unwrap(); + let invitation = bob_client + .get_workspace_invitation(&invite_id) + .await + .unwrap(); + + assert_eq!(invitation.status, AFWorkspaceInvitationStatus::Accepted); + assert_eq!(invitation.member_count.unwrap_or(0), 2); + // list invitation with accepted filter let accepted_invs = bob_client .list_workspace_invitations(Some(AFWorkspaceInvitationStatus::Accepted))