Insights Architecture

Model the differences as configuration, not branches

Three markets, three tax regimes. The way to collapse them was not abstraction — it was deliberately refusing to make the rules engine general.

Three markets, three systems

TSUKI ran separate commerce backends in Taipei, Tokyo and Singapore, maintained by three teams. One price change meant doing the work three times, and one of the three was regularly missed. Nobody decided on this structure. It accumulated: each time a new market opened, copying the existing system was the fastest option available that week.

The pull towards abstraction

Faced with this, the first instinct is always to build a general rules engine. Tax becomes an expression, payment becomes a plugin interface, fulfilment becomes a lookup table — abstract it far enough and the fourth, fifth and tenth markets all fit. The idea is genuinely attractive, and it is wrong.

We deliberately kept it narrow

The engine we shipped supports only the rule shapes these three markets actually use: tax inclusive or exclusive, three named payment integrations, fulfilment by weight band or flat rate. That is the whole vocabulary. An engine that can express any rule eventually becomes a second programming language — one with no type system, no debugger, and nobody who can read it.

Write down what it cannot express

This is the step most often skipped and the one that matters most. The documentation has a section titled "rules this engine cannot express", listing seven cases and, for each, what to do instead — usually, change the code. Without that section, someone in two years will try to express the eighth case in configuration, fail, and blame the design.

The fourth market

They opened Malaysia in early 2026. The rule shapes fell inside the supported set and no code changed; evaluation went from six weeks to two days. The bet paid. But to be honest about it: had that market needed an eighth rule shape, we would have written code, and that would still have been cheaper than maintaining a general engine for two years.

When generality is right

When you have twenty markets and you add one every quarter. The cost of generalising is roughly fixed and the benefit scales with count, so above some number it becomes worth it. TSUKI was not above that number, and most companies are not. The difficulty is that nearly every team believes it is.