Viato
A multi-tenant ERP for travel agencies
Travel agencies run on WhatsApp, spreadsheets and a mid-office tool that talks to neither. Viato gives an agency one system from enquiry to invoice, and gives every agency its own isolated infrastructure, built by a provisioning pipeline instead of by hand.

// The Problem
Three things break when an agency runs on chat and spreadsheets. Margin is discovered after the trip instead of before the quote goes out. Revenue can't be traced back to the channel that produced the enquiry, so nobody knows which channel pays. And the back office (who worked, who approved what) lives apart from the money.
The customers are small agencies: price-sensitive, working on phones, issuing Indian GST invoices, and nervous about putting their client list in somebody else's shared database.
// How It's Built
Operator console
Pipeline, agencies, billing and team access at viato.pro/admin
Provisioning job
8 steps; each checks what exists, so re-running resumes
Google Cloud project per agency
Firestore in Mumbai, email sign-in, security rules, two narrow service accounts
Vercel project per agency
Same workspace code, the agency's own config, <agency>.viato.pro over HTTPS
Agency workspace
18 modules, installable, works offline
// Decisions & Trade-offs
- 01
A project per agency, not tenant IDs in one database
A mistake in one workspace's security rules can't expose another agency's bookings, and an agency that leaves takes its whole database with it rather than a filtered export. The cost is many deployments to keep in step, so every agency deploys from the same repository and provisioning is safe to re-run.
- 02
Provisioning as code that is safe to re-run
Every step checks what already exists and only does what is missing: it never creates a second project or mints a second key. The decisions (names, rules, roles, environment) live in a side-effect-free module with unit tests; the script itself is only the sequence of API calls.
- 03
Least privilege for every service account
The console and each workspace server get exactly two roles (auth admin and datastore user), never Owner or Editor. That is enough to issue logins and read roles, and nothing more.
- 04
The quote is where margin gets decided
Every quote line carries cost and selling price side by side, so profit is checked before the quote is sent. Bookings keep the quote and lead they came from, which is what lets revenue be traced back to its channel.
- 05
Storage behind an interface
Modules talk to a typed Collection interface with Firestore and local-storage adapters. The same workspace runs against a real database in production and with no backend at all as a demo.
- 06
Permissions below the module level
A role can be granted a whole module, one desk inside it, or a single permission such as overriding attendance. The UI hides what a person can't use; the database rules decide what they can write.
// Problems Worth Telling
- 01
Production builds that silently didn't happen
A build-skip rule meant to ignore preview branches also skipped real production builds from main, leaving an agency on an old version with no error anywhere. Provisioning now clears that setting on every run, and the reason is written next to the code.
- 02
An LLM that ran out of room before answering
The daily prospect-scoring job asks for JSON. The model sometimes spent its token budget reasoning and returned nothing, flagged only by finish_reason "length". The job now retries once at a lower temperature, caps model calls per run and stops after consecutive failures instead of burning through them.
// Quality
- 220 tests on the workspace and 94 on the console, run with node:test: money math, invoice and ticket PDFs, geofencing, grants, CSV and e-ticket import, provisioning decisions, billing and pipeline ranking.
- Pure functions for anything that decides money or access, so they can be tested without a network.
- The console's "Today" screen is a pure ranking function (warnings first, then people waiting, then routine), tested like the rest.
// Where It Stands
- Live at viato.pro and sold to travel agencies. Each agency runs on infrastructure provisioned for it alone.
- The operator console runs the whole business: pipeline, onboarding links, billing and per-person access codes.
NextLetting an AI assistant work inside the ERP under the same permissions and approval rules as staff, with an evaluation suite to prove it behaves.
// Stack
Building something similar?
Let's talk