A second shop, warehouse, or venue is not a second application. It is a column the queries must not forget.
How we build scalable web applications says you can open another branch on a shared permissions model. It does not say which tables are shared. This article does.
It is still one deployable. A modular monolith is that decision. You also do not “integrate” your own branches through a no-code tool when both sites are rows in your database. Composable integrations is for systems you do not own.
Shared versus scoped
| Usually shared | Usually branch-scoped |
|---|---|
| A customer who really visits more than one site | Stock on hand |
| Staff identity, plus the branches that person may open | Schedules, courts, rooms |
| A catalog SKU that is the same item everywhere | Drawers, daily totals, prices that differ by site |
If a customer must never appear at the other branch, that customer is not shared. Write the rule down before the migration. A branch dropdown on the form is not the control. The query is the control.
Every read of branch data includes the branch, including exports and admin search. Background jobs too. A nightly report that forgets the branch is how one site sees another site’s stock. The same mistake in a queued job is worse, because nobody is looking at the screen when it runs.
What we will not build
- A copy of the database per branch, merged by spreadsheet on Fridays.
- A service per branch.
- A platform for other companies. This design is one operator and many sites. Selling the system to other operators is a different boundary, and we would scope it before calling it the same feature.
Permissions still matter: a person at branch A does not get branch B because the row exists. The role check and the branch check are both required. Neither replaces the other.
Straight next step
Send the list of records that must never show up at the other branch. We will mark shared tables and scoped tables before anyone adds a dropdown.



