The problem, concretely
The CPIM body of knowledge has around 96 formulas spread across seven modules — inventory, forecasting, capacity, master planning, detailed scheduling, execution, and strategy. On their own, none of them is hard. The friction is everywhere else:
- notation drifts between sources — is it
H, oriC, or “annual carrying cost per unit”? - the ones you need mid-problem are never on the page you’re looking at
- there’s no fast way to sanity-check an answer, especially away from a desk
I wanted a single place where every formula is stated once, consistently, with inputs you can actually type numbers into.
Approach
The core decision was to treat the formulas as data, not code paths. Each formula is a
self-describing object: its inputs (with units and validation bounds), a pure compute
function, a human-readable expression, and an optional plain-English interpretation of the
result.
That structure pays off three times over:
- One engine, many surfaces. The web app, the mobile app, and this website’s demo all import the same package. There is no re-implementation to keep in sync.
- It’s testable. Every formula has unit tests — does EOQ actually return
√(2DS/H)? Do ordering and carrying cost balance at the optimum? The suite also asserts registry-wide invariants: unique IDs, every default inside its own bounds, a finite result for every formula from its own defaults. - The UI is generated. Add a formula object and it shows up in the picker, with the right fields, automatically.
The maths, worked live
Take the flagship example — Economic Order Quantity. The textbook statement is a square root, but the why is a cost trade-off: order in big batches and you hold expensive inventory; order in small batches and you pay the ordering cost over and over. EOQ is the quantity where those two costs are equal.
That’s much clearer as a picture than a paragraph, so the case study embeds the actual chart — move the sliders and watch the optimum move:
The dot tracks the minimum of the total-cost curve. Push holding cost H up and the EOQ
shrinks (inventory got expensive, so order less, more often). Push ordering cost S up and
it grows. The calculator returns the same number, plus orders-per-year and total annual
cost.
Tech notes
- TypeScript throughout,
strictmode. The formula registry fails at import time on a duplicate ID or an unknown module, and the test suite asserts every formula stays finite from its own defaults. - Vitest for the engine; it runs in CI on every push.
- Expo for the mobile build — one React Native codebase to both stores. The shared engine is plain ES modules with no DOM or Node dependencies, so it drops straight in.
- Statistical helpers (normal CDF / inverse-CDF) are hand-implemented from standard rational approximations rather than pulling in a stats library — keeps the browser bundle small and the mobile app dependency-light.
What I’d do next
Add per-formula worked examples pulled from the study guide, and a “given these three values, which formula do I want?” search. The data-first structure means both are additive, not rewrites.