From c7dac2f4de917d073f368041a9528dcf504c5ca2 Mon Sep 17 00:00:00 2001 From: Mythie Date: Mon, 26 Feb 2024 10:01:13 +1100 Subject: [PATCH] fix: update delete endpoint and add limits --- .../documents/data-table-action-dropdown.tsx | 1 + .../documents/delete-document-dialog.tsx | 8 ++++--- packages/api/v1/implementation.ts | 23 +++++++++++++++++++ .../trpc/server/document-router/router.ts | 8 +++---- .../trpc/server/document-router/schema.ts | 3 ++- 5 files changed, 35 insertions(+), 8 deletions(-) diff --git a/apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx b/apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx index 6231b834c..a43d37af7 100644 --- a/apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx +++ b/apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx @@ -193,6 +193,7 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr documentTitle={row.title} open={isDeleteDialogOpen} onOpenChange={setDeleteDialogOpen} + teamId={team?.id} /> )} {isDuplicateDialogOpen && ( diff --git a/apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx b/apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx index 14249a2e2..59fd21e60 100644 --- a/apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx +++ b/apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx @@ -16,12 +16,13 @@ import { import { Input } from '@documenso/ui/primitives/input'; import { useToast } from '@documenso/ui/primitives/use-toast'; -type DeleteDraftDocumentDialogProps = { +type DeleteDocumentDialogProps = { id: number; open: boolean; onOpenChange: (_open: boolean) => void; status: DocumentStatus; documentTitle: string; + teamId?: number; }; export const DeleteDocumentDialog = ({ @@ -30,7 +31,8 @@ export const DeleteDocumentDialog = ({ onOpenChange, status, documentTitle, -}: DeleteDraftDocumentDialogProps) => { + teamId, +}: DeleteDocumentDialogProps) => { const router = useRouter(); const { toast } = useToast(); @@ -61,7 +63,7 @@ export const DeleteDocumentDialog = ({ const onDelete = async () => { try { - await deleteDocument({ id }); + await deleteDocument({ id, teamId }); } catch { toast({ title: 'Something went wrong', diff --git a/packages/api/v1/implementation.ts b/packages/api/v1/implementation.ts index a5144cff3..675c3b532 100644 --- a/packages/api/v1/implementation.ts +++ b/packages/api/v1/implementation.ts @@ -1,5 +1,6 @@ import { createNextRoute } from '@ts-rest/next'; +import { getServerLimits } from '@documenso/ee/server-only/limits/server'; import { createDocumentData } from '@documenso/lib/server-only/document-data/create-document-data'; import { upsertDocumentMeta } from '@documenso/lib/server-only/document-meta/upsert-document-meta'; import { createDocument } from '@documenso/lib/server-only/document/create-document'; @@ -131,6 +132,17 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, { }; } + const { remaining } = await getServerLimits({ email: user.email, teamId: team?.id }); + + if (remaining.documents <= 0) { + return { + status: 400, + body: { + message: 'You have reached the maximum number of documents allowed for this month', + }, + }; + } + const fileName = body.title.endsWith('.pdf') ? body.title : `${body.title}.pdf`; const { url, key } = await getPresignPostUrl(fileName, 'application/pdf'); @@ -183,6 +195,17 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, { createDocumentFromTemplate: authenticatedMiddleware(async (args, user, team) => { const { body, params } = args; + const { remaining } = await getServerLimits({ email: user.email, teamId: team?.id }); + + if (remaining.documents <= 0) { + return { + status: 400, + body: { + message: 'You have reached the maximum number of documents allowed for this month', + }, + }; + } + const templateId = Number(params.templateId); const fileName = body.title.endsWith('.pdf') ? body.title : `${body.title}.pdf`; diff --git a/packages/trpc/server/document-router/router.ts b/packages/trpc/server/document-router/router.ts index 9a7556821..cac41e181 100644 --- a/packages/trpc/server/document-router/router.ts +++ b/packages/trpc/server/document-router/router.ts @@ -21,7 +21,7 @@ import { extractNextApiRequestMetadata } from '@documenso/lib/universal/extract- import { authenticatedProcedure, procedure, router } from '../trpc'; import { ZCreateDocumentMutationSchema, - ZDeleteDraftDocumentMutationSchema, + ZDeleteDraftDocumentMutationSchema as ZDeleteDocumentMutationSchema, ZFindDocumentAuditLogsQuerySchema, ZGetDocumentByIdQuerySchema, ZGetDocumentByTokenQuerySchema, @@ -106,17 +106,17 @@ export const documentRouter = router({ }), deleteDocument: authenticatedProcedure - .input(ZDeleteDraftDocumentMutationSchema) + .input(ZDeleteDocumentMutationSchema) .mutation(async ({ input, ctx }) => { try { - const { id } = input; + const { id, teamId } = input; const userId = ctx.user.id; return await deleteDocument({ id, userId, - // TODO: Get teamId + teamId, requestMetadata: extractNextApiRequestMetadata(ctx.req), }); } catch (err) { diff --git a/packages/trpc/server/document-router/schema.ts b/packages/trpc/server/document-router/schema.ts index 985ba7795..f32b4b6a7 100644 --- a/packages/trpc/server/document-router/schema.ts +++ b/packages/trpc/server/document-router/schema.ts @@ -2,7 +2,7 @@ import { z } from 'zod'; import { URL_REGEX } from '@documenso/lib/constants/url-regex'; import { ZBaseTableSearchParamsSchema } from '@documenso/lib/types/search-params'; -import { DocumentStatus, FieldType, RecipientRole } from '@documenso/prisma/client'; +import { FieldType, RecipientRole } from '@documenso/prisma/client'; export const ZFindDocumentAuditLogsQuerySchema = ZBaseTableSearchParamsSchema.extend({ documentId: z.number().min(1), @@ -115,6 +115,7 @@ export type TSendDocumentMutationSchema = z.infer;