feat(eoi): add Documenso template payload builder

This commit is contained in:
Matt Ciaccio
2026-04-24 16:09:27 +02:00
parent db74c9394b
commit 7200c31486
2 changed files with 330 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
import type { EoiContext } from '@/lib/services/eoi-context';
export interface DocumensoTemplatePayload {
title: string;
externalId: string;
meta: {
message: string;
subject: string;
redirectUrl: string;
distributionMethod: 'NONE' | 'EMAIL';
};
formValues: {
Name: string;
Email: string;
Address: string;
'Yacht Name': string;
Length: string;
Width: string;
Draft: string;
'Berth Number': string;
Lease_10: boolean;
Purchase: boolean;
};
recipients: Array<{
id: number;
name: string;
email: string;
role: 'SIGNER' | 'APPROVER';
signingOrder: number;
}>;
}
export interface DocumensoPayloadOptions {
/** `interestId` used to build `externalId` and Documenso referencing. */
interestId: string;
/** Documenso recipient IDs — come from env vars. */
clientRecipientId: number;
developerRecipientId: number;
approvalRecipientId: number;
/** Hardcoded developer + approver names/emails (legacy). */
developerName?: string;
developerEmail?: string;
approverName?: string;
approverEmail?: string;
/** Redirect URL after signing. Defaults to the app URL. */
redirectUrl?: string;
}
const DEFAULT_DEVELOPER_NAME = 'David Mizrahi';
const DEFAULT_DEVELOPER_EMAIL = 'dm@portnimara.com';
const DEFAULT_APPROVER_NAME = 'Abbie May';
const DEFAULT_APPROVER_EMAIL = 'sales@portnimara.com';
const DEFAULT_REDIRECT_URL = 'https://portnimara.com';
function formatAddress(address: EoiContext['client']['address']): string {
if (!address) return '';
return [address.street, address.city, address.country].filter(Boolean).join(', ');
}
function buildMessage(context: EoiContext): string {
const greeting = `Dear ${context.client.fullName},`;
const body = `Thank you for your interest in a berth at ${context.port.name}. Please click the link above to sign your LOI.`;
const onBehalf =
context.owner.type === 'company' && context.company
? `\n\nOn behalf of ${context.company.legalName ?? context.company.name} (representing the yacht's owner).`
: '';
const footer = `\n\nBest Regards,\n${context.port.name} Team`;
return `${greeting}\n\n${body}${onBehalf}${footer}`;
}
export function buildDocumensoPayload(
context: EoiContext,
options: DocumensoPayloadOptions,
): DocumensoTemplatePayload {
return {
title: `${context.client.fullName}-EOI-NDA`,
externalId: `loi-${options.interestId}`,
meta: {
message: buildMessage(context),
subject: 'Your LOI is ready to be signed',
redirectUrl: options.redirectUrl ?? DEFAULT_REDIRECT_URL,
distributionMethod: 'NONE',
},
formValues: {
Name: context.client.fullName,
Email: context.client.primaryEmail ?? '',
Address: formatAddress(context.client.address),
'Yacht Name': context.yacht.name,
Length: context.yacht.lengthFt ?? '',
Width: context.yacht.widthFt ?? '',
Draft: context.yacht.draftFt ?? '',
'Berth Number': context.berth.mooringNumber,
Lease_10: false,
Purchase: true,
},
recipients: [
{
id: options.clientRecipientId,
name: context.client.fullName,
email: context.client.primaryEmail ?? '',
role: 'SIGNER',
signingOrder: 1,
},
{
id: options.developerRecipientId,
name: options.developerName ?? DEFAULT_DEVELOPER_NAME,
email: options.developerEmail ?? DEFAULT_DEVELOPER_EMAIL,
role: 'SIGNER',
signingOrder: 2,
},
{
id: options.approvalRecipientId,
name: options.approverName ?? DEFAULT_APPROVER_NAME,
email: options.approverEmail ?? DEFAULT_APPROVER_EMAIL,
role: 'APPROVER',
signingOrder: 3,
},
],
};
}