fix: move sealing to a background job (#1287)

When signing a document the final signer is often
greeted with a super long completing spinner since
we are synchronously signing the document and sending
emails to all recipients. This is frustrating and
has caused issues for customers and self-hosters.

Moving sealing to a background job resolves this
and improves the overall snappiness of the app while
also supporting retrying the sealing if it were to
fail in the future.

This has the implication of a document no longer
immediately being in a "completed" state once all
signers have signed. To assist with this we now
refetch the page every 5 seconds upon signing
completion until the document status as shifted to
completed.
This commit is contained in:
Lucas Smith
2024-08-14 13:12:32 +10:00
committed by GitHub
parent 20ec2dde3d
commit ab8701526c
9 changed files with 326 additions and 23 deletions

View File

@ -1,5 +1,3 @@
'use server';
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
@ -7,9 +5,9 @@ import { prisma } from '@documenso/prisma';
import { DocumentStatus, SigningStatus } from '@documenso/prisma/client';
import { WebhookTriggerEvents } from '@documenso/prisma/client';
import { jobs } from '../../jobs/client';
import type { TRecipientActionAuth } from '../../types/document-auth';
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
import { sealDocument } from './seal-document';
import { sendPendingEmail } from './send-pending-email';
export type CompleteDocumentWithTokenOptions = {
@ -45,8 +43,6 @@ export const completeDocumentWithToken = async ({
documentId,
requestMetadata,
}: CompleteDocumentWithTokenOptions) => {
'use server';
const document = await getDocument({ token, documentId });
if (document.status !== DocumentStatus.PENDING) {
@ -149,7 +145,13 @@ export const completeDocumentWithToken = async ({
});
if (haveAllRecipientsSigned) {
await sealDocument({ documentId: document.id, requestMetadata });
await jobs.triggerJob({
name: 'internal.seal-document',
payload: {
documentId: document.id,
requestMetadata,
},
});
}
const updatedDocument = await getDocument({ token, documentId });

View File

@ -1,5 +1,3 @@
'use server';
import { nanoid } from 'nanoid';
import path from 'node:path';
import { PDFDocument } from 'pdf-lib';
@ -36,8 +34,6 @@ export const sealDocument = async ({
isResealing = false,
requestMetadata,
}: SealDocumentOptions) => {
'use server';
const document = await prisma.document.findFirstOrThrow({
where: {
id: documentId,

View File

@ -1,4 +1,3 @@
import { sealDocument } from '@documenso/lib/server-only/document/seal-document';
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
import { putPdfFile } from '@documenso/lib/universal/upload/put-file';
@ -7,7 +6,7 @@ import { prisma } from '@documenso/prisma';
import { DocumentStatus, RecipientRole, SendStatus, SigningStatus } from '@documenso/prisma/client';
import { WebhookTriggerEvents } from '@documenso/prisma/client';
import { jobsClient } from '../../jobs/client';
import { jobs } from '../../jobs/client';
import { getFile } from '../../universal/upload/get-file';
import { insertFormValuesInPdf } from '../pdf/insert-form-values-in-pdf';
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
@ -141,7 +140,7 @@ export const sendDocument = async ({
return;
}
await jobsClient.triggerJob({
await jobs.triggerJob({
name: 'send.signing.requested.email',
payload: {
userId,
@ -160,7 +159,13 @@ export const sendDocument = async ({
);
if (allRecipientsHaveNoActionToTake) {
await sealDocument({ documentId, requestMetadata });
await jobs.triggerJob({
name: 'internal.seal-document',
payload: {
documentId,
requestMetadata,
},
});
// Keep the return type the same for the `sendDocument` method
return await prisma.document.findFirstOrThrow({