projects/cantrip
$ cat projects/cantrip/README.md

CanTrip

Drop in your booking receipts, get a day-by-day itinerary, and see what's still missing before you fly.

status
beta
url
cantrips.fly.dev ↗
started
10/2026
stack
Go · Hotwire · SQLite/Turso · OpenRouter · Google Maps + HERE
CanTrip homepage
fig.1 — a trip's itinerary, worked out from its receipts

## why

Every trip ends up scattered across a dozen confirmation emails, PDFs and app screenshots. Putting them into one itinerary by hand is tedious, and the hard part isn’t what’s booked, it’s noticing what isn’t: the night with no hotel, or how you’ll get from the airport to the hotel.

So CanTrip starts from the receipts. Drop them in and it lays out the trip day by day, then shows what’s still left to sort. Trip can or not? It tells you.

## how it works

  1. The Bookings tab of the Japan Spring trip, with the box to drop receipts in above the flights and stays sorted from them2 views
    01 drop in your receipts Upload PDFs, screenshots or photos, or paste a confirmation email. Each one is read in the background and sorted into flights, stays, activities, food, transport, and rentals. Every detail says whether it came from the receipt or was a guess, and a booking that's seen twice is merged, not added again.
  2. The week calendar of the Japan Spring trip, days across and hours down, with stays in a lane on top and plans in a column beside it2 views
    02 see the itinerary Bookings become a day-by-day list on the phone and a week calendar on desktop. Each day is drawn in its own local time, so a flight from Singapore lands at the Japan time it really lands.
  3. A pop-up over the calendar with the ways to get to dinner in Gion, a subway, a bus and a train with their fares, a taxi and a walk2 views
    03 sort what's missing CanTrip points out the gaps nobody booked for, like nights without a bed, a change of city with no ride, two places too far apart to walk. Tap a gap to see transit routes with the fare, a taxi time and a walk, timed to arrive before the next thing starts.
  4. The Plans tab, with places not on a day yet beside those on one, and Ichiran Ramen marked closed on Wednesdays2 views
    04 plan the rest Paste Google Maps links for places to eat or things to do. They come with opening hours, warn you when a place is closed on the day you picked, and can be dragged onto the calendar. Once one is reserved, its receipt turns it into a booking.

## stack

Go net/http + html/template// backend
The same setup as Expensieve and Jalan; the server renders every page as plain HTML, and the itinerary is worked out fresh on each load.
SQLite / Turso// database
SQLite for fast iteration in development; Turso, a hosted SQLite, in production.
OpenRouter// ai
Reads the receipts. A digital PDF's text is extracted on the server and scrubbed of emails, phone numbers and card digits before it's sent; only scans and photos go to the vision model.
Google Maps + HERE// maps
Google Maps for places, opening hours and routes. HERE fills in public transport where Google has none, like Japan.
Turbo + Stimulus// frontend
Pages swap in place and the calendar's pop-ups stay put, with no build step, and every page still works with JavaScript off.
Google Drive / S3// storage
Receipts go to a CanTrip folder in your own Google Drive, filed by trip and kind, or to an S3 bucket if you'd rather not connect it.
Fly.io// infra
Cheap, and friendly to both users and agents.

$ git log --oneline

  1. HEAD → main2026-10-10

    Export the itinerary as a PDF or an Excel sheet

    The calendar or the day-by-day list, downloaded or saved straight into the trip's Google Drive folder.

  2. 2026-10-10

    Placeholder flights for tickets not bought yet

    Add a flight by its number and day; check-in and the rides around it are worked out as if it were booked, and the real ticket replaces it once its receipt comes in.

  3. 2026-10-09

    Plans on a day their place is closed are flagged

    Opening hours from Google Maps turn "closed on Wednesdays" into a gap to sort, warned of the moment the plan is put there.

  4. 2026-10-08

    Pages swap in place with Turbo; the JavaScript is split into Stimulus controllers

  5. 2026-10-06

    A ride can go through a stop you pick

    The quickest way isn't always the easiest, so a ride can be asked to pass the station with the express train.

  6. 2026-10-04

    Rides between places, check-in times and layovers

    Gaps between bookings get transit routes from Google, or from HERE where Google has no timetables, and flights get a check-in and a ride to the airport.

  7. 2026-10-03

    Plans from Google Maps links

    Things you don't book, with their opening hours, dragged onto a day on the calendar.

  8. 2026-10-02 · initial commit

    Receipts in, day-by-day itinerary out

    The first MVP: receipts read into bookings, the travellers named on them, and a week calendar on desktop.