Problem
unitsFromCosts resolves a per-feature multiplier with a direct key lookup and falls back to a hardcoded 1:
// modules/billing/services/billing.meter.service.js:80
const ratio = typeof ratios[key] === 'number' && ratios[key] >= 0 ? ratios[key] : 1;
The default key is never consulted, even though the config schema documents it as part of the contract:
// modules/billing/config/billing.config.zod.js:12
* ratios — feature multiplier map (e.g. { default: 1, autofix: 2 })
Impact
A consumer configuring ratios: { default: 2, autofix: 3 } gets 2 applied to nothing: every cost key that is not literally autofix bills at 1, not at the configured default. The result is silent under-billing with no warning and no error.
This is invisible in practice today because the shipped example value is default: 1, which happens to equal the hardcoded fallback. Any consumer setting a default other than 1 is silently ignored.
Reproduction
- Configure a plan with
ratios: { default: 2 }.
- Call
BillingMeterService.attribute() with a cost map whose keys are not present in ratios (e.g. { someFeature: 1.0 }).
- Observed: units computed with
ratio = 1. Expected: ratio = 2.
Options
- (a) Honour the documented key — consult
ratios.default before the hardcoded 1. Smallest change, matches the documented contract.
- (b) Drop
default from the schema docs — keep the hardcoded fallback and stop advertising a key the code ignores.
- (c) Refuse unknown keys — when a plan snapshot resolved with a non-empty ratio map, a cost key absent from it is not a billable feature of that plan; throw instead of billing it at an implicit
1.
(c) is the strongest: besides fixing the default contract, it stops the meter from billing an arbitrary object of positive numbers whose keys have no relationship to the plan's feature taxonomy. Today any such object is accepted and charged at flat rate. It is also a behaviour change for consumers that rely on the implicit 1, so it needs a MIGRATIONS entry.
Acceptance
- The documented contract and the implemented behaviour agree.
- A cost key that is not a feature of the resolved plan cannot be silently billed at an unintended rate.
- Unit test covering a plan whose
default differs from 1.
Problem
unitsFromCostsresolves a per-feature multiplier with a direct key lookup and falls back to a hardcoded1:The
defaultkey is never consulted, even though the config schema documents it as part of the contract:Impact
A consumer configuring
ratios: { default: 2, autofix: 3 }gets2applied to nothing: every cost key that is not literallyautofixbills at1, not at the configured default. The result is silent under-billing with no warning and no error.This is invisible in practice today because the shipped example value is
default: 1, which happens to equal the hardcoded fallback. Any consumer setting a default other than1is silently ignored.Reproduction
ratios: { default: 2 }.BillingMeterService.attribute()with a cost map whose keys are not present inratios(e.g.{ someFeature: 1.0 }).ratio = 1. Expected:ratio = 2.Options
ratios.defaultbefore the hardcoded1. Smallest change, matches the documented contract.defaultfrom the schema docs — keep the hardcoded fallback and stop advertising a key the code ignores.1.(c) is the strongest: besides fixing the
defaultcontract, it stops the meter from billing an arbitrary object of positive numbers whose keys have no relationship to the plan's feature taxonomy. Today any such object is accepted and charged at flat rate. It is also a behaviour change for consumers that rely on the implicit1, so it needs a MIGRATIONS entry.Acceptance
defaultdiffers from1.