mirror of
https://github.com/documenso/documenso.git
synced 2026-07-07 03:24:58 +10:00
844af17ec2
Each direct mailer.sendMail() call is replaced by a dedicated background job so that email delivery failures can be retried independently. New jobs: send-pending-email, send-completed-email, send-forgot-password-email, send-document-super-delete-email, send-recipient-removed-email, send-document-deleted-emails, send-2fa-token-email, send-resend-document-email, send-direct-template-created-email. Existing handlers (send-document-cancelled-emails, send-organisation-member-*, send-recipient-signed-email) have io.runTask wrappers removed since they interfere with the job scheduler. Job triggers are dispatched after transactions commit to avoid race conditions with uncommitted data.
83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
import { prisma } from '@documenso/prisma';
|
|
|
|
import { AppError, AppErrorCode } from '../../errors/app-error';
|
|
import { jobs } from '../../jobs/client';
|
|
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
|
import { extractDerivedDocumentEmailSettings } from '../../types/document-email';
|
|
import type { RequestMetadata } from '../../universal/extract-request-metadata';
|
|
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
|
|
|
export type AdminSuperDeleteDocumentOptions = {
|
|
envelopeId: string;
|
|
reason: string;
|
|
requestMetadata?: RequestMetadata;
|
|
};
|
|
|
|
export const adminSuperDeleteDocument = async ({
|
|
envelopeId,
|
|
reason,
|
|
requestMetadata,
|
|
}: AdminSuperDeleteDocumentOptions) => {
|
|
const envelope = await prisma.envelope.findUnique({
|
|
where: {
|
|
id: envelopeId,
|
|
},
|
|
include: {
|
|
documentMeta: true,
|
|
user: {
|
|
select: {
|
|
id: true,
|
|
email: true,
|
|
name: true,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
if (!envelope) {
|
|
throw new AppError(AppErrorCode.NOT_FOUND, {
|
|
message: 'Document not found',
|
|
});
|
|
}
|
|
|
|
const { user } = envelope;
|
|
|
|
const isDocumentDeletedEmailEnabled = extractDerivedDocumentEmailSettings(
|
|
envelope.documentMeta,
|
|
).documentDeleted;
|
|
|
|
// Always hard delete if deleted from admin.
|
|
const deletedEnvelope = await prisma.$transaction(async (tx) => {
|
|
await tx.documentAuditLog.create({
|
|
data: createDocumentAuditLogData({
|
|
envelopeId,
|
|
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED,
|
|
user,
|
|
requestMetadata,
|
|
data: {
|
|
type: 'HARD',
|
|
},
|
|
}),
|
|
});
|
|
|
|
return await tx.envelope.delete({ where: { id: envelopeId } });
|
|
});
|
|
|
|
// Notify the document owner after the hard delete transaction commits.
|
|
// We only send the owner notification; recipient cancellation emails are
|
|
// omitted because the recipients are hard-deleted with the envelope.
|
|
if (isDocumentDeletedEmailEnabled) {
|
|
await jobs.triggerJob({
|
|
name: 'send.document.super.delete.email',
|
|
payload: {
|
|
userId: user.id,
|
|
documentTitle: envelope.title,
|
|
reason,
|
|
teamId: envelope.teamId,
|
|
},
|
|
});
|
|
}
|
|
|
|
return deletedEnvelope;
|
|
};
|