import { nanoid } from 'nanoid'; import { prisma } from '@documenso/prisma'; import { SendStatus, SigningStatus } from '@documenso/prisma/client'; export interface SetRecipientsForDocumentOptions { userId: number; documentId: number; recipients: { id?: number | null; email: string; name: string; }[]; } export const setRecipientsForDocument = async ({ userId, documentId, recipients, }: SetRecipientsForDocumentOptions) => { const document = await prisma.document.findFirst({ where: { id: documentId, userId, }, }); if (!document) { throw new Error('Document not found'); } const existingRecipients = await prisma.recipient.findMany({ where: { documentId, }, }); const removedRecipients = existingRecipients.filter( (existingRecipient) => !recipients.find( (recipient) => recipient.id === existingRecipient.id || recipient.email === existingRecipient.email, ), ); const linkedRecipients = recipients .map((recipient) => { const existing = existingRecipients.find( (existingRecipient) => existingRecipient.id === recipient.id || existingRecipient.email === recipient.email, ); return { ...recipient, ...existing, }; }) .filter((recipient) => { return ( recipient.sendStatus !== SendStatus.SENT && recipient.signingStatus !== SigningStatus.SIGNED ); }); const persistedRecipients = await prisma.$transaction( linkedRecipients.map((recipient) => recipient.id ? prisma.recipient.update({ where: { id: recipient.id, documentId, }, data: { name: recipient.name, email: recipient.email, documentId, }, }) : prisma.recipient.create({ data: { name: recipient.name, email: recipient.email, token: nanoid(), documentId, }, }), ), ); if (removedRecipients.length > 0) { await prisma.recipient.deleteMany({ where: { id: { in: removedRecipients.map((recipient) => recipient.id), }, }, }); } return persistedRecipients; };