Terra Technologies Let’s talk

Engineering · Application Development

Application Development

Most software we are asked to take over works. The problem is that nobody can change it safely, and the person who could has left. [Draft copy]

The problem

The rules got tangled up with the plumbing.

It was built quickly, which was the right call at the time. The business rules ended up inside the database, or the controller, or a stored procedure written by a contractor in 2019. A change to how a discount is calculated now touches the UI, the data layer and two reports.

So estimates inflate, because every change is really an archaeology exercise. Tests exist, but they test the framework rather than the rules, so they pass while the behaviour changes underneath them. And the system cannot move — it is married to a runtime version on a particular server.

What enterprise-grade looks like here

The rules sit in the middle and depend on nothing.

We build on an onion architecture: the domain at the centre, infrastructure at the edges, and every dependency pointing inward. The rules do not know what database they are stored in, what framework serves them, or which cloud they run on. Swap any of those and the rules do not change.

SOLID, KISS and DRY are not a credential to put on a slide. They are the reason a change stays where you put it: one responsibility per unit so a change has one home, the simplest thing that works so the next person can read it, and one definition of each rule so fixing it once fixes it everywhere.

We mostly build this in .NET, because that is where the deepest bench of our experience is and because it is straightforward to hire for in this market. The shape matters more than the stack, and we are not limited to it — if your team is a Java or a TypeScript team, the architecture is the same and we build it there instead.

This framing repeats on every capability page. It is the differentiator, and it reads consistently across all of them (§9 T3).

What we do

Five moves, in this order.

  1. Model the domain before writing the application

    The rules, written in the language the business already uses. If we cannot describe them without mentioning a table name, they are not understood yet.

  2. Put the domain at the centre

    Onion architecture: domain, then application services, then infrastructure. Dependencies point inward, always, and that constraint is enforced in the build rather than trusted to discipline.

  3. Test the rules, not the framework

    The domain is testable without a database or a web server, so the suite is fast enough that people actually run it. Integration tests cover the edges where the plumbing lives.

  4. Record the decisions as they are taken

    Short architecture decision records, including the option rejected and why. This is what makes the codebase legible to whoever comes next, including your own new starters.

  5. Hand it over so you can hire for it

    Conventional structure, no in-house cleverness, and documentation written during the build. A competent developer should be productive in it without us.

[Draft copy]

What you end up owning

Documents and configuration, not a dependency.

Deliverables and the team that owns each one after handover
DeliverableOwned by
Source code with the domain isolated and testableYour engineering team
Architecture decision recordsYour engineering team
Test suite covering the business rulesYour engineering team
Build and deployment definitionsPlatform team
Handover documentation and pairingYour engineering team

[Draft copy]

Tell us what you are being asked to prove.

Bring the system you are afraid to change, or the one you are about to commission.

Start a conversation