This is not a specific business. We constructed the common shape of one person running two cafés. The shop names, prices and menus are invented; the code, screens and logs actually ran.
A second shop has opened. You want to use the first shop's app as it is.
Here is what usually happens.
if (shopName == 'Riverside') { ... } else { ... }
And again at the third shop, and again at the fourth. Two years later the file still holds a branch for a shop that closed, and nobody dares delete it.
The app must not know the shop
This sample has one rule.
/// The tempting shape is a `shopName` switch somewhere. Then the second shop
/// is a code change, the third shop is a code change, and eventually the file
/// has a branch for a shop that closed two years ago.
///
/// So nothing here knows any shop's name. The config file is an argument.
A shop is a config file, and the config file lives outside the app.
shop.mbd/ ← the app. shared by both shops
configs/
riverside.json ← shop 1
hilltop.json ← shop 2
Same files, different shops

Charge 7000 won
shop.mbd — 3 files, sha256:f5f905958eac
[riverside.json] RIVERSIDE · 07:00 - 20:00 · 3 items on the menu
[hilltop.json] HILLTOP · 09:00 - 18:00 · 4 items on the menu
same screen file, two shops: RIVERSIDE due 7000 won vs HILLTOP due 12100 won
The whole bundle is hashed. Whatever differs between the two shops, it is not in there.
The verification is one grep
This piece's claim reduces to a single check.
for NAME in Riverside Hilltop; do
if grep -RIiq "$NAME" shop.mbd shop_server/bin; then
echo " \"$NAME\" appears inside the app — the difference has leaked in"; exit 1
fi
done
neither shop name appears in shop.mbd or shop_server/bin
If a shop name appears inside the app, it fails. This check goes red the moment somebody in a hurry adds one line of if (shop == 'Hilltop'). That is why it exists — that line always arrives when somebody is in a hurry.
Press something that is not on the menu
The screen file is the same, so the carrot cake button is on both shops' screens.
Riverside does not have carrot cake.
[riverside.json] add CK -> "CK is not on this menu"
[hilltop.json] add CK -> "added Carrot cake"
The server refuses.
// A sku that is on one shop's menu and not the other's must be refused
// here, not hidden by the screen. The screen is the same file in both
// shops and cannot know.
if (item.isEmpty) {
return _state(notice: '$sku is not on this menu');
}
This is the other face of the same story as Who May Press This. There, authorisation lived outside the screen; here, the catalogue lives outside the screen. What they share is that the screen is the same file, and the same file cannot decide anything.
This content requires Developer or above
Sign in and upgrade your plan to continue reading.
View Plans