Skip to content
Architecture

One core, eighteen entries in the ledger and one in production

What our industry products share, what has to be written from scratch every time, and why we publish a ledger of statuses instead of a count of products.


Mikhail Savchenko·May 18, 2026·4 min read
ArchitectureMulti-tenantStrategy

What sits under all the products at once

In any system with staff and customers the same things repeat. Someone signs in under their own account. They hold a role. The role permits some things and forbids others. Notifications go to someone, an invoice to someone else, the correspondence lives in one place and is findable, and a log remembers who changed what.

That is five mandatory entities - user, company, the role between them, an access key, and a permission override for an individual company - plus nineteen capability packages and three services: sign-in, invoices and assistant. Written once, never rewritten for an industry.

The fifth entity did not come from a plan. It came from a case. A branch manager in the rental business needed access to reporting meant for fleet co-owners, and an ordinary manager role does not grant it. The role table could not express that. The trigger was industry-specific; the fix turned out to be general, and every product now inherits it.

How much actually transfers

The custom here is to quote a large share. We measured twice, and both figures were inconvenient.

The rental CRM we moved onto the shared base is 318,757 lines and four years of accumulated rules. Of 1872 schema lines, 1650 were industry-specific, that is 88%. The shared scaffolding was 220 lines.

The second measurement is harsher. We built a rental platform, then a real-estate platform. Adjacent industries, both about an object handed to somebody for a while or for good. Of 113 business concepts across the two products, seven were shared. About 6%, and that number is worth reading about on its own.

Which yields a consequence useful well outside our own kitchen. "We already have this, we just need to configure it" is a sentence about scaffolding, not about your business. Where four weeks comes from works through the same thing from the side of the person choosing a vendor.

What backs this up

The rental move took four weeks, and operators were working in the rebuilt application from the third, running real bookings through it.

The bottleneck was not build time. Three times it turned out that the real rental data contradicted the specification of the base, and each time we rewrote the specification rather than the data. A base that cannot survive contact with a four-year-old working product is not a base yet.

One side effect mattered more than anything planned. Business rules such as "no vehicle handover until the contract is signed and the deposit is in" went straight into the layer that external AI agents call. The agent now cannot get around the rule without even knowing it exists: the layer returns a refusal naming the condition it broke. Every product after that gets it for free.

The scoreboard, unflattering

StatusCount
In production1
Pilot2
Awaiting migration4
Drifting from the specification4
Not brought onto the base2
Named, not started3
Replaced by another2
Full conformance with the specification0

Eighteen entries. One in production. And the status the specification names as the goal has not been reached by any of them yet.

A product count is a marketing number, a ledger of statuses is an engineering one, and only the first can be wrong in a way nobody notices. "Eighteen products on a shared base" outlives any drift underneath it. "One in production, none in full conformance" creates work.

For anyone building a family of products of their own, what transfers from here is not our code. It is the habit: decide before the first product which layer is allowed to have opinions, put the shared base behind a version, and keep the ledger honest enough to be unpleasant to look at. A ledger nobody winces at is a ledger nobody updates.

What this looks like from the customer's side rather than the builder's is worked through in what to automate first.

Frequently Asked Questions
  • 01What exactly is shared, and what gets written again every time?+

    Shared is whatever works the same way in any system with staff and customers: who signed in under their own account, what role they hold, what the role permits and forbids, who gets notifications, who gets invoiced, where the correspondence lives and who changed what. Encryption of personal data and translations belong here too. None of it depends on whether you rent out excavators or sell apartments, so it is written once. Written again is the subject matter: the objects of the industry and the rules for moving between stages. A rental business has a unit of equipment, a booking and a dispatch. A property agency has a property, a listing and a deal. The words look alike, the rules inside do not, and it is the rules that cost time.

  • 02How large is the share that has to be written from scratch?+

    Larger than almost anyone expects, ourselves included at the start. Two figures, both measured. First: in the rental CRM we moved onto the shared base, 1650 of 1872 schema lines turned out to be industry-specific, that is 88%, and only 220 lines were the scaffolding the base provides. The second is harsher. When we built a second product in an adjacent industry, 7 of the 113 business concepts across the two products were shared. About 6%. Which gives a simple consequence for anyone choosing a vendor: the phrase we already have this, we just need to configure it describes the scaffolding, not your business. We wrote that second case up separately, because the number is inconvenient and deserves the detail.

  • 03Why build a shared base at all if so little transfers?+

    Because the saving does not come from where people look for it. Before a new product can deal with its own industry, it needs sign-ins, companies, roles and permissions, invoices wired to a real payment provider, incoming messages from customers, notifications, translations, a change log and encryption of personal data. The first time, that list takes months; it is identical for any industry; and any quiet mistake in it surfaces not in a demo but in a security audit. Built once, it lets the next product start where the business actually begins. The industry rules would have differed anyway, and the winnings were never there.

  • 04Why publish a ledger of statuses instead of a product count?+

    Because a product count is a marketing number and a ledger of statuses is an engineering one, and only the first can be wrong in a way nobody notices. The sentence eighteen products on a shared base will outlive any amount of drift underneath it: it stays true as long as anything at all is running. The line one in production, two in pilot, none in full conformance creates work, because every status is something somebody has to move. The ledger is kept by hand and updated on every release of the specification precisely so it does not quietly slide back into the first phrasing. The same reasoning keeps the specification repository free of executable code: a specification that ships a runtime stops being checkable against anything.

Keep reading