Skip to content

feat: Workbench Phase 1 — gate admin page, order lifecycle buttons, currency, theme-safe pills, honest errors - #1

Merged
DanMat merged 1 commit into
mainfrom
feat/workbench-phase1
Aug 30, 2026
Merged

DanMat merged 1 commit into
mainfrom
feat/workbench-phase1

Conversation

@DanMat

@DanMat DanMat commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Part of the Inventory/Commerce Phase 1 "Workbench" slice (Fable's Stocked & Shipped). Depends on core ADR 0020 (NimbusCMS/nimbus#195, merged) and pairs with NimbusCMS/plugin-inventory#1.

What

  • Authorization parity. The Commerce page + all actions require nimbuscms.commerce:write — the wildcard-immune cap the MCP tools already gate on. A content-only editor can no longer place or advance orders from the UI. (Closes the High from the pre-build security review.)
  • Order lifecycle buttons. Per-row Pay / Fulfil / Cancel (CSRF-protected POSTs), shown by status — the admin could place an order but not advance it. The UI catching up to the MCP tools.
  • Theme-safe status pills. var(--nb-*-bg/-text) semantic tokens instead of hard-coded hex + color:#fff — legible in dark and every selectable theme. (bug fix)
  • Currency-aware totals. A small symbol map from commerce_order.currency (now selected) instead of a literal $. (bug fix)
  • SKU datalist on the place form, from this plugin's own commerce_order_line — never inventory_* (the plugin boundary).
  • Allow-listed ?status= filter (bound; junk ignored, never reflected).
  • Honest errors via typed exceptions: OrderNotFound → notfound, IllegalTransition → badstate, NoInventory → noinventory, bad qty/price → badqty (validated at the boundary so a DECIMAL DB error can't masquerade as "install Inventory"), InsufficientStock → short.

OrderBook now throws the typed exceptions (all extend \RuntimeException, so existing catchers — incl. ChoreographyTest — keep working).

Tests

  • CommerceAdminTest — rendering: theme-token pills (no hex), currency ($ / / code fallback), lifecycle buttons by status, allow-listed filter (junk → no filter, escaped), datalist.
  • CommerceAdminActionsTest — the H3 actions through the real loader with Inventory loaded alongside (Commerce resolves Inventory's port as the kernel wires it): full place→pay→fulfil / cancel lifecycle + every honest-error path (short, badqty, notfound, badstate). Also proves the page gates on the plugin capability (registration throws on a pre-0020 core).

22 tests green; PHPStan + php-cs-fixer clean. Reviewed pre-build by nimbus-review-loop and nimbus-security-review.

🤖 Generated with Claude Code

…s, currency, theme-safe pills, honest errors

Now that core can gate a plugin admin page on the plugin's own capability
(ADR 0020), the Commerce page and all its actions require
`nimbuscms.commerce:write` — parity with the MCP tools, so a content-only editor
can no longer place or advance orders from the UI.

- Per-row lifecycle buttons: pay / fulfil / cancel (CSRF-protected POSTs to H3
  actions), shown by status. The UI catching up to the MCP tools.
- Status pills now use the admin theme's semantic tokens (var(--nb-*-bg/-text))
  instead of hard-coded hex, so they stay legible in dark and every theme.
- Totals render in the order's currency (a small symbol map from the
  commerce_order.currency column, which the query now selects) instead of a
  literal "$".
- SKU datalist on the place form, sourced from this plugin's own order lines
  (never inventory_* — the plugin boundary).
- Allow-listed ?status= filter on the orders table (bound; junk is ignored, not
  reflected).
- Honest errors via typed exceptions: OrderNotFound -> notfound, IllegalTransition
  -> badstate, NoInventory -> noinventory, bad qty/price -> badqty (validated at
  the boundary, so a DECIMAL DB error can't masquerade as something else),
  InsufficientStock -> short.

OrderBook now throws the typed exceptions (all extend \RuntimeException, so
existing catchers keep working).

Tests: CommerceAdminTest (render — theme-token pills, currency, lifecycle
buttons, allow-listed filter, datalist) and CommerceAdminActionsTest (the H3
actions through the real loader with Inventory alongside — the full lifecycle and
every honest-error path). 22 tests green; PHPStan + php-cs-fixer clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@DanMat
DanMat merged commit 875354c into main Aug 30, 2026
2 checks passed
@DanMat
DanMat deleted the feat/workbench-phase1 branch August 30, 2026 18:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant