commerce: promo rules (percent/fixed/bundle/member) as relations (17 tests)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 57s

promo.sx — four promo types as tagged tuples; per-promo discount is pure
integer arithmetic, but enumeration is relational: promo-discounto and
promo-applieso run forward ("which codes apply, for how much?") and backward
("which code yields this discount?"). project grounds the membero-bound promo.
applicable-promos / promo-amount-for deterministic helpers. Total 83/83.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 00:17:26 +00:00
parent a0f3a1177e
commit 79fa28e55d
6 changed files with 313 additions and 7 deletions

View File

@@ -21,7 +21,7 @@ reconciliation — all auditable via the event log.
## Status (rolling)
`bash lib/commerce/conformance.sh`**66/66** (4 suites: catalog, cart, price, api) — Phase 1 done
`bash lib/commerce/conformance.sh`**83/83** (5 suites: catalog, cart, price, api, promo) — Phase 1 done, Phase 2 in progress
## Ground rules
@@ -61,7 +61,7 @@ lib/commerce/api.sx ── (commerce/add) (commerce/total) (commerce/checkout)
- [x] `api.sx` + tests + scoreboard + conformance.sh
## Phase 2 — Promotions (relational)
- [ ] promo rules: percentage, fixed, bundle, member rate
- [x] promo rules: percentage, fixed, bundle, member rate
- [ ] explicit stacking precedence; "best price" backward query
- [ ] tests: stacking order, mutually-exclusive promos, member vs guest
@@ -76,6 +76,14 @@ lib/commerce/api.sx ── (commerce/add) (commerce/total) (commerce/checkout)
- [ ] tests: webhook replay, partial refund, double-charge guard
## Progress log
- 2026-06-07 — `promo.sx` (Phase 2 piece 1): four promo types as tagged tuples
`(:percent code class bps)`/`(:fixed code threshold amount)`/`(:bundle code sku
n)`/`(:member code class bps)`. Per-promo discount is pure integer arithmetic;
`promo-discounto`/`promo-applieso` enumerate (code, amount) relationally —
forward ("which apply?") and backward ("which code yields 2000?" → run* over
applieso). `applicable-promos`/`promo-amount-for` deterministic helpers. promo
amounts via `project` to ground the membero-bound promo. promo suite 17/17;
total 83/83. Next: stacking precedence + best-price (stack.sx).
- 2026-06-06 — `api.sx` (**Phase 1 complete**): session facade
`{:ctx :cart}` with `commerce-add`/`-remove`/`-set-qty`/`-total`/`-count`/
`-lines`, `commerce-can-add?` catalog validation, `commerce-explain` per-line