One price list, and no page carries a price
One product was advertised at three different prices depending on which Rutba site you opened, and nothing could tell. Every figure now comes from one record as the page renders — and a test fails the build if anybody types a price into the site.
· 3 min read

Here is a failure that never announces itself. A price changes. Somebody updates the pricing page. The same figure is also on a product page, in a comparison table, in three blog posts, in the checkout on a console and in a partner’s deck — and each of those was correct on the day it was written.
We had exactly that: each site carried its own compiled-in copy of the price list, so one product could be advertised at three different prices depending on which Rutba site you opened, and nothing in the system could detect the disagreement.
Prices are records now
The price list lives in one place: records in our own backend, with the allowances that go with each tier. Every site — rutba.io, Sign, the Relay, Office, the partner pages — and every console reads that when a page renders. There is one authored list behind it, one file that a person edits and reviews, and an importer that only ever creates what is missing: moving a live price takes a deliberate flag, prints every change, and writes an audit row.
Changing what a tier includes is the same kind of edit — a change to the plan’s allowances, made in the console or the importer. Not a code change, not a deploy, and not a sentence on a marketing page that drifts from what the licence actually grants.
Two different sentences that used to be one
A page that asks for prices has to cope with not getting them, and the wrong way is a dash or a blank where a number should be. So there are two answers, and they are deliberately not the same:
- “Custom.” A tier we quote individually, because what it costs depends on what you need. That is an answer.
- “We cannot tell you right now.” The price list could not be read. The page says so and points you at a person, and the checkout refuses to ask anybody to confirm a price it cannot read.
Treating the second as the first would be a lie by omission at the exact moment somebody is deciding to buy.
A test that fails on a typed price
None of this survives good intentions. The discipline is a test: a currency amount typed anywhere into the site’s content fails the build. When we moved to one list, twenty-two blog posts were carrying price tables somebody had typed; each now names the listing it is about and the table is drawn from the same record the pricing page reads.
There are exactly three exceptions, and they are the kind that prove the rule. The dated changelog, because that is history — “was this, now that” is a record of a day, and correcting it later would be rewriting the record. And two posts whose subject is the arithmetic itself, where replacing the worked example with a live price would make the sums stop adding up. Those are worth reading for their own sake: every rounding goes to the customer and ask for your money back.
Why a customer should care
- The price you were shown is the price that is charged. One record answers the marketing page, the quote and the invoice.
- A price change is visible. It is an edit with an audit row behind it, not a thousand pages quietly disagreeing.
- Allowances are numbers, not adjectives. What a tier includes is a figure a licence carries, which is what makes it checkable.
The prices themselves were reviewed and cut at the same time, and the shop stopped paying per person — that is the previous post in this series.
Every price, in one place
The pricing page reads the same record every other page does.
See the prices

