fix: update create envelope item endpoint to use formdata

This commit is contained in:
David Nguyen
2025-11-05 22:10:17 +11:00
parent fc2e9af6a0
commit db2f912a08
10 changed files with 84 additions and 127 deletions

View File

@ -2,6 +2,7 @@ import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { getEnvelopeWhereInput } from '@documenso/lib/server-only/envelope/get-envelope-by-id';
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
import { prefixedId } from '@documenso/lib/universal/id';
import { putNormalizedPdfFileServerSide } from '@documenso/lib/universal/upload/put-file.server';
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
import { canEnvelopeItemsBeModified } from '@documenso/lib/utils/envelope';
import { prisma } from '@documenso/prisma';
@ -13,7 +14,6 @@ import {
} from './create-envelope-items.types';
export const createEnvelopeItemsRoute = authenticatedProcedure
// Todo: Envelopes - Pending direct uploads
.meta({
openapi: {
method: 'POST',
@ -27,7 +27,8 @@ export const createEnvelopeItemsRoute = authenticatedProcedure
.output(ZCreateEnvelopeItemsResponseSchema)
.mutation(async ({ input, ctx }) => {
const { user, teamId, metadata } = ctx;
const { envelopeId, data: items } = input;
const { payload, files } = input;
const { envelopeId } = payload;
ctx.logger.info({
input: {
@ -81,7 +82,7 @@ export const createEnvelopeItemsRoute = authenticatedProcedure
const organisationClaim = envelope.team.organisation.organisationClaim;
const remainingEnvelopeItems =
organisationClaim.envelopeItemCount - envelope.envelopeItems.length - items.length;
organisationClaim.envelopeItemCount - envelope.envelopeItems.length - files.length;
if (remainingEnvelopeItems < 0) {
throw new AppError('ENVELOPE_ITEM_LIMIT_EXCEEDED', {
@ -90,41 +91,24 @@ export const createEnvelopeItemsRoute = authenticatedProcedure
});
}
const foundDocumentData = await prisma.documentData.findMany({
where: {
id: {
in: items.map((item) => item.documentDataId),
},
},
select: {
envelopeItem: {
select: {
id: true,
},
},
},
});
// For each file, stream to s3 and create the document data.
const envelopeItems = await Promise.all(
files.map(async (file) => {
const { id: documentDataId } = await putNormalizedPdfFileServerSide(file);
// Check that all the document data was found.
if (foundDocumentData.length !== items.length) {
throw new AppError(AppErrorCode.NOT_FOUND, {
message: 'Document data not found',
});
}
// Check that it doesn't already have an envelope item.
if (foundDocumentData.some((documentData) => documentData.envelopeItem?.id)) {
throw new AppError(AppErrorCode.INVALID_REQUEST, {
message: 'Document data not found',
});
}
return {
title: file.name,
documentDataId,
};
}),
);
const currentHighestOrderValue =
envelope.envelopeItems[envelope.envelopeItems.length - 1]?.order ?? 1;
const result = await prisma.$transaction(async (tx) => {
const createdItems = await tx.envelopeItem.createManyAndReturn({
data: items.map((item) => ({
data: envelopeItems.map((item) => ({
id: prefixedId('envelope_item'),
envelopeId,
title: item.title,

View File

@ -1,38 +1,29 @@
import { z } from 'zod';
import { zfd } from 'zod-form-data';
import DocumentDataSchema from '@documenso/prisma/generated/zod/modelSchema/DocumentDataSchema';
import EnvelopeItemSchema from '@documenso/prisma/generated/zod/modelSchema/EnvelopeItemSchema';
import { ZDocumentTitleSchema } from '../document-router/schema';
import { zodFormData } from '../../utils/zod-form-data';
export const ZCreateEnvelopeItemsRequestSchema = z.object({
export const ZCreateEnvelopeItemsPayloadSchema = z.object({
envelopeId: z.string(),
data: z
.object({
title: ZDocumentTitleSchema,
documentDataId: z.string(),
})
.array(),
// data: z.object() // Currently not used.
});
export const ZCreateEnvelopeItemsRequestSchema = zodFormData({
payload: zfd.json(ZCreateEnvelopeItemsPayloadSchema),
files: zfd.repeatableOfType(zfd.file()),
});
export const ZCreateEnvelopeItemsResponseSchema = z.object({
createdEnvelopeItems: EnvelopeItemSchema.pick({
id: true,
title: true,
documentDataId: true,
envelopeId: true,
order: true,
})
.extend({
documentData: DocumentDataSchema.pick({
type: true,
id: true,
data: true,
initialData: true,
}),
})
.array(),
}).array(),
});
export type TCreateEnvelopeItemsPayload = z.infer<typeof ZCreateEnvelopeItemsPayloadSchema>;
export type TCreateEnvelopeItemsRequest = z.infer<typeof ZCreateEnvelopeItemsRequestSchema>;
export type TCreateEnvelopeItemsResponse = z.infer<typeof ZCreateEnvelopeItemsResponseSchema>;