Let's talk
operations

The pickup point moved and nobody told the driver

The office changed a booking's pickup place on the booking site. The portal quietly overwrote its copy, logged nothing, and the driver drove to the old address.

·

A customer rings your office the evening before their trip and asks to be met at a different hotel. Your staff change the pickup place on the booking site, as they always have. The next morning the driver is at the old hotel with the car, the customer is at the new one, and both are ringing you.

You run a self-drive car rental business in Goa, and the owner’s question was simple: when the office changes a booking’s place or time, how does that reach us, and who gets told? The honest answer was that it reached the back-office portal within fifteen minutes and told nobody. The portal’s copy of the booking was overwritten, the booking’s own history showed no trace that anything had ever been different, the customer got no message, and the driver’s phone got no alert. If he happened to reopen the job he would see the new address with nothing to say it had changed.

The log for this work records no count of how often it had happened. That is part of the problem: a change that leaves no trace cannot be counted.

What was actually going on

The portal takes its bookings from the public booking site by copying them across. There are two ways a copy happens: a member of staff opens a booking and it is refreshed on demand, or a job runs every fifteen minutes and refreshes everything that has changed. The on-demand path did notice a changed place or date and wrote it to the booking’s history. The fifteen-minute job, which is the one that actually runs unattended and so handles almost every edit, did not compare anything. It took the new copy and wrote it over the old one.

An earlier answer to the owner had said the portal did log these changes. It did, on the path nobody uses. That claim was corrected as part of this work.

On the driver’s side, the phone was only ever alerted for two events: being given a job, and a payment. A moved pickup was neither.

What we changed

There is now one place in the portal that decides whether a change to a booking is worth telling someone about, and both copy paths go through it. It compares the booking as it stood at the last copy with the booking as it arrives now, and routes what it finds by who needs to act on it. The customer is told about a changed place or time, by email and WhatsApp, with a map link. The driver is told about those plus a changed car, flight, insurance extras or contact number, because that is the job he is about to do. Changes to charges, notes, duration and payment are written to the booking’s history for the office and sent to nobody, because the settlement decides what a customer owes, and a price correction arriving as “your booking has changed” reads as a demand.

Everything is gated on the trip still being ahead and the booking not cancelled. The booking site is edited for bookkeeping long after trips end, and emailing people about a holiday they took in March would destroy the credibility of every message after it.

The owner’s own suggestion improved the design: rather than compare the four columns the portal mirrors, compare the whole stored record from the booking site, all 79 fields of it, which the portal already keeps and overwrites on every copy. Immediately before that overwrite it is the only record of the previous state, and it sees far more than the columns do.

The alert on the driver’s phone needed no app release. The installed app already accepts any event the server sends.

What it did not fix

Cancellations were left out on purpose. Another part of the copy already tells the drivers when a booking is cancelled, and adding it here would have told them twice.

The rule for what counts as a change is an allow-list: only the named fields are watched. That is deliberate, and it means a change to a field nobody thought to name goes unannounced. The alternative was worse. Several of the 79 fields change on every copy by design, and the timestamp that triggers the copy is one of them, so “announce anything that changed” would have messaged every customer every fifteen minutes for ever.

The mechanism, briefly

A single change-detection service diffs the previous sync snapshot of the upstream JSON against the incoming row on an allow-list, with four normalisations the comparison would otherwise trip on: Postgres dates against ISO strings, whole-second formatting against sub-second column precision, money as strings so 1000.00 and 1000 compare equal, and extras held as JSON-in-a-string with no guaranteed key order. Any one of them would have produced not an error but a real email to a real customer on every run. It fans out to email, WhatsApp and push, each awaited independently so one failing channel cannot silence the others, and is covered by 22 assertions, most of which check that nothing is sent.

Where this ends up

A driver at the wrong hotel is a change that reached the database and not the person, which is why Sazinga Rentals treats a moved pickup as something the customer and the driver are told about, not something the record quietly absorbs.

This came out of building Sazinga Rentals

Bookings, availability and the fleet standing behind them. The problem above is one we met while building it, and what we did about it is in the product.

If you run something like this, tell us how it works today and we will tell you what it would take to move.