feat: Workbench Phase 1 — gate admin page, order lifecycle buttons, currency, theme-safe pills, honest errors - #1
Merged
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
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.)var(--nb-*-bg/-text)semantic tokens instead of hard-coded hex +color:#fff— legible in dark and every selectable theme. (bug fix)commerce_order.currency(now selected) instead of a literal$. (bug fix)commerce_order_line— neverinventory_*(the plugin boundary).?status=filter (bound; junk ignored, never reflected).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.OrderBooknow 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-loopandnimbus-security-review.🤖 Generated with Claude Code