From 98ca0a739d99493e07febd73763a50a859ecabce Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Tue, 19 Mar 2024 10:45:02 +0800 Subject: [PATCH] feat: allow get invitations by invitee --- packages/core/src/queries/organization/index.ts | 11 ++++++++++- .../core/src/routes/organization/invitations.ts | 4 +++- .../organization-invitation.get.test.ts | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/core/src/queries/organization/index.ts b/packages/core/src/queries/organization/index.ts index bdb648d24..e5d74641c 100644 --- a/packages/core/src/queries/organization/index.ts +++ b/packages/core/src/queries/organization/index.ts @@ -92,6 +92,7 @@ type OrganizationInvitationSearchOptions = { invitationId?: string; organizationId?: string; inviterId?: string; + invitee?: string; }; class OrganizationInvitationsQueries extends SchemaQueries< @@ -115,7 +116,12 @@ class OrganizationInvitationsQueries extends SchemaQueries< return this.pool.any(this.#findEntity({ ...options, invitationId: undefined })); } - #findEntity({ invitationId, organizationId, inviterId }: OrganizationInvitationSearchOptions) { + #findEntity({ + invitationId, + organizationId, + inviterId, + invitee, + }: OrganizationInvitationSearchOptions) { const { table, fields } = convertToIdentifiers(OrganizationInvitations, true); const roleRelations = convertToIdentifiers(OrganizationInvitationRoleRelations, true); const roles = convertToIdentifiers(OrganizationRoles, true); @@ -159,6 +165,9 @@ class OrganizationInvitationsQueries extends SchemaQueries< ${conditionalSql(inviterId, (id) => { return sql`and ${fields.inviterId} = ${id}`; })} + ${conditionalSql(invitee, (email) => { + return sql`and ${fields.invitee} = ${email}`; + })} group by ${fields.id} ${conditionalSql(this.orderBy, ({ field, order }) => { return sql`order by ${fields[field]} ${order === 'desc' ? sql`desc` : sql`asc`}`; diff --git a/packages/core/src/routes/organization/invitations.ts b/packages/core/src/routes/organization/invitations.ts index 49e5627a8..4136532b0 100644 --- a/packages/core/src/routes/organization/invitations.ts +++ b/packages/core/src/routes/organization/invitations.ts @@ -39,7 +39,9 @@ export default function organizationInvitationRoutes( router.get( '/', koaGuard({ - query: z.object({ organizationId: z.string().optional(), inviterId: z.string().optional() }), + query: z + .object({ organizationId: z.string(), inviterId: z.string(), invitee: z.string() }) + .partial(), response: organizationInvitationEntityGuard.array(), status: [200], }), diff --git a/packages/integration-tests/src/tests/api/organization/organization-invitation.get.test.ts b/packages/integration-tests/src/tests/api/organization/organization-invitation.get.test.ts index c54215496..e59e3c4c1 100644 --- a/packages/integration-tests/src/tests/api/organization/organization-invitation.get.test.ts +++ b/packages/integration-tests/src/tests/api/organization/organization-invitation.get.test.ts @@ -61,6 +61,20 @@ describe('organization invitation creation', () => { await Promise.all([deleteUser(inviter.id), deleteUser(inviter2.id)]); }); + it('should be able to get invitations by invitee', async () => { + const organization = await organizationApi.create({ name: 'test' }); + const invitee = `${randomId()}@example.com`; + await invitationApi.create({ + organizationId: organization.id, + invitee, + expiresAt: Date.now() + 1_000_000, + }); + + const invitations = await invitationApi.getList(new URLSearchParams({ invitee })); + expect(invitations.length).toBe(1); + expect(invitations[0]?.invitee).toBe(invitee); + }); + it('should have no pagination', async () => { const organization = await organizationApi.create({ name: 'test' }); await Promise.all(