Single source of truth, applied to product data

Everyone agrees on single source of truth in the abstract and nobody agrees on it per field. The phrase only becomes useful when it is written down as a list…

One authoritative record card at the centre with five teal threads to partial views around it, one of them an amber full copy with a cut thread

Every architecture document contains the phrase. Every architecture built from those documents contains the same product title in four places, three of which are editable.

The phrase is not wrong. It is just not a design until it names fields.

Short answer: single source of truth means, for each field, exactly one system where it can be edited. Everything else holds a reference, or a clearly labelled read-only cache with a defined refresh. Written that way it is enforceable. Written as a principle it is a sentence everyone agrees with while building the opposite.

Write it as a table of fields, not as a principle

The artefact you need is unglamorous: a list of every field that appears in more than one system, with the system that owns it, and the systems that consume it. Fifty to two hundred rows for most catalogues.

Producing it takes about two days and it is the highest-value two days in any integration project, because it converts an architectural opinion into a set of decisions people can disagree with specifically. Vague disagreement recurs forever. Specific disagreement gets resolved once.

The rules that make the list decidable are in DAM vs PIM for two systems and the four-system boundary map when the CMS and ERP are involved. Single source of truth as a concept is old and stable; the work is entirely in the application.

What a legitimate copy looks like

Absolutism here is unhelpful, because some copying is necessary. A storefront that resolves every field from an upstream API on every page load is slow and fragile. The distinction is not copy versus no copy. It is governed copy versus ungoverned copy.

A legitimate copy has four properties:

It is read-only in the consuming system. Not by convention. Enforced, with the edit control absent from the interface. If a person can edit it, someone eventually will, and their edit will be silently overwritten or silently authoritative, and you will not know which.

It has a defined refresh path. Either an event that invalidates it or an interval that bounds its staleness. “It gets updated when we run the job” is a schedule; “it is refreshed within a minute of a change event” is a contract.

It is labelled as derived. In the schema, in the interface, and in the documentation. The next person to look at it should not have to work out whether it is authoritative.

It exists because a specific query needs it. Not because it was convenient to have. The discipline of naming the query is what stops a read model growing into a full duplicate over a year.

Anything with all four is a cache. Anything missing one is a second source of truth wearing a disguise.

One pedestal holding a teal-edged plate with five dishes of translucent replicas around it, two of them solid amber and mismatched

The three fields that always cause trouble

Product title. Owned by the product record, and immediately wanted by the CMS for page titles, by the DAM for asset naming, and by search indexes. The trap is the CMS letting an editor “adjust it for this page”, which produces a per-page override that is invisible from the product side. If overrides are legitimate, model them as an override field with the original still visible. If they are not, remove the edit control.

Price. Usually originates in the ERP or a pricing engine, is consumed everywhere, and is the field where staleness is most expensive. It should never be copied without a short and enforced refresh, and it is the strongest case in the catalogue for pushing changes rather than polling for them.

Image association. Which images represent this product. Owned by the product record. Copied into the CMS as a page-level selection, which is legitimate if the CMS choice is understood as “which of the product’s images to place here” rather than as an independent list. When it becomes an independent list, images that were withdrawn upstream keep appearing on pages, which is the failure that reaches customers.

Reference resolution beats field replication

The pattern that keeps the list short is to store an identifier and resolve it, rather than storing the values.

A product record holding an asset identifier is one field. The same product record holding the asset’s URL, dimensions, alt text, rights status and expiry date is five fields, all of which can go stale independently, and each of which is a row on your ownership list.

The same applies in the other direction. A CMS page that stores a product identifier and resolves the title, price and images at render time has one field to govern. A page that stores copies of all three has three.

The reason this is not obvious is that resolution has a cost, and the cost is paid at request time in a system somebody is measuring. It is worth paying, and where it is not, the answer is the governed cache above rather than an ungoverned copy. The mechanics are in wiring a DAM to a PIM, which works through the same decision for the asset side specifically.

A schematic of one source feeding three caches with different refresh intervals, teal one-way arrows, and a struck-through amber reverse line

How the list decays, and what to do about it

The ownership list is accurate on the day it is signed and drifts from then on. Three things cause the drift.

A new system arrives and nobody adds its fields. Usually a marketing tool, a review platform or an analytics product that turns out to be writing back.

A migration inverts an ownership. A replatform moves a field’s home and the list still describes the old arrangement. This is the most dangerous kind, because integrations built after the migration will follow the code rather than the document.

A shortcut becomes permanent. Someone enables editing in a consuming system to unblock a launch, and it is still enabled two years later.

The countermeasure is small and boring. Review the list when any system in it is replaced, and once a year otherwise. Put the review on the same calendar as something that already happens. A list nobody reviews is a historical document, and the first time it misleads someone it will cost more than the review would have.

What is the smallest useful version of this?

Ten rows, on one page, covering the fields that appear in more than two systems. Title, price, description, images, category, stock, identifier, rights, approval state, and whichever tenth field your team already argues about.

Write the owner. Write the consumers. Write, for each consumer, whether it references or caches, and if it caches, what invalidates it. Get the owner of each system to sign the page.

That page is worth more than the diagram it will eventually be drawn as, and it is the input to what to demand from a PIM API before you buy, because an API that cannot resolve references cheaply will force you into caching decisions you did not want to make. The modelling groundwork underneath it is in the product data model that survives growth.