Back to blog

How we built a command center for a tour operator

Engineering22 October 20268 min read

Four lead sources, a CRM with a thin API, PDF bank statements and analytics in a spreadsheet. What we built in six weeks and where we got it wrong.


Lilo Tour is a tour operator in Kazakhstan. Leads arrive from Instagram, WhatsApp, Telegram and the website, deals live in U-ON Travel, payments sit in bank statements, and the overall picture was assembled by hand in Google Sheets once a week. We were brought in to turn that into one working loop.

Week one: we wrote no code

We sat with the managers and traced twenty leads from the first message to payment or refusal. That turned out to be more useful than any technical audit. We found things that appeared in no process description.

  • An Instagram lead waited 12 minutes longer for a reply on average: managers kept the Instagram tab open less often.
  • A third of deals were stuck at “waiting for the balance payment” and nobody knew which ones, because payments were reconciled weekly.
  • Two managers kept their clients in personal notes because the CRM was awkward for them.

The third point matters more than the first two. When a system is awkward, people work around it, and from then on any analytics counts incomplete data.

Architecture: one loop, hourly reconciliation

We did not build realtime sync. For travel, where a deal lives for weeks, that is complexity for nothing. We went with hourly reconciliation plus integrity checks instead.

  • U-ON Travel API — deals, tours, contacts, funnel stages.
  • Wazzup — WhatsApp and Instagram Direct, conversations and read receipts.
  • Telegram Bot API — a separate lead channel and notification delivery.
  • Payments — from statements, matched to a deal by amount, date and reference.
  • Node.js and PostgreSQL on Railway, nothing exotic in the stack.

The nastiest part is matching a payment to a deal. The reference field is filled in by humans and contains anything: the traveller's name, a booking number, an empty string. We match in three passes and send whatever does not reconcile to a person in a separate queue. Automation that silently guesses is unacceptable where money is involved.

The “on fire” screen

The home page shows four queues: deals with no movement, conversations with no reply, unpaid invoices, overdue tasks. Everything sorts by amount. The founder does not see “47 open deals”, they see “these six, worth 4.2 million, and they are stuck”.

We moved the “stuck” threshold into per-stage settings, which proved to be the right call: forty minutes of silence is normal at the “picking a tour” stage and already a risk at “waiting for the balance payment”.

Where we got it wrong

We shipped a dark theme by default

It felt modern. Two weeks later the managers asked for a light one: a dark background wears you out on long tables of numbers, and they live in the system all day. We rebuilt the palette as white cards on a light background, Inter with no bold weights, colour only on data. The dark theme stayed, behind a toggle.

At first we showed the agent everything

The first version of conversation review took the whole day of chats as input and produced a long text nobody read. We rewrote it as separate questions: “where did we lose the client”, “what did they complain about”, “what did we promise and not deliver”. Each conclusion is two sentences plus links to sources.

We thought notifications were easy

For the first week the center sent a notification for every event. People turned them all off. We had to cut it down to two things: a morning digest in Telegram and an urgent alert only where money can be lost today.

Where it landed

The stand-up starts from a ready screen. A stalled deal shows up within the hour. Managers work in one window instead of four tabs, and the personal notes disappeared on their own, without any mandate. We are counting the quantitative results together with the client over the first quarter and will publish them once both sides confirm the numbers.

The main lesson from six weeks: the hard part of a command center is not the models or the integrations, it is working out which question belongs on the home screen. Every business has its own, and you cannot learn it from API documentation.

Let us show it on your data

Half an hour that leaves you with a clear picture of what the command center fixes first and what it costs.