One platform, six branches: what we learned

Multi-branch is not a filter you add later. Lessons from building the platform that runs contracts, billing, bookings and doors across six locations.

Most business software is written for one location and then asked, later, to handle several. The request usually arrives as something small: "can we add a branch filter?" It is never small. Branch is not a filter on a list — it is a property of almost every record, permission and total in the system, and retrofitting it touches all three.

We learned this properly while building and running the platform behind Iraq's leading serviced-office provider: contracts, billing, bookings, reporting and meeting-room doors, across six branches, in production and still operated by us today. These are the lessons that transferred to everything we have built since.

Branch belongs in the model, not in the query

If branch lives only in the WHERE clause, then every new report is a chance to forget it — and the first time a manager in one location sees another location's numbers, trust in the entire system takes a hit that is disproportionate to the bug.

Put it in the model instead. Every record that belongs to a location carries it. Every query scopes by default and has to opt out deliberately for the group-level view. The safe direction is the default one: a developer who forgets the scope should get too little data, never too much.

Permissions are two questions, not one

"What can this person do?" and "where can they do it?" are separate axes, and collapsing them creates a role explosion — branch-manager-A, branch-manager-B, accountant-A, and so on until nobody can audit anything.

The model that held up: a role describes capability, and a scope describes reach. A person is an accountant at these branches. Group finance is the same accountant role with a wider scope. New branch, no new roles — you extend one person's scope, and the audit trail still means something.

One ledger, six views

The instinct with multiple locations is to give each one its own books and add them up at the end of the month. It reconciles badly, and it makes the group number a spreadsheet exercise rather than a fact the system knows.

One ledger, with the branch as a dimension on every entry, gives you both readings from the same source: the branch view is a filter, the group view is the sum, and they cannot disagree because they are the same rows. Transfers between locations then become explicit entries rather than an adjustment somebody remembers to make. We wrote more about that discipline in what automated billing looks like when it is done right.

The physical world is part of the data model

A meeting room is not a row in a table. It is a room, with a door, that a member expects to open when their booking starts.

Wiring the booking system to the access device on the door collapsed a whole category of daily work: no reception step, no key handover, no "the room says it's free but the door is locked". The reservation is the permission. That only works if the two systems share one source of truth rather than syncing two — and if the door can decide locally, because a network hiccup must never mean a member stands outside a room they have paid for.

The general lesson: when software controls something physical, the physical constraints have to be first-class in the design. Doors, printers and payment terminals do not retry politely.

Migration is the project, not the prologue

Every multi-location rollout carries a decade of existing arrangements: contracts with unusual terms, prices agreed verbally, a client who has always been invoiced on the 5th. The temptation is to normalise all of it and start clean. That is how a rollout stalls — the business simply cannot afford to renegotiate its entire book to suit a database.

What works better is to model the exceptions honestly, import history as it actually was, and let the new rules apply going forward. Data migration should be rehearsed more than once, on real data, with the client's own staff checking the results — they will spot in ten minutes what a developer would never question.

Roll out one branch at a time

Going live everywhere on the same morning multiplies both risk and support load at exactly the moment your team is least experienced with the system.

One branch first, for long enough to hit a full billing cycle. That branch's staff become the people who train the next site, in their own words, in Arabic, with the shortcuts they discovered. By the sixth location the rollout is routine, and the training material has been tested by the people who actually use it.

Reports are the adoption test

Staff will forgive a clunky screen. Management will not forgive a number they cannot explain. If the group report disagrees with a branch's own count — even for a good reason, like a booking counted at reservation in one view and at completion in another — the credibility of the platform is spent arguing about arithmetic.

Define what each number counts, and when it counts it, before building the dashboard. Then show that definition next to the number in the interface, not in a manual nobody opens.

What we would tell anyone starting this

  • Decide early whether branches share customers, prices and stock — the answer shapes the schema more than any feature does.
  • Make scope a first-class concept in permissions on day one; it is nearly impossible to add safely later.
  • Keep one ledger. Always.
  • Rehearse migration on real data, with the client's staff verifying.
  • Roll out sequentially, and let the first branch train the second.
  • Agree the definition of every headline number before anyone builds a chart of it.
  • Write the scope down first — a project this size is exactly where a written scope stops being paperwork and starts being the thing keeping the project predictable.

None of this is exotic. It is the difference between software that a growing company outgrows in two years and software that is still running the business six branches later — which is the only test that has ever mattered.

More from the blog

All articles