> ## 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.

# Operator settings

> The operator-settings module owns the operator-tenant configuration domain: the operator profile, payment instructions and defaults, and booking-tax settings, mounted as a standard schema-owning module.

The operator-settings module owns the per-tenant configuration that the rest of the platform reads but does not own. It holds the operator's legal and trading identity, its customer-facing payment instructions and default payment policy, and its booking-tax knobs. Standard modules such as finance and bookings inject these readers rather than carrying operator identity or tax defaults themselves.

It ships as `@voyant-travel/operator-settings`: a Drizzle schema plus transport-agnostic readers and writers, with HTTP routes. It is a standard schema-owning module in the product graph, resolved into the application at build time rather than mounted by hand.

```bash theme={null}
pnpm add @voyant-travel/operator-settings
```

## Key concepts

The domain is split into narrow single-row tables, each with its own TypeID prefix, rather than one catch-all settings blob.

* **Operator profile.** The single-row legal and trading identity that contracts with the traveler: `name`, `legalName`, `vatId`, `registrationNumber`, contact fields, travel license, and the signing officer. Table `operator_profile`, TypeID prefix `oppf`. Contract variables and public booking-preview legal blocks read from it.
* **Payment instructions.** Single-row customer-facing collection details such as the bank-transfer beneficiary, IBAN, bank, and notes. Table `operator_payment_instructions`, TypeID prefix `opin`.
* **Payment defaults.** The operator-level default customer payment policy plus checkout and invoice pay-URL templates. The booking payment-policy cascade uses this only when supplier, category, listing, and booking-level policies do not override it. Table `operator_payment_defaults`, TypeID prefix `opdp`. The policy is stored as `jsonb` mirroring the `PaymentPolicy` shape in `@voyant-travel/finance`.
* **Booking-tax settings.** Single-row booking tax configuration (`taxPriceMode`, `taxPolicyProfileId`) used by booking-create previews, quote recomputation, and booking item tax-line materialization. Table `booking_tax_settings`, TypeID prefix `btxs`.

<Note>
  An older catch-all `operator_settings` table (TypeID prefix `opset`) is retained for migration parity from the first booking-journey settings pass. Runtime code reads and writes the narrower tables above.
</Note>

## What it owns

### Schema

The `./schema` subpath exports the Drizzle tables (`operatorProfile`, `operatorPaymentInstructions`, `operatorPaymentDefaults`, `bookingTaxSettings`, and the retained `operatorSettings`) with their inferred select and insert types. A deployment lists this package in `voyant.config` so its tables fold into the combined migration history.

### Service

The `./service` subpath exports transport-agnostic readers and writers plus the resolvers that standard modules inject. Readers and upserts are single-row by convention (`getOperatorProfile`, `upsertOperatorProfile`, and the same pair for payment instructions, payment defaults, and the catch-all settings). Two resolvers are the consumption seam:

* `resolveOperatorDefaultPaymentPolicy(db)` returns the configured default `PaymentPolicy` or `null`, so the booking cascade can fall through to its hard-coded policy.
* `resolveBookingTaxSettings(db)` returns the effective `taxPriceMode` and `taxPolicyProfileId`, defaulting to `inclusive`.

The service also exports `toPublicOperatorProfile` and `toPublicOperatorSettings` projections plus the Zod update schemas (`updateOperatorProfileSchema`, `updateOperatorPaymentInstructionsSchema`, `updateOperatorPaymentDefaultsSchema`, `updateOperatorSettingsSchema`).

### Routes

The `./routes` subpath exports `mountOperatorSettingsRoutes(hono)`. Routes are thin: they parse the request body with `parseJsonBody`, call a service function, and serialize the result. The paths are stable absolute paths:

* `GET` and `PATCH` `/v1/admin/settings/operator-profile`
* `GET` and `PATCH` `/v1/admin/settings/operator-payment-instructions`
* `GET` and `PATCH` `/v1/admin/settings/operator-payment-defaults`
* `GET` and `PATCH` `/v1/admin/settings/operator` (the catch-all settings)
* `GET` `/v1/public/operator-profile` (profile plus payment defaults, cached)
* `GET` `/v1/public/settings/operator` (the public settings projection, cached)

## Working with it

Read settings directly through the service from any runtime that has a database handle:

```ts theme={null}
import {
  getOperatorProfile,
  resolveBookingTaxSettings,
} from "@voyant-travel/operator-settings/service"

const profile = await getOperatorProfile(db)
const tax = await resolveBookingTaxSettings(db)
// tax.taxPriceMode is "inclusive" or "exclusive"
```

Inject a resolver into a standard module rather than coupling that module to operator settings. The operator application passes `resolveBookingTaxSettings` into the booking tax-line rebuild:

```ts theme={null}
import { rebuildBookingItemTaxLines } from "@voyant-travel/commerce/checkout"
import { resolveBookingTaxSettings } from "@voyant-travel/operator-settings"

await rebuildBookingItemTaxLines(db, bookingId, {
  resolveBookingTaxSettings,
})
```

Standard modules are not registered by hand. `@voyant-travel/operator-settings` 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).

<Note>
  In the operator application you do not call this factory by hand. Listing `@voyant-travel/operator-settings` in `voyant.config` registers the schema for migration and the platform composition mounts the module at its stable paths.
</Note>

## Links to other modules

* **Finance.** The default customer payment policy stored on payment defaults mirrors the `PaymentPolicy` shape in `@voyant-travel/finance`, and `resolveOperatorDefaultPaymentPolicy` feeds the booking payment-policy cascade. See [Finance](/docs/platform/modules/finance).
* **Bookings.** Booking-create previews, quote recomputation, and tax-line materialization read `resolveBookingTaxSettings`. See [Bookings](/docs/platform/modules/bookings).
* **Legal.** Contract document variables and public booking-preview legal blocks read the operator profile for the operator-side signing identity. See [Legal](/docs/platform/modules/legal).

## Next steps

<CardGroup cols={2}>
  <Card title="Configuration" icon="gear" href="/docs/platform/fundamentals/configuration">
    How a deployment lists a schema-owning module in voyant.config.
  </Card>

  <Card title="Finance" icon="receipt" href="/docs/platform/modules/finance">
    The PaymentPolicy shape behind the default payment policy.
  </Card>

  <Card title="Bookings" icon="ticket" href="/docs/platform/modules/bookings">
    The booking previews and tax-line materialization that read these settings.
  </Card>

  <Card title="Modules" icon="cubes" href="/docs/concepts/how-it-is-built">
    What it means to be a standard schema-owning module.
  </Card>
</CardGroup>
