/** * Default mapping from a `BookingDraftV1` (+ live quote pricing + * resolved entity summary + operator / acceptance context) to the * variable bag the operator's contract templates render against. * * The variable surface is designed around Voyant's domain model: * * - sell vs cost money split (`sellAmountCents`, `sellCurrency`, * `costAmountCents`, `costCurrency`, `baseCurrency`) * - vertical-aware schedule blocks — `departureSlot` for products, * `sailing` for cruises, `stay` for accommodations * - pax-bands as a record (Voyant doesn't lock you into adult / * child / infant — descriptors can declare any band code) * - sourced vs owned booking arms (`booking.source.kind`, * `booking.source.supplier`) * - CRM customer + lead traveler split, kept distinct because the * buyer + the lead passenger are often different people * * Naming is camelCase by default. A handful of snake_case aliases * are emitted for keys the seeded `customer-sales-agreement` * template references (`contract.date`, `booking.startDate`, * `travelers[].participantType` …) so authored templates render * out-of-the-box. * * Notes on what is + isn't filled at preview time: * * - The booking row has not been created yet — `booking.bookingId`, * `booking.bookingNumber`, the persisted status, and * `contract.contractNumber` / `contract.signedAt` are empty. The * a later Legal-owned document command uses the contract's persisted, * immutable rendered body. * - `acceptance.ipAddress` / `userAgent` are captured server-side * at `/checkout/start` from request headers. Empty during preview. * - `operator.*` reads from the `operatorInfo` block injected by the * storefront wrapper (fetched from `/v1/public/operator-profile`). * Anything not configured renders as the empty string. * - Vertical-specific blocks (`sailing`, `stay`, `departureSlot`) * are populated only when `entitySummary` carries enough context. */ import type { BookingDraftV1, PricingBreakdownV1 } from "@voyant-travel/catalog-contracts/booking-engine/contracts"; import type { ComputedScheduleEntry, PaymentPolicySource } from "@voyant-travel/finance/payment-policy"; import type { BookingEntitySummary } from "../journey/index.js"; export interface OperatorInfoVariables { /** Trading name shown to customers. */ name?: string; /** Legal company name when different from `name`. */ legalName?: string; /** Tax / VAT id. */ vatId?: string; /** Trade register number (RO: J-number; UK: company number; …). */ registrationNumber?: string; /** Postal address — single string or markdown for the contract block. */ address?: string; phone?: string; email?: string; website?: string; iban?: string; bank?: string; /** License number — tour-operator license, hotel rating registry, * cruise flag-state number, depending on what the operator is. */ license?: string; /** Issuing authority for the license. */ licenseAuthority?: string; /** Human whose name appears on the operator-side signature line. */ signatoryName?: string; /** Their role / title (e.g. "Managing Director"). */ signatoryRole?: string; } interface AcceptanceContextVariables { ipAddress?: string; userAgent?: string; acceptedAt?: string; marketingConsent?: boolean; templateSlug?: string; templateId?: string; } /** * Source provenance for the booked entity, resolved from the catalog * plane (the public content endpoint returns it as `provenance` + * `product.supplier`). Threaded into the contract preview so the * `booking.source` block reflects the real sourced/owned arm instead * of defaulting to `owned` with a blank supplier (voyant#2619). * * When absent (or `kind` is empty / `"owned"`), the contract renders * the owned arm — blank connection/ref/supplier — exactly as before. */ export interface ContractSourceContext { /** Provenance kind — `"owned"` for owned inventory, otherwise the * upstream source kind (e.g. `marketplace:demo`). */ kind?: string; /** Source connection that produced the row (sourced only). */ connectionId?: string; /** Stable upstream object id (sourced only). */ ref?: string; /** Supplier disclosed to the customer in the contract. */ supplier?: { id?: string; name?: string; }; } export interface ResolveContractVariablesContext { entityModule: string; entityId: string; entitySummary?: BookingEntitySummary; pricing?: PricingBreakdownV1 | null; /** Operator profile — fetched from `/v1/public/operator-profile` by * the storefront wrapper. Anything missing renders as empty. */ operatorInfo?: OperatorInfoVariables; /** Acceptance fingerprint — populated only on server-side persistence. * At preview time the * storefront leaves this undefined and the variables render * empty. */ acceptance?: AcceptanceContextVariables; /** Pre-computed schedule from `computePaymentSchedule()`. The * storefront wrapper computes this in real time as the customer * picks their date so the contract preview shows live deposit * / balance numbers. */ paymentSchedule?: ComputedScheduleEntry[] | null; /** Which layer of the cascade the active policy came from. Used * for traceability in contract templates. */ paymentPolicySource?: PaymentPolicySource; /** Resolved source provenance for the booked entity. Populated by * the storefront wrapper from the public content endpoint's * `provenance` + supplier. When omitted the booking renders as the * owned arm (voyant#2619). */ source?: ContractSourceContext; } export declare function resolveContractVariables(draft: BookingDraftV1, ctx: ResolveContractVariablesContext): Record; export {};