7.1 KiB
Documenso EOI Template — Field Mapping
Purpose: This doc is the canonical reference for mapping the Documenso EOI template's formValues keys to the new data model's EoiContext shape. It drives buildDocumensoPayload() (Task 11.2), the in-app Standard EOI HTML tokens (Task 11.3), and the Spec 2 importer's yacht/company hydration.
Source
The legacy field list comes from client-portal/server/api/eoi/generate-quick-eoi.ts, specifically the POST body sent to POST /api/v1/templates/{templateId}/generate-document (Documenso template 8). The relevant lines in that file are around the createDocumentPayload.formValues object.
Documenso template formValues keys
Documenso template IDs and recipient IDs are configured via env vars:
NUXT_DOCUMENSO_TEMPLATE_ID(default:8)NUXT_DOCUMENSO_CLIENT_RECIPIENT_ID(default:192) — signing order 1NUXT_DOCUMENSO_DEVELOPER_RECIPIENT_ID(default:193) — signing order 2NUXT_DOCUMENSO_APPROVAL_RECIPIENT_ID(default:194) — APPROVER, signing order 3
The template exposes eight text fields (formValues keys) and two boolean checkboxes.
Field mapping
| Documenso key | Type | Legacy source | New EoiContext path |
Notes |
|---|---|---|---|---|
Name |
text | interest['Full Name'] |
context.client.fullName |
The interest's point-of-contact client (billing signer). |
Email |
text | interest['Email Address'] |
context.client.primaryEmail |
Primary email contact from client_contacts. |
Address |
text | interest['Address'] |
concat context.client.address.{street,city,country} |
Concatenate street, city, country with ', '. Empty if address is null. |
Yacht Name |
text | interest['Yacht Name'] |
context.yacht.name |
Yacht is now a first-class row; pulled via interest.yachtId. |
Length |
text | interest['Length'] |
context.yacht.lengthFt |
Send as string. Documenso doesn't enforce numeric format. |
Width |
text | interest['Width'] |
context.yacht.widthFt |
Same. |
Draft |
text | interest['Depth'] |
context.yacht.draftFt |
Legacy field was named "Depth" in NocoDB; Documenso key is "Draft". |
Berth Number |
text | berthNumbers (joined) |
context.berth.mooringNumber |
One berth per reservation. Multi-berth case was multi-interest in legacy. |
Lease_10 |
boolean | hardcoded false |
false |
Hardcoded — legacy flow defaults to Purchase (not Lease). |
Purchase |
boolean | hardcoded true |
true |
Hardcoded — legacy flow defaults to Purchase. |
Document meta fields (non-formValues)
| Documenso key | Type | Legacy source | New source |
|---|---|---|---|
meta.message |
text | Dear ${interest['Full Name']}... |
Dear ${context.client.fullName}, ...port name interpolated |
meta.subject |
text | "Your LOI is ready to be signed" |
Same — constant. |
meta.redirectUrl |
text | "https://portnimara.com" |
context.port.redirectUrl if per-port; otherwise global app URL. |
meta.distributionMethod |
text | "NONE" |
Same — constant. We use manual send flow (Documenso webhook). |
title |
text | `${interest['Full Name']}-EOI-NDA` |
`${context.client.fullName}-EOI-NDA` |
externalId |
text | `loi-${interestId}` |
Same. |
Recipients (non-formValues)
| Recipient | Role | Name | Signing order | |
|---|---|---|---|---|
| Client (signer) | SIGNER | context.client.fullName |
context.client.primaryEmail |
1 |
| Developer (signer) | SIGNER | "David Mizrahi" |
"dm@portnimara.com" |
2 |
| Approval (approver) | APPROVER | "Abbie May" |
"sales@portnimara.com" |
3 |
The Developer and Approval recipients are currently hardcoded in the legacy flow. In the new system these should eventually come from port-level settings (e.g., ports.settings.eoi.developerName + email). For Task 11.2, keep them hardcoded as the legacy system does — tracking as TODO: "Replace hardcoded Developer/Approval recipients with port-level configuration."
Company-owned yacht handling
The legacy flow has no concept of company ownership — the signer is always the interest's client. In the new system:
- If
context.yacht.ownerType === 'client': behavior unchanged. - If
context.yacht.ownerType === 'company': the interest's point-of-contact client still signs (they're the representative of the yacht's owning company), but an extra block should appear in the message body:"On behalf of ${context.company.legalName ?? context.company.name} (representing the yacht's owner).". This isn't a separate Documenso field — it's woven intometa.message.
Tracking this in the mapping doc rather than as a hard TODO because company-owned EOIs were rare in the legacy system and need product input before committing to the final wording.
Deprecated fields (no longer sourced from clients)
The legacy system read these fields from the client row. They are now sourced elsewhere:
| Legacy source | New source |
|---|---|
client.yachtName |
yachts.name via interest.yachtId |
client.yachtLengthFt |
yachts.lengthFt via interest.yachtId |
client.yachtWidthFt |
yachts.widthFt via interest.yachtId |
client.yachtDraftFt |
yachts.draftFt via interest.yachtId |
client.companyName |
companies.name via polymorphic owner resolution |
client.berthSizeDesired |
Removed. Berth is picked via reservation, not text. |