# ORDERS · flagship round 1 · Orders index + Order detail · brand-006 RJ Laravel Admin

**Sheet:** https://orders.pina-brand-006-rj-laravel-admin.pages.dev/ · **artboards:** /canvas/ (2 pages: Orders index · Order detail) · **one image:** /contact-sheet.png
**Status:** round 1 for Frank's review, 2026-10-18. Design only; no code, no ledger.
**Boards:** 31 = 1 summary + 11 index + 19 detail. Each board = burned-in label chip + the screen at 1440×900 in the locked 4b·R shell + an annotation panel (decisions, sources, tags).
**Source:** `src/o_data.py` (fixtures, every vocabulary item cited) · `src/o_pages.py` (screens) · `src/o_build.py` (composites, shots, sheet, canvas, dist) · `src/orders.css`. Shell = `phase-2/archetypes/src/arch_pages.py` (Find order · Jobs button with right-aligned list · bell · globe-only locale · clickable clock).

## Truth rules applied on every board

- **Order numbers are bare 4-digit ids** (`4521`), pieces `4521-1`, garment groups `4521-1-2` — `Order::getFormattedIdAttribute()`, `ProductNumberService` (TRUTH §1). Ids sit in the live range (prod max ≈ 4528).
- **Only the 11 real statuses** with their real labels and colours (`OrderStatus::getStatusList()`, TRUTH §2). No Quality check / Shipped / Cancelled / Confirmed / Paid.
- **Production steps are `ProcessList` titles** (`PRODUCTION IN-PROGRESS | 0.2` …), piece phases use the real gantt colours (TRUTH §5).
- **Factories are short codes** FX · FRR · F3.5 · FPS (the live ones), hand finishing shown as `HF: F3.5`; no location anywhere (TRUTH §5, `factories`, `order_assigned_hand_finish_factories`).
- **Product types** = the real main products (2-Piece, Shirt, 3-Piece, Trousers, Blazer …) and piece label codes (JA, TR, WC, SH, OC, CH, TC, CDY, SHO, POL, GV, BJA, DTR, OS) (TRUTH §3.1, `products.label`).
- **No Hold button.** Hold lives in Raise Issue → "Put Order On Hold" (TRUTH §4.3). The new API's `POST /orders/{order}/hold` is shown once, in ⋯, tagged *proposal (API exists)*.
- **Void only where allowed** (draft · awaiting payment · RFF, index row today); on the detail page it is a tagged proposal only.
- **People are placeholders** (initial + surname); retailers are fictional; dotted underline = example value. No staging screenshot is published.
- Tags: purple dashed = **proposal**, amber dashed = **needs backend**, blue = **API only** (backed by the new API, not on the web page today).

## ORDERS INDEX — decisions

| # | Decision | Real element · source |
|---|---|---|
| I1 | **Default tab set:** Active (= RFF + Build + Manufacturing + On Hold) · Ready For Fulfilment · Build · Manufacturing · Outbound · On Hold (count shown at 0) · More ▾ | TRUTH §2 "Recommended default tab set"; Active = `custom` alias, `getOverviewStatuses()` `OrderStatus.php:233` |
| I2 | **Customise tabs:** all 14 tabs that exist (11 statuses + Active + All + Paid Shipping) with counts; tick = on the bar, drag to reorder, rest under More ▾; "New stacked tab" keeps the old "+" corner | status catalogue `GET /admin/orders/status-catalogue`; multi-status `index.blade.php:697-735` · storage **needs backend H01** |
| I3 | **Saved views** = tabs + filters + columns + density; My views (one default) + Shared with the team; dirty dot → Update / Save as new; filters also live in the URL | POWERUPS #05/#06 · personal = **H01** (`GET/PUT /admin/me/prefs/{key}`); shared = **new team-views store** (not yet in BACKEND-HELPERS) |
| I4 | **Columns:** Order # (+ `R` returning, `Plus Size re-check`) · Customer · Retailer pill · **Product type** (new) · Pieces (piece codes coloured by each piece's phase) · Status (176 px — "Ready For Fulfilment" never truncates; + ✓ Accepted / ● Pending on completed/delivered) · Factory (+ HF line) · Express (Urgent) · next step + ⋯ | `index.blade.php:824-1180`, TRUTH §3.1 |
| I5 | **Meas. dropped** — it equals the piece count on 4,309 of 4,314 orders; shown struck-through in the column chooser with the reason | `OrderResource.php:69`, TRUTH §3.1 |
| I6 | **Column chooser** offers real API fields the old page never showed: Status changed, Created, Paid, In production since | `GET /admin/orders` row fields |
| I7 | **Filters:** one search box (order number or customer name, `/`), Brand, Returning only, Plus Size re-check; Build / Manufacturing sub-filters (Order Bill · Fabric Purchase / Assembly · In-Production) | TRUTH §3.2; `getFilterViewsForStatus()` |
| I8 | **Search pauses the tabs** and searches every status (the API refuses status + customer together) — the filtered-empty board says so | TRUTH §3.2 |
| I9 | **Sort stays order # ↓** (fixed today); no sortable headers drawn | TRUTH §3.3 |
| I10 | **Row: one inline next step** where the row moves on — Assembly (RFF) · Build (Build) · Resolve (On Hold) · Completed (Outbound); everything else in ⋯ with the real per-row list (View, Edit, Measurement, Cloud Print, Print ▸ Markup/Order/QC Tags/Shirt Code/All, Cloud Order, Photos, Raise Ticket, Void only draft/awaiting payment/RFF) | `index.blade.php:995-1157`, TRUTH §3.4 |
| I11 | **Bulk = the real ones:** Print bar (Markup · Order · QC Tags · Shirt Tags · Buying Sheet · Single Buying Sheet) + **Complete only on the Delivered tab** + Data Export. "Select all 2,131 matching → batches of 100 → Stop after this batch" is a **proposal** on the same `POST orders/completed` endpoint (T003 #13 frontend batches ≤ 100) | `index.blade.php:839-869`, TRUTH §3.5 |
| I12 | **Peek sheet** (Space / click; ↑↓ walks the list; ↵ opens): facts, garments by group with the grouped label, each piece's current ProcessList step + due date, factory per group, latest note, open ticket; actions = Cloud print ▾ + Raise issue (no Hold) | `GET /admin/orders/{order}` + `/phase-summary` |
| I13 | **Empty states:** On Hold at 0 (true today) explains where holds come from; filtered-empty explains the search scope | live count MCP 2026-10-18; 101 holds in `order_status`, last 24 Sep |
| I14 | **Phone /m/orders** is its own layout: Find (one big field, results as you type, recently opened) · Queue (status chips, cards) · Peek bottom sheet with Cloud print / Open order. Assembly validation stays desktop | STACK-AND-PACKAGES §2, EVIDENCE §7 |
| I15 | **Counts:** RFF / Build / Manufacturing / On Hold on the boards are a normal working morning (dotted); every other count is the live prod count of 18 Oct (plain) | MCP `find_orders` 2026-10-18 |

**How you'd use it (board O11):** 1 Morning triage view → RFF rows' inline Assembly · 2 Build rows (Bills Printed + Fabric Ordered; Cloud Order ticks it) · 3 On Hold → ⋯ Resolve hold / open its ticket · 4 `/` or ⌘K → type 4521 → ↵ · 5 Space to peek, ↑↓ to walk · 6 More ▾ → Delivered → tick → Complete; Data Export for the CSV (runs in the Jobs list).

## ORDER DETAIL — decisions

### The action model (one line)
**One dark next-step button by status (Edit · Assembly ▾ · Build ▾ · Resolve hold) + a Cloud print ▾ split (Cloud: Order bill / Shirt code · Open PDF: Mark-Up / Order / Shirt Tag / QC Tag) + Edit + Raise issue (holds live here) + ⋯ grouped by intent (Send · Check · Express · proposals). 4–5 controls instead of 8–10.**

| Slot | Content | Status rule (TRUTH §4.1) |
|---|---|---|
| 1 · next step (dark) | Edit (draft · awaiting payment · awaiting fit) · **Assembly ▾** = Fabric / Fit / Designs Validated + factory (RFF) · **Build ▾** = Bills Printed / Fabric Ordered + Cloud Order + Re-sync Cloud Build when stuck (Build) · **Resolve hold** (On Hold, *proposal*: index row today, API `remove-hold`) · none after Manufacturing | #9–#15 |
| 2 · Cloud print ▾ | click = cloud print dialog (job type Order bill / Shirt code → groups); ▾ = Cloud + Open PDF (Mark-Up, Order, Shirt Tag, QC Tag) + link to Order print jobs. Becomes the dark button when there is no next step | #2–#6, `print orders` |
| 3 · Edit | status ≠ voided | #9 |
| 4 · Raise issue | always; carries "Put Order On Hold" (offered for RFF / Build / Manufacturing) | #1 |
| 5 · ⋯ | Send: Cloud Order · Check: QC photos (Manufacturing → Delivered) · Express: FitQ Transform / Undo · Status *proposals*: Put on hold without a ticket (API exists), Void (draft/awaiting payment/RFF) | #7, #8, #16 |
| in tabs | Settle (Pricing) · Add / edit note (Notes) · Copy All / Copy All + Supplier (Production) · + Add photo (Photos) · Recalled from #id (Overview + side) | in-body #17–#21 |

The full status × action matrix is board **D03** (21 real actions + 4 proposals × 11 statuses).

### Header, tabs, side panel (A02·a)
| # | Decision | Real element · source |
|---|---|---|
| D1 | Header: `Order #4521` (real title) · status pill · `Returning` badge (+ account-type badge Express / Express Pro when the retailer has one) · sub-line "created · customer · id" | `_header.blade.php`, TRUTH §4.2; `users.account_type` express_pro / express_lite |
| D2 | Front matter: Retailer (+ id, settlement currency) · Customer (**name + city only**) · Created · Paid · In production since · Status changed | `OrderResource.php:8-30` (PII withheld) |
| D3 | **10 tabs**, one sub-resource each: Overview · Garments · Designs · Measurements · Production · Pricing · Notes · Photos · Issues · Activity (today: 5 tabs Summary · Measurements · Designs · Production · Customer) | `show.blade.php:27-33` + the 70 `/admin/orders…` API paths |
| D4 | Side panel: Factories by piece (codes only) · FABRIC OVERDUE (supplier alerted Xh ago) · Cloud print state per group · Order journey (Original → Recalled from → this) · Open issues · Delivery acceptance on completed/delivered | `_header` cards; `cloud-print/groups`; `ancestry`; `fabric_overdue_alerts` |
| D5 | Overview: where each piece is (ProcessList step, progress, due), order summary totals + DR owed, latest note, special handling | `phase-summary`, `_summary`, `_pricing` |
| D6 | Garments: the real Order Summary table (#ID · Garment · Fabric Collection · Fabric Code · Factory · Size · Cost · Retail, add-ons under each piece, Sub Total · Payment Method Charge · TOTAL) + the piece's phase | `_summary.blade.php`; `combinations` |
| D7 | Designs: per piece `▼ 4521-1 · Jacket · fabric · collection` + Extra Meterage (cm) + design → choice. Design and option names are the real catalogue | `_designs`; prod `designs` (products 1/2/4) |
| D8 | Measurements: real labels/order (`$upper_parts`, `$lower_parts`), one column per piece with source label (Recalled / Manual …), **gold** = changed from carried-over value, Fitting Validation Audit | `measurements-table.blade.php`, `_measurements.blade.php:8`, `fitting-validation-logs` |
| D9 | Production: ProcessList steps per piece · Order Design Components · Buying Sheet with Copy All / Copy All + Supplier · Send phase summary 3.2 / HF slip 3.5.2 (**API only**) | `ProcessList.php`; `_designcomponents`, `_buyingsheet`; `phase-summary/cloud-export`, `hand-finishing/cloud-export` |
| D10 | Pricing: real Order Pricing History columns, **Settle** only on a settleable row; tab shows "DR" while money is owed | `_pricing.blade.php:29-34`; `GET /orders/{order}/pricing` (`settleable`, `direction`) |
| D11 | Notes: indexed notes (index + text only — the notes API keeps no author or time) + Add Note / Edit; Special Handling Notes read-only (Owner · Code `SP-0001` · Audience · Instruction) | `notes`, `special-handling` |
| D12 | Photos: Customer Photos (Photo 1–3 + Add photo ×3, as today) + QC photos by the 4 real checkpoints: Design p1.1 · Quality p2.1 · HF Design p3.5.4 · HF Quality p3.5.5 | `_photos`; `CheckpointTableRegistry.php:60-63` |
| D13 | Issues: tickets on the order with the real taxonomy, severities and statuses (+ colours); the hold round-trip and the ticket that caused it | prod `tickets_categories`, `tickets_severity`, `tickets_statuses` · order filter **needs backend** |
| D14 | Activity: status history (order_status — **needs backend** read) · payload audits · fitting validation log · print + agent jobs for the order | `payload-audits`, `fitting-validation-logs`, `print-jobs` |

### States
| Board | State | Real backing |
|---|---|---|
| D13 | Loading skeleton: order number paints at once (it is in the URL), the rest in its final shape; each tab fetches its own endpoint | POWERUPS #24 |
| D14 | Permission denied (support role): actions the role lacks are **absent** (no Cloud print, Edit, Settle); one banner names the missing permissions (`edit orders` · `print orders` · `settle_order_dr/cr_discrepancy orders`) | `GET /admin/me` permissions[]; TRUTH §4.1 perms |
| D15 | "Someone else changed this" on measurements: mock 409 text verbatim, yours amber / theirs bold, Compare · Reload theirs · Keep mine | T001 Q22; `PUT measurements` `expected_version` · **H03 verify on staging** |
| D16 | Raise Issue with **Put Order On Hold** on top; the real fields in the real order (Type Free / Premium disabled · Title · Category → Sub Category · Severity default High · Brand · Order ID · Sub-Order-ID · body with Record + templates · attachments); the submit reads "Raise Issue + hold order" | `_raiseissue_modal.blade.php:224-229`; `TicketsController@store:189-210`; prod ticket taxonomy |
| D17 | Cloud print dialog (Order bill / Shirt code → groups, printed groups unticked) + the shell Jobs list (right edge aligned to its button) walking queued → dispatching → accepted → printing → printed; a failed job points back to the order (Reprint exists only for DHL-label jobs) | `cloud-print`, `cloud-print/groups`; dispatch/print enums TRUTH §7.1; T001 Q2 polling |
| D18 | Settle ladder: confirm · consequences (wallet, debit, balance before → after, surcharge switch) · type `4521`; safe to retry | `POST payment-settlement {include_payment_surcharge}` → `replayed`; T001 Q14 |
| D19 | Phone /m/orders/4521: facts → garments with current step → FABRIC OVERDUE → latest note; thumb bar Cloud print · Raise issue · ⋯; Print as a bottom sheet | STACK-AND-PACKAGES §2 |

## Open questions for Frank

1. **What does a click on the print button do?** 1a · opens the Cloud print dialog (drawn) · 1b · repeats the last print you used (cloud or PDF) · 1c · no default, the button only opens the menu.
2. **Resolve hold on the order page?** 2a · yes, as the dark next step when On Hold (API `remove-hold` exists) (drawn) · 2b · keep it on the index row only, as today.
3. **Saved views scope for v1?** 3a · personal + shared with the team (needs a new team-views store) · 3b · personal only (H01 only), shared later.
4. **Customer details?** 4a · no Customer tab; name + city in the front matter (the API withholds the rest) (drawn) · 4b · keep a Customer tab for super admins with the full bio (needs a PII-scoped endpoint).
5. **Tab set on the order page?** 5a · 10 tabs, one sub-resource each (drawn) · 5b · closer to today: Summary · Measurements · Designs · Production + Issues · Activity.
6. **Measurement-check values (body / pattern / factory / alterations)?** 6a · stay in the measurement-check popup, as today (drawn) · 6b · merge into the Measurements tab grid.
7. **Complete on Delivered across pages?** 7a · select all matching, sent in batches of 100 with Stop (proposal on the existing endpoint) · 7b · page only (≤ 100), as today.
8. **Put on hold without a ticket (API `POST hold`)?** 8a · offer it in ⋯ (drawn as proposal) · 8b · never — every hold keeps its ticket.
9. **Default view when you open Orders?** 9a · Active (drawn) · 9b · Ready For Fulfilment.
10. **Sort?** 10a · keep order # ↓ (drawn) · 10b · add "Status changed ↓" (the v2 API can seed it with `change_status_date`).
11. **Void on the order page?** 11a · add it to ⋯ for draft / awaiting payment / RFF with the typed ladder · 11b · keep it on the index row only (drawn).
12. **Product type column content?** 12a · main product per group, "2-Piece + Shirt" (drawn) · 12b · piece codes only (the Pieces column already has them).

## Could not verify

- Which permissions the live **support** role holds (D14 shows a role without edit/print/settle).
- That **DR** always means "debit the retailer wallet" on Settle (drawn that way; settlement endpoint says "settle a DR/CR discrepancy to the wallet").
- Real values of payload-audit `source` (examples drawn, dotted).
- Whether the web detail page will expose the phase-summary / hand-finishing **cloud-export** sends (API exists; tagged API only).
- A tickets **order filter** (only `has_order` and `search` exist) and an **order_status history read** (no endpoint) — both tagged needs backend.

## Archetype sheet patch (same round)

`phase-2/archetypes/src`: every 5-digit id remapped to bare 4-digit ids (`842NN` → `4492+NN`, 4505–4528; ticket/vision ids too), factories = FX · FRR · F3.5 · FPS, ProcessList phases, staff strip 4 days, agent-job types use the exact `CloudJob::TYPES` labels, dashboard overdue components grouped by supplier code, shell Jobs list = real job kinds. Redeployed to the `archetypes` branch.
