chore: allow same signer docs

This commit is contained in:
Catalin Pit
2025-02-06 14:27:37 +02:00
parent 516435fa2a
commit c41002313a
10 changed files with 42 additions and 38 deletions

View File

@ -94,9 +94,7 @@ export const setFieldsForDocument = async ({
const linkedFields = fields.map((field) => { const linkedFields = fields.map((field) => {
const existing = existingFields.find((existingField) => existingField.id === field.id); const existing = existingFields.find((existingField) => existingField.id === field.id);
const recipient = document.recipients.find( const recipient = document.recipients.find((recipient) => recipient.id === field.recipientId);
(recipient) => recipient.email.toLowerCase() === field.signerEmail.toLowerCase(),
);
// Each field MUST have a recipient associated with it. // Each field MUST have a recipient associated with it.
if (!recipient) { if (!recipient) {
@ -127,8 +125,6 @@ export const setFieldsForDocument = async ({
const persistedFields = await prisma.$transaction(async (tx) => { const persistedFields = await prisma.$transaction(async (tx) => {
return await Promise.all( return await Promise.all(
linkedFields.map(async (field) => { linkedFields.map(async (field) => {
const fieldSignerEmail = field.signerEmail.toLowerCase();
const parsedFieldMeta = field.fieldMeta const parsedFieldMeta = field.fieldMeta
? ZFieldMetaSchema.parse(field.fieldMeta) ? ZFieldMetaSchema.parse(field.fieldMeta)
: undefined; : undefined;
@ -211,6 +207,13 @@ export const setFieldsForDocument = async ({
id: field._persisted?.id ?? -1, id: field._persisted?.id ?? -1,
documentId, documentId,
}, },
include: {
recipient: {
select: {
email: true,
},
},
},
update: { update: {
page: field.pageNumber, page: field.pageNumber,
positionX: field.pageX, positionX: field.pageX,
@ -236,10 +239,7 @@ export const setFieldsForDocument = async ({
}, },
recipient: { recipient: {
connect: { connect: {
documentId_email: { id: field.recipientId,
documentId,
email: fieldSignerEmail,
},
}, },
}, },
}, },
@ -251,7 +251,7 @@ export const setFieldsForDocument = async ({
const baseAuditLog = { const baseAuditLog = {
fieldId: upsertedField.secondaryId, fieldId: upsertedField.secondaryId,
fieldRecipientEmail: fieldSignerEmail, fieldRecipientEmail: upsertedField.recipient?.email ?? '',
fieldRecipientId: upsertedField.recipientId, fieldRecipientId: upsertedField.recipientId,
fieldType: upsertedField.type, fieldType: upsertedField.type,
}; };
@ -339,7 +339,7 @@ export const setFieldsForDocument = async ({
type FieldData = { type FieldData = {
id?: number | null; id?: number | null;
type: FieldType; type: FieldType;
signerEmail: string; recipientId: number;
pageNumber: number; pageNumber: number;
pageX: number; pageX: number;
pageY: number; pageY: number;

View File

@ -23,6 +23,7 @@ export type SetFieldsForTemplateOptions = {
id?: number | null; id?: number | null;
type: FieldType; type: FieldType;
signerEmail: string; signerEmail: string;
recipientId: number;
pageNumber: number; pageNumber: number;
pageX: number; pageX: number;
pageY: number; pageY: number;

View File

@ -125,16 +125,12 @@ export const setDocumentRecipients = async ({
const removedRecipients = existingRecipients.filter( const removedRecipients = existingRecipients.filter(
(existingRecipient) => (existingRecipient) =>
!normalizedRecipients.find( !normalizedRecipients.find((recipient) => recipient.id === existingRecipient.id),
(recipient) =>
recipient.id === existingRecipient.id || recipient.email === existingRecipient.email,
),
); );
const linkedRecipients = normalizedRecipients.map((recipient) => { const linkedRecipients = normalizedRecipients.map((recipient) => {
const existing = existingRecipients.find( const existing = existingRecipients.find(
(existingRecipient) => (existingRecipient) => existingRecipient.id === recipient.id,
existingRecipient.id === recipient.id || existingRecipient.email === recipient.email,
); );
if ( if (

View File

@ -0,0 +1,2 @@
-- DropIndex
DROP INDEX "Recipient_documentId_email_key";

View File

@ -0,0 +1,5 @@
-- DropIndex
DROP INDEX "Recipient_templateId_email_key";
-- CreateIndex
CREATE INDEX "Recipient_email_idx" ON "Recipient"("email");

View File

@ -443,11 +443,10 @@ model Recipient {
fields Field[] fields Field[]
signatures Signature[] signatures Signature[]
@@unique([documentId, email])
@@unique([templateId, email])
@@index([documentId]) @@index([documentId])
@@index([templateId]) @@index([templateId])
@@index([token]) @@index([token])
@@index([email])
} }
enum FieldType { enum FieldType {

View File

@ -429,6 +429,7 @@ export const fieldRouter = router({
teamId, teamId,
fields: fields.map((field) => ({ fields: fields.map((field) => ({
id: field.nativeId, id: field.nativeId,
recipientId: field.recipientId,
signerEmail: field.signerEmail, signerEmail: field.signerEmail,
type: field.type, type: field.type,
pageNumber: field.pageNumber, pageNumber: field.pageNumber,

View File

@ -112,14 +112,15 @@ export const ZSetDocumentFieldsRequestSchema = z.object({
z.object({ z.object({
formId: z.string().min(1), formId: z.string().min(1),
nativeId: z.number().optional(), nativeId: z.number().optional(),
id: z.number().optional(),
type: z.nativeEnum(FieldType), type: z.nativeEnum(FieldType),
signerEmail: z.string().min(1), recipientId: z.number(),
pageNumber: z.number().min(1), pageNumber: ZFieldPageNumberSchema,
pageX: z.number().min(0), pageX: ZFieldPageXSchema,
pageY: z.number().min(0), pageY: ZFieldPageYSchema,
pageWidth: z.number().min(0), pageWidth: ZFieldWidthSchema,
pageHeight: z.number().min(0), pageHeight: ZFieldHeightSchema,
fieldMeta: ZFieldMetaSchema, fieldMeta: ZFieldMetaSchema.optional(),
}), }),
), ),
}); });

View File

@ -92,7 +92,7 @@ export type FieldFormType = {
pageY: number; pageY: number;
pageWidth: number; pageWidth: number;
pageHeight: number; pageHeight: number;
signerEmail: string; recipientId: number;
fieldMeta?: FieldMeta; fieldMeta?: FieldMeta;
}; };
@ -143,8 +143,7 @@ export const AddFieldsFormPartial = ({
pageY: Number(field.positionY), pageY: Number(field.positionY),
pageWidth: Number(field.width), pageWidth: Number(field.width),
pageHeight: Number(field.height), pageHeight: Number(field.height),
signerEmail: recipientId: field.recipientId,
recipients.find((recipient) => recipient.id === field.recipientId)?.email ?? '',
fieldMeta: field.fieldMeta ? ZFieldMetaSchema.parse(field.fieldMeta) : undefined, fieldMeta: field.fieldMeta ? ZFieldMetaSchema.parse(field.fieldMeta) : undefined,
})), })),
typedSignatureEnabled: typedSignatureEnabled ?? false, typedSignatureEnabled: typedSignatureEnabled ?? false,
@ -348,7 +347,7 @@ export const AddFieldsFormPartial = ({
pageY, pageY,
pageWidth: fieldPageWidth, pageWidth: fieldPageWidth,
pageHeight: fieldPageHeight, pageHeight: fieldPageHeight,
signerEmail: selectedSigner.email, recipientId: selectedSigner.id,
fieldMeta: undefined, fieldMeta: undefined,
}; };
@ -441,7 +440,7 @@ export const AddFieldsFormPartial = ({
const newField: TAddFieldsFormSchema['fields'][0] = { const newField: TAddFieldsFormSchema['fields'][0] = {
...structuredClone(lastActiveField), ...structuredClone(lastActiveField),
formId: nanoid(12), formId: nanoid(12),
signerEmail: selectedSigner?.email ?? lastActiveField.signerEmail, recipientId: selectedSigner?.id ?? lastActiveField.recipientId,
pageX: lastActiveField.pageX + 3, pageX: lastActiveField.pageX + 3,
pageY: lastActiveField.pageY + 3, pageY: lastActiveField.pageY + 3,
}; };
@ -449,7 +448,7 @@ export const AddFieldsFormPartial = ({
append(newField); append(newField);
} }
}, },
[append, lastActiveField, selectedSigner?.email, toast], [append, lastActiveField, selectedSigner?.id, toast],
); );
const onFieldPaste = useCallback( const onFieldPaste = useCallback(
@ -462,13 +461,13 @@ export const AddFieldsFormPartial = ({
append({ append({
...copiedField, ...copiedField,
formId: nanoid(12), formId: nanoid(12),
signerEmail: selectedSigner?.email ?? copiedField.signerEmail, recipientId: selectedSigner?.id ?? copiedField.recipientId,
pageX: copiedField.pageX + 3, pageX: copiedField.pageX + 3,
pageY: copiedField.pageY + 3, pageY: copiedField.pageY + 3,
}); });
} }
}, },
[append, fieldClipboard, selectedSigner?.email], [append, fieldClipboard, selectedSigner?.id],
); );
useEffect(() => { useEffect(() => {
@ -567,7 +566,7 @@ export const AddFieldsFormPartial = ({
localFields.some( localFields.some(
(field) => (field) =>
(field.type === FieldType.SIGNATURE || field.type === FieldType.FREE_SIGNATURE) && (field.type === FieldType.SIGNATURE || field.type === FieldType.FREE_SIGNATURE) &&
field.signerEmail === signer.email, field.recipientId === signer.id,
), ),
); );
@ -637,7 +636,7 @@ export const AddFieldsFormPartial = ({
{isDocumentPdfLoaded && {isDocumentPdfLoaded &&
localFields.map((field, index) => { localFields.map((field, index) => {
const recipientIndex = recipients.findIndex((r) => r.email === field.signerEmail); const recipientIndex = recipients.findIndex((r) => r.id === field.recipientId);
const hasFieldError = const hasFieldError =
emptyCheckboxFields.find((f) => f.formId === field.formId) || emptyCheckboxFields.find((f) => f.formId === field.formId) ||
emptyRadioFields.find((f) => f.formId === field.formId) || emptyRadioFields.find((f) => f.formId === field.formId) ||
@ -649,7 +648,7 @@ export const AddFieldsFormPartial = ({
recipientIndex={recipientIndex === -1 ? 0 : recipientIndex} recipientIndex={recipientIndex === -1 ? 0 : recipientIndex}
field={field} field={field}
disabled={ disabled={
selectedSigner?.email !== field.signerEmail || selectedSigner?.id !== field.recipientId ||
!canRecipientBeModified(selectedSigner, fields) !canRecipientBeModified(selectedSigner, fields)
} }
minHeight={MIN_HEIGHT_PX} minHeight={MIN_HEIGHT_PX}

View File

@ -9,7 +9,7 @@ export const ZAddFieldsFormSchema = z.object({
formId: z.string().min(1), formId: z.string().min(1),
nativeId: z.number().optional(), nativeId: z.number().optional(),
type: z.nativeEnum(FieldType), type: z.nativeEnum(FieldType),
signerEmail: z.string().min(1), recipientId: z.number(),
pageNumber: z.number().min(1), pageNumber: z.number().min(1),
pageX: z.number().min(0), pageX: z.number().min(0),
pageY: z.number().min(0), pageY: z.number().min(0),