Travel + AI trip planner

Tripsmith

A travel agency’s booking site: an AI trip planner on the real catalogue, live seats, Razorpay checkout, GST invoices and an owner desk.

Role
Solo — design, frontend, API, database, deploy
Year
2026
Status
v3 live · complete — AI trip planner + bookings
Version
v3 — complete
Next.jsTypeScriptFastAPIPostgreSQLGoogle GeminiTailwind CSSRazorpay

The problem

A small Indian tour agency sells fixed-date group trips: a set itinerary, a price per person and a limited number of seats per departure. Most run on WhatsApp, phone calls and a spreadsheet, so two people can pay for the same last seat, prices are worked out by hand, and nobody can see who changed a booking. Tripsmith is that agency’s own site, built so every seat, rupee and change is accounted for.

What I built

A Next.js site with 14 packages and 51 departures; package and destination pages are generated ahead of time and refresh on demand when the owner edits them. A FastAPI + Postgres API behind it. Customers book with live seats, add-ons, deals, early-bird prices and coupons; pay in full or a 25% deposit through Razorpay in test mode; get a PDF voucher and GST invoice; and sign in with an emailed 6-digit code to manage their trips. Customers can also join a waitlist on a sold-out date, change their date, save and compare trips, fill in traveller details and open a trip pack a week before they leave. The owner runs bookings, refunds, enquiries, packages, coupons, reviews and counter bookings over Razorpay Payment Links from an admin desk on the same API, with a departure calendar and reports that reconcile with the bookings CSV. On every public page an AI trip planner plans the trip in a chat: it searches live packages, checks dates and seats, opens the booking sheet pre-filled or hands the chat to a person, and the owner reads every conversation in a log.

Key decisions

  1. The server owns the price

    Every quote is built on the server in whole paise: deal, then early-bird, then coupon, with add-ons added last. The browser never sends a price; the owner’s counter screen sends the total it expects and gets 409 price_changed if it moved.

  2. Seats are held, not hoped for

    Pressing Pay creates a 10-minute hold. The server locks the customer’s email or phone, then the departure row (FOR UPDATE). A test fires two orders for the last seat at once: exactly one wins, the other gets 409 sold_out.

  3. All payments go through one capture function

    The Checkout callback, the sync when Checkout closes, the webhook and payment links all lead into it. Signatures are checked with HMAC and a unique Razorpay payment id turns replays into no-ops. A payment that lands after the seats are gone is cancelled and refunded automatically through the Razorpay refund API.

  4. History can’t be rewritten

    Every booking change is written to booking_events, and a Postgres trigger refuses any UPDATE or DELETE on it. The owner sees it as a timeline, the customer as “Activity”.

  5. The trip planner can only quote the database

    A tool-calling agent on Gemini’s free tier, with our own loop instead of a framework. Every card and price comes from a tool result, and a guardrail checks the reply while it streams: an invented package or ₹ amount is replaced before it reaches the browser. Phone numbers and emails are removed before the model sees them, the site-wide cap lives in Postgres so it holds if the rate limiter fails, and when the free turns run out a no-AI finder takes over. 23 scripted real-model conversations pass, prompt injections included.

Versions

  • v1 Agency website Shipped

    Catalog, search, package pages, enquiries + WhatsApp, itinerary PDF, owner admin.

  • v2 Booking engine Shipped

    Razorpay checkout, webhooks, accounts, deals, coupons, reviews, owner bookings desk.

  • v2.5 Strengthen Shipped

    Deposits, add-ons, early-bird, a waitlist, date change, refunds + GST documents, traveller details, a trip pack, saved trips + compare, counter booking, a departure calendar, reports and automatic emails.

  • v2.6 Hardening Shipped

    A four-track audit closed: money edge cases, demo-owner limits, CI gates, indexes, and every business rule served from one API.

  • v3 AI trip planner Shipped

    Chat that searches the catalog, checks live seats, opens the booking or hands off to a person; streaming guardrail, owner log, no-AI quick finder.

Outcome

Complete and live at tripsmith.virajdomadia.com, taking bookings in Razorpay test mode, with the AI trip planner on every public page at ₹0 a chat. Over 1,150 API tests and over 740 web tests, with a forced-race test on every lock path, plus 23 real-model evals run by hand (23/23). CI runs three jobs: web, api, and an OpenAPI contract check that fails if the generated types drift. The booking page scores 88 on PageSpeed mobile with the booking sheet open.

Updated

← All projects