Inkress ADRsarchitecture decisions
Overview / Catalog
ADR 0038

Inventory is an advisory checkout-time gate, never reserved or decremented

AcceptedCatalog

Context

Products can carry a stock count. The platform has to decide how much inventory discipline to enforce at checkout. Full inventory management — reserve on add-to-cart, decrement on sale, restock on refund/cancel — is a real subsystem with concurrency and lifecycle complexity that most of the current merchant base does not need.

Decision

Treat stock as an advisory gate checked only at order time, and never mutate it from the order flow.

  • Validated, not reserved. At order creation the path checks the requested quantity against the product/variant's remaining units and rejects an obviously out-of-stock or over-quantity line; a per-product/variant unlimited flag opts out of the check entirely.
  • No write-back. The order path performs no decrement, no reservation, and no restock — nothing in checkout, payment, refund or cancellation adjusts the counter. Merchants set and adjust stock out of band.

Consequences

  • Positive: simple and fast — no reservation lifecycle, no restock-on-refund logic, no distributed inventory locking on the hot checkout path.
  • Neutral / to revisit: because the check is read-only and nothing decrements, concurrent orders can oversell a limited product, and counters drift from reality unless a merchant maintains them. This is a deliberate simplicity/throughput trade; unlimited is the common escape. True stock accuracy would require a real inventory subsystem (reserve + decrement + restock) and is out of scope until a merchant needs it.

Alternatives considered

  • Reserve-on-checkout + decrement-on-sale + restock-on-refund (real inventory management): not adopted — heavy and concurrency-sensitive for little current benefit; the advisory gate is deliberately minimal and can be upgraded later.
  • No stock check at all: rejected — the advisory gate still blocks clearly out-of-stock purchases at order time, which is most of the value for the least cost.
← 0037 commerce-api keeps a general, app-written audit trail (append-only by convention) 0039 Product options and custom data are schemaless JSON frozen onto order lines →