Files
documenso/packages/trpc/server/envelope-router/bulk-delete-envelopes.ts
T
2026-05-08 16:04:22 +10:00

107 lines
3.1 KiB
TypeScript

import { deleteDocument } from '@documenso/lib/server-only/document/delete-document';
import { getMultipleEnvelopeWhereInput } from '@documenso/lib/server-only/envelope/get-envelopes-by-ids';
import { deleteTemplate } from '@documenso/lib/server-only/template/delete-template';
import { prisma } from '@documenso/prisma';
import { EnvelopeType } from '@prisma/client';
import pMap from 'p-map';
import { authenticatedProcedure } from '../trpc';
import { ZBulkDeleteEnvelopesRequestSchema, ZBulkDeleteEnvelopesResponseSchema } from './bulk-delete-envelopes.types';
export const bulkDeleteEnvelopesRoute = authenticatedProcedure
// .meta(bulkDeleteEnvelopesMeta) // Keeping this as a private API for a little while until we're sure it's stable and the request/response schemas are finalized.
.input(ZBulkDeleteEnvelopesRequestSchema)
.output(ZBulkDeleteEnvelopesResponseSchema)
.mutation(async ({ input, ctx }) => {
const { teamId, user } = ctx;
const { envelopeIds } = input;
ctx.logger.info({
input: {
envelopeIds,
},
});
const { envelopeWhereInput } = await getMultipleEnvelopeWhereInput({
ids: {
type: 'envelopeId',
ids: envelopeIds,
},
userId: user.id,
teamId,
type: null,
});
const envelopes = await prisma.envelope.findMany({
where: envelopeWhereInput,
select: {
id: true,
type: true,
},
});
const results = await pMap(
envelopes,
async (envelope) => {
const { id: envelopeId, type: envelopeType } = envelope;
try {
if (envelopeType === EnvelopeType.DOCUMENT) {
await deleteDocument({
id: {
type: 'envelopeId',
id: envelopeId,
},
userId: user.id,
teamId,
requestMetadata: ctx.metadata,
});
} else if (envelopeType === EnvelopeType.TEMPLATE) {
await deleteTemplate({
id: {
type: 'envelopeId',
id: envelopeId,
},
userId: user.id,
teamId,
});
}
return {
success: true,
envelopeId,
};
} catch (err) {
ctx.logger.warn(
{
envelopeId,
error: err,
},
'Failed to delete envelope during bulk delete',
);
return {
success: false,
envelopeId,
};
}
},
{
concurrency: 10,
stopOnError: false,
},
);
const deletedCount = results.filter((r) => r.success).length;
const failedIds = results.filter((r) => !r.success).map((r) => r.envelopeId);
// Include envelope IDs that were not attempted (unauthorized/not found)
const attemptedIds = new Set(envelopes.map((e) => e.id));
const unattemptedIds = envelopeIds.filter((id) => !attemptedIds.has(id));
return {
deletedCount,
failedIds: [...failedIds, ...unattemptedIds],
};
});