From 312ebf1a88b93a551c3be3c7b82837e9e333a905 Mon Sep 17 00:00:00 2001 From: Matt Ciaccio Date: Tue, 5 May 2026 04:13:32 +0200 Subject: [PATCH] docs(eoi): document multi-berth Berth Range field + legacy parity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The user asked us to confirm we copied the Documenso template's auto-fill schema verbatim from the legacy system. Confirmed and documented in the canonical mapping file: - Every legacy formValues key (Name, Email, Address, Yacht Name, Length, Width, Draft, Berth Number, Lease_10, Purchase) is still emitted with identical names and types — single-berth EOIs are byte-for-byte compatible with template id 8. - Phase 5 added one new field: `Berth Range` (compact range string for multi-berth EOIs from the is_in_eoi_bundle junction rows). Documenso silently drops unknown formValues, so the live template will simply not render the range until someone adds the field. The doc now flags this explicitly. - Verified buildDocumensoPayload() populates all 11 fields from the resolved EoiContext; tests at tests/unit/services/documenso-payload cover every field. The "rest is handled inside Documenso" (signature, date, terms) - those fields live on the template itself and don't appear in our formValues map. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/eoi-documenso-field-mapping.md | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/docs/eoi-documenso-field-mapping.md b/docs/eoi-documenso-field-mapping.md index 02c5ce7..6ae3c32 100644 --- a/docs/eoi-documenso-field-mapping.md +++ b/docs/eoi-documenso-field-mapping.md @@ -19,18 +19,23 @@ The template exposes eight text fields (`formValues` keys) and two boolean check ## 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. | +The legacy template (Documenso template `8`, configured in production) auto-fills exactly the fields below. All eight text fields + two booleans are populated by `buildDocumensoPayload()` from the resolved `EoiContext`. Anything else on the form (signature, date, terms acknowledgment) is filled in by the client inside Documenso. + +| 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`. Empty string when no yacht is linked yet. | +| `Length` | text | `interest['Length']` | `context.yacht.lengthFt` | Boat dimension. Send as string. Documenso doesn't enforce numeric format. Empty string when not applicable. | +| `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` | The interest's PRIMARY berth (resolved via `interest_berths.is_primary=true`). Empty string when no primary set. | +| `Berth Range` | text | (new) | `context.eoiBerthRange` | **NEW IN PHASE 5** — compact range string for multi-berth EOIs (e.g. `"A1-A3, B5-B7"`) covering every junction row marked `is_in_eoi_bundle=true`. Empty string when the bundle is empty. **The live Documenso template (id `8`) does NOT yet have this field. Add a `Berth Range` text field to the template before multi-berth EOIs render the range; until then Documenso silently drops the value and only `Berth Number` (the primary mooring) renders.** | +| `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. | + +**Backwards-compatibility guarantee**: every legacy `formValues` key is still emitted with the same name and type. The only addition is `Berth Range` (Phase 5). Documenso silently ignores unknown formValues keys, so old templates that don't have `Berth Range` will simply not render it — single-berth EOIs continue to work identically. No template changes are required for legacy use. ## Document `meta` fields (non-`formValues`)