feat: add envelopes api (#2105)

This commit is contained in:
David Nguyen
2025-11-07 14:17:52 +11:00
committed by GitHub
parent d2a009d52e
commit d05bfa9fed
230 changed files with 10066 additions and 2812 deletions

View File

@ -1,18 +1,24 @@
import { getServerLimits } from '@documenso/ee/server-only/limits/server';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { createEnvelope } from '@documenso/lib/server-only/envelope/create-envelope';
import { putNormalizedPdfFileServerSide } from '@documenso/lib/universal/upload/put-file.server';
import { authenticatedProcedure } from '../trpc';
import {
ZCreateEnvelopeRequestSchema,
ZCreateEnvelopeResponseSchema,
createEnvelopeMeta,
} from './create-envelope.types';
export const createEnvelopeRoute = authenticatedProcedure
.meta(createEnvelopeMeta)
.input(ZCreateEnvelopeRequestSchema)
.output(ZCreateEnvelopeResponseSchema)
.mutation(async ({ input, ctx }) => {
const { user, teamId } = ctx;
const { payload, files } = input;
const {
title,
type,
@ -20,12 +26,12 @@ export const createEnvelopeRoute = authenticatedProcedure
visibility,
globalAccessAuth,
globalActionAuth,
formValues,
recipients,
folderId,
items,
meta,
attachments,
} = input;
} = payload;
ctx.logger.info({
input: {
@ -45,13 +51,62 @@ export const createEnvelopeRoute = authenticatedProcedure
});
}
if (items.length > maximumEnvelopeItemCount) {
if (files.length > maximumEnvelopeItemCount) {
throw new AppError('ENVELOPE_ITEM_LIMIT_EXCEEDED', {
message: `You cannot upload more than ${maximumEnvelopeItemCount} envelope items per envelope`,
statusCode: 400,
});
}
// 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);
return {
title: file.name,
documentDataId,
};
}),
);
const recipientsToCreate = recipients?.map((recipient) => ({
email: recipient.email,
name: recipient.name,
role: recipient.role,
signingOrder: recipient.signingOrder,
accessAuth: recipient.accessAuth,
actionAuth: recipient.actionAuth,
fields: recipient.fields?.map((field) => {
let documentDataId: string | undefined = undefined;
if (typeof field.identifier === 'string') {
documentDataId = envelopeItems.find(
(item) => item.title === field.identifier,
)?.documentDataId;
}
if (typeof field.identifier === 'number') {
documentDataId = envelopeItems.at(field.identifier)?.documentDataId;
}
if (field.identifier === undefined) {
documentDataId = envelopeItems.at(0)?.documentDataId;
}
if (!documentDataId) {
throw new AppError(AppErrorCode.NOT_FOUND, {
message: 'Document data not found',
});
}
return {
...field,
documentDataId,
};
}),
}));
const envelope = await createEnvelope({
userId: user.id,
teamId,
@ -60,16 +115,16 @@ export const createEnvelopeRoute = authenticatedProcedure
type,
title,
externalId,
formValues,
visibility,
globalAccessAuth,
globalActionAuth,
recipients,
recipients: recipientsToCreate,
folderId,
envelopeItems: items,
envelopeItems,
},
attachments,
meta,
normalizePdf: true,
requestMetadata: ctx.metadata,
});