mirror of
https://github.com/documenso/documenso.git
synced 2025-11-16 01:32:06 +10:00
feat: add queue for creating audit logs
This commit is contained in:
@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import {
|
import { diffDocumentMetaChanges } from '@documenso/lib/utils/document-audit-logs';
|
||||||
createDocumentAuditLogData,
|
|
||||||
diffDocumentMetaChanges,
|
|
||||||
} from '@documenso/lib/utils/document-audit-logs';
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
|
|
||||||
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export type CreateDocumentMetaOptions = {
|
export type CreateDocumentMetaOptions = {
|
||||||
documentId: number;
|
documentId: number;
|
||||||
subject?: string;
|
subject?: string;
|
||||||
@ -65,8 +64,7 @@ export const upsertDocumentMeta = async ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return await prisma.$transaction(async (tx) => {
|
const upsertedDocumentMeta = await prisma.documentMeta.upsert({
|
||||||
const upsertedDocumentMeta = await tx.documentMeta.upsert({
|
|
||||||
where: {
|
where: {
|
||||||
documentId,
|
documentId,
|
||||||
},
|
},
|
||||||
@ -92,8 +90,9 @@ export const upsertDocumentMeta = async ({
|
|||||||
const changes = diffDocumentMetaChanges(originalDocumentMeta ?? {}, upsertedDocumentMeta);
|
const changes = diffDocumentMetaChanges(originalDocumentMeta ?? {}, upsertedDocumentMeta);
|
||||||
|
|
||||||
if (changes.length > 0) {
|
if (changes.length > 0) {
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_META_UPDATED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_META_UPDATED,
|
||||||
documentId,
|
documentId,
|
||||||
user,
|
user,
|
||||||
@ -101,10 +100,9 @@ export const upsertDocumentMeta = async ({
|
|||||||
data: {
|
data: {
|
||||||
changes: diffDocumentMetaChanges(originalDocumentMeta ?? {}, upsertedDocumentMeta),
|
changes: diffDocumentMetaChanges(originalDocumentMeta ?? {}, upsertedDocumentMeta),
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return upsertedDocumentMeta;
|
return upsertedDocumentMeta;
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { DocumentStatus, SigningStatus } from '@documenso/prisma/client';
|
import { DocumentStatus, SigningStatus } from '@documenso/prisma/client';
|
||||||
import { WebhookTriggerEvents } from '@documenso/prisma/client';
|
import { WebhookTriggerEvents } from '@documenso/prisma/client';
|
||||||
@ -93,8 +92,7 @@ export const completeDocumentWithToken = async ({
|
|||||||
// throw new AppError(AppErrorCode.UNAUTHORIZED, 'Invalid authentication values');
|
// throw new AppError(AppErrorCode.UNAUTHORIZED, 'Invalid authentication values');
|
||||||
// }
|
// }
|
||||||
|
|
||||||
await prisma.$transaction(async (tx) => {
|
await prisma.recipient.update({
|
||||||
await tx.recipient.update({
|
|
||||||
where: {
|
where: {
|
||||||
id: recipient.id,
|
id: recipient.id,
|
||||||
},
|
},
|
||||||
@ -104,8 +102,9 @@ export const completeDocumentWithToken = async ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED,
|
||||||
documentId: document.id,
|
documentId: document.id,
|
||||||
user: {
|
user: {
|
||||||
@ -120,8 +119,7 @@ export const completeDocumentWithToken = async ({
|
|||||||
recipientRole: recipient.role,
|
recipientRole: recipient.role,
|
||||||
// actionAuth: derivedRecipientActionAuth || undefined,
|
// actionAuth: derivedRecipientActionAuth || undefined,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const pendingRecipients = await prisma.recipient.count({
|
const pendingRecipients = await prisma.recipient.count({
|
||||||
|
|||||||
@ -3,10 +3,10 @@
|
|||||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { WebhookTriggerEvents } from '@documenso/prisma/client';
|
import { WebhookTriggerEvents } from '@documenso/prisma/client';
|
||||||
|
|
||||||
|
import { queueJob } from '../queue/job';
|
||||||
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
|
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
|
||||||
|
|
||||||
export type CreateDocumentOptions = {
|
export type CreateDocumentOptions = {
|
||||||
@ -44,8 +44,7 @@ export const createDocument = async ({
|
|||||||
throw new AppError(AppErrorCode.NOT_FOUND, 'Team not found');
|
throw new AppError(AppErrorCode.NOT_FOUND, 'Team not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
return await prisma.$transaction(async (tx) => {
|
const document = await prisma.document.create({
|
||||||
const document = await tx.document.create({
|
|
||||||
data: {
|
data: {
|
||||||
title,
|
title,
|
||||||
documentDataId,
|
documentDataId,
|
||||||
@ -54,8 +53,9 @@ export const createDocument = async ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_CREATED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_CREATED,
|
||||||
documentId: document.id,
|
documentId: document.id,
|
||||||
user,
|
user,
|
||||||
@ -63,7 +63,7 @@ export const createDocument = async ({
|
|||||||
data: {
|
data: {
|
||||||
title,
|
title,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await triggerWebhook({
|
await triggerWebhook({
|
||||||
@ -74,5 +74,4 @@ export const createDocument = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return document;
|
return document;
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app';
|
|||||||
import { FROM_ADDRESS, FROM_NAME } from '../../constants/email';
|
import { FROM_ADDRESS, FROM_NAME } from '../../constants/email';
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export type DeleteDocumentOptions = {
|
export type DeleteDocumentOptions = {
|
||||||
id: number;
|
id: number;
|
||||||
@ -61,11 +61,11 @@ export const deleteDocument = async ({
|
|||||||
|
|
||||||
// if the document is a draft, hard-delete
|
// if the document is a draft, hard-delete
|
||||||
if (status === DocumentStatus.DRAFT) {
|
if (status === DocumentStatus.DRAFT) {
|
||||||
return await prisma.$transaction(async (tx) => {
|
|
||||||
// Currently redundant since deleting a document will delete the audit logs.
|
// Currently redundant since deleting a document will delete the audit logs.
|
||||||
// However may be useful if we disassociate audit lgos and documents if required.
|
// However may be useful if we disassociate audit lgos and documents if required.
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
documentId: id,
|
documentId: id,
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED,
|
||||||
user,
|
user,
|
||||||
@ -73,11 +73,10 @@ export const deleteDocument = async ({
|
|||||||
data: {
|
data: {
|
||||||
type: 'HARD',
|
type: 'HARD',
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return await tx.document.delete({ where: { id, status: DocumentStatus.DRAFT } });
|
return await prisma.document.delete({ where: { id, status: DocumentStatus.DRAFT } });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the document is pending, send cancellation emails to all recipients
|
// if the document is pending, send cancellation emails to all recipients
|
||||||
@ -111,9 +110,9 @@ export const deleteDocument = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the document is not a draft, only soft-delete.
|
// If the document is not a draft, only soft-delete.
|
||||||
return await prisma.$transaction(async (tx) => {
|
await queueJob({
|
||||||
await tx.documentAuditLog.create({
|
job: 'create-document-audit-log',
|
||||||
data: createDocumentAuditLogData({
|
args: {
|
||||||
documentId: id,
|
documentId: id,
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED,
|
||||||
user,
|
user,
|
||||||
@ -121,10 +120,10 @@ export const deleteDocument = async ({
|
|||||||
data: {
|
data: {
|
||||||
type: 'SOFT',
|
type: 'SOFT',
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return await tx.document.update({
|
return await prisma.document.update({
|
||||||
where: {
|
where: {
|
||||||
id,
|
id,
|
||||||
},
|
},
|
||||||
@ -132,5 +131,4 @@ export const deleteDocument = async ({
|
|||||||
deletedAt: new Date().toISOString(),
|
deletedAt: new Date().toISOString(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -10,13 +10,13 @@ import {
|
|||||||
} from '@documenso/lib/constants/recipient-roles';
|
} from '@documenso/lib/constants/recipient-roles';
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
|
||||||
import { renderCustomEmailTemplate } from '@documenso/lib/utils/render-custom-email-template';
|
import { renderCustomEmailTemplate } from '@documenso/lib/utils/render-custom-email-template';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { DocumentStatus, RecipientRole, SigningStatus } from '@documenso/prisma/client';
|
import { DocumentStatus, RecipientRole, SigningStatus } from '@documenso/prisma/client';
|
||||||
import type { Prisma } from '@documenso/prisma/client';
|
import type { Prisma } from '@documenso/prisma/client';
|
||||||
|
|
||||||
import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app';
|
import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app';
|
||||||
|
import { queueJob } from '../queue/job';
|
||||||
import { getDocumentWhereInput } from './get-document-by-id';
|
import { getDocumentWhereInput } from './get-document-by-id';
|
||||||
|
|
||||||
export type ResendDocumentOptions = {
|
export type ResendDocumentOptions = {
|
||||||
@ -128,8 +128,9 @@ export const resendDocument = async ({
|
|||||||
text: render(template, { plainText: true }),
|
text: render(template, { plainText: true }),
|
||||||
});
|
});
|
||||||
|
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT,
|
type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT,
|
||||||
documentId: document.id,
|
documentId: document.id,
|
||||||
user,
|
user,
|
||||||
@ -142,9 +143,10 @@ export const resendDocument = async ({
|
|||||||
recipientId: recipient.id,
|
recipientId: recipient.id,
|
||||||
isResending: true,
|
isResending: true,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// Hopefully the queue makes this redundant
|
||||||
{ timeout: 30_000 },
|
{ timeout: 30_000 },
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -5,13 +5,12 @@ import path from 'node:path';
|
|||||||
import { PDFDocument } from 'pdf-lib';
|
import { PDFDocument } from 'pdf-lib';
|
||||||
|
|
||||||
import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-post-hog-server-client';
|
import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-post-hog-server-client';
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
|
||||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { DocumentStatus, RecipientRole, SigningStatus } from '@documenso/prisma/client';
|
import { DocumentStatus, RecipientRole, SigningStatus } from '@documenso/prisma/client';
|
||||||
import { WebhookTriggerEvents } from '@documenso/prisma/client';
|
import { WebhookTriggerEvents } from '@documenso/prisma/client';
|
||||||
import { signPdf } from '@documenso/signing';
|
import { signPdf } from '@documenso/signing';
|
||||||
|
|
||||||
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||||
import { getFile } from '../../universal/upload/get-file';
|
import { getFile } from '../../universal/upload/get-file';
|
||||||
import { putFile } from '../../universal/upload/put-file';
|
import { putFile } from '../../universal/upload/put-file';
|
||||||
@ -126,8 +125,7 @@ export const sealDocument = async ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.$transaction(async (tx) => {
|
await prisma.documentData.update({
|
||||||
await tx.documentData.update({
|
|
||||||
where: {
|
where: {
|
||||||
id: documentData.id,
|
id: documentData.id,
|
||||||
},
|
},
|
||||||
@ -136,8 +134,9 @@ export const sealDocument = async ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED,
|
||||||
documentId: document.id,
|
documentId: document.id,
|
||||||
requestMetadata,
|
requestMetadata,
|
||||||
@ -145,8 +144,7 @@ export const sealDocument = async ({
|
|||||||
data: {
|
data: {
|
||||||
transactionId: nanoid(),
|
transactionId: nanoid(),
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (sendEmail && !isResealing) {
|
if (sendEmail && !isResealing) {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app';
|
|||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||||
import { getFile } from '../../universal/upload/get-file';
|
import { getFile } from '../../universal/upload/get-file';
|
||||||
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export interface SendDocumentOptions {
|
export interface SendDocumentOptions {
|
||||||
documentId: number;
|
documentId: number;
|
||||||
@ -86,8 +86,9 @@ export const sendCompletedEmail = async ({ documentId, requestMetadata }: SendDo
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
await prisma.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT,
|
type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT,
|
||||||
documentId: document.id,
|
documentId: document.id,
|
||||||
user: null,
|
user: null,
|
||||||
@ -100,7 +101,7 @@ export const sendCompletedEmail = async ({ documentId, requestMetadata }: SendDo
|
|||||||
recipientRole: 'OWNER',
|
recipientRole: 'OWNER',
|
||||||
isResending: false,
|
isResending: false,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,8 +137,9 @@ export const sendCompletedEmail = async ({ documentId, requestMetadata }: SendDo
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
await prisma.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT,
|
type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT,
|
||||||
documentId: document.id,
|
documentId: document.id,
|
||||||
user: null,
|
user: null,
|
||||||
@ -150,7 +152,7 @@ export const sendCompletedEmail = async ({ documentId, requestMetadata }: SendDo
|
|||||||
recipientRole: recipient.role,
|
recipientRole: recipient.role,
|
||||||
isResending: false,
|
isResending: false,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import { DocumentInviteEmailTemplate } from '@documenso/email/templates/document
|
|||||||
import { FROM_ADDRESS, FROM_NAME } from '@documenso/lib/constants/email';
|
import { FROM_ADDRESS, FROM_NAME } from '@documenso/lib/constants/email';
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
|
||||||
import { renderCustomEmailTemplate } from '@documenso/lib/utils/render-custom-email-template';
|
import { renderCustomEmailTemplate } from '@documenso/lib/utils/render-custom-email-template';
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { DocumentStatus, RecipientRole, SendStatus } from '@documenso/prisma/client';
|
import { DocumentStatus, RecipientRole, SendStatus } from '@documenso/prisma/client';
|
||||||
@ -17,6 +16,7 @@ import {
|
|||||||
RECIPIENT_ROLES_DESCRIPTION,
|
RECIPIENT_ROLES_DESCRIPTION,
|
||||||
RECIPIENT_ROLE_TO_EMAIL_TYPE,
|
RECIPIENT_ROLE_TO_EMAIL_TYPE,
|
||||||
} from '../../constants/recipient-roles';
|
} from '../../constants/recipient-roles';
|
||||||
|
import { queueJob } from '../queue/job';
|
||||||
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
|
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
|
||||||
|
|
||||||
export type SendDocumentOptions = {
|
export type SendDocumentOptions = {
|
||||||
@ -113,8 +113,7 @@ export const sendDocument = async ({
|
|||||||
|
|
||||||
const { actionVerb } = RECIPIENT_ROLES_DESCRIPTION[recipient.role];
|
const { actionVerb } = RECIPIENT_ROLES_DESCRIPTION[recipient.role];
|
||||||
|
|
||||||
await prisma.$transaction(
|
// TODO: Move this to a seperate queue of it's own
|
||||||
async (tx) => {
|
|
||||||
await mailer.sendMail({
|
await mailer.sendMail({
|
||||||
to: {
|
to: {
|
||||||
address: email,
|
address: email,
|
||||||
@ -131,7 +130,7 @@ export const sendDocument = async ({
|
|||||||
text: render(template, { plainText: true }),
|
text: render(template, { plainText: true }),
|
||||||
});
|
});
|
||||||
|
|
||||||
await tx.recipient.update({
|
await prisma.recipient.update({
|
||||||
where: {
|
where: {
|
||||||
id: recipient.id,
|
id: recipient.id,
|
||||||
},
|
},
|
||||||
@ -140,8 +139,9 @@ export const sendDocument = async ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT,
|
type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT,
|
||||||
documentId: document.id,
|
documentId: document.id,
|
||||||
user,
|
user,
|
||||||
@ -154,28 +154,25 @@ export const sendDocument = async ({
|
|||||||
recipientId: recipient.id,
|
recipientId: recipient.id,
|
||||||
isResending: false,
|
isResending: false,
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
{ timeout: 30_000 },
|
});
|
||||||
);
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const updatedDocument = await prisma.$transaction(async (tx) => {
|
|
||||||
if (document.status === DocumentStatus.DRAFT) {
|
if (document.status === DocumentStatus.DRAFT) {
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_SENT,
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_SENT,
|
||||||
documentId: document.id,
|
documentId: document.id,
|
||||||
requestMetadata,
|
requestMetadata,
|
||||||
user,
|
user,
|
||||||
data: {},
|
data: {},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return await tx.document.update({
|
const updatedDocument = await prisma.document.update({
|
||||||
where: {
|
where: {
|
||||||
id: documentId,
|
id: documentId,
|
||||||
},
|
},
|
||||||
@ -186,7 +183,6 @@ export const sendDocument = async ({
|
|||||||
Recipient: true,
|
Recipient: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
await triggerWebhook({
|
await triggerWebhook({
|
||||||
event: WebhookTriggerEvents.DOCUMENT_SENT,
|
event: WebhookTriggerEvents.DOCUMENT_SENT,
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app';
|
|||||||
import { FROM_ADDRESS, FROM_NAME } from '../../constants/email';
|
import { FROM_ADDRESS, FROM_NAME } from '../../constants/email';
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export type SuperDeleteDocumentOptions = {
|
export type SuperDeleteDocumentOptions = {
|
||||||
id: number;
|
id: number;
|
||||||
@ -66,10 +66,9 @@ export const superDeleteDocument = async ({ id, requestMetadata }: SuperDeleteDo
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// always hard delete if deleted from admin
|
await queueJob({
|
||||||
return await prisma.$transaction(async (tx) => {
|
job: 'create-document-audit-log',
|
||||||
await tx.documentAuditLog.create({
|
args: {
|
||||||
data: createDocumentAuditLogData({
|
|
||||||
documentId: id,
|
documentId: id,
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED,
|
||||||
user,
|
user,
|
||||||
@ -77,9 +76,9 @@ export const superDeleteDocument = async ({ id, requestMetadata }: SuperDeleteDo
|
|||||||
data: {
|
data: {
|
||||||
type: 'HARD',
|
type: 'HARD',
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return await tx.document.delete({ where: { id } });
|
// always hard delete if deleted from admin
|
||||||
});
|
return await prisma.document.delete({ where: { id } });
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
|
|
||||||
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export type UpdateTitleOptions = {
|
export type UpdateTitleOptions = {
|
||||||
userId: number;
|
userId: number;
|
||||||
teamId?: number;
|
teamId?: number;
|
||||||
@ -51,11 +52,10 @@ export const updateTitle = async ({
|
|||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await prisma.$transaction(async (tx) => {
|
|
||||||
// Instead of doing everything in a transaction we can use our knowledge
|
// Instead of doing everything in a transaction we can use our knowledge
|
||||||
// of the current document title to ensure we aren't performing a conflicting
|
// of the current document title to ensure we aren't performing a conflicting
|
||||||
// update.
|
// update.
|
||||||
const updatedDocument = await tx.document.update({
|
const updatedDocument = await prisma.document.update({
|
||||||
where: {
|
where: {
|
||||||
id: documentId,
|
id: documentId,
|
||||||
title: document.title,
|
title: document.title,
|
||||||
@ -65,8 +65,9 @@ export const updateTitle = async ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_TITLE_UPDATED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_TITLE_UPDATED,
|
||||||
documentId,
|
documentId,
|
||||||
user,
|
user,
|
||||||
@ -75,9 +76,8 @@ export const updateTitle = async ({
|
|||||||
from: document.title,
|
from: document.title,
|
||||||
to: updatedDocument.title,
|
to: updatedDocument.title,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return updatedDocument;
|
return updatedDocument;
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { ReadStatus } from '@documenso/prisma/client';
|
import { ReadStatus } from '@documenso/prisma/client';
|
||||||
import { WebhookTriggerEvents } from '@documenso/prisma/client';
|
import { WebhookTriggerEvents } from '@documenso/prisma/client';
|
||||||
|
|
||||||
import type { TDocumentAccessAuthTypes } from '../../types/document-auth';
|
import type { TDocumentAccessAuthTypes } from '../../types/document-auth';
|
||||||
|
import { queueJob } from '../queue/job';
|
||||||
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
|
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
|
||||||
import { getDocumentAndRecipientByToken } from './get-document-by-token';
|
import { getDocumentAndRecipientByToken } from './get-document-by-token';
|
||||||
|
|
||||||
@ -33,8 +33,7 @@ export const viewedDocument = async ({
|
|||||||
|
|
||||||
const { documentId } = recipient;
|
const { documentId } = recipient;
|
||||||
|
|
||||||
await prisma.$transaction(async (tx) => {
|
await prisma.recipient.update({
|
||||||
await tx.recipient.update({
|
|
||||||
where: {
|
where: {
|
||||||
id: recipient.id,
|
id: recipient.id,
|
||||||
},
|
},
|
||||||
@ -43,8 +42,9 @@ export const viewedDocument = async ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED,
|
||||||
documentId,
|
documentId,
|
||||||
user: {
|
user: {
|
||||||
@ -59,8 +59,7 @@ export const viewedDocument = async ({
|
|||||||
recipientRole: recipient.role,
|
recipientRole: recipient.role,
|
||||||
accessAuth: recipientAccessAuth || undefined,
|
accessAuth: recipientAccessAuth || undefined,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const document = await getDocumentAndRecipientByToken({ token, requireAccessAuth: false });
|
const document = await getDocumentAndRecipientByToken({ token, requireAccessAuth: false });
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { prisma } from '@documenso/prisma';
|
|||||||
import type { FieldType, Team } from '@documenso/prisma/client';
|
import type { FieldType, Team } from '@documenso/prisma/client';
|
||||||
|
|
||||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export type CreateFieldOptions = {
|
export type CreateFieldOptions = {
|
||||||
documentId: number;
|
documentId: number;
|
||||||
@ -103,8 +103,9 @@ export const createField = async ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await prisma.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: 'FIELD_CREATED',
|
type: 'FIELD_CREATED',
|
||||||
documentId,
|
documentId,
|
||||||
user: {
|
user: {
|
||||||
@ -119,7 +120,7 @@ export const createField = async ({
|
|||||||
fieldType: field.type,
|
fieldType: field.type,
|
||||||
},
|
},
|
||||||
requestMetadata,
|
requestMetadata,
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return field;
|
return field;
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { prisma } from '@documenso/prisma';
|
|||||||
import type { Team } from '@documenso/prisma/client';
|
import type { Team } from '@documenso/prisma/client';
|
||||||
|
|
||||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export type DeleteFieldOptions = {
|
export type DeleteFieldOptions = {
|
||||||
fieldId: number;
|
fieldId: number;
|
||||||
@ -67,8 +67,9 @@ export const deleteField = async ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: 'FIELD_DELETED',
|
type: 'FIELD_DELETED',
|
||||||
documentId,
|
documentId,
|
||||||
user: {
|
user: {
|
||||||
@ -83,7 +84,7 @@ export const deleteField = async ({
|
|||||||
fieldType: field.type,
|
fieldType: field.type,
|
||||||
},
|
},
|
||||||
requestMetadata,
|
requestMetadata,
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return field;
|
return field;
|
||||||
|
|||||||
@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
|
||||||
import { prisma } from '@documenso/prisma';
|
import { prisma } from '@documenso/prisma';
|
||||||
import { DocumentStatus, SigningStatus } from '@documenso/prisma/client';
|
import { DocumentStatus, SigningStatus } from '@documenso/prisma/client';
|
||||||
|
|
||||||
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export type RemovedSignedFieldWithTokenOptions = {
|
export type RemovedSignedFieldWithTokenOptions = {
|
||||||
token: string;
|
token: string;
|
||||||
fieldId: number;
|
fieldId: number;
|
||||||
@ -65,9 +66,11 @@ export const removeSignedFieldWithToken = async ({
|
|||||||
fieldId: field.id,
|
fieldId: field.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_UNINSERTED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_UNINSERTED,
|
||||||
documentId: document.id,
|
documentId: document.id,
|
||||||
user: {
|
user: {
|
||||||
@ -79,7 +82,6 @@ export const removeSignedFieldWithToken = async ({
|
|||||||
field: field.type,
|
field: field.type,
|
||||||
fieldId: field.secondaryId,
|
fieldId: field.secondaryId,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -8,6 +8,8 @@ import { prisma } from '@documenso/prisma';
|
|||||||
import type { Field, FieldType } from '@documenso/prisma/client';
|
import type { Field, FieldType } from '@documenso/prisma/client';
|
||||||
import { SendStatus, SigningStatus } from '@documenso/prisma/client';
|
import { SendStatus, SigningStatus } from '@documenso/prisma/client';
|
||||||
|
|
||||||
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export interface SetFieldsForDocumentOptions {
|
export interface SetFieldsForDocumentOptions {
|
||||||
userId: number;
|
userId: number;
|
||||||
documentId: number;
|
documentId: number;
|
||||||
@ -155,8 +157,9 @@ export const setFieldsForDocument = async ({
|
|||||||
|
|
||||||
// Handle field updated audit log.
|
// Handle field updated audit log.
|
||||||
if (field._persisted && changes.length > 0) {
|
if (field._persisted && changes.length > 0) {
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_UPDATED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_UPDATED,
|
||||||
documentId: documentId,
|
documentId: documentId,
|
||||||
user,
|
user,
|
||||||
@ -165,14 +168,15 @@ export const setFieldsForDocument = async ({
|
|||||||
changes,
|
changes,
|
||||||
...baseAuditLog,
|
...baseAuditLog,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle field created audit log.
|
// Handle field created audit log.
|
||||||
if (!field._persisted) {
|
if (!field._persisted) {
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_CREATED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_CREATED,
|
||||||
documentId: documentId,
|
documentId: documentId,
|
||||||
user,
|
user,
|
||||||
@ -180,7 +184,7 @@ export const setFieldsForDocument = async ({
|
|||||||
data: {
|
data: {
|
||||||
...baseAuditLog,
|
...baseAuditLog,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,9 +12,9 @@ import { AppError, AppErrorCode } from '../../errors/app-error';
|
|||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
||||||
import type { TRecipientActionAuth } from '../../types/document-auth';
|
import type { TRecipientActionAuth } from '../../types/document-auth';
|
||||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
|
||||||
import { extractDocumentAuthMethods } from '../../utils/document-auth';
|
import { extractDocumentAuthMethods } from '../../utils/document-auth';
|
||||||
import { isRecipientAuthorized } from '../document/is-recipient-authorized';
|
import { isRecipientAuthorized } from '../document/is-recipient-authorized';
|
||||||
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export type SignFieldWithTokenOptions = {
|
export type SignFieldWithTokenOptions = {
|
||||||
token: string;
|
token: string;
|
||||||
@ -168,8 +168,9 @@ export const signFieldWithToken = async ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_INSERTED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_INSERTED,
|
||||||
documentId: document.id,
|
documentId: document.id,
|
||||||
user: {
|
user: {
|
||||||
@ -199,7 +200,7 @@ export const signFieldWithToken = async ({
|
|||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return updatedField;
|
return updatedField;
|
||||||
|
|||||||
@ -3,7 +3,8 @@ import type { FieldType, Team } from '@documenso/prisma/client';
|
|||||||
|
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData, diffFieldChanges } from '../../utils/document-audit-logs';
|
import { diffFieldChanges } from '../../utils/document-audit-logs';
|
||||||
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export type UpdateFieldOptions = {
|
export type UpdateFieldOptions = {
|
||||||
fieldId: number;
|
fieldId: number;
|
||||||
@ -77,8 +78,9 @@ export const updateField = async ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_UPDATED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_UPDATED,
|
||||||
documentId,
|
documentId,
|
||||||
user: {
|
user: {
|
||||||
@ -94,7 +96,7 @@ export const updateField = async ({
|
|||||||
changes: diffFieldChanges(oldField, updatedField),
|
changes: diffFieldChanges(oldField, updatedField),
|
||||||
},
|
},
|
||||||
requestMetadata,
|
requestMetadata,
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return updatedField;
|
return updatedField;
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
import type { WorkHandler } from 'pg-boss';
|
import type { WorkHandler } from 'pg-boss';
|
||||||
|
|
||||||
|
import { prisma } from '@documenso/prisma';
|
||||||
|
|
||||||
import { initQueue } from '.';
|
import { initQueue } from '.';
|
||||||
|
import type { CreateDocumentAuditLogDataOptions } from '../../utils/document-audit-logs';
|
||||||
|
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
||||||
import {
|
import {
|
||||||
type SendDocumentOptions as SendCompletedDocumentOptions,
|
type SendDocumentOptions as SendCompletedDocumentOptions,
|
||||||
sendCompletedEmail,
|
sendCompletedEmail,
|
||||||
@ -10,6 +14,7 @@ import { type SendPendingEmailOptions, sendPendingEmail } from '../document/send
|
|||||||
type JobOptions = {
|
type JobOptions = {
|
||||||
'send-completed-email': SendCompletedDocumentOptions;
|
'send-completed-email': SendCompletedDocumentOptions;
|
||||||
'send-pending-email': SendPendingEmailOptions;
|
'send-pending-email': SendPendingEmailOptions;
|
||||||
|
'create-document-audit-log': CreateDocumentAuditLogDataOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const jobHandlers: {
|
export const jobHandlers: {
|
||||||
@ -27,6 +32,24 @@ export const jobHandlers: {
|
|||||||
recipientId,
|
recipientId,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Audit Logs Queue
|
||||||
|
'create-document-audit-log': async ({
|
||||||
|
data: { documentId, type, requestMetadata, user, data },
|
||||||
|
id,
|
||||||
|
}) => {
|
||||||
|
console.log('Running Queue ID', id);
|
||||||
|
|
||||||
|
await prisma.documentAuditLog.create({
|
||||||
|
data: createDocumentAuditLogData({
|
||||||
|
type,
|
||||||
|
documentId,
|
||||||
|
requestMetadata,
|
||||||
|
user,
|
||||||
|
data,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const queueJob = async ({
|
export const queueJob = async ({
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import type { Team } from '@documenso/prisma/client';
|
|||||||
import { SendStatus } from '@documenso/prisma/client';
|
import { SendStatus } from '@documenso/prisma/client';
|
||||||
|
|
||||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export type DeleteRecipientOptions = {
|
export type DeleteRecipientOptions = {
|
||||||
documentId: number;
|
documentId: number;
|
||||||
@ -73,15 +73,15 @@ export const deleteRecipient = async ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const deletedRecipient = await prisma.$transaction(async (tx) => {
|
const deletedRecipient = await prisma.recipient.delete({
|
||||||
const deleted = await tx.recipient.delete({
|
|
||||||
where: {
|
where: {
|
||||||
id: recipient.id,
|
id: recipient.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: 'RECIPIENT_DELETED',
|
type: 'RECIPIENT_DELETED',
|
||||||
documentId,
|
documentId,
|
||||||
user: {
|
user: {
|
||||||
@ -96,10 +96,7 @@ export const deleteRecipient = async ({
|
|||||||
recipientRole: recipient.role,
|
recipientRole: recipient.role,
|
||||||
},
|
},
|
||||||
requestMetadata,
|
requestMetadata,
|
||||||
}),
|
},
|
||||||
});
|
|
||||||
|
|
||||||
return deleted;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return deletedRecipient;
|
return deletedRecipient;
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { RecipientRole } from '@documenso/prisma/client';
|
|||||||
import { SendStatus, SigningStatus } from '@documenso/prisma/client';
|
import { SendStatus, SigningStatus } from '@documenso/prisma/client';
|
||||||
|
|
||||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||||
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export interface SetRecipientsForDocumentOptions {
|
export interface SetRecipientsForDocumentOptions {
|
||||||
userId: number;
|
userId: number;
|
||||||
@ -203,8 +204,9 @@ export const setRecipientsForDocument = async ({
|
|||||||
|
|
||||||
// Handle recipient updated audit log.
|
// Handle recipient updated audit log.
|
||||||
if (recipient._persisted && changes.length > 0) {
|
if (recipient._persisted && changes.length > 0) {
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_UPDATED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_UPDATED,
|
||||||
documentId: documentId,
|
documentId: documentId,
|
||||||
user,
|
user,
|
||||||
@ -213,14 +215,15 @@ export const setRecipientsForDocument = async ({
|
|||||||
changes,
|
changes,
|
||||||
...baseAuditLog,
|
...baseAuditLog,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle recipient created audit log.
|
// Handle recipient created audit log.
|
||||||
if (!recipient._persisted) {
|
if (!recipient._persisted) {
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_CREATED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_CREATED,
|
||||||
documentId: documentId,
|
documentId: documentId,
|
||||||
user,
|
user,
|
||||||
@ -229,7 +232,7 @@ export const setRecipientsForDocument = async ({
|
|||||||
...baseAuditLog,
|
...baseAuditLog,
|
||||||
actionAuth: recipient.actionAuth || undefined,
|
actionAuth: recipient.actionAuth || undefined,
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,8 @@ import type { RecipientRole, Team } from '@documenso/prisma/client';
|
|||||||
|
|
||||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
||||||
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
||||||
import { createDocumentAuditLogData, diffRecipientChanges } from '../../utils/document-audit-logs';
|
import { diffRecipientChanges } from '../../utils/document-audit-logs';
|
||||||
|
import { queueJob } from '../queue/job';
|
||||||
|
|
||||||
export type UpdateRecipientOptions = {
|
export type UpdateRecipientOptions = {
|
||||||
documentId: number;
|
documentId: number;
|
||||||
@ -75,8 +76,7 @@ export const updateRecipient = async ({
|
|||||||
throw new Error('Recipient not found');
|
throw new Error('Recipient not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedRecipient = await prisma.$transaction(async (tx) => {
|
const updatedRecipient = await prisma.recipient.update({
|
||||||
const persisted = await prisma.recipient.update({
|
|
||||||
where: {
|
where: {
|
||||||
id: recipient.id,
|
id: recipient.id,
|
||||||
},
|
},
|
||||||
@ -87,11 +87,12 @@ export const updateRecipient = async ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const changes = diffRecipientChanges(recipient, persisted);
|
const changes = diffRecipientChanges(recipient, updatedRecipient);
|
||||||
|
|
||||||
if (changes.length > 0) {
|
if (changes.length > 0) {
|
||||||
await tx.documentAuditLog.create({
|
await queueJob({
|
||||||
data: createDocumentAuditLogData({
|
job: 'create-document-audit-log',
|
||||||
|
args: {
|
||||||
type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_UPDATED,
|
type: DOCUMENT_AUDIT_LOG_TYPE.RECIPIENT_UPDATED,
|
||||||
documentId: documentId,
|
documentId: documentId,
|
||||||
user: {
|
user: {
|
||||||
@ -103,16 +104,15 @@ export const updateRecipient = async ({
|
|||||||
data: {
|
data: {
|
||||||
changes,
|
changes,
|
||||||
recipientId,
|
recipientId,
|
||||||
recipientEmail: persisted.email,
|
recipientEmail: updatedRecipient.email,
|
||||||
recipientName: persisted.name,
|
recipientName: updatedRecipient.name,
|
||||||
recipientRole: persisted.role,
|
recipientRole: updatedRecipient.role,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
return persisted;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return updatedRecipient;
|
||||||
|
}
|
||||||
|
|
||||||
return updatedRecipient;
|
return updatedRecipient;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -25,7 +25,7 @@ import {
|
|||||||
import { ZRecipientAuthOptionsSchema } from '../types/document-auth';
|
import { ZRecipientAuthOptionsSchema } from '../types/document-auth';
|
||||||
import type { RequestMetadata } from '../universal/extract-request-metadata';
|
import type { RequestMetadata } from '../universal/extract-request-metadata';
|
||||||
|
|
||||||
type CreateDocumentAuditLogDataOptions<T = TDocumentAuditLog['type']> = {
|
export type CreateDocumentAuditLogDataOptions<T = TDocumentAuditLog['type']> = {
|
||||||
documentId: number;
|
documentId: number;
|
||||||
type: T;
|
type: T;
|
||||||
data: Extract<TDocumentAuditLog, { type: T }>['data'];
|
data: Extract<TDocumentAuditLog, { type: T }>['data'];
|
||||||
|
|||||||
Reference in New Issue
Block a user