Openfront Travel Agent

Inquiries, proposals, trips, supplier bookings, client payments, refunds, and commission tracking for an agency.

Source · Live site · Catalog

Openfront Travel Agent is a back office for an independent advisor or a small host agency that sells custom trips. A trip is built from supplier components (hotels, cruises, tours, flights, transfers, rail, insurance) plus the agency's planning fee.

The source is public under the MIT license. The live site at travel-agent.openship.org runs the full onboarding seed. The storefront is a plain set of pages that waits for a design. Card payments use Stripe test mode, including on the live site.

It is built on Next.js 16, React 19, Keystone 6 (GraphQL), Prisma, and PostgreSQL. Start with Getting started.

Two streams of money

  1. Client payments. The planning fee is agency revenue. Deposits and finals for components marked agency_collects are client money that the agency pays on to the supplier. Components marked client_pays_supplier never touch the agency.
  2. Supplier commissions. Each component stores an expected commission, set when it is booked. Suppliers pay it weeks or months after travel. The app tracks expected, invoiced, received, short-paid, and written-off amounts.

Money is stored as whole cents with a currency code. Commission rates are basis points (1% = 100). Expected commission is the sell price times the rate, rounded down.

Who uses what

UserSurfaceTypical jobs
AdvisorDashboardWork inquiries, build and send proposals, book components, invoice clients, record commissions
ManagerDashboardApprove refunds, over-payments, and write-offs; settings
ClientTokenised pagesRead a proposal and accept an option, view an itinerary, pay an invoice, look up a booking
VisitorStorefrontBrowse destinations, send an inquiry

Surfaces

  • Dashboard at /dashboard. Agency pages live under /dashboard/platform/*. The generic Keystone list screens at /dashboard/[listKey] stay available for every list. See External dashboards.
  • Storefront at /: destinations, an inquiry form, and client pages opened by a private link. See External storefronts.
  • GraphQL at /api/graphql. See GraphQL API.
  • MCP at /api/mcp-transport/[transport]. See MCP.
  • Dashboard assistant at /api/completion.

Lifecycle

A trip moves through these states, and only through a custom mutation:

planning → proposal_sent → accepted → booked → final_payment_due → paid_in_full → traveling → completed. A trip can also be cancelled.

A trip cannot reach paid_in_full, traveling, or completed while the client still owes money the agency collects.

A proposal moves draft → sent → viewed → accepted, or becomes superseded or declined. Sending a new version supersedes the older one.

Tenancy

There is one agency per deployment. There is no organization or tenant list. Role flags apply to the whole agency. Travelers and documents are the exception: an advisor sees only the travelers and documents of trips assigned to them, and a user who can manage roles sees all.

Onboarding

New dashboard users see a setup card in the sidebar. The dialog offers two templates, Full agency and Minimal. See Getting started.

Not built

  • Live air booking or any supplier API. Components are entered by hand.
  • Card authorisation forms.
  • Accounting sync.
  • E-signature. Accepting a proposal records a name and a time.
  • A designed storefront.

On this page