Let's talk
engineering

Price the feature, not the product, or your catalogue grows faster than you can maintain it

The most complicated item in the catalogue of a made-to-order fabrication business carried 24 features, 62 sub-feature variants, 20 dimension variables and 85 material slots. It resolved to 140 separate pricing mappings.

There is no price list for that item. There is no table you can build, because the number of distinct configurations a customer can order is the product of every optional feature and every variant of each. The first design question on a quoting system for bespoke manufacturing is not what the screens look like. It is what unit you attach a price rule to.

Attach it to the product and you lose immediately. Attach it to the feature and the whole thing becomes tractable, for a reason that is not obvious until you look at the arithmetic.

The arithmetic

Across the whole catalogue there were 57 product types, 86 features, 175 sub-features and 613 assignments of a feature to a product type. The pricing rules themselves numbered 362.

Note the shape of those numbers. There are more feature-to-product assignments than there are formulas, and there are far more mappings than formulas — 1,400 mappings pointing at 362 rules. That ratio is the entire argument. A pricing rule is reused across many product-and-feature contexts, so the number of rules grows with the number of distinct calculations, not with the number of things you sell.

A splashback is a splashback. It is priced from its length, its height and the sheet it is made from, and that calculation does not change because it is bolted to a work table this week and a service counter next week. Once the rule exists, adding a new product that has a splashback costs you one mapping row, not one formula.

Price at product level and the opposite happens. Every new product type needs its own rule, and every rule has to re-derive the splashback arithmetic inside itself. The catalogue and the rule count grow together, and the rules drift apart, because nobody updates 40 copies of the same calculation consistently.

What a feature-level rule actually needs

The useful consequence is that each rule only has to answer a very narrow question, and therefore only needs a very small number of inputs.

Legs need a height and a count. A cross support needs a length and a breadth. A splashback needs length, breadth and its own height. A sink bowl needs its own three dimensions, which are not the item’s outer dimensions. A covering needs the item’s height, breadth and length plus a covering height.

Each of those is three or four variables. None of them requires knowing anything about the other features. A product’s full dimension requirement is then just the union of its features’ needs, computed rather than authored — which matters, because nobody has to maintain a per-product list of “these are the fields to show”.

That union is also what the quoting interface renders. The user picks a product, the system walks the features that product offers, unions their input requirements, and shows exactly those fields. Add a feature to a product and its dimension fields appear without anyone editing a form.

Where I got this wrong

I assumed the client’s fabrication drawings would give me the dimension list for each product. They are engineering drawings of the actual items; the dimensions are annotated on them; it seemed obvious.

It was wrong, and the way it was wrong is instructive. For one work table with a sink, the model wanted 11 dimension variables. The drawing annotated 5. The drawing was not incomplete — it was a drawing of one specific instance that had been ordered, and it did not separately dimension the sink bowl because the bowl was a standard size on that job.

The model, by contrast, parameterises every optional feature, because the model has to price the instance that has not been ordered yet. A drawing of a built item and a parametric model of a sellable item are different artefacts with different completeness requirements. Drawings cannot be the sole dimension source for pricing, and some inputs will always have to come from the estimator.

The mapping layer is where the product knowledge lives

Separating the rule from the product creates a third thing that has to exist: something that says which rule applies to which feature of which product.

That layer carried more than the obvious. A mapping is keyed on the product type and the feature, and optionally on the specific variant of that feature, and optionally on the material grade. Any of those can be left open, which makes the mapping a wildcard across all variants or all grades.

That optionality is what keeps the mapping count sane. Most features price the same regardless of which variant the customer chose, so one wildcard mapping covers them all. Only the features where the variant genuinely changes the arithmetic need a mapping per variant. The 1,400 mappings would have been several times that if every combination had to be enumerated.

It also means the catalogue can be audited. Because the mappings are rows rather than code, you can ask a direct question — which product-and-feature combinations have no pricing rule attached — and get a list. That question is how you know whether a catalogue is actually ready to quote from, and it is unanswerable in a design where the rules are conditionals in a service class.

The cost of the split

Two things get harder, and it is dishonest to pretend otherwise.

Debugging becomes indirect. When a price is wrong you now have to establish which rule fired before you can look at the rule, and the mapping that fired is invisible in the output unless you deliberately expose it. That has to be built, not assumed.

And a rule shared across many products is a rule you cannot casually change. A tweak that suits one product silently repriced everything else pointing at the same rule. Reuse is the benefit and the hazard in the same mechanism, so the interface has to tell an editor how many features are using the rule they are about to edit. Showing that count is cheap and it stops a whole category of accident.

The rule

Find the smallest thing that has a stable calculation — for physical made-to-order goods it is almost always the feature, not the finished item — and attach the pricing rule to that. Then make the product a list of features and let everything else be computed: the input fields, the price, the readiness check.

If your rule count is growing in step with your product count, you have attached it to the wrong unit, and the drift between near-identical copies has already started whether or not you have noticed it.

Working on something like this?

We build this kind of software, and we staff the teams that do.

Get in touch