# commerce-on-sx: Catalog, cart, pricing & orders on miniKanren > **DRAFT outline.** The revenue vertical. Depends on `persist-on-sx` (durable > orders) and `flow-on-sx` (checkout as a durable flow). Don't start before > persist-on-sx Phase 1 is green. rose-ash's revenue engine — market (catalog), cart (checkout), orders (SumUp payment, reconciliation) — has no SX subsystem. The hard part of commerce isn't CRUD; it's **pricing**: discounts, bundles, tax, membership rates, promotions that stack (or don't). These are relations, and a relational engine can run them in multiple directions — forward ("what's the total?") and backward ("what promo code yields this total?", "which line item triggered the discount?"). That's a miniKanren fit. Pricing/promotion rules are relational; cart and order *lifecycle* (reserve → pay → fulfil → reconcile) is a durable `flow`; the order ledger is a `persist` stream. Commerce is the first real **composition** subsystem. End-state: a catalog model, a relational pricing/promotion engine, a cart with deterministic totals, and an order lifecycle flow with payment-webhook reconciliation — all auditable via the event log. ## Status (rolling) `bash lib/commerce/conformance.sh` → **0/0** (not yet started) ## Ground rules - **Scope:** only `lib/commerce/**` and `plans/commerce-on-sx.md`. May **import** from `lib/minikanren/`, and (once they exist) `lib/persist/` + `lib/flow/`. Do not edit substrates. - **Architecture:** prices/promotions are miniKanren relations over catalog facts; a cart total is a *deterministic* query result (first solution under a fixed rule order). Order lifecycle is a `flow` that suspends at the payment IO boundary. Money is integer minor units — never floats. - **Determinism:** promotion stacking must have explicit, tested precedence; totals must be reproducible from the cart + catalog snapshot. - **Commits:** one feature per commit. Progress log + tick boxes. ## Architecture sketch ``` Catalog + cart Total / order product(id,price,tags) {:subtotal :discounts :tax :total} │ ▲ ▼ │ lib/commerce/catalog.sx lib/commerce/price.sx — product / variant / stock facts — miniKanren pricing relations │ — promo stacking, membership rates ▼ ▲ lib/commerce/cart.sx lib/commerce/order.sx (flow + store) — line items, quantities — reserve→pay→fulfil→reconcile │ — SumUp webhook = flow resume ▼ │ lib/commerce/api.sx ── (commerce/add) (commerce/total) (commerce/checkout) ──┘ ``` ## Phase 1 — Catalog + cart + deterministic totals - [ ] `catalog.sx` — product/variant/stock as facts - [ ] `cart.sx` — line items, add/remove/qty - [ ] `price.sx` — base pricing relation, subtotal; tax - [ ] `api.sx` + tests + scoreboard + conformance.sh ## Phase 2 — Promotions (relational) - [ ] promo rules: percentage, fixed, bundle, member rate - [ ] explicit stacking precedence; "best price" backward query - [ ] tests: stacking order, mutually-exclusive promos, member vs guest ## Phase 3 — Order lifecycle (flow + store) - [ ] order flow: reserve stock → await payment → fulfil - [ ] payment webhook resumes the suspended flow - [ ] order ledger as a `persist` stream; idempotent reconciliation ## Phase 4 — Reconciliation + federation - [ ] mismatch detection (paid≠ordered) as queries over the ledger - [ ] cross-instance catalog (federated marketplace) — out-of-scope stub - [ ] tests: webhook replay, partial refund, double-charge guard ## Progress log (loop fills this in) ## Blockers (loop fills this in)