Files
documenso/packages/trpc/server/team-router/router.ts
David Nguyen 5df1a6602e fix: refactor search routes (#1529)
Refactor find endpoints to be consistent in terms of input and output.
2024-12-11 19:39:50 +09:00

655 lines
20 KiB
TypeScript

import { TRPCError } from '@trpc/server';
import { z } from 'zod';
import { getTeamPrices } from '@documenso/ee/server-only/stripe/get-team-prices';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { acceptTeamInvitation } from '@documenso/lib/server-only/team/accept-team-invitation';
import { createTeam } from '@documenso/lib/server-only/team/create-team';
import { createTeamBillingPortal } from '@documenso/lib/server-only/team/create-team-billing-portal';
import { createTeamPendingCheckoutSession } from '@documenso/lib/server-only/team/create-team-checkout-session';
import { createTeamEmailVerification } from '@documenso/lib/server-only/team/create-team-email-verification';
import { createTeamMemberInvites } from '@documenso/lib/server-only/team/create-team-member-invites';
import { declineTeamInvitation } from '@documenso/lib/server-only/team/decline-team-invitation';
import { deleteTeam } from '@documenso/lib/server-only/team/delete-team';
import { deleteTeamEmail } from '@documenso/lib/server-only/team/delete-team-email';
import { deleteTeamEmailVerification } from '@documenso/lib/server-only/team/delete-team-email-verification';
import { deleteTeamMemberInvitations } from '@documenso/lib/server-only/team/delete-team-invitations';
import { deleteTeamMembers } from '@documenso/lib/server-only/team/delete-team-members';
import { deleteTeamPending } from '@documenso/lib/server-only/team/delete-team-pending';
import { deleteTeamTransferRequest } from '@documenso/lib/server-only/team/delete-team-transfer-request';
import { findTeamInvoices } from '@documenso/lib/server-only/team/find-team-invoices';
import { findTeamMemberInvites } from '@documenso/lib/server-only/team/find-team-member-invites';
import { findTeamMembers } from '@documenso/lib/server-only/team/find-team-members';
import { findTeams } from '@documenso/lib/server-only/team/find-teams';
import { findTeamsPending } from '@documenso/lib/server-only/team/find-teams-pending';
import { getTeamById } from '@documenso/lib/server-only/team/get-team';
import { getTeamEmailByEmail } from '@documenso/lib/server-only/team/get-team-email-by-email';
import { getTeamInvitations } from '@documenso/lib/server-only/team/get-team-invitations';
import { getTeamMembers } from '@documenso/lib/server-only/team/get-team-members';
import { getTeams } from '@documenso/lib/server-only/team/get-teams';
import { leaveTeam } from '@documenso/lib/server-only/team/leave-team';
import { requestTeamOwnershipTransfer } from '@documenso/lib/server-only/team/request-team-ownership-transfer';
import { resendTeamEmailVerification } from '@documenso/lib/server-only/team/resend-team-email-verification';
import { resendTeamMemberInvitation } from '@documenso/lib/server-only/team/resend-team-member-invitation';
import { updateTeam } from '@documenso/lib/server-only/team/update-team';
import { updateTeamBrandingSettings } from '@documenso/lib/server-only/team/update-team-branding-settings';
import { updateTeamDocumentSettings } from '@documenso/lib/server-only/team/update-team-document-settings';
import { updateTeamEmail } from '@documenso/lib/server-only/team/update-team-email';
import { updateTeamMember } from '@documenso/lib/server-only/team/update-team-member';
import { updateTeamPublicProfile } from '@documenso/lib/server-only/team/update-team-public-profile';
import { authenticatedProcedure, router } from '../trpc';
import {
ZAcceptTeamInvitationMutationSchema,
ZCreateTeamBillingPortalMutationSchema,
ZCreateTeamEmailVerificationMutationSchema,
ZCreateTeamMemberInvitesMutationSchema,
ZCreateTeamMutationSchema,
ZCreateTeamPendingCheckoutMutationSchema,
ZDeclineTeamInvitationMutationSchema,
ZDeleteTeamEmailMutationSchema,
ZDeleteTeamEmailVerificationMutationSchema,
ZDeleteTeamMemberInvitationsMutationSchema,
ZDeleteTeamMembersMutationSchema,
ZDeleteTeamMutationSchema,
ZDeleteTeamPendingMutationSchema,
ZDeleteTeamTransferRequestMutationSchema,
ZFindTeamInvoicesQuerySchema,
ZFindTeamMemberInvitesQuerySchema,
ZFindTeamMembersQuerySchema,
ZFindTeamsPendingQuerySchema,
ZFindTeamsQuerySchema,
ZGetTeamMembersQuerySchema,
ZGetTeamQuerySchema,
ZLeaveTeamMutationSchema,
ZRequestTeamOwnerhsipTransferMutationSchema,
ZResendTeamEmailVerificationMutationSchema,
ZResendTeamMemberInvitationMutationSchema,
ZUpdateTeamBrandingSettingsMutationSchema,
ZUpdateTeamDocumentSettingsMutationSchema,
ZUpdateTeamEmailMutationSchema,
ZUpdateTeamMemberMutationSchema,
ZUpdateTeamMutationSchema,
ZUpdateTeamPublicProfileMutationSchema,
} from './schema';
export const teamRouter = router({
// Internal endpoint for now.
getTeams: authenticatedProcedure.query(async ({ ctx }) => {
return await getTeams({ userId: ctx.user.id });
}),
findTeams: authenticatedProcedure
.meta({
openapi: {
method: 'GET',
path: '/team',
summary: 'Find teams',
description: 'Find your teams based on a search criteria',
tags: ['Teams'],
},
})
.input(ZFindTeamsQuerySchema)
.output(z.unknown())
.query(async ({ input, ctx }) => {
return await findTeams({
userId: ctx.user.id,
...input,
});
}),
getTeam: authenticatedProcedure
.meta({
openapi: {
method: 'GET',
path: '/team/{teamId}',
summary: 'Get team',
tags: ['Teams'],
},
})
.input(ZGetTeamQuerySchema)
.output(z.unknown())
.query(async ({ input, ctx }) => {
return await getTeamById({ teamId: input.teamId, userId: ctx.user.id });
}),
createTeam: authenticatedProcedure
.meta({
openapi: {
method: 'POST',
path: '/team/create',
summary: 'Create team',
tags: ['Teams'],
},
})
.input(ZCreateTeamMutationSchema)
.output(z.unknown())
.mutation(async ({ input, ctx }) => {
return await createTeam({
userId: ctx.user.id,
...input,
});
}),
updateTeam: authenticatedProcedure
.meta({
openapi: {
method: 'POST',
path: '/team/{teamId}',
summary: 'Update team',
tags: ['Teams'],
},
})
.input(ZUpdateTeamMutationSchema)
.output(z.unknown())
.mutation(async ({ input, ctx }) => {
return await updateTeam({
userId: ctx.user.id,
...input,
});
}),
deleteTeam: authenticatedProcedure
.meta({
openapi: {
method: 'POST',
path: '/team/{teamId}/delete',
summary: 'Delete team',
tags: ['Teams'],
},
})
.input(ZDeleteTeamMutationSchema)
.output(z.unknown())
.mutation(async ({ input, ctx }) => {
return await deleteTeam({
userId: ctx.user.id,
...input,
});
}),
leaveTeam: authenticatedProcedure
.meta({
openapi: {
method: 'POST',
path: '/team/{teamId}/leave',
summary: 'Leave a team',
description: '',
tags: ['Teams'],
},
})
.input(ZLeaveTeamMutationSchema)
.output(z.unknown())
.mutation(async ({ input, ctx }) => {
return await leaveTeam({
userId: ctx.user.id,
...input,
});
}),
findTeamMemberInvites: authenticatedProcedure
.meta({
openapi: {
method: 'GET',
path: '/team/{teamId}/member/invite',
summary: 'Find member invites',
description: 'Returns pending team member invites',
tags: ['Teams'],
},
})
.input(ZFindTeamMemberInvitesQuerySchema)
.output(z.unknown())
.query(async ({ input, ctx }) => {
return await findTeamMemberInvites({
userId: ctx.user.id,
...input,
});
}),
createTeamMemberInvites: authenticatedProcedure
.meta({
openapi: {
method: 'POST',
path: '/team/{teamId}/member/invite',
summary: 'Invite members',
description: 'Send email invitations to users to join the team',
tags: ['Teams'],
},
})
.input(ZCreateTeamMemberInvitesMutationSchema)
.output(z.unknown())
.mutation(async ({ input, ctx }) => {
return await createTeamMemberInvites({
userId: ctx.user.id,
userName: ctx.user.name ?? '',
...input,
});
}),
resendTeamMemberInvitation: authenticatedProcedure
.meta({
openapi: {
method: 'POST',
path: '/team/{teamId}/member/invite/{invitationId}/resend',
summary: 'Resend member invite',
description: 'Resend an email invitation to a user to join the team',
tags: ['Teams'],
},
})
.input(ZResendTeamMemberInvitationMutationSchema)
.output(z.unknown())
.mutation(async ({ input, ctx }) => {
await resendTeamMemberInvitation({
userId: ctx.user.id,
userName: ctx.user.name ?? '',
...input,
});
}),
deleteTeamMemberInvitations: authenticatedProcedure
.meta({
openapi: {
method: 'POST',
path: '/team/{teamId}/member/invite/delete',
summary: 'Delete member invite',
description: 'Delete a pending team member invite',
tags: ['Teams'],
},
})
.input(ZDeleteTeamMemberInvitationsMutationSchema)
.output(z.unknown())
.mutation(async ({ input, ctx }) => {
return await deleteTeamMemberInvitations({
userId: ctx.user.id,
...input,
});
}),
getTeamMembers: authenticatedProcedure
.meta({
openapi: {
method: 'GET',
path: '/team/{teamId}/member',
summary: 'Get members',
tags: ['Teams'],
},
})
.input(ZGetTeamMembersQuerySchema)
.output(z.unknown())
.query(async ({ input, ctx }) => {
return await getTeamMembers({ teamId: input.teamId, userId: ctx.user.id });
}),
findTeamMembers: authenticatedProcedure
.meta({
openapi: {
method: 'GET',
path: '/team/{teamId}/member/find',
summary: 'Find members',
description: 'Find team members based on a search criteria',
tags: ['Teams'],
},
})
.input(ZFindTeamMembersQuerySchema)
.output(z.unknown())
.query(async ({ input, ctx }) => {
return await findTeamMembers({
userId: ctx.user.id,
...input,
});
}),
updateTeamMember: authenticatedProcedure
.meta({
openapi: {
method: 'POST',
path: '/team/{teamId}/member/{teamMemberId}',
summary: 'Update member',
tags: ['Teams'],
},
})
.input(ZUpdateTeamMemberMutationSchema)
.output(z.unknown())
.mutation(async ({ input, ctx }) => {
return await updateTeamMember({
userId: ctx.user.id,
...input,
});
}),
deleteTeamMembers: authenticatedProcedure
.meta({
openapi: {
method: 'POST',
path: '/team/{teamId}/member/delete',
summary: 'Delete members',
description: '',
tags: ['Teams'],
},
})
.input(ZDeleteTeamMembersMutationSchema)
.output(z.unknown())
.mutation(async ({ input, ctx }) => {
return await deleteTeamMembers({
userId: ctx.user.id,
...input,
});
}),
// Internal endpoint for now.
createTeamEmailVerification: authenticatedProcedure
// .meta({
// openapi: {
// method: 'POST',
// path: '/team/{teamId}/email/create',
// summary: 'Create team email',
// description: 'Add an email to a team and send an email request to verify it',
// tags: ['Teams'],
// },
// })
.input(ZCreateTeamEmailVerificationMutationSchema)
.mutation(async ({ input, ctx }) => {
return await createTeamEmailVerification({
teamId: input.teamId,
userId: ctx.user.id,
data: {
email: input.email,
name: input.name,
},
});
}),
// Internal endpoint for now.
getTeamInvitations: authenticatedProcedure
// .meta({
// openapi: {
// method: 'GET',
// path: '/team/invite',
// summary: 'Get team invitations',
// description: '',
// tags: ['Teams'],
// },
// })
.input(z.void())
.query(async ({ ctx }) => {
return await getTeamInvitations({ email: ctx.user.email });
}),
updateTeamPublicProfile: authenticatedProcedure
.meta({
openapi: {
method: 'POST',
path: '/team/{teamId}/profile',
summary: 'Update a team public profile',
description: '',
tags: ['Teams'],
},
})
.input(ZUpdateTeamPublicProfileMutationSchema)
.output(z.unknown())
.mutation(async ({ input, ctx }) => {
try {
const { teamId, bio, enabled } = input;
await updateTeamPublicProfile({
userId: ctx.user.id,
teamId,
data: {
bio,
enabled,
},
});
} catch (err) {
console.error(err);
const error = AppError.parseError(err);
if (error.code !== AppErrorCode.UNKNOWN_ERROR) {
throw error;
}
throw new TRPCError({
code: 'BAD_REQUEST',
message:
'We were unable to update your public profile. Please review the information you provided and try again.',
});
}
}),
// Internal endpoint for now.
requestTeamOwnershipTransfer: authenticatedProcedure
// .meta({
// openapi: {
// method: 'POST',
// path: '/team/{teamId}/transfer',
// summary: 'Request a team ownership transfer',
// description: '',
// tags: ['Teams'],
// },
// })
.input(ZRequestTeamOwnerhsipTransferMutationSchema)
.mutation(async ({ input, ctx }) => {
return await requestTeamOwnershipTransfer({
userId: ctx.user.id,
userName: ctx.user.name ?? '',
...input,
});
}),
// Internal endpoint for now.
deleteTeamTransferRequest: authenticatedProcedure
// .meta({
// openapi: {
// method: 'POST',
// path: '/team/{teamId}/transfer/delete',
// summary: 'Delete team transfer request',
// tags: ['Teams'],
// },
// })
.input(ZDeleteTeamTransferRequestMutationSchema)
.mutation(async ({ input, ctx }) => {
return await deleteTeamTransferRequest({
userId: ctx.user.id,
...input,
});
}),
// Todo
getTeamEmailByEmail: authenticatedProcedure.query(async ({ ctx }) => {
return await getTeamEmailByEmail({ email: ctx.user.email });
}),
// Internal endpoint for now.
updateTeamEmail: authenticatedProcedure
// .meta({
// openapi: {
// method: 'POST',
// path: '/team/{teamId}/email',
// summary: 'Update a team email',
// description: '',
// tags: ['Teams'],
// },
// })
.input(ZUpdateTeamEmailMutationSchema)
.mutation(async ({ input, ctx }) => {
return await updateTeamEmail({
userId: ctx.user.id,
...input,
});
}),
// Internal endpoint for now.
deleteTeamEmail: authenticatedProcedure
// .meta({
// openapi: {
// method: 'POST',
// path: '/team/{teamId}/email/delete',
// summary: 'Delete team email',
// description: '',
// tags: ['Teams'],
// },
// })
.input(ZDeleteTeamEmailMutationSchema)
.mutation(async ({ input, ctx }) => {
return await deleteTeamEmail({
userId: ctx.user.id,
userEmail: ctx.user.email,
...input,
});
}),
// Internal endpoint for now.
resendTeamEmailVerification: authenticatedProcedure
// .meta({
// openapi: {
// method: 'POST',
// path: '/team/{teamId}/email/resend',
// summary: 'Resend team email verification',
// tags: ['Teams'],
// },
// })
.input(ZResendTeamEmailVerificationMutationSchema)
.mutation(async ({ input, ctx }) => {
await resendTeamEmailVerification({
userId: ctx.user.id,
...input,
});
}),
// Internal endpoint for now.
deleteTeamEmailVerification: authenticatedProcedure
// .meta({
// openapi: {
// method: 'POST',
// path: '/team/{teamId}/email/verify/delete',
// summary: 'Delete team email verification',
// tags: ['Teams'],
// },
// })
.input(ZDeleteTeamEmailVerificationMutationSchema)
.mutation(async ({ input, ctx }) => {
return await deleteTeamEmailVerification({
userId: ctx.user.id,
...input,
});
}),
// Internal endpoint. Use updateTeam instead.
updateTeamBrandingSettings: authenticatedProcedure
.input(ZUpdateTeamBrandingSettingsMutationSchema)
.mutation(async ({ ctx, input }) => {
const { teamId, settings } = input;
return await updateTeamBrandingSettings({
userId: ctx.user.id,
teamId,
settings,
});
}),
// Internal endpoint for now.
createTeamPendingCheckout: authenticatedProcedure
.input(ZCreateTeamPendingCheckoutMutationSchema)
.mutation(async ({ input, ctx }) => {
return await createTeamPendingCheckoutSession({
userId: ctx.user.id,
...input,
});
}),
// Internal endpoint for now.
findTeamInvoices: authenticatedProcedure
.input(ZFindTeamInvoicesQuerySchema)
.query(async ({ input, ctx }) => {
return await findTeamInvoices({
userId: ctx.user.id,
...input,
});
}),
// Internal endpoint for now.
getTeamPrices: authenticatedProcedure.query(async () => {
return await getTeamPrices();
}),
// Internal endpoint. Use updateTeam instead.
updateTeamDocumentSettings: authenticatedProcedure
.input(ZUpdateTeamDocumentSettingsMutationSchema)
.mutation(async ({ ctx, input }) => {
const { teamId, settings } = input;
return await updateTeamDocumentSettings({
userId: ctx.user.id,
teamId,
settings,
});
}),
// Internal endpoint for now.
acceptTeamInvitation: authenticatedProcedure
.input(ZAcceptTeamInvitationMutationSchema)
.mutation(async ({ input, ctx }) => {
return await acceptTeamInvitation({
teamId: input.teamId,
userId: ctx.user.id,
});
}),
// Internal endpoint for now.
declineTeamInvitation: authenticatedProcedure
.input(ZDeclineTeamInvitationMutationSchema)
.mutation(async ({ input, ctx }) => {
return await declineTeamInvitation({
teamId: input.teamId,
userId: ctx.user.id,
});
}),
// Internal endpoint for now.
createBillingPortal: authenticatedProcedure
.input(ZCreateTeamBillingPortalMutationSchema)
.mutation(async ({ input, ctx }) => {
return await createTeamBillingPortal({
userId: ctx.user.id,
...input,
});
}),
// Internal endpoint for now.
findTeamsPending: authenticatedProcedure
// .meta({
// openapi: {
// method: 'GET',
// path: '/team/pending',
// summary: 'Find pending teams',
// description: 'Find teams that are pending payment',
// tags: ['Teams'],
// },
// })
.input(ZFindTeamsPendingQuerySchema)
.query(async ({ input, ctx }) => {
return await findTeamsPending({
userId: ctx.user.id,
...input,
});
}),
// Internal endpoint for now.
deleteTeamPending: authenticatedProcedure
// .meta({
// openapi: {
// method: 'POST',
// path: '/team/pending/{pendingTeamId}/delete',
// summary: 'Delete pending team',
// description: '',
// tags: ['Teams'],
// },
// })
.input(ZDeleteTeamPendingMutationSchema)
.mutation(async ({ input, ctx }) => {
return await deleteTeamPending({
userId: ctx.user.id,
...input,
});
}),
});