Jul 30, 2026·5 min read

The patterns don't belong to a domain (building a resort PMS, part 3/3)

#distributed-systems#builder#architecture#series

This is part 3 of a three-part series on building a resort PMS solo. Part 1 was coordination (sagas, outbox, inbox); part 2 was time and identity (business date, snapshots, folio-anchoring). This part is about money, humans, and why every one of these patterns came with me from a completely different industry.

No silent decisions on money — override ledgers and confidence buckets

Two more that the money forced. Every rule-bypass — voiding a charge, walking a guest, overriding a rate, re-running the audit — requires an authorization tier, a reason code, and a note, all append-only, all exportable. And every heuristic (is this a duplicate profile? a duplicate booking?) emits a confidence and routes to one of three buckets: auto-act, suggest-to-a-human, or ignore. No heuristic silently mutates guest data or money. Both are just the operational honesty any system handling money needs, hotel or not.

The desk can't stop when the internet does

One more the physical world forced. A hotel's front desk, housekeeping, and restaurant cannot freeze because the connection dropped for thirty minutes — guests are still arriving and ordering. So the clients hold a local cache and write mutations to a local log while offline, then replay those through the same sagas on reconnect, surfacing genuine conflicts to a human rather than silently overwriting. Offline-first isn't a nicety here; it's the difference between a working desk and a lobby full of angry guests. It's the same conflict-reconciliation problem as any occasionally-connected system, made unavoidable by the fact that the building keeps operating whether the WiFi does or not.

The real lesson: the patterns are domain-independent

The thing I keep coming back to is that I didn't have to invent anything. Sagas, outbox and inbox, idempotency, business-date modeling, snapshotting, stable keys, override ledgers — I brought every one of these from a completely different industry, and the hotel welcomed them because the underlying problem was the same: coordinate multiple unreliable systems, over an unreliable network, with money and real people on the line, and never lie about what happened. Good distributed-systems thinking doesn't belong to a domain. It's a way of respecting failure that transfers wholesale.

Building it solo, end to end, is what made that legible. On a big team you inherit the outbox and the idempotency middleware from a platform someone else owns, and you can go years using patterns without ever feeling why they exist. Rebuilding all of it alone, in a domain I didn't know, stripped away that inheritance. I had to understand each pattern well enough to re-derive it from the hotel's problems — and that re-derivation taught me my own day-job systems better than years of using them had.

The fastest way to understand the patterns in your own domain is to go build them in one you don't know. Stripped of the familiar vocabulary, you find out whether you actually understood the pattern or just the local name for it.

I set out to build a hotel a booking system. I came back understanding order pipelines, event-time semantics, and idempotency more deeply than when I left. The transfer runs both ways — which is the whole case for being a builder who'll take an unfamiliar problem end to end, instead of staying safely inside the one domain you already know.

Built something similar, or want to argue with an approach here?

contact@singhpratap.dev