Every modernization project starts with the same temptation. Rewrite the whole thing from scratch. We resist that temptation every single time, because almost every project that has actually succeeded resisted it too. A full rewrite always underestimates the business logic built up over a decade of ...
Not every approval process needs a workflow engine. If everyone follows the same stable path, a simple hard-coded check is often easier to understand and cheaper to maintain. The mistake is introducing a heavy abstraction before any real variation exists. The number of approval steps is rarely the d...
Every application that lives a long time faces the same question eventually. How do you keep adding features for ten years without the whole codebase collapsing under its own weight. Most systems that age well settle on some form of plugin architecture, and the difference between a plugin system tha...
Most business applications spend a huge share of their engineering time on one small, repeated problem. Show a form, check it, save it, and show it back as a table or a detail view. Writing each of these by hand for every single feature is slow and inconsistent, and we learned this lesson more slowl...
Almost every business application we build eventually needs approval chains. A purchase order above a certain amount needs a manager's sign off. A budget needs finance approval before it goes live. A discharge needs a doctor to confirm it. The easy way to build this is to hard code each chain a...
Multi-tenancy is not a single architecture decision. Some platforms give every customer their own database and application instance, while others share the same application and database between all customers. Most systems sit somewhere between these two approaches. The right choice depends on how mu...
Many plugin systems load every enabled plugin on every request. This is simple to implement, but the startup cost grows as the platform grows. A request that only needs one feature still pays the cost of discovering, loading, and registering code that it will never use. We only load a small manifest...