Output:
Chunk ID: 38ed25
Wall time: 5.0041 seconds
Process running with session ID 73138
Original token count: 3
Output:
............


Output:
Chunk ID: 91406c
Wall time: 5.0024 seconds
Process running with session ID 73138
Original token count: 0
Output:


Output:
Chunk ID: 05e6e5
Wall time: 5.0010 seconds
Process running with session ID 73138
Original token count: 0
Output:


Output:
Chunk ID: 0eb754
Wall time: 5.0011 seconds
Process running with session ID 73138
Original token count: 0
Output:


Output:
Chunk ID: 2709a9
Wall time: 5.0005 seconds
Process running with session ID 73138
Original token count: 0
Output:


Output:
Chunk ID: b3615c
Wall time: 5.0014 seconds
Process running with session ID 73138
Original token count: 0
Output:


Output:
Chunk ID: 14a1d4
Wall time: 5.0008 seconds
Process running with session ID 73138
Original token count: 0
Output:


Output:
Chunk ID: 301a45
Wall time: 5.0020 seconds
Process running with session ID 73138
Original token count: 0
Output:


Output:
Chunk ID: 936dee
Wall time: 5.0016 seconds
Process running with session ID 73138
Original token count: 0
Output:


Output:
Chunk ID: e868e3
Wall time: 5.0013 seconds
Process running with session ID 73138
Original token count: 0
Output:


Output:
Chunk ID: 6fd99c
Wall time: 5.0013 seconds
Process running with session ID 73138
Original token count: 4
Output:
.............


Output:
Chunk ID: 3c8cdb
Wall time: 5.0002 seconds
Process running with session ID 73138
Original token count: 0
Output:


Output:
Chunk ID: 7856ca
Wall time: 5.0010 seconds
Process running with session ID 73138
Original token count: 3
Output:
............


Output:
Chunk ID: 022fea
Wall time: 5.0014 seconds
Process running with session ID 73138
Original token count: 1
Output:
....


Output:
Chunk ID: 4f14d7
Wall time: 5.0026 seconds
Process running with session ID 73138
Original token count: 0
Output:


Output:
Chunk ID: 4f2ba8
Wall time: 5.0006 seconds
Process running with session ID 73138
Original token count: 0
Output:


Output:
Chunk ID: 5dd98e
Wall time: 5.0005 seconds
Process running with session ID 73138
Original token count: 2
Output:
........


php -d memory_limit=512M vendor/bin/pest --compact


Output:
Chunk ID: d167a5
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 18
Output:
.....

  Tests:    361 passed (2161 assertions)
  Duration: 486.36s


The full suite passed: 361 tests, 2161 assertions. I’m cleaning/checking the worktree, then I’ll record Suite 4 evidence in `specs/progress.md` and commit.


find tests/Browser/Screenshots -type f -print


find tests/Browser/Screenshots -type f -print

find: tests/Browser/Screenshots: No such file or directory


 M app/Livewire/Admin/Orders/Show.php
 M resources/views/livewire/admin/orders/show.blade.php
 M tests/Browser/Admin/ProductManagementTest.php
?? .playwright-mcp/console-2026-05-03T23-28-42-443Z.log
?? .playwright-mcp/console-2026-05-04T04-24-15-455Z.log
?? .playwright-mcp/console-2026-05-04T12-05-13-581Z.log
?? tests/Browser/Admin/OrderManagementTest.php


Output:
Chunk ID: 6c8c0c
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 90
Output:
 M app/Livewire/Admin/Orders/Show.php
 M resources/views/livewire/admin/orders/show.blade.php
 M tests/Browser/Admin/ProductManagementTest.php
?? .playwright-mcp/console-2026-05-03T23-28-42-443Z.log
?? .playwright-mcp/console-2026-05-04T04-24-15-455Z.log
?? .playwright-mcp/console-2026-05-04T12-05-13-581Z.log
?? tests/Browser/Admin/OrderManagementTest.php


Output:
Chunk ID: 435d8b
Wall time: 0.0000 seconds
Process exited with code 1
Original token count: 15
Output:
find: tests/Browser/Screenshots: No such file or directory


 app/Livewire/Admin/Orders/Show.php                 |  7 +++
 .../views/livewire/admin/orders/show.blade.php     | 73 +++++++++++++++++++---
 tests/Browser/Admin/ProductManagementTest.php      | 13 ++--
 3 files changed, 76 insertions(+), 17 deletions(-)


Output:
Chunk ID: 745baa
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 64
Output:
 app/Livewire/Admin/Orders/Show.php                 |  7 +++
 .../views/livewire/admin/orders/show.blade.php     | 73 +++++++++++++++++++---
 tests/Browser/Admin/ProductManagementTest.php      | 13 ++--
 3 files changed, 76 insertions(+), 17 deletions(-)


Output:
Chunk ID: a51fe3
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


Input:
*** Begin Patch
*** Update File: /Users/fabianwesner/Herd/shop/specs/progress.md
@@
-| Browser E2E plan | `specs/08-PLAYWRIGHT-E2E-PLAN.md` | partial | Manual Playwright MCP smoke coverage has verified storefront catalog browsing on `shop.test` and `acme-fashion.test`, product detail, add-to-cart, cart drawer/page, checkout through order completion, order confirmation, customer order list/detail, SQLite-backed search and search API JSON, analytics event ingestion API, DB-backed content pages, seeded nested navigation dropdowns, admin dashboard on desktop/mobile, admin analytics, admin app list/detail, admin developers token/webhook flows, admin product/collection/inventory/order/customer/discount/content/navigation/settings/theme/search pages, admin checkout/notification settings pages, admin product media section rendering, admin analytics CSV export, admin customer address creation, admin discount creation/editing/filtering, admin page creation, admin nested navigation rendering/item creation/save, admin theme editor preview, admin theme file list/editor, admin search reindexing, admin fulfillment creation/shipping/delivery, and auth flows without console warnings/errors on successful pages. Automated Pest browser coverage now checks storefront core pages, storefront account auth/reset pages including the customer root reset paths and account aliases, authenticated admin navigation/pages/settings/theme/search/apps/developers surfaces, Suite 2 admin authentication login/validation/redirect/logout/sidebar navigation interactions, Suite 3 admin product listing/create/edit/archive/search/status-filter/draft visibility interactions, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account registration/login/orders/addresses/logout, Suite 11 inventory policy enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile flows, Suite 14 accessibility checks, and mobile storefront rendering for JavaScript errors. The remaining Spec 08 interaction/permutation browser suites are still incomplete. |
+| Browser E2E plan | `specs/08-PLAYWRIGHT-E2E-PLAN.md` | partial | Manual Playwright MCP smoke coverage has verified storefront catalog browsing on `shop.test` and `acme-fashion.test`, product detail, add-to-cart, cart drawer/page, checkout through order completion, order confirmation, customer order list/detail, SQLite-backed search and search API JSON, analytics event ingestion API, DB-backed content pages, seeded nested navigation dropdowns, admin dashboard on desktop/mobile, admin analytics, admin app list/detail, admin developers token/webhook flows, admin product/collection/inventory/order/customer/discount/content/navigation/settings/theme/search pages, admin checkout/notification settings pages, admin product media section rendering, admin analytics CSV export, admin customer address creation, admin discount creation/editing/filtering, admin page creation, admin nested navigation rendering/item creation/save, admin theme editor preview, admin theme file list/editor, admin search reindexing, admin fulfillment creation/shipping/delivery, and auth flows without console warnings/errors on successful pages. Automated Pest browser coverage now checks storefront core pages, storefront account auth/reset pages including the customer root reset paths and account aliases, authenticated admin navigation/pages/settings/theme/search/apps/developers surfaces, Suite 2 admin authentication login/validation/redirect/logout/sidebar navigation interactions, Suite 3 admin product listing/create/edit/archive/search/status-filter/draft visibility interactions, Suite 4 admin order listing/filtering/detail/timeline/fulfillment/refund/bank-payment/guard/shipment interactions, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account registration/login/orders/addresses/logout, Suite 11 inventory policy enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile flows, Suite 14 accessibility checks, and mobile storefront rendering for JavaScript errors. The remaining Spec 08 interaction/permutation browser suites are still incomplete. |
@@
 - 2026-05-04: `php artisan test --compact tests/Browser/Admin/ProductManagementTest.php` passed for the new Suite 3 admin product-management browser coverage: 7 tests, 98 assertions.
 - 2026-05-04: `php artisan test --compact tests/Browser` passed after adding Suite 3: 101 tests, 630 assertions.
 - 2026-05-04: `php -d memory_limit=512M vendor/bin/pest --compact` passed the full suite after Suite 3: 350 tests, 2069 assertions.
+- 2026-05-04: `mcp__laravel_boost__.search_docs` consulted Pest browser testing, Livewire modal/form/action docs, Flux modal/button/callout docs, Laravel factories/session testing docs, and project order feature tests before adding the Spec 08 admin order-management browser suite.
+- 2026-05-04: `php artisan make:test --pest Browser/Admin/OrderManagementTest --no-interaction` created the Suite 4 order-management browser test, which was moved into the Spec 08 browser directory structure.
+- 2026-05-04: `vendor/bin/pint --dirty --format agent` passed after adding Suite 4 and the order-detail UI action messages/timeline/fulfillment guard.
+- 2026-05-04: `php artisan test --compact tests/Browser/Admin/OrderManagementTest.php` passed for the new Suite 4 admin order-management browser coverage: 11 tests, 146 assertions.
+- 2026-05-04: `php artisan test --compact tests/Feature/Admin/OrderManagementTest.php tests/Feature/Orders` passed after the order-detail UI changes: 22 tests, 120 assertions.
+- 2026-05-04: `php artisan test --compact tests/Browser/Admin/OrderManagementTest.php tests/Browser/Admin/ProductManagementTest.php` passed after hardening authenticated admin browser entry points: 18 tests, 190 assertions.
+- 2026-05-04: `npm run build` passed after the order-detail Blade changes.
+- 2026-05-04: `php artisan test --compact tests/Browser` passed after adding Suite 4: 112 tests, 722 assertions.
+- 2026-05-04: `php -d memory_limit=512M vendor/bin/pest --compact` passed the full suite after Suite 4: 361 tests, 2161 assertions.
@@
-- Automated browser coverage now combines smoke coverage with Suite 2 admin-auth interactions, Suite 3 admin product-management interactions, Suite 7 storefront browsing interactions, Suite 8 cart-flow interactions, Suite 9 checkout-flow interactions, Suite 10 customer-account interactions, Suite 11 inventory-policy interactions, Suite 12 tenant-isolation interactions, Suite 13 responsive/mobile interactions, and Suite 14 accessibility interactions: storefront catalog/content/search/cart, storefront account auth/reset pages, the full authenticated admin navigation surface, admin login validation, protected-route redirects, logout, sidebar navigation, admin product listing/create/edit/archive/search/status-filter/draft visibility guards, mobile storefront rendering, seeded collection/product/search/static page browsing, sale/compare-at pricing, draft-product storefront visibility guards, stock/backorder messaging, main-navigation clicks, add-to-cart, cart quantity updates/removal, multi-product carts, subtotal/total display, valid/invalid/expired/maxed/free-shipping/fixed discount code handling, domestic/international checkout shipping, checkout discount carryover, address validation, empty-cart checkout protection, credit-card/PayPal/bank-transfer order completion, payment decline handling, payment-method UI switching, customer registration validation, customer login validation, account auth redirects, customer order history/detail, address book create/update, customer logout, deny-policy sold-out blocking, continue-policy backorder add-to-cart, in-stock status display, deny-policy cart stock-limit feedback, storefront product/collection/search store isolation, admin product/order store isolation, customer account store isolation, mobile hamburger navigation, mobile product/cart/checkout flows, mobile collection filtering, tablet admin login/sidebar navigation, console-clean home/cart pages, heading hierarchy, form labels, product image placeholder accessible text, checkout error linkage, keyboard navigation, and search input labeling.
+- Automated browser coverage now combines smoke coverage with Suite 2 admin-auth interactions, Suite 3 admin product-management interactions, Suite 4 admin order-management interactions, Suite 7 storefront browsing interactions, Suite 8 cart-flow interactions, Suite 9 checkout-flow interactions, Suite 10 customer-account interactions, Suite 11 inventory-policy interactions, Suite 12 tenant-isolation interactions, Suite 13 responsive/mobile interactions, and Suite 14 accessibility interactions: storefront catalog/content/search/cart, storefront account auth/reset pages, the full authenticated admin navigation surface, admin login validation, protected-route redirects, logout, sidebar navigation, admin product listing/create/edit/archive/search/status-filter/draft visibility guards, admin order listing/filtering/detail/timeline/customer info, fulfillment creation, refund processing, bank-transfer payment confirmation, unpaid fulfillment guard, shipped/delivered fulfillment transitions, mobile storefront rendering, seeded collection/product/search/static page browsing, sale/compare-at pricing, draft-product storefront visibility guards, stock/backorder messaging, main-navigation clicks, add-to-cart, cart quantity updates/removal, multi-product carts, subtotal/total display, valid/invalid/expired/maxed/free-shipping/fixed discount code handling, domestic/international checkout shipping, checkout discount carryover, address validation, empty-cart checkout protection, credit-card/PayPal/bank-transfer order completion, payment decline handling, payment-method UI switching, customer registration validation, customer login validation, account auth redirects, customer order history/detail, address book create/update, customer logout, deny-policy sold-out blocking, continue-policy backorder add-to-cart, in-stock status display, deny-policy cart stock-limit feedback, storefront product/collection/search store isolation, admin product/order store isolation, customer account store isolation, mobile hamburger navigation, mobile product/cart/checkout flows, mobile collection filtering, tablet admin login/sidebar navigation, console-clean home/cart pages, heading hierarchy, form labels, product image placeholder accessible text, checkout error linkage, keyboard navigation, and search input labeling.
 - The admin product-management browser suite uses Laravel `actingAs()` and `withSession()` to create deterministic authenticated browser visits; the separate Suite 2 admin-auth suite owns login-form coverage so persisted browser cookies from earlier tests cannot leak into product CRUD assertions.
+- The admin order-management browser suite creates deterministic per-test `#1001`, `#1002`, and `#1005` order fixtures because order/payment seed data is still deferred; the browser suite covers the spec interactions without changing the global seed contract.
+- Admin order detail now shows visible action feedback, a simple event timeline, and an explicit unpaid-fulfillment guard. Refund and fulfillment buttons are only exposed when the current financial/fulfillment state allows the backing service action.
@@
-- Full automated browser interaction/permutation suites from Spec 08 are still incomplete beyond the expanded Pest browser smoke coverage, Suite 2 admin authentication, Suite 3 admin product management, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account flow, Suite 11 inventory enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile, and Suite 14 accessibility.
+- Full automated browser interaction/permutation suites from Spec 08 are still incomplete beyond the expanded Pest browser smoke coverage, Suite 2 admin authentication, Suite 3 admin product management, Suite 4 admin order management, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account flow, Suite 11 inventory enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile, and Suite 14 accessibility.
@@
-Not complete. Phase 1 foundation, Phase 2 catalog data/UI surfaces, product media processing/admin upload controls, Phase 3 storefront theme/content/navigation data, the Phase 4 cart/checkout/pricing backend foundation, cart/checkout storefront UI through order completion, cart-page estimates, cart/checkout REST APIs, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, customer account order/address/logout views, admin dashboard/order/customer/discount/content/settings/theme-file/navigation/search/analytics/apps/developers management, storefront search and analytics APIs, product/customer/collection/discount/content page/store settings/search/analytics/shipping/tax/theme/order/export API surfaces, deferred OAuth/app route stubs, expanded automated browser smoke coverage, Suite 2 admin authentication browser coverage, Suite 3 admin product-management browser coverage, Suite 7 storefront browsing browser coverage, Suite 8 cart-flow browser coverage, Suite 9 checkout-flow browser coverage, Suite 10 customer-account browser coverage, Suite 11 inventory-enforcement browser coverage, Suite 12 tenant-isolation browser coverage, Suite 13 responsive/mobile browser coverage, Suite 14 accessibility browser coverage, outbound webhook delivery foundations, spec-root customer password reset routes, and representative database CHECK constraint coverage are implemented, with the remaining full browser-suite gap tracked above.
+Not complete. Phase 1 foundation, Phase 2 catalog data/UI surfaces, product media processing/admin upload controls, Phase 3 storefront theme/content/navigation data, the Phase 4 cart/checkout/pricing backend foundation, cart/checkout storefront UI through order completion, cart-page estimates, cart/checkout REST APIs, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, customer account order/address/logout views, admin dashboard/order/customer/discount/content/settings/theme-file/navigation/search/analytics/apps/developers management, storefront search and analytics APIs, product/customer/collection/discount/content page/store settings/search/analytics/shipping/tax/theme/order/export API surfaces, deferred OAuth/app route stubs, expanded automated browser smoke coverage, Suite 2 admin authentication browser coverage, Suite 3 admin product-management browser coverage, Suite 4 admin order-management browser coverage, Suite 7 storefront browsing browser coverage, Suite 8 cart-flow browser coverage, Suite 9 checkout-flow browser coverage, Suite 10 customer-account browser coverage, Suite 11 inventory-enforcement browser coverage, Suite 12 tenant-isolation browser coverage, Suite 13 responsive/mobile browser coverage, Suite 14 accessibility browser coverage, outbound webhook delivery foundations, spec-root customer password reset routes, and representative database CHECK constraint coverage are implemented, with the remaining full browser-suite gap tracked above.
*** End Patch


Success. Updated the following files:
M /Users/fabianwesner/Herd/shop/specs/progress.md

@@ -35,3 +35,3 @@
 | Seed/test data | `specs/07-SEEDERS-AND-TEST-DATA.md` | partial | Seeders create Acme Fashion and Acme Electronics stores/domains/settings/admin access with checkout and notification defaults, 2 apps, 4 app installations, 4 OAuth clients, 4 OAuth tokens, 8 webhook subscriptions, 2 search settings rows, 25 indexed products, 60 analytics_daily rows, 210 analytics_events rows, 6 collections, 127 variants, 127 inventory rows, 206 variant option pivots, 2 themes, 6 theme files with local disk contents and metadata, 2 theme settings rows, 6 pages, 4 navigation menus, 21 navigation items including 6 child items, 2 tax settings rows, 2 shipping zones, 6 shipping rates, 6 discounts, the seeded customer, 1 default seeded customer address, and no product media/runtime carts. Order/payment seed data is still missing. |
-| Browser E2E plan | `specs/08-PLAYWRIGHT-E2E-PLAN.md` | partial | Manual Playwright MCP smoke coverage has verified storefront catalog browsing on `shop.test` and `acme-fashion.test`, product detail, add-to-cart, cart drawer/page, checkout through order completion, order confirmation, customer order list/detail, SQLite-backed search and search API JSON, analytics event ingestion API, DB-backed content pages, seeded nested navigation dropdowns, admin dashboard on desktop/mobile, admin analytics, admin app list/detail, admin developers token/webhook flows, admin product/collection/inventory/order/customer/discount/content/navigation/settings/theme/search pages, admin checkout/notification settings pages, admin product media section rendering, admin analytics CSV export, admin customer address creation, admin discount creation/editing/filtering, admin page creation, admin nested navigation rendering/item creation/save, admin theme editor preview, admin theme file list/editor, admin search reindexing, admin fulfillment creation/shipping/delivery, and auth flows without console warnings/errors on successful pages. Automated Pest browser coverage now checks storefront core pages, storefront account auth/reset pages including the customer root reset paths and account aliases, authenticated admin navigation/pages/settings/theme/search/apps/developers surfaces, Suite 2 admin authentication login/validation/redirect/logout/sidebar navigation interactions, Suite 3 admin product listing/create/edit/archive/search/status-filter/draft visibility interactions, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account registration/login/orders/addresses/logout, Suite 11 inventory policy enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile flows, Suite 14 accessibility checks, and mobile storefront rendering for JavaScript errors. The remaining Spec 08 interaction/permutation browser suites are still incomplete. |
+| Browser E2E plan | `specs/08-PLAYWRIGHT-E2E-PLAN.md` | partial | Manual Playwright MCP smoke coverage has verified storefront catalog browsing on `shop.test` and `acme-fashion.test`, product detail, add-to-cart, cart drawer/page, checkout through order completion, order confirmation, customer order list/detail, SQLite-backed search and search API JSON, analytics event ingestion API, DB-backed content pages, seeded nested navigation dropdowns, admin dashboard on desktop/mobile, admin analytics, admin app list/detail, admin developers token/webhook flows, admin product/collection/inventory/order/customer/discount/content/navigation/settings/theme/search pages, admin checkout/notification settings pages, admin product media section rendering, admin analytics CSV export, admin customer address creation, admin discount creation/editing/filtering, admin page creation, admin nested navigation rendering/item creation/save, admin theme editor preview, admin theme file list/editor, admin search reindexing, admin fulfillment creation/shipping/delivery, and auth flows without console warnings/errors on successful pages. Automated Pest browser coverage now checks storefront core pages, storefront account auth/reset pages including the customer root reset paths and account aliases, authenticated admin navigation/pages/settings/theme/search/apps/developers surfaces, Suite 2 admin authentication login/validation/redirect/logout/sidebar navigation interactions, Suite 3 admin product listing/create/edit/archive/search/status-filter/draft visibility interactions, Suite 4 admin order listing/filtering/detail/timeline/fulfillment/refund/bank-payment/guard/shipment interactions, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account registration/login/orders/addresses/logout, Suite 11 inventory policy enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile flows, Suite 14 accessibility checks, and mobile storefront rendering for JavaScript errors. The remaining Spec 08 interaction/permutation browser suites are still incomplete. |
 | Roadmap phases | `specs/09-IMPLEMENTATION-ROADMAP.md` | in progress | Phase 1 foundation, Phase 2 catalog data/UI, Phase 3 theme/content/navigation data with storefront consumption, Phase 4 cart/checkout/pricing backend foundation, Phase 4 storefront cart/checkout UI through `payment_selected`, the Phase 4 cart/checkout REST API surface, cart-page estimates, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, Phase 5 storefront order completion/customer order surfaces, Phase 5 admin order management, Phase 5 order API surfaces, Phase 6 admin dashboard/customer/discount/content/settings/theme/navigation management, Phase 7 search, Phase 7 analytics, and Phase 7 apps/webhooks are implemented. Final verification and completion audit are next. |
@@ -495,2 +495,11 @@
 - 2026-05-04: `php -d memory_limit=512M vendor/bin/pest --compact` passed the full suite after Suite 3: 350 tests, 2069 assertions.
+- 2026-05-04: `mcp__laravel_boost__.search_docs` consulted Pest browser testing, Livewire modal/form/action docs, Flux modal/button/callout docs, Laravel factories/session testing docs, and project order feature tests before adding the Spec 08 admin order-management browser suite.
+- 2026-05-04: `php artisan make:test --pest Browser/Admin/OrderManagementTest --no-interaction` created the Suite 4 order-management browser test, which was moved into the Spec 08 browser directory structure.
+- 2026-05-04: `vendor/bin/pint --dirty --format agent` passed after adding Suite 4 and the order-detail UI action messages/timeline/fulfillment guard.
+- 2026-05-04: `php artisan test --compact tests/Browser/Admin/OrderManagementTest.php` passed for the new Suite 4 admin order-management browser coverage: 11 tests, 146 assertions.
+- 2026-05-04: `php artisan test --compact tests/Feature/Admin/OrderManagementTest.php tests/Feature/Orders` passed after the order-detail UI changes: 22 tests, 120 assertions.
+- 2026-05-04: `php artisan test --compact tests/Browser/Admin/OrderManagementTest.php tests/Browser/Admin/ProductManagementTest.php` passed after hardening authenticated admin browser entry points: 18 tests, 190 assertions.
+- 2026-05-04: `npm run build` passed after the order-detail Blade changes.
+- 2026-05-04: `php artisan test --compact tests/Browser` passed after adding Suite 4: 112 tests, 722 assertions.
+- 2026-05-04: `php -d memory_limit=512M vendor/bin/pest --compact` passed the full suite after Suite 4: 361 tests, 2161 assertions.

@@ -564,4 +573,6 @@
 - Laravel's SQLite `enum()` migrations generate database `CHECK` clauses in this app; `DatabaseConstraintTest` locks representative constraints across tenancy, roles, catalog, orders, tax settings, and exports.
-- Automated browser coverage now combines smoke coverage with Suite 2 admin-auth interactions, Suite 3 admin product-management interactions, Suite 7 storefront browsing interactions, Suite 8 cart-flow interactions, Suite 9 checkout-flow interactions, Suite 10 customer-account interactions, Suite 11 inventory-policy interactions, Suite 12 tenant-isolation interactions, Suite 13 responsive/mobile interactions, and Suite 14 accessibility interactions: storefront catalog/content/search/cart, storefront account auth/reset pages, the full authenticated admin navigation surface, admin login validation, protected-route redirects, logout, sidebar navigation, admin product listing/create/edit/archive/search/status-filter/draft visibility guards, mobile storefront rendering, seeded collection/product/search/static page browsing, sale/compare-at pricing, draft-product storefront visibility guards, stock/backorder messaging, main-navigation clicks, add-to-cart, cart quantity updates/removal, multi-product carts, subtotal/total display, valid/invalid/expired/maxed/free-shipping/fixed discount code handling, domestic/international checkout shipping, checkout discount carryover, address validation, empty-cart checkout protection, credit-card/PayPal/bank-transfer order completion, payment decline handling, payment-method UI switching, customer registration validation, customer login validation, account auth redirects, customer order history/detail, address book create/update, customer logout, deny-policy sold-out blocking, continue-policy backorder add-to-cart, in-stock status display, deny-policy cart stock-limit feedback, storefront product/collection/search store isolation, admin product/order store isolation, customer account store isolation, mobile hamburger navigation, mobile product/cart/checkout flows, mobile collection filtering, tablet admin login/sidebar navigation, console-clean home/cart pages, heading hierarchy, form labels, product image placeholder accessible text, checkout error linkage, keyboard navigation, and search input labeling.
+- Automated browser coverage now combines smoke coverage with Suite 2 admin-auth interactions, Suite 3 admin product-management interactions, Suite 4 admin order-management interactions, Suite 7 storefront browsing interactions, Suite 8 cart-flow interactions, Suite 9 checkout-flow interactions, Suite 10 customer-account interactions, Suite 11 inventory-policy interactions, Suite 12 tenant-isolation interactions, Suite 13 responsive/mobile interactions, and Suite 14 accessibility interactions: storefront catalog/content/search/cart, storefront account auth/reset pages, the full authenticated admin navigation surface, admin login validation, protected-route redirects, logout, sidebar navigation, admin product listing/create/edit/archive/search/status-filter/draft visibility guards, admin order listing/filtering/detail/timeline/customer info, fulfillment creation, refund processing, bank-transfer payment confirmation, unpaid fulfillment guard, shipped/delivered fulfillment transitions, mobile storefront rendering, seeded collection/product/search/static page browsing, sale/compare-at pricing, draft-product storefront visibility guards, stock/backorder messaging, main-navigation clicks, add-to-cart, cart quantity updates/removal, multi-product carts, subtotal/total display, valid/invalid/expired/maxed/free-shipping/fixed discount code handling, domestic/international checkout shipping, checkout discount carryover, address validation, empty-cart checkout protection, credit-card/PayPal/bank-transfer order completion, payment decline handling, payment-method UI switching, customer registration validation, customer login validation, account auth redirects, customer order history/detail, address book create/update, customer logout, deny-policy sold-out blocking, continue-policy backorder add-to-cart, in-stock status display, deny-policy cart stock-limit feedback, storefront product/collection/search store isolation, admin product/order store isolation, customer account store isolation, mobile hamburger navigation, mobile product/cart/checkout flows, mobile collection filtering, tablet admin login/sidebar navigation, console-clean home/cart pages, heading hierarchy, form labels, product image placeholder accessible text, checkout error linkage, keyboard navigation, and search input labeling.
 - The admin product-management browser suite uses Laravel `actingAs()` and `withSession()` to create deterministic authenticated browser visits; the separate Suite 2 admin-auth suite owns login-form coverage so persisted browser cookies from earlier tests cannot leak into product CRUD assertions.
+- The admin order-management browser suite creates deterministic per-test `#1001`, `#1002`, and `#1005` order fixtures because order/payment seed data is still deferred; the browser suite covers the spec interactions without changing the global seed contract.
+- Admin order detail now shows visible action feedback, a simple event timeline, and an explicit unpaid-fulfillment guard. Refund and fulfillment buttons are only exposed when the current financial/fulfillment state allows the backing service action.
 - Pest's per-visit browser `host` option is temporary, so host-sensitive storefront browser tests set the Playwright host for the whole test lifecycle to keep clicked absolute URLs resolving through `shop.test`.
@@ -578,3 +589,3 @@

-- Full automated browser interaction/permutation suites from Spec 08 are still incomplete beyond the expanded Pest browser smoke coverage, Suite 2 admin authentication, Suite 3 admin product management, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account flow, Suite 11 inventory enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile, and Suite 14 accessibility.
+- Full automated browser interaction/permutation suites from Spec 08 are still incomplete beyond the expanded Pest browser smoke coverage, Suite 2 admin authentication, Suite 3 admin product management, Suite 4 admin order management, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account flow, Suite 11 inventory enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile, and Suite 14 accessibility.
 - The full suite now needs a higher PHP memory limit when all browser suites run in one process; the default `php artisan test --compact` command hits 128 MB in Pest's browser WebSocket client, while `php -d memory_limit=512M vendor/bin/pest --compact` passes.
@@ -583,2 +594,2 @@

-Not complete. Phase 1 foundation, Phase 2 catalog data/UI surfaces, product media processing/admin upload controls, Phase 3 storefront theme/content/navigation data, the Phase 4 cart/checkout/pricing backend foundation, cart/checkout storefront UI through order completion, cart-page estimates, cart/checkout REST APIs, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, customer account order/address/logout views, admin dashboard/order/customer/discount/content/settings/theme-file/navigation/search/analytics/apps/developers management, storefront search and analytics APIs, product/customer/collection/discount/content page/store settings/search/analytics/shipping/tax/theme/order/export API surfaces, deferred OAuth/app route stubs, expanded automated browser smoke coverage, Suite 2 admin authentication browser coverage, Suite 3 admin product-management browser coverage, Suite 7 storefront browsing browser coverage, Suite 8 cart-flow browser coverage, Suite 9 checkout-flow browser coverage, Suite 10 customer-account browser coverage, Suite 11 inventory-enforcement browser coverage, Suite 12 tenant-isolation browser coverage, Suite 13 responsive/mobile browser coverage, Suite 14 accessibility browser coverage, outbound webhook delivery foundations, spec-root customer password reset routes, and representative database CHECK constraint coverage are implemented, with the remaining full browser-suite gap tracked above.
+Not complete. Phase 1 foundation, Phase 2 catalog data/UI surfaces, product media processing/admin upload controls, Phase 3 storefront theme/content/navigation data, the Phase 4 cart/checkout/pricing backend foundation, cart/checkout storefront UI through order completion, cart-page estimates, cart/checkout REST APIs, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, customer account order/address/logout views, admin dashboard/order/customer/discount/content/settings/theme-file/navigation/search/analytics/apps/developers management, storefront search and analytics APIs, product/customer/collection/discount/content page/store settings/search/analytics/shipping/tax/theme/order/export API surfaces, deferred OAuth/app route stubs, expanded automated browser smoke coverage, Suite 2 admin authentication browser coverage, Suite 3 admin product-management browser coverage, Suite 4 admin order-management browser coverage, Suite 7 storefront browsing browser coverage, Suite 8 cart-flow browser coverage, Suite 9 checkout-flow browser coverage, Suite 10 customer-account browser coverage, Suite 11 inventory-enforcement browser coverage, Suite 12 tenant-isolation browser coverage, Suite 13 responsive/mobile browser coverage, Suite 14 accessibility browser coverage, outbound webhook delivery foundations, spec-root customer password reset routes, and representative database CHECK constraint coverage are implemented, with the remaining full browser-suite gap tracked above.


Output: {"output":"Success. Updated the following files:\nM /Users/fabianwesner/Herd/shop/specs/progress.md\n","metadata":{"exit_code":0,"duration_seconds":0.0}}


git diff -- app/Livewire/Admin/Orders/Show.php resources/views/livewire/admin/orders/show.blade.php tests/Browser/Admin/ProductManagementTest.php specs/progress.md


 M app/Livewire/Admin/Orders/Show.php
 M resources/views/livewire/admin/orders/show.blade.php
 M specs/progress.md
 M tests/Browser/Admin/ProductManagementTest.php
?? tests/Browser/Admin/OrderManagementTest.php


 app/Livewire/Admin/Orders/Show.php                 |  7 +++
 .../views/livewire/admin/orders/show.blade.php     | 73 +++++++++++++++++++---
 specs/progress.md                                  | 19 ++++--
 tests/Browser/Admin/ProductManagementTest.php      | 13 ++--
 4 files changed, 91 insertions(+), 21 deletions(-)


Output:
Chunk ID: 6298f6
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 53
Output:
 M app/Livewire/Admin/Orders/Show.php
 M resources/views/livewire/admin/orders/show.blade.php
 M specs/progress.md
 M tests/Browser/Admin/ProductManagementTest.php
?? tests/Browser/Admin/OrderManagementTest.php


Output:
Chunk ID: fb231c
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 80
Output:
 app/Livewire/Admin/Orders/Show.php                 |  7 +++
 .../views/livewire/admin/orders/show.blade.php     | 73 +++++++++++++++++++---
 specs/progress.md                                  | 19 ++++--
 tests/Browser/Admin/ProductManagementTest.php      | 13 ++--
 4 files changed, 91 insertions(+), 21 deletions(-)


git diff -- app/Livewire/Admin/Orders/Show.php resources/views/livewire/admin/orders/show.blade.php tests/Browser/Admin/ProductManagementTest.php specs/progress.md

diff --git a/app/Livewire/Admin/Orders/Show.php b/app/Livewire/Admin/Orders/Show.php
index 72abb7e1..b2154941 100644
--- a/app/Livewire/Admin/Orders/Show.php
+++ b/app/Livewire/Admin/Orders/Show.php
@@ -42,6 +42,8 @@ class Show extends Component

     public string $trackingUrl = '';

+    public string $actionMessage = '';
+
     public function mount(Order $order): void
     {
         $store = app('current_store');
@@ -65,6 +67,7 @@ public function confirmBankTransferPayment(OrderService $orders): void
         try {
             $orders->confirmBankTransferPayment($this->order());
             $this->resetFulfillmentLineQuantities($this->order());
+            $this->actionMessage = __('Payment confirmed');
             $this->dispatch('toast', type: 'success', message: __('Payment confirmed'));
         } catch (InvalidOrderOperationException $exception) {
             throw ValidationException::withMessages([
@@ -92,6 +95,7 @@ public function processRefund(RefundService $refunds): void
             $refunds->process($this->order(), $request);
             $this->refundAmount = '';
             $this->refundReason = '';
+            $this->actionMessage = __('Refund processed');
             $this->modal('refund-order')->close();
             $this->dispatch('toast', type: 'success', message: __('Refund processed'));
         } catch (InvalidRefundOperationException $exception) {
@@ -132,6 +136,7 @@ public function createFulfillment(FulfillmentService $fulfillments): void
             $this->trackingNumber = '';
             $this->trackingUrl = '';
             $this->resetFulfillmentLineQuantities($this->order());
+            $this->actionMessage = __('Fulfillment created');
             $this->modal('fulfillment-order')->close();
             $this->dispatch('toast', type: 'success', message: __('Fulfillment created'));
         } catch (InvalidFulfillmentOperationException $exception) {
@@ -145,6 +150,7 @@ public function markFulfillmentShipped(int $fulfillmentId, FulfillmentService $f
     {
         try {
             $fulfillments->markShipped($this->fulfillment($fulfillmentId));
+            $this->actionMessage = __('Fulfillment marked as shipped');
             $this->dispatch('toast', type: 'success', message: __('Fulfillment marked as shipped'));
         } catch (InvalidFulfillmentOperationException $exception) {
             throw ValidationException::withMessages([
@@ -157,6 +163,7 @@ public function markFulfillmentDelivered(int $fulfillmentId, FulfillmentService
     {
         try {
             $fulfillments->markDelivered($this->fulfillment($fulfillmentId));
+            $this->actionMessage = __('Fulfillment marked as delivered');
             $this->dispatch('toast', type: 'success', message: __('Fulfillment marked as delivered'));
         } catch (InvalidFulfillmentOperationException $exception) {
             throw ValidationException::withMessages([
diff --git a/resources/views/livewire/admin/orders/show.blade.php b/resources/views/livewire/admin/orders/show.blade.php
index 90bcc3fc..53d8918c 100644
--- a/resources/views/livewire/admin/orders/show.blade.php
+++ b/resources/views/livewire/admin/orders/show.blade.php
@@ -13,14 +13,14 @@

         <div class="flex flex-wrap gap-2">
             @if ($order->payment_method === \App\Enums\PaymentMethod::BankTransfer && $order->financial_status === \App\Enums\FinancialStatus::Pending)
-                <flux:button wire:click="confirmBankTransferPayment" variant="primary" icon="banknotes">
+                <flux:button wire:click="confirmBankTransferPayment" variant="primary" icon="banknotes" data-test="confirm-payment-button">
                     Confirm payment
                 </flux:button>
             @endif

-            @if ($refundableAmount > 0)
+            @if (in_array($order->financial_status, [\App\Enums\FinancialStatus::Paid, \App\Enums\FinancialStatus::PartiallyRefunded], true) && $refundableAmount > 0)
                 <flux:modal.trigger name="refund-order">
-                    <flux:button variant="danger" icon="receipt-refund">
+                    <flux:button variant="danger" icon="receipt-refund" data-test="refund-modal-button">
                         Refund
                     </flux:button>
                 </flux:modal.trigger>
@@ -28,7 +28,7 @@

             @if (in_array($order->financial_status, [\App\Enums\FinancialStatus::Paid, \App\Enums\FinancialStatus::PartiallyRefunded], true) && collect($remainingFulfillmentQuantities)->sum() > 0)
                 <flux:modal.trigger name="fulfillment-order">
-                    <flux:button variant="filled" icon="truck">
+                    <flux:button variant="filled" icon="truck" data-test="fulfillment-modal-button">
                         Create fulfillment
                     </flux:button>
                 </flux:modal.trigger>
@@ -36,6 +36,10 @@
         </div>
     </div>

+    @if ($actionMessage !== '')
+        <flux:callout color="gree…24265 chars truncated…nsive/mobile, and Suite 14 accessibility.
+- Full automated browser interaction/permutation suites from Spec 08 are still incomplete beyond the expanded Pest browser smoke coverage, Suite 2 admin authentication, Suite 3 admin product management, Suite 4 admin order management, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account flow, Suite 11 inventory enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile, and Suite 14 accessibility.
 - The full suite now needs a higher PHP memory limit when all browser suites run in one process; the default `php artisan test --compact` command hits 128 MB in Pest's browser WebSocket client, while `php -d memory_limit=512M vendor/bin/pest --compact` passes.

 ## Completion Summary

-Not complete. Phase 1 foundation, Phase 2 catalog data/UI surfaces, product media processing/admin upload controls, Phase 3 storefront theme/content/navigation data, the Phase 4 cart/checkout/pricing backend foundation, cart/checkout storefront UI through order completion, cart-page estimates, cart/checkout REST APIs, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, customer account order/address/logout views, admin dashboard/order/customer/discount/content/settings/theme-file/navigation/search/analytics/apps/developers management, storefront search and analytics APIs, product/customer/collection/discount/content page/store settings/search/analytics/shipping/tax/theme/order/export API surfaces, deferred OAuth/app route stubs, expanded automated browser smoke coverage, Suite 2 admin authentication browser coverage, Suite 3 admin product-management browser coverage, Suite 7 storefront browsing browser coverage, Suite 8 cart-flow browser coverage, Suite 9 checkout-flow browser coverage, Suite 10 customer-account browser coverage, Suite 11 inventory-enforcement browser coverage, Suite 12 tenant-isolation browser coverage, Suite 13 responsive/mobile browser coverage, Suite 14 accessibility browser coverage, outbound webhook delivery foundations, spec-root customer password reset routes, and representative database CHECK constraint coverage are implemented, with the remaining full browser-suite gap tracked above.
+Not complete. Phase 1 foundation, Phase 2 catalog data/UI surfaces, product media processing/admin upload controls, Phase 3 storefront theme/content/navigation data, the Phase 4 cart/checkout/pricing backend foundation, cart/checkout storefront UI through order completion, cart-page estimates, cart/checkout REST APIs, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, customer account order/address/logout views, admin dashboard/order/customer/discount/content/settings/theme-file/navigation/search/analytics/apps/developers management, storefront search and analytics APIs, product/customer/collection/discount/content page/store settings/search/analytics/shipping/tax/theme/order/export API surfaces, deferred OAuth/app route stubs, expanded automated browser smoke coverage, Suite 2 admin authentication browser coverage, Suite 3 admin product-management browser coverage, Suite 4 admin order-management browser coverage, Suite 7 storefront browsing browser coverage, Suite 8 cart-flow browser coverage, Suite 9 checkout-flow browser coverage, Suite 10 customer-account browser coverage, Suite 11 inventory-enforcement browser coverage, Suite 12 tenant-isolation browser coverage, Suite 13 responsive/mobile browser coverage, Suite 14 accessibility browser coverage, outbound webhook delivery foundations, spec-root customer password reset routes, and representative database CHECK constraint coverage are implemented, with the remaining full browser-suite gap tracked above.
diff --git a/tests/Browser/Admin/ProductManagementTest.php b/tests/Browser/Admin/ProductManagementTest.php
index 1a9a726f..88207e07 100644
--- a/tests/Browser/Admin/ProductManagementTest.php
+++ b/tests/Browser/Admin/ProductManagementTest.php
@@ -23,25 +23,20 @@ function adminProductHost(): array
     return ['host' => 'shop.test'];
 }

-function adminProductLogin(mixed $testCase): mixed
+function adminProductAuthenticate(mixed $testCase): void
 {
     $store = Store::query()->where('handle', 'acme-fashion')->firstOrFail();
     $user = User::query()->where('email', 'admin@acme.test')->firstOrFail();

     $testCase->actingAs($user);
     $testCase->withSession(['current_store_id' => $store->getKey()]);
-
-    return visit('/admin', adminProductHost())
-        ->wait(1)
-        ->assertPathIs('/admin')
-        ->assertSee('Dashboard')
-        ->assertNoJavaScriptErrors();
 }

 function adminProductOpenProducts(mixed $testCase): mixed
 {
-    return adminProductLogin($testCase)
-        ->click('a[href$="/admin/products"]')
+    adminProductAuthenticate($testCase);
+
+    return visit('/admin/products', adminProductHost())
         ->wait(1)
         ->assertPathIs('/admin/products')
         ->assertSee('Products')


Output:
Chunk ID: c67dc2
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 8567
Output:
diff --git a/app/Livewire/Admin/Orders/Show.php b/app/Livewire/Admin/Orders/Show.php
index 72abb7e1..b2154941 100644
--- a/app/Livewire/Admin/Orders/Show.php
+++ b/app/Livewire/Admin/Orders/Show.php
@@ -42,6 +42,8 @@ class Show extends Component

     public string $trackingUrl = '';

+    public string $actionMessage = '';
+
     public function mount(Order $order): void
     {
         $store = app('current_store');
@@ -65,6 +67,7 @@ public function confirmBankTransferPayment(OrderService $orders): void
         try {
             $orders->confirmBankTransferPayment($this->order());
             $this->resetFulfillmentLineQuantities($this->order());
+            $this->actionMessage = __('Payment confirmed');
             $this->dispatch('toast', type: 'success', message: __('Payment confirmed'));
         } catch (InvalidOrderOperationException $exception) {
             throw ValidationException::withMessages([
@@ -92,6 +95,7 @@ public function processRefund(RefundService $refunds): void
             $refunds->process($this->order(), $request);
             $this->refundAmount = '';
             $this->refundReason = '';
+            $this->actionMessage = __('Refund processed');
             $this->modal('refund-order')->close();
             $this->dispatch('toast', type: 'success', message: __('Refund processed'));
         } catch (InvalidRefundOperationException $exception) {
@@ -132,6 +136,7 @@ public function createFulfillment(FulfillmentService $fulfillments): void
             $this->trackingNumber = '';
             $this->trackingUrl = '';
             $this->resetFulfillmentLineQuantities($this->order());
+            $this->actionMessage = __('Fulfillment created');
             $this->modal('fulfillment-order')->close();
             $this->dispatch('toast', type: 'success', message: __('Fulfillment created'));
         } catch (InvalidFulfillmentOperationException $exception) {
@@ -145,6 +150,7 @@ public function markFulfillmentShipped(int $fulfillmentId, FulfillmentService $f
     {
         try {
             $fulfillments->markShipped($this->fulfillment($fulfillmentId));
+            $this->actionMessage = __('Fulfillment marked as shipped');
             $this->dispatch('toast', type: 'success', message: __('Fulfillment marked as shipped'));
         } catch (InvalidFulfillmentOperationException $exception) {
             throw ValidationException::withMessages([
@@ -157,6 +163,7 @@ public function markFulfillmentDelivered(int $fulfillmentId, FulfillmentService
     {
         try {
             $fulfillments->markDelivered($this->fulfillment($fulfillmentId));
+            $this->actionMessage = __('Fulfillment marked as delivered');
             $this->dispatch('toast', type: 'success', message: __('Fulfillment marked as delivered'));
         } catch (InvalidFulfillmentOperationException $exception) {
             throw ValidationException::withMessages([
diff --git a/resources/views/livewire/admin/orders/show.blade.php b/resources/views/livewire/admin/orders/show.blade.php
index 90bcc3fc..53d8918c 100644
--- a/resources/views/livewire/admin/orders/show.blade.php
+++ b/resources/views/livewire/admin/orders/show.blade.php
@@ -13,14 +13,14 @@

             @if ($order->payment_method === \App\Enums\PaymentMethod::BankTransfer && $order->financial_status === \App\Enums\FinancialStatus::Pending)
-                <flux:button wire:click="confirmBankTransferPayment" variant="primary" icon="banknotes">
+                <flux:button wire:click="confirmBankTransferPayment" variant="primary" icon="banknotes" data-test="confirm-payment-button">
                     Confirm payment
                 </flux:button>
             @endif

-            @if ($refundableAmount > 0)
+            @if (in_array($order->financial_status, [\App\Enums\FinancialStatus::Paid, \App\Enums\FinancialStatus::PartiallyRefunded], true) && $refundableAmount > 0)
                 <flux:modal.trigger name="refund-order">
-                    <flux:button variant="danger" icon="receipt-refund">
+                    <flux:button variant="danger" icon="receipt-refund" data-test="refund-modal-button">
                         Refund
                     </flux:button>
                 </flux:modal.trigger>
@@ -28,7 +28,7 @@

             @if (in_array($order->financial_status, [\App\Enums\FinancialStatus::Paid, \App\Enums\FinancialStatus::PartiallyRefunded], true) && collect($remainingFulfillmentQuantities)->sum() > 0)
                 <flux:modal.trigger name="fulfillment-order">
-                    <flux:button variant="filled" icon="truck">
+                    <flux:button variant="filled" icon="truck" data-test="fulfillment-modal-button">
                         Create fulfillment
                     </flux:button>
                 </flux:modal.trigger>
@@ -36,6 +36,10 @@

+    @if ($actionMessage !== '')
+        <flux:callout color="green" icon="check-circle" data-test="order-action-message">{{ $actionMessage }}</flux:callout>
+    @endif
+
     @error('orderAction')

             {{ $message }}
@@ -48,6 +52,12 @@

     @enderror

+    @if (! in_array($order->financial_status, [\App\Enums\FinancialStatus::Paid, \App\Enums\FinancialStatus::PartiallyRefunded], true) && collect($remainingFulfillmentQuantities)->sum() > 0)
+        <flux:callout color="amber" icon="exclamation-triangle" data-test="fulfillment-guard-message">
+            Cannot create fulfillment. Payment must be confirmed before items can be fulfilled. Current financial status: {{ Str::headline($order->financial_status->value) }}.
+        </flux:callout>
+    @endif
+

Order

@@ -119,6 +129,53 @@

+

+

+                    <flux:heading size="lg">Timeline</flux:heading>
+

+

+

+

+

+
Order placed

+
{{ $order->placed_at?->format('M j, Y H:i') }}

+

+

+
+                    @foreach ($order->payments as $payment)
+
getKey() }}">
+

+

+

+                                    {{ $payment->status === \App\Enums\PaymentStatus::Captured ? 'Payment received' : Str::headline($payment->status->value) }}
+

+
{{ Str::headline($payment->method->value) }} · {{ \App\Support\Money::format($payment->amount, $payment->currency) }}

+

+

+                    @endforeach
+
+                    @foreach ($order->fulfillments as $fulfillment)
+
getKey() }}">
+

+

+
Fulfillment created

+
{{ Str::headline($fulfillment->status->value) }}

+

+

+                    @endforeach
+
+                    @foreach ($order->refunds as $refund)
+
getKey() }}">
+

+

+
Refunded

+
{{ \App\Support\Money::format($refund->amount, $order->currency) }} · {{ Str::headline($refund->status->value) }}

+

+

+                    @endforeach
+

+

+

                     <flux:heading size="lg">Fulfillments</flux:heading>
@@ -135,10 +192,10 @@

                                     @if ($fulfillment->status === \App\Enums\FulfillmentShipmentStatus::Pending)
-                                        <flux:button wire:click="markFulfillmentShipped({{ $fulfillment->getKey() }})" size="sm" variant="filled">Mark shipped</flux:button>
+                                        <flux:button wire:click="markFulfillmentShipped({{ $fulfillment->getKey() }})" size="sm" variant="filled" data-test="mark-fulfillment-shipped-button">Mark as shipped</flux:button>
                                     @endif
                                     @if ($fulfillment->status === \App\Enums\FulfillmentShipmentStatus::Shipped)
-                                        <flux:button wire:click="markFulfillmentDelivered({{ $fulfillment->getKey() }})" size="sm" variant="filled">Mark delivered</flux:button>
+                                        <flux:button wire:click="markFulfillmentDelivered({{ $fulfillment->getKey() }})" size="sm" variant="filled" data-test="mark-fulfillment-delivered-button">Mark as delivered</flux:button>
                                     @endif

@@ -231,7 +288,7 @@
                 <flux:modal.close>
                     <flux:button variant="filled">Cancel</flux:button>
                 </flux:modal.close>
-                <flux:button type="submit" variant="danger">Process refund</flux:button>
+                <flux:button type="submit" variant="danger" data-test="refund-submit-button">Process refund</flux:button>

         </form>
     </flux:modal>
@@ -271,7 +328,7 @@
                 <flux:modal.close>
                     <flux:button variant="filled">Cancel</flux:button>
                 </flux:modal.close>
-                <flux:button type="submit" variant="primary">Create fulfillment</flux:button>
+                <flux:button type="submit" variant="primary" data-test="fulfillment-submit-button">Create fulfillment</flux:button>

         </form>
     </flux:modal>
diff --git a/specs/progress.md b/specs/progress.md
index 9150b1de..e27b2d18 100644
--- a/specs/progress.md
+++ b/specs/progress.md
@@ -33,7 +33,7 @@ ## Acceptance Checklist
 | Business logic | `specs/05-BUSINESS-LOGIC.md` | partial | `ResolveStore`, `BelongsToStore`, `StoreScope`, role checks, customer guard provider, store-scoped `CustomerPasswordResetService`, catalog product lifecycle transitions, SKU uniqueness, variant matrix rebuilding, inventory reserve/release/commit/restock, automatic variant inventory, variant option mapping, media resize/cleanup job, `SearchService` with per-store synonym expansion and stop-word removal, product observer FTS sync, search query logging, search API rate limiting, `AnalyticsService`, analytics event deduplication, daily analytics aggregation, scheduled `AggregateAnalytics`, analytics API rate limiting, `WebhookService`, timestamped HMAC signing/verification, database-queued `DeliverWebhook`, delivery logging/retry backoff metadata, webhook circuit breaker pausing, domain-event webhook dispatch listener, developer token generation backed by `oauth_tokens`, `OrderExportService`, `CartService`, `DiscountService` including one-per-customer code discount redemption checks and automatic/code order-line attribution, `ShippingCalculator`, `TaxCalculator`, `PricingEngine`, checkout transitions through completion, checkout expiration, abandoned cart cleanup, session cart lookup, cart discount handoff to checkout, customer login cart merge, product add-to-cart mutations, storefront cart stock-limit feedback for deny-policy inventory, `PaymentService`, mock PSP, idempotent order creation, checkout UI/API order submission, session/customer/token-gated order confirmation and lookup, customer order-history scoping, customer address book management, customer logout session invalidation, admin dashboard order aggregates, admin analytics reporting, admin customer address management, admin discount rule management, admin content/theme/navigation/settings/search/apps/developers orchestration, admin order UI/API action orchestration, `RefundService`, `FulfillmentService`, bank-transfer payment confirmation, and unpaid bank-transfer cancellation are implemented. |
 | Auth/security | `specs/06-AUTH-AND-SECURITY.md` | partial | Admin Livewire login/logout/reset, customer guard/provider, customer login/register/logout, customer password reset GET/POST routes at `/forgot-password` and `/reset-password/{token}` with store-scoped hashed tokens, reset-link throttling, generic reset responses, login rate limiting, session hardening, concrete resource policies, encrypted app client/webhook secrets, one-time display developer token generation, and a compatible hashed bearer-token admin API middleware with store/ability enforcement are implemented. |
 | Seed/test data | `specs/07-SEEDERS-AND-TEST-DATA.md` | partial | Seeders create Acme Fashion and Acme Electronics stores/domains/settings/admin access with checkout and notification defaults, 2 apps, 4 app installations, 4 OAuth clients, 4 OAuth tokens, 8 webhook subscriptions, 2 search settings rows, 25 indexed products, 60 analytics_daily rows, 210 analytics_events rows, 6 collections, 127 variants, 127 inventory rows, 206 variant option pivots, 2 themes, 6 theme files with local disk contents and metadata, 2 theme settings rows, 6 pages, 4 navigation menus, 21 navigation items including 6 child items, 2 tax settings rows, 2 shipping zones, 6 shipping rates, 6 discounts, the seeded customer, 1 default seeded customer address, and no product media/runtime carts. Order/payment seed data is still missing. |
-| Browser E2E plan | `specs/08-PLAYWRIGHT-E2E-PLAN.md` | partial | Manual Playwright MCP smoke coverage has verified storefront catalog browsing on `shop.test` and `acme-fashion.test`, product detail, add-to-cart, cart drawer/page, checkout through order completion, order confirmation, customer order list/detail, SQLite-backed search and search API JSON, analytics event ingestion API, DB-backed content pages, seeded nested navigation dropdowns, admin dashboard on desktop/mobile, admin analytics, admin app list/detail, admin developers token/webhook flows, admin product/collection/inventory/order/customer/discount/content/navigation/settings/theme/search pages, admin checkout/notification settings pages, admin product media section rendering, admin analytics CSV export, admin customer address creation, admin discount creation/editing/filtering, admin page creation, admin nested navigation rendering/item creation/save, admin theme editor preview, admin theme file list/editor, admin search reindexing, admin fulfillment creation/shipping/delivery, and auth flows without console warnings/errors on successful pages. Automated Pest browser coverage now checks storefront core pages, storefront account auth/reset pages including the customer root reset paths and account aliases, authenticated admin navigation/pages/settings/theme/search/apps/developers surfaces, Suite 2 admin authentication login/validation/redirect/logout/sidebar navigation interactions, Suite 3 admin product listing/create/edit/archive/search/status-filter/draft visibility interactions, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account registration/login/orders/addresses/logout, Suite 11 inventory policy enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile flows, Suite 14 accessibility checks, and mobile storefront rendering for JavaScript errors. The remaining Spec 08 interaction/permutation browser suites are still incomplete. |
+| Browser E2E plan | `specs/08-PLAYWRIGHT-E2E-PLAN.md` | partial | Manual Playwright MCP smoke coverage has verified storefront catalog browsing on `shop.test` and `acme-fashion.test`, product detail, add-to-cart, cart drawer/page, checkout through order completion, order confirmation, customer order list/detail, SQLite-backed search and search API JSON, analytics event ingestion API, DB-backed content pages, seeded nested navigation dropdowns, admin dashboard on desktop/mobile, admin analytics, admin app list/detail, admin developers token/webhook flows, admin product/collection/inventory/order/customer/discount/content/navigation/settings/theme/search pages, admin checkout/notification settings pages, admin product media section rendering, admin analytics CSV export, admin customer address creation, admin discount creation/editing/filtering, admin page creation, admin nested navigation rendering/item creation/save, admin theme editor preview, admin theme file list/editor, admin search reindexing, admin fulfillment creation/shipping/delivery, and auth flows without console warnings/errors on successful pages. Automated Pest browser coverage now checks storefront core pages, storefront account auth/reset pages including the customer root reset paths and account aliases, authenticated admin navigation/pages/settings/theme/search/apps/developers surfaces, Suite 2 admin authentication login/validation/redirect/logout/sidebar navigation interactions, Suite 3 admin product listing/create/edit/archive/search/status-filter/draft visibility interactions, Suite 4 admin order listing/filtering/detail/timeline/fulfillment/refund/bank-payment/guard/shipment interactions, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account registration/login/orders/addresses/logout, Suite 11 inventory policy enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile flows, Suite 14 accessibility checks, and mobile storefront rendering for JavaScript errors. The remaining Spec 08 interaction/permutation browser suites are still incomplete. |
 | Roadmap phases | `specs/09-IMPLEMENTATION-ROADMAP.md` | in progress | Phase 1 foundation, Phase 2 catalog data/UI, Phase 3 theme/content/navigation data with storefront consumption, Phase 4 cart/checkout/pricing backend foundation, Phase 4 storefront cart/checkout UI through `payment_selected`, the Phase 4 cart/checkout REST API surface, cart-page estimates, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, Phase 5 storefront order completion/customer order surfaces, Phase 5 admin order management, Phase 5 order API surfaces, Phase 6 admin dashboard/customer/discount/content/settings/theme/navigation management, Phase 7 search, Phase 7 analytics, and Phase 7 apps/webhooks are implemented. Final verification and completion audit are next. |

 ## Verification Evidence
@@ -493,6 +493,15 @@ ## Verification Evidence
 - 2026-05-04: `php artisan test --compact tests/Browser/Admin/ProductManagementTest.php` passed for the new Suite 3 admin product-management browser coverage: 7 tests, 98 assertions.
 - 2026-05-04: `php artisan test --compact tests/Browser` passed after adding Suite 3: 101 tests, 630 assertions.
 - 2026-05-04: `php -d memory_limit=512M vendor/bin/pest --compact` passed the full suite after Suite 3: 350 tests, 2069 assertions.
+- 2026-05-04: `mcp__laravel_boost__.search_docs` consulted Pest browser testing, Livewire modal/form/action docs, Flux modal/button/callout docs, Laravel factories/session testing docs, and project order feature tests before adding the Spec 08 admin order-management browser suite.
+- 2026-05-04: `php artisan make:test --pest Browser/Admin/OrderManagementTest --no-interaction` created the Suite 4 order-management browser test, which was moved into the Spec 08 browser directory structure.
+- 2026-05-04: `vendor/bin/pint --dirty --format agent` passed after adding Suite 4 and the order-detail UI action messages/timeline/fulfillment guard.
+- 2026-05-04: `php artisan test --compact tests/Browser/Admin/OrderManagementTest.php` passed for the new Suite 4 admin order-management browser coverage: 11 tests, 146 assertions.
+- 2026-05-04: `php artisan test --compact tests/Feature/Admin/OrderManagementTest.php tests/Feature/Orders` passed after the order-detail UI changes: 22 tests, 120 assertions.
+- 2026-05-04: `php artisan test --compact tests/Browser/Admin/OrderManagementTest.php tests/Browser/Admin/ProductManagementTest.php` passed after hardening authenticated admin browser entry points: 18 tests, 190 assertions.
+- 2026-05-04: `npm run build` passed after the order-detail Blade changes.
+- 2026-05-04: `php artisan test --compact tests/Browser` passed after adding Suite 4: 112 tests, 722 assertions.
+- 2026-05-04: `php -d memory_limit=512M vendor/bin/pest --compact` passed the full suite after Suite 4: 361 tests, 2161 assertions.

 ## Decisions

@@ -562,8 +571,10 @@ ## Decisions
 - Product media uploads use Livewire temporary file uploads on the existing product form, create `ProductMedia` rows in `processing` status, and dispatch the existing `ProcessMediaUpload` job instead of adding a second media-processing path.
 - Resource policies now type concrete model parameters for Product, Collection, Customer, Discount, Order, Fulfillment, Refund, Page, and Theme actions; `ChecksStoreRole::storeIdForModel()` stays generic because it is the shared store-id extraction helper.
 - Laravel's SQLite `enum()` migrations generate database `CHECK` clauses in this app; `DatabaseConstraintTest` locks representative constraints across tenancy, roles, catalog, orders, tax settings, and exports.
-- Automated browser coverage now combines smoke coverage with Suite 2 admin-auth interactions, Suite 3 admin product-management interactions, Suite 7 storefront browsing interactions, Suite 8 cart-flow interactions, Suite 9 checkout-flow interactions, Suite 10 customer-account interactions, Suite 11 inventory-policy interactions, Suite 12 tenant-isolation interactions, Suite 13 responsive/mobile interactions, and Suite 14 accessibility interactions: storefront catalog/content/search/cart, storefront account auth/reset pages, the full authenticated admin navigation surface, admin login validation, protected-route redirects, logout, sidebar navigation, admin product listing/create/edit/archive/search/status-filter/draft visibility guards, mobile storefront rendering, seeded collection/product/search/static page browsing, sale/compare-at pricing, draft-product storefront visibility guards, stock/backorder messaging, main-navigation clicks, add-to-cart, cart quantity updates/removal, multi-product carts, subtotal/total display, valid/invalid/expired/maxed/free-shipping/fixed discount code handling, domestic/international checkout shipping, checkout discount carryover, address validation, empty-cart checkout protection, credit-card/PayPal/bank-transfer order completion, payment decline handling, payment-method UI switching, customer registration validation, customer login validation, account auth redirects, customer order history/detail, address book create/update, customer logout, deny-policy sold-out blocking, continue-policy backorder add-to-cart, in-stock status display, deny-policy cart stock-limit feedback, storefront product/collection/search store isolation, admin product/order store isolation, customer account store isolation, mobile hamburger navigation, mobile product/cart/checkout flows, mobile collection filtering, tablet admin login/sidebar navigation, console-clean home/cart pages, heading hierarchy, form labels, product image placeholder accessible text, checkout error linkage, keyboard navigation, and search input labeling.
+- Automated browser coverage now combines smoke coverage with Suite 2 admin-auth interactions, Suite 3 admin product-management interactions, Suite 4 admin order-management interactions, Suite 7 storefront browsing interactions, Suite 8 cart-flow interactions, Suite 9 checkout-flow interactions, Suite 10 customer-account interactions, Suite 11 inventory-policy interactions, Suite 12 tenant-isolation interactions, Suite 13 responsive/mobile interactions, and Suite 14 accessibility interactions: storefront catalog/content/search/cart, storefront account auth/reset pages, the full authenticated admin navigation surface, admin login validation, protected-route redirects, logout, sidebar navigation, admin product listing/create/edit/archive/search/status-filter/draft visibility guards, admin order listing/filtering/detail/timeline/customer info, fulfillment creation, refund processing, bank-transfer payment confirmation, unpaid fulfillment guard, shipped/delivered fulfillment transitions, mobile storefront rendering, seeded collection/product/search/static page browsing, sale/compare-at pricing, draft-product storefront visibility guards, stock/backorder messaging, main-navigation clicks, add-to-cart, cart quantity updates/removal, multi-product carts, subtotal/total display, valid/invalid/expired/maxed/free-shipping/fixed discount code handling, domestic/international checkout shipping, checkout discount carryover, address validation, empty-cart checkout protection, credit-card/PayPal/bank-transfer order completion, payment decline handling, payment-method UI switching, customer registration validation, customer login validation, account auth redirects, customer order history/detail, address book create/update, customer logout, deny-policy sold-out blocking, continue-policy backorder add-to-cart, in-stock status display, deny-policy cart stock-limit feedback, storefront product/collection/search store isolation, admin product/order store isolation, customer account store isolation, mobile hamburger navigation, mobile product/cart/checkout flows, mobile collection filtering, tablet admin login/sidebar navigation, console-clean home/cart pages, heading hierarchy, form labels, product image placeholder accessible text, checkout error linkage, keyboard navigation, and search input labeling.
 - The admin product-management browser suite uses Laravel `actingAs()` and `withSession()` to create deterministic authenticated browser visits; the separate Suite 2 admin-auth suite owns login-form coverage so persisted browser cookies from earlier tests cannot leak into product CRUD assertions.
+- The admin order-management browser suite creates deterministic per-test `#1001`, `#1002`, and `#1005` order fixtures because order/payment seed data is still deferred; the browser suite covers the spec interactions without changing the global seed contract.
+- Admin order detail now shows visible action feedback, a simple event timeline, and an explicit unpaid-fulfillment guard. Refund and fulfillment buttons are only exposed when the current financial/fulfillment state allows the backing service action.
 - Pest's per-visit browser `host` option is temporary, so host-sensitive storefront browser tests set the Playwright host for the whole test lifecycle to keep clicked absolute URLs resolving through `shop.test`.
 - The discount seeder now includes the Spec 07/08 codes `WELCOME10`, `FLAT5`, `FREESHIP`, `EXPIRED20`, and `MAXED` while preserving the earlier implementation/test fixture codes `SAVE10` and `5OFF`.
 - Expired discount codes return an expired validation message before the generic non-active status message so storefront/cart validation can present the expected customer-facing error.
@@ -576,9 +587,9 @@ ## Decisions

 ## Open Issues

-- Full automated browser interaction/permutation suites from Spec 08 are still incomplete beyond the expanded Pest browser smoke coverage, Suite 2 admin authentication, Suite 3 admin product management, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account flow, Suite 11 inventory enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile, and Suite 14 accessibility.
+- Full automated browser interaction/permutation suites from Spec 08 are still incomplete beyond the expanded Pest browser smoke coverage, Suite 2 admin authentication, Suite 3 admin product management, Suite 4 admin order management, Suite 7 storefront browsing, Suite 8 cart flow, Suite 9 checkout flow, Suite 10 customer account flow, Suite 11 inventory enforcement, Suite 12 tenant isolation, Suite 13 responsive/mobile, and Suite 14 accessibility.
 - The full suite now needs a higher PHP memory limit when all browser suites run in one process; the default `php artisan test --compact` command hits 128 MB in Pest's browser WebSocket client, while `php -d memory_limit=512M vendor/bin/pest --compact` passes.

 ## Completion Summary

-Not complete. Phase 1 foundation, Phase 2 catalog data/UI surfaces, product media processing/admin upload controls, Phase 3 storefront theme/content/navigation data, the Phase 4 cart/checkout/pricing backend foundation, cart/checkout storefront UI through order completion, cart-page estimates, cart/checkout REST APIs, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, customer account order/address/logout views, admin dashboard/order/customer/discount/content/settings/theme-file/navigation/search/analytics/apps/developers management, storefront search and analytics APIs, product/customer/collection/discount/content page/store settings/search/analytics/shipping/tax/theme/order/export API surfaces, deferred OAuth/app route stubs, expanded automated browser smoke coverage, Suite 2 admin authentication browser coverage, Suite 3 admin product-management browser coverage, Suite 7 storefront browsing browser coverage, Suite 8 cart-flow browser coverage, Suite 9 checkout-flow browser coverage, Suite 10 customer-account browser coverage, Suite 11 inventory-enforcement browser coverage, Suite 12 tenant-isolation browser coverage, Suite 13 responsive/mobile browser coverage, Suite 14 accessibility browser coverage, outbound webhook delivery foundations, spec-root customer password reset routes, and representative database CHECK constraint coverage are implemented, with the remaining full browser-suite gap tracked above.
+Not complete. Phase 1 foundation, Phase 2 catalog data/UI surfaces, product media processing/admin upload controls, Phase 3 storefront theme/content/navigation data, the Phase 4 cart/checkout/pricing backend foundation, cart/checkout storefront UI through order completion, cart-page estimates, cart/checkout REST APIs, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, customer account order/address/logout views, admin dashboard/order/customer/discount/content/settings/theme-file/navigation/search/analytics/apps/developers management, storefront search and analytics APIs, product/customer/collection/discount/content page/store settings/search/analytics/shipping/tax/theme/order/export API surfaces, deferred OAuth/app route stubs, expanded automated browser smoke coverage, Suite 2 admin authentication browser coverage, Suite 3 admin product-management browser coverage, Suite 4 admin order-management browser coverage, Suite 7 storefront browsing browser coverage, Suite 8 cart-flow browser coverage, Suite 9 checkout-flow browser coverage, Suite 10 customer-account browser coverage, Suite 11 inventory-enforcement browser coverage, Suite 12 tenant-isolation browser coverage, Suite 13 responsive/mobile browser coverage, Suite 14 accessibility browser coverage, outbound webhook delivery foundations, spec-root customer password reset routes, and representative database CHECK constraint coverage are implemented, with the remaining full browser-suite gap tracked above.
diff --git a/tests/Browser/Admin/ProductManagementTest.php b/tests/Browser/Admin/ProductManagementTest.php
index 1a9a726f..88207e07 100644
--- a/tests/Browser/Admin/ProductManagementTest.php
+++ b/tests/Browser/Admin/ProductManagementTest.php
@@ -23,25 +23,20 @@ function adminProductHost(): array
     return ['host' => 'shop.test'];
 }

-function adminProductLogin(mixed $testCase): mixed
+function adminProductAuthenticate(mixed $testCase): void
 {
     $store = Store::query()->where('handle', 'acme-fashion')->firstOrFail();
     $user = User::query()->where('email', 'admin@acme.test')->firstOrFail();

     $testCase->actingAs($user);
     $testCase->withSession(['current_store_id' => $store->getKey()]);
-
-    return visit('/admin', adminProductHost())
-        ->wait(1)
-        ->assertPathIs('/admin')
-        ->assertSee('Dashboard')
-        ->assertNoJavaScriptErrors();
 }

 function adminProductOpenProducts(mixed $testCase): mixed
 {
-    return adminProductLogin($testCase)
-        ->click('a[href$="/admin/products"]')
+    adminProductAuthenticate($testCase);
+
+    return visit('/admin/products', adminProductHost())
         ->wait(1)
         ->assertPathIs('/admin/products')
         ->assertSee('Products')