feat: signing order (#1290)

Adds the ability to specify an optional signing order for documents.
When specified a document will be considered sequential with recipients
only being allowed to sign in the order that they were specified in.
This commit is contained in:
Ephraim Duncan
2024-09-16 12:36:45 +00:00
committed by GitHub
parent 357bdd374f
commit 3d644db286
66 changed files with 1999 additions and 606 deletions

View File

@ -0,0 +1,46 @@
import { prisma } from '@documenso/prisma';
import { DocumentSigningOrder, SigningStatus } from '@documenso/prisma/client';
export type GetIsRecipientTurnOptions = {
token: string;
};
export async function getIsRecipientsTurnToSign({ token }: GetIsRecipientTurnOptions) {
const document = await prisma.document.findFirstOrThrow({
where: {
Recipient: {
some: {
token,
},
},
},
include: {
documentMeta: true,
Recipient: {
orderBy: {
signingOrder: 'asc',
},
},
},
});
if (document.documentMeta?.signingOrder !== DocumentSigningOrder.SEQUENTIAL) {
return true;
}
const recipients = document.Recipient;
const currentRecipientIndex = recipients.findIndex((r) => r.token === token);
if (currentRecipientIndex === -1) {
return false;
}
for (let i = 0; i < currentRecipientIndex; i++) {
if (recipients[i].signingStatus !== SigningStatus.SIGNED) {
return false;
}
}
return true;
}

View File

@ -27,6 +27,7 @@ export interface SetRecipientsForDocumentOptions {
email: string;
name: string;
role: RecipientRole;
signingOrder?: number | null;
actionAuth?: TRecipientActionAuthTypes | null;
}[];
requestMetadata?: RequestMetadata;
@ -156,6 +157,7 @@ export const setRecipientsForDocument = async ({
name: recipient.name,
email: recipient.email,
role: recipient.role,
signingOrder: recipient.signingOrder,
documentId,
sendStatus: recipient.role === RecipientRole.CC ? SendStatus.SENT : SendStatus.NOT_SENT,
signingStatus:
@ -166,6 +168,7 @@ export const setRecipientsForDocument = async ({
name: recipient.name,
email: recipient.email,
role: recipient.role,
signingOrder: recipient.signingOrder,
token: nanoid(),
documentId,
sendStatus: recipient.role === RecipientRole.CC ? SendStatus.SENT : SendStatus.NOT_SENT,

View File

@ -24,6 +24,7 @@ export type SetRecipientsForTemplateOptions = {
email: string;
name: string;
role: RecipientRole;
signingOrder?: number | null;
actionAuth?: TRecipientActionAuthTypes | null;
}[];
};
@ -162,6 +163,7 @@ export const setRecipientsForTemplate = async ({
name: recipient.name,
email: recipient.email,
role: recipient.role,
signingOrder: recipient.signingOrder,
templateId,
authOptions,
},
@ -169,6 +171,7 @@ export const setRecipientsForTemplate = async ({
name: recipient.name,
email: recipient.email,
role: recipient.role,
signingOrder: recipient.signingOrder,
token: nanoid(),
templateId,
authOptions,

View File

@ -18,6 +18,7 @@ export type UpdateRecipientOptions = {
email?: string;
name?: string;
role?: RecipientRole;
signingOrder?: number | null;
actionAuth?: TRecipientActionAuthTypes | null;
userId: number;
teamId?: number;
@ -30,6 +31,7 @@ export const updateRecipient = async ({
email,
name,
role,
signingOrder,
actionAuth,
userId,
teamId,
@ -112,6 +114,7 @@ export const updateRecipient = async ({
email: email?.toLowerCase() ?? recipient.email,
name: name ?? recipient.name,
role: role ?? recipient.role,
signingOrder,
authOptions: createRecipientAuthOptions({
accessAuth: recipientAuthOptions.accessAuth,
actionAuth: actionAuth ?? null,