Files
pn-new-crm/docs/eoi-documenso-field-mapping.md
Matt Ciaccio db74c9394b docs(eoi): document Documenso template field name mapping
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:06:39 +02:00

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 1
  • NUXT_DOCUMENSO_DEVELOPER_RECIPIENT_ID (default: 193) — signing order 2
  • NUXT_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 Email 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 into meta.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.