The hard part isn’t building the first version.It’s the moment customer two signs.

Right now you have one customer, and every assumption in the system is free. Your terminology. Your hierarchy. Your scoring rules. Your exceptions. Your permission model. The day a second business signs, every one of those becomes a product question.

For operators whose internal software already works, and who have been asked for it by someone else.

What changes on day one of customer two

Four questions, asked of every assumption you made.

Not once, in a planning session. Every field, every rule, every screen — and the answers are not obvious from inside the business that wrote them.

What is universal?

True for every business in this vertical, so it belongs in the core and gets fixed once.

What becomes configuration?

Differs per customer but along a dimension you can predict. A setting, not a branch.

What stays customer-only?

Genuinely theirs. It has to live somewhere that never touches another install.

What do you refuse?

The one nobody writes down, and the one that decides whether you have a product or twenty projects.

The transition

Custom to vertical platform, in six rungs.

Most internal software stops at rung three and gets sold as if it were at rung six. The Readiness Review exists to tell you which rung you are actually on.

Custom — built for us Working internal tool Production system, operated daily Repeated deployments Shared core + config Vertical platform
Rungs 1–3Bespoke, then useful, then load-bearing. The business runs on it. Every assumption still free.Where most are
Rung 4Similar needs, different details. The first fork happens here, usually by copying the repository.The trap
Rung 5One core, one config layer. A fix written once applies everywhere. This is the expensive rung.The work
Rung 6Many businesses, one system they can rely on, and onboarding that does not need you in the room.The goal

Rung three, in detail

What a system carrying real work is actually made of.

97 numbered migrations, 86 row-level security policies, 136 API routes and 157 components across 87,138 lines. One operating system built for a property agency, running that company’s entire client-facing operation. Read off the repository, not estimated.

97 migrationsNumbered 001 to 099. Every schema change is a migration and a commit — never a snapshot, never a hand edit against production.versioned
86 RLS policiesRow-level security across 30 migrations. Tenant isolation lives in the database, not in a where-clause somebody can forget.isolation
136 API routesWebhooks in, third-party calls out, scheduled jobs. This is where most of the integration cost actually sits.integration
157 components87,138 lines across app, components and lib. TypeScript strict, no exemptions.surface

4,700 listings, every enquiry from three channels landing in one inbox, in two languages.

DWOSOPERATOR
  • Overview
  • Installs
  • Blueprints
  • Runs
  • Approvals
  • Economics
  • Activity
CORE2.4.1current

Installs

One core, pinned per business. A fix written once reaches every install on that version.

BusinessVerticalCorePinned blueprintsHealth30d
Northgate Dental GroupDental 2.4.1 intake@1.8.2recall@2.0.1 healthy$84
Halstead Plumbing Co.Plumbing 2.4.1 intake@1.8.2dispatch@1.4.0 healthy$126
Meridian PropertyLettings 2.4.1 intake@1.8.2viewing@3.2.0 waiting$203
Brightline HVACHVAC 2.3.0 intake@1.7.4 degraded$61
Ashcroft VeterinaryVeterinary 2.4.1 intake@1.8.2 never reported

intake@1.8.2 runs on four installs in four different trades. That is the shared core doing its job — and Brightline, two versions behind, is the reason absence is an alarm.

The operator view: one versioned core, pinned per install, across verticals. Example fleet.

Four months of production data

Things you only learn by operating it.

Activity across the first four months: 828 actions, then 1,462, then 5,182, then 9,689. Users went from 5 to 20. Actions per person stayed flat.

36% of activity was lookups

Over a third of everything people did was finding something out. Search that answers a simple question is not a nice-to-have — it replaces an interruption to somebody else.

62% came from one person

Adoption is never even. Design for the real distribution, not the average, or you build for a user who does not exist.

Money changed the rules

The moment commission was involved, that path had to become deterministic. The AI explains and flags. It does not decide.

BLUEPRINT intake@1.8.2 pinned on 4 installs

SHARED CORE

  • Channel intake and de-duplication
  • Contact resolution
  • Consent and retention rules
  • Audit ledger write

Written once. Fixed once.

CONFIGURED PER INSTALL

  • Qualifying questions
  • Service area and hours
  • Escalation thresholds
  • Price bands

A setting, not a branch.

CUSTOMER-ONLY

Their records, prices, customers and voice. Never leaves the install, never reaches the core, exportable at any time.

View diff Roll forward to 1.9.0 verified on 4 installs
The same boundary, enforced: what is shared, what is a setting, and what never leaves the customer.

Twelve times the activity, at the same effort per person. That is the whole argument for building it properly.

Rung four, measured

The lazy answer is to fork it.

You built it for one business. The next one needs it slightly different, so you copy the repository. It works, it ships, and nobody argues with it. Do that a few times and here is what you are holding: 60 shared migration numbers, 29 of them carrying the same number and different content, and 11 tables out of 103 still identical. Ours, read live from all three databases a few months later.

Migrations60 numbers shared across the three. 31 byte-identical. 29 carrying the same number and different content — so a fix written once cannot be applied to the others.29 diverged
Schema103 tables across the three. 24 present in all three. Only 11 identical column for column.11 of 103
Silent drift13 tables that started identical changed shape separately after the copy, without anyone deciding to.13 drifted
Central objectThe main business object differs by 41 columns between two of them. That part is correct — the object is supposed to differ per vertical.by design
Shared corePlanned at roughly 80% shared. Measured on the ground after three installs.~25%

The business object should differ between customers. The plumbing underneath it should not. Ours did both.

The uncomfortable half: you cannot merge the past. Once installs have drifted this far they stay the first of their own line, and compounding starts at the next one. Worth knowing before you promise a customer a date.

Why this is hard to hire for

Packaging is harder than the original build.

It needs somebody who will sit on the floor and watch how the work actually happens, and who can then turn what they saw into something a hundred other businesses can run. Most engineers are good at one half or the other.

A fractional CTO decides

Judgement, architecture review, a hiring plan. Genuinely useful, and it stops before anything is built.

A development shop builds

To your specification — which assumes you already know where the boundary goes. That is the thing you needed help finding.

One senior hire does both

After two to three months of recruiting, at a permanent salary line, as a single point of failure who can resign.

The fourth option

Decide and build, with the boundary drawn from evidence rather than a diagram — and a team behind it, so it never lives in one person's head.

How the work runs

Sit with the owner. Sit on the floor. Then build it.

Four steps, and the first two happen before any code is written. Discovery is not a meeting — it is time at the desk where the work actually happens, at the speed it really runs.

01

Sit with the owner

Understand what the business actually sells, and what it is afraid of. Those are different questions and both matter.

02

Sit on the floor

Watch how the work actually happens — at the real desk, at the speed it really runs.

03

Build it and ship it

Architecture, integrations, migrations, rollout. In your repository and your cloud from the first commit.

04

Operate it

Owning it in production is where the learning starts. It is also where you find out which clever ideas were actually clever.

Half of what people tell you about their own process is the version they wish were true. You only get the real one by watching.

Before you get in touch

Questions operators ask

How do I know which rung we are actually on?

The test is whether a fix written once reaches every install. If you have one customer, you are at rung three at best. If you have two and a change has to be made twice, you are at rung four — which feels like a platform and is not one yet.

Should we be single-tenant or multi-tenant?

It depends on how many customers you expect and how different they are. Single-tenant gives each customer their own database and physical isolation, with one deploy per customer. Multi-tenant puts everyone in one database separated by row-level security, so one deploy reaches everyone — cheaper per customer, and a policy mistake exposes all of them. Few high-value customers with divergent needs favour single-tenant; many similar price-sensitive ones favour multi-tenant.

What is the most expensive thing to retrofit?

The tenant key. Adding an organisation column to every table and rewriting every access policy after you already have a live customer is the single most costly change on this road. Systems that carried a tenant key from early on can move between deployment models without touching the schema.

Can you fix the forks we already have?

Usually not economically, and we will tell you that plainly. Once installs have drifted — same migration numbers with different contents, tables that changed shape separately — merging them costs more than leaving them. The realistic plan is that existing installs stay as they are and compounding starts with the next one.

Do you keep the core and license it back to us?

Not on this engagement. When an operator platformizes their own software, the platform is theirs. We run a shared-core model with partners, where the client relationship is protected by deal registration in the agreement, but that is a different arrangement.

Which rung are you actually on?

Seven days, $2,500. A map of what you have built, where the core and configuration boundary really falls, the assumptions that break when a second business signs, and a 90-day plan including what to deliberately postpone. If it is not ready to be productized, we say so and you keep the map.

Chat with founder Imtiaz Hasan