> ## Documentation Index
> Fetch the complete documentation index at: https://voyant.travel/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Proposals

> The sales pipeline before commitment: pipelines, stages, proposals, immutable proposal versions, participants, activities, and the proposal lifecycle that accepts a version into the reserve workflow.

The proposals module (`@voyant-travel/proposals`) owns the pre-commitment sales plane. A bespoke travel sale starts as a tracked pursuit with a Person or Organization, moves through a series of stages, and produces one or more priced proposals. Proposals is where that pursuit, those proposals, and their decisions live, right up to the moment a client accepts a proposal and the [reserve workflow](/docs/platform/modules/bookings) takes over.

It sits at the top of the **bespoke travel sales chain**:

```
Proposal -> accepted Proposal Version -> Booking Session -> Quote + optional Hold
  -> Commit -> Booking / Component Booking -> Fulfillment
```

Each step hardens the commitment, and proposals owns the first two. Accepting a Proposal Version is a sales decision, not supplier confirmation: it marks the version accepted, closes the Proposal won, and seeds reservation. It does not by itself confirm suppliers or create a Booking.

<Warning>
  **"Quote" does not mean a sales pursuit.** A **Quote** is an immutable, expiring, server-produced price and terms result for an exact Booking Session revision. It is a pricing artifact, and it is distinct from a Proposal Version. The sales pursuit is a **Proposal**. This module was previously called Quotes, and the older meaning still shows up in some code and conversation — the vocabulary above is the current one.
</Warning>

People and organizations are referenced by plain id. This module does not import [relationships](/docs/platform/modules/relationships) schema or own any identity lifecycle state.

## Key concepts

<ResponseField name="Proposal" type="tracked sales pursuit">
  A tracked travel sales pursuit with a Person and/or Organization. It moves through stages, owns value, participants, activities, and one or more proposal versions, and may close won or lost. This is the canonical sales pursuit; avoid "opportunity" or "deal". See [Proposal](/docs/concepts/glossary).
</ResponseField>

<ResponseField name="Proposal Version" type="immutable proposal revision">
  An immutable proposal revision or alternative sent to the client. It freezes a [Trip Envelope](/docs/concepts/glossary) snapshot, pricing, validity, and decision state. Editing a sent version creates another version rather than mutating the one already in the client's hands. See [Proposal Version](/docs/concepts/glossary).
</ResponseField>

<ResponseField name="Pipeline" type="ordered stage set">
  An ordered set of stages a Proposal moves through. An operator can run several pipelines (for example one for FIT, one for groups). See [Pipeline](/docs/concepts/glossary).
</ResponseField>

<ResponseField name="Stage" type="pipeline step">
  A step within a pipeline (for example Qualified, then Proposal, then Negotiation), carrying win and lost flags so the pipeline knows which stages close a proposal. See [Stage](/docs/concepts/glossary).
</ResponseField>

<ResponseField name="Proposal participant" type="role on the pursuit">
  A [Participant](/docs/concepts/glossary) on a proposal: the booker, the decision-maker, the finance contact, or a traveler. Each participant points at a Person by id and carries the role they play on this pursuit.
</ResponseField>

<ResponseField name="Activity" type="logged interaction">
  A logged interaction (call, email, meeting, task, follow-up) recorded against a proposal. Activities give a proposal its history and drive follow-up. See [Activity](/docs/concepts/glossary).
</ResponseField>

<ResponseField name="Proposal products and version lines" type="proposal contents">
  Proposal products attach catalog references to the pursuit, and proposal version lines freeze the priced contents of a specific version. Both belong to the proposal side, not to a booking, until a version is accepted.
</ResponseField>

## The proposal lifecycle

A proposal version moves through an explicit status: `draft` to `sent` to a decision. A version can only be **accepted** after it has been **sent**, and a proposal can hold exactly one accepted version. Sending freezes the proposal; accepting records the decision and closes the pursuit.

```mermaid theme={null}
stateDiagram-v2
    [*] --> draft
    draft --> sent: sendProposalVersion
    sent --> accepted: acceptProposalVersion
    sent --> declined
    sent --> expired
    draft --> superseded: revised
    sent --> superseded: revised
    accepted --> [*]
    declined --> [*]
    expired --> [*]
    superseded --> [*]
```

The proposal itself closes alongside the version decision: accepting a version closes the proposal `won`, and a proposal can otherwise end `lost` or `archived`.

<Steps>
  <Step title="Draft">
    A version is created in `draft` and can be revised freely. It carries a frozen Trip Envelope snapshot, pricing, and validity.
  </Step>

  <Step title="Sent">
    Sending the version (`sendProposalVersion`) hands it to the client. Once sent, edits create a new version rather than mutating this one.
  </Step>

  <Step title="Accepted">
    Accepting the version (`acceptProposalVersion`) marks it `accepted`, stamps the proposal's `acceptedVersionId`, closes the proposal won, and declines the sibling versions on the same proposal. A second accept on a proposal that already has a different accepted version raises a conflict.
  </Step>
</Steps>

<Warning>
  Accepting a proposal version is a sales decision, not supplier confirmation. It seeds the reserve workflow but does not by itself guarantee that every live or manual component is confirmed by its supplier. The hardening happens downstream in [bookings](/docs/platform/modules/bookings).
</Warning>

## What it owns

Proposals owns the sales pipeline and the proposal artifacts.

* **Pipelines and stages** (`./schema`), including win and lost flags on stages.
* **Proposals**, their value, owner, status, source, and stage tracking (a stage change stamps `stageChangedAt`, and closing stamps the close).
* **Proposal versions**, their immutable snapshots, validity, and decision state, plus the accept-and-decline-siblings transaction.
* **Proposal participants** and **activities** scoped to a proposal.
* **Proposal products and proposal version lines** that hold the proposal contents.
* **Custom fields** on proposals, validated on write against the deployment [custom-field registry](/docs/platform/fundamentals/custom-fields).
* **The booking proposal-details extension** (`./booking-extension`): a small `booking_crm_details` table that links a created Booking back to the proposal and version it came from, so the bookings side can carry provenance without coupling to proposal schema.

It does **not** own identities, commitments, inventory holds, or money collection. Those belong to [relationships](/docs/platform/modules/relationships), [bookings](/docs/platform/modules/bookings), and the finance module.

## Working with it

Standard modules are not registered by hand. `@voyant-travel/proposals` is part of the standard product graph, so its routes, services, subscribers, and jobs are resolved into the application at build time. See [Configuration](/docs/platform/fundamentals/configuration).

Create a pursuit against an existing Person, build a proposal, send it, and accept it.

```ts theme={null}
import { proposalsService } from "@voyant-travel/proposals";

const proposal = await proposalsService.createProposal(db, {
  title: "Henderson family, two weeks in Egypt",
  personId: "pers_01h...",
  pipelineId: "pipe_default",
  stageId: "stage_qualified",
});

const version = await proposalsService.createProposalVersion(db, {
  proposalId: proposal.id,
  // freezes a Trip Envelope snapshot, pricing, and validity
});

await proposalsService.sendProposalVersion(db, version.id);

// The client says yes. Accept closes the proposal won and declines siblings.
const result = await proposalsService.acceptProposalVersion(db, version.id);
// result.proposalVersion.status === "accepted"
// result.proposal is closed won; result.closedProposalVersions lists declined siblings
```

Record the touches that move a deal, and add the people who matter on it.

```ts theme={null}
await proposalsService.createProposalParticipant(db, proposal.id, {
  personId: "pers_01h...",
  role: "decision_maker",
});
```

<Note>
  A proposal can hold only one accepted version. Calling `acceptProposalVersion` on a version that has not been sent, or on a proposal that already accepted a different version, raises a `ProposalVersionConflictError` rather than silently overwriting the decision.
</Note>

## Links to other modules

* **[relationships](/docs/platform/modules/relationships)** owns the People and Organizations a proposal points at by id. Proposal panels surface on person and organization detail pages.
* **[bookings](/docs/platform/modules/bookings)** consumes the accepted proposal version: its [Booking Origin](/docs/concepts/glossary) records `accepted_proposal_version` and the version id, and the `booking_crm_details` extension links the booking back to its proposal.
* **[trips](/docs/platform/modules/trips)** is the shape a proposal version's Trip Envelope snapshot mirrors when the proposal composes several components.
* The finance and legal modules attach invoices, contracts, and policy acceptances against a proposal version once it is accepted.

## React package

`@voyant-travel/proposals-react` provides hooks (`useProposals`, `useStages`, and the version and participant equivalents), query keys, the `VoyantProvider`, and reusable UI including `ProposalsBoard` for a stage-by-stage pipeline view. Proposals are represented by ids on proposal records, so person and organization UI comes from `@voyant-travel/relationships-react`. Styled components require the optional `@voyant-travel/ui` peer.

## Next steps

<CardGroup cols={2}>
  <Card title="Relationships" icon="address-book" href="/docs/platform/modules/relationships">
    The CRM core that owns the People and Organizations a proposal pursues.
  </Card>

  <Card title="Bookings" icon="ticket" href="/docs/platform/modules/bookings">
    Where an accepted proposal version becomes a durable commitment through reserve.
  </Card>

  <Card title="Trips" icon="route" href="/docs/platform/modules/trips">
    The Trip Envelope shape a multi-component proposal composes and freezes.
  </Card>

  <Card title="Glossary" icon="book-open" href="/docs/concepts/glossary">
    The shared vocabulary: Proposal, Proposal Version, Pipeline, Stage, and the commitment chain.
  </Card>
</CardGroup>
