# PROPOSALS · brand-006 RJ Laravel Admin (consolidated, phase 3)

**Generated:** 2026-10-18 by `phase-3/waves/build_page_map.py` from `phase-3/waves/proposals_data.py`. Machine copy: [`PROPOSALS.json`](PROPOSALS.json).
**Rule (PL-065):** anything beyond today's admin is tagged **UI-only**, **needs-backend** or **needs-a-decision**, with a recommended default and its source. Deduped across the old `PROPOSALS.md`, `POWERUPS.md`, `ADVANCED.md` / `BACKEND-HELPERS.md`, `COMPONENT-INVENTORY.md` (P1/P2), `STACK-AND-PACKAGES.md`, `TRUTH-{ORDERS,TICKETS,PRICING,DESIGNS}.md`, `MENU-OPTIONS.md`, `GANTT-R1.md` and `ORDERS-R1.md`. Needs-backend items become `api-request` issues in `RJmtm/newadmin-api-kit` (HANDOFF §5); **none filed yet**. Do not design them as if they exist: draw the dashed amber ghost.

**Totals: 82** · UI-only **11** · needs-a-decision **22** · needs-backend **49**

## Decisions made (not proposals)

- **Frontend stack decided.** Next.js (App Router) + React 19 + TypeScript + shadcn/Radix + Tailwind tokens, same as the DTC admin. Frank 2026-10-18: "I have absolutely no problem with that stack whatsoever." *Source:* `phase-0/STACK-AND-PACKAGES.md §1`.
- **Dedicated mobile rule.** Every page with a phone answer gets its own /m/… route and view file; only the view layer forks; pages without a phone view fall back to /m/not-on-phone. Frank 2026-10-18. *Source:* `phase-0/STACK-AND-PACKAGES.md §2`.
- **Menu IA out of scope.** Menu regroup is a separate evidence-led exercise with backend (AdminMenu.php); design supports any depth ≤3 (T-d flyout, T-f breadcrumb dropdowns, accordion). Frank 2026-10-18. *Source:* `phase-1/menu-techniques/MENU-TECHNIQUES.md`.
- **Power-ups: all 24 round-1 patterns adopted.** Frank in chat 2026-10-18. Their three needs-backend items are PR-001 (saved views), PR-003 (activity panel) and PR-004 (conflict banner, now backed). *Source:* `phase-1/powerups/POWERUPS.md`.
- **DTC Midnight green shipped.** Recorded as shipped by the supervisor brief for this run (2026-10-18); no B6 design change follows from it. *Source:* `supervisor brief, phase-3 waves`.
- **Gantt pick deferred to the end.** A07 folds into A05 as its timeline variant; the gantt direction (PR-056) is picked at the end of the run. /admin/gantt points at phase-3/flagships/gantt/. *Source:* `phase-3/flagships/gantt/GANTT-R1.md`.
- **Archetypes approved for non-flagship pages; five flagships.** Orders index · Order detail · Support tickets · Pricing · Designs get bespoke rounds. A02·a and A11·a approved; A05 renamed 'Dashboard / report'. *Source:* `phase-2/FEEDBACK-B-r1.md`.
- **Every designs-module page is flagship.** Frank 2026-10-18: "everything with the designs we have to get perfect". All 25 designs-module pages are flagship:true and point at phase-3/flagships/designs/. Round 1 drew the 4 /admin/designs* pages (index, create, edit, Bulk Hub); the other 21 (combinations, component default rules, design blockers, design components, PT colours, PT components) are queued for designs round 2 and must not be built off the generic archetype hero. *Source:* `phase-3/flagships/designs/DESIGNS-R1.md`.
- **Layout picks.** A01·a full-width table · A02·a tabs · A03·a section nav left · A06·a table of runs · A11·a 3-pane. *Source:* `phase-2/archetypes/ARCHETYPES.md`.

## Decision defaults (P0)

Supervisor defaults applied during page-map classification (2026-10-18). Each is the recommended default; Frank can overturn at decision B.

- **A07 Timeline / gantt stays its own archetype, flagged as a fold candidate.** Reason: exactly 1 live page (`/admin/gantt`; `/admin/v1/gantt` is retired) and it is a distinct component. Recommended default: keep A07 separate. Candidate fold into A05 as a variant. Frank can overturn at decision B.
- **A10 renamed to "Preview / document / layout designer".** Reason: it covers email-template editors, the container thermal ticket and print-preview launchers; Print Studio's canvas stays light touch; printed PDFs are server-side per T001 Q26. Recommended default: new name. Frank can overturn at decision B.
- **`/admin/pricing/master`: override "propose retire, do not design".** Reason: the handler returns 403 and is retired in code (L1033/L1034). Recommended default: do not design, propose retiring the route. Frank can overturn at decision B.
- **`/admin/posts`, `/admin/watermark-text`, `/admin/reference/system-values`: override "no-design" (archetype kept).** Reason: `/admin/posts` returns 403 for everyone, `/admin/watermark-text` is a developer test page, `/admin/reference/system-values` is a redirect only. Recommended default: keep the row and archetype, spend no design effort. Frank can overturn at decision B.
- **Heroes per archetype (one per archetype, `hero:true`).** Reason: pick the busiest, highest-tier real page of each pattern. Recommended default: A01 `/admin/orders`, A02 `/admin/orders/{order}`, A03 `/admin/designs/{design}/edit`, A04 `/admin/designs/bulk-hub`, A05 `/admin/dashboard`, A06 `/admin/orders/print-jobs`, A07 `/admin/gantt`, A08 `/admin/vision-checks/results`, A09 `/admin/settings`, A10 `/admin/email-templates/{templateKey}/edit`, A11 `/admin/tickets/{ticket}`, A12 `/admin/pricing/create`. Three `example:true` rows per archetype (fewer where the archetype has fewer live pages: A07 and A11 have none, A08 has one); full lists in `phase-0/page-map/SUMMARY.json`. Frank can overturn at decision B.
- **Flag: A08 Media / photo review shrank to 2 live pages** (`/admin/vision-checks/results`, `/admin/media-library`). Reason: 15 of the 17 `/admin/photoMarket/*` pages were reclassified to A01 / A03 (list with drag-sort and active switch; media-picker form), not review-with-verdict. Recommended default: keep A08 for now because the vision-results verdict flow and the media library are distinct components; candidate fold into A01/A05 variants. Same for A11 (1 live page, `/admin/tickets/{ticket}`): recommended default keep, candidate fold into A02 as a variant. Frank can overturn at decision B.
- **Menu IA regroup — out of design scope per Frank 2026-10-18; separate evidence-led exercise with backend (AdminMenu.php); design supports any depth ≤3.** Mechanics reference: `phase-1/menu-techniques/MENU-TECHNIQUES.md`.

*Status after decision B (2026-10-18):* the A07 default is overturned (A07 folds into A05 as its timeline variant); the A08/A11 keep and hero defaults stand; A10's name stands; the four no-design rows stay no-design (PR-071, PR-079).

## needs-a-decision (22)

| id | proposal | recommended default | area · pages | helper | source |
|---|---|---|---|---|---|
| PR-002 | Shared team saved views (views shared with a team, not just personal) | 3b: personal views only in v1 (H01); shared team views later on a new team-views store. | orders · `/admin/orders` | — | phase-3/flagships/orders/ORDERS-R1.md Q3; phase-0/COMPONENT-INVENTORY.md P2 |
| PR-019 | Second approver for money (maker-checker) | Not in v1; needs a policy on per-currency thresholds first, then H18 (L). Money writes keep the typed confirmation ladder. | billing · `/admin/tickets/{ticket}`, `/admin/wallet/{user}` | H18 | phase-1/powerups/advanced/ADVANCED.md #15; phase-1/powerups/advanced/BACKEND-HELPERS.md H18 |
| PR-032 | Round-2 advanced power-ups adoption (29 patterns) | Adopt the 10 ★ (presence, one search, do-that-again, phase timers, explain, dry-run, paste-from-Excel, QR, ticket summary, health) in backend-helper build order; the other 19 later. | shell · shell | — | phase-1/powerups/advanced/ADVANCED.md Recommendation |
| PR-038 | Link / change the order on an existing ticket | First check whether admin.tickets.update accepts order_id; if not, add it. Tickets may have no order (design the no-order layout regardless). | tickets · `/admin/tickets/{ticket}` | — | phase-2/truth/TRUTH-TICKETS.md §10.4 |
| PR-044 | Orders Q1: what a click on the print button does | 1a: opens the Cloud print dialog (drawn). | orders · `/admin/orders/{order}` | — | phase-3/flagships/orders/ORDERS-R1.md Q1 |
| PR-045 | Orders Q2: Resolve hold on the order page | 2a: yes, dark next-step when On Hold (API remove-hold exists). | orders · `/admin/orders/{order}` | — | phase-3/flagships/orders/ORDERS-R1.md Q2 |
| PR-046 | Orders Q4: customer details on the order | 4a: no Customer tab; name + city in the front matter (4b needs a PII-scoped endpoint). | orders · `/admin/orders/{order}` | — | phase-3/flagships/orders/ORDERS-R1.md Q4 |
| PR-047 | Orders Q5: tab set on the order page | 5a: 10 tabs, one sub-resource each (drawn). | orders · `/admin/orders/{order}` | — | phase-3/flagships/orders/ORDERS-R1.md Q5; phase-2/truth/TRUTH-ORDERS.md §8 #16 |
| PR-048 | Orders Q6: where measurement-check values live | 6a: stay in the measurement-check popup (drawn). | orders · `/admin/orders/{order}` | — | phase-3/flagships/orders/ORDERS-R1.md Q6; phase-2/truth/TRUTH-ORDERS.md §8 #17 |
| PR-049 | Orders Q7: Complete on Delivered across pages | 7a: select all matching, sent in batches of 100 with Stop, on the existing POST orders/completed (T003 #13). | orders · `/admin/orders` | — | phase-3/flagships/orders/ORDERS-R1.md Q7 / I11; phase-2/truth/TRUTH-ORDERS.md §3.5 |
| PR-050 | Orders Q8: put on hold without a ticket (API POST hold) | 8b: never; every hold keeps its Raise Issue ticket (Frank: no Hold button). | orders · `/admin/orders/{order}` | — | phase-3/flagships/orders/ORDERS-R1.md Q8; phase-2/FEEDBACK-B-r1.md global truth rule |
| PR-051 | Orders Q9: default view when Orders opens | 9a: Active (drawn). | orders · `/admin/orders` | — | phase-3/flagships/orders/ORDERS-R1.md Q9 |
| PR-052 | Orders Q10: sort | 10a: keep order # descending (drawn). | orders · `/admin/orders` | — | phase-3/flagships/orders/ORDERS-R1.md Q10 |
| PR-053 | Orders Q11: Void on the order page | 11b: keep Void on the index row only (drawn), draft / awaiting payment / RFF. | orders · `/admin/orders/{order}`, `/admin/orders` | — | phase-3/flagships/orders/ORDERS-R1.md Q11; phase-2/truth/TRUTH-ORDERS.md §8 #9 |
| PR-054 | Orders Q12: Product type column content | 12a: main product per group, e.g. '2-Piece + Shirt' (drawn). | orders · `/admin/orders` | — | phase-3/flagships/orders/ORDERS-R1.md Q12; phase-2/FEEDBACK-B-r1.md orders index |
| PR-055 | Rename 'Fabric Purchase Jobs' to 'Agent jobs' | Rename to Agent jobs (covers Order, Notification, Factory Message, Scheduled Message, Event Message). | orders · `/admin/orders/fabric-jobs` | — | phase-2/FEEDBACK-B-r1.md A06; phase-2/archetypes/ARCHETYPES.md A06; phase-2/truth/TRUTH-ORDERS.md §7.2 |
| PR-056 | Gantt direction pick (G1 Ledger / G2 Floor / G3 Countdown) | G1 Ledger, with G2 as its Factories toggle and G3 as the dashboard widget. Pick deferred to the end of the run (Frank). | orders · `/admin/gantt`, `/admin/dashboard` | — | phase-3/flagships/gantt/GANTT-R1.md §3 |
| PR-067 | Per-design popup bulk routes still registered though UI retired | Retire the routes; the Bulk Hub covers bulk work. Do not show them half-wired. | designs · `/admin/designs/{design}/edit`, `/admin/designs/bulk-hub` | — | phase-2/truth/TRUTH-DESIGNS.md §8 G6 |
| PR-069 | CSV import/export for design pricing | Not in v1; add pricing/designs/export\|import per retailer × main product only if Frank wants it. | pricing · `/admin/pricing`, `/admin/pricing/create` | — | phase-2/truth/TRUTH-PRICING.md P-G3 |
| PR-074 | Menu regroup by job (M2), job names EN/中文, leaf relabels, HQ corner = Home | Parked: menu IA is out of design scope (Frank 2026-10-18); separate evidence-led exercise with backend (AdminMenu.php). The shell renders any server tree of depth ≤3. | shell · shell | — | phase-1/menu/MENU-OPTIONS.md recommendation / proposals raised; PROPOSALS.md (pre-consolidation) P0 |
| PR-075 | Where the shared kit package lives | B: its own repo RJmtm/admin-kit (neither admin owns it). | stack · shell | — | phase-0/STACK-AND-PACKAGES.md §5.2; PROPOSALS.md (pre-consolidation) stack |
| PR-079 | Port or drop /admin/posts and /admin/watermark-text (T001 Q10 still open) | Do not design either: /admin/posts is 403 for everyone (use news/trainings); /admin/watermark-text is a developer test page. Propose retiring both routes. | content · `/admin/posts`, `/admin/watermark-text` | — | PROPOSALS.md (pre-consolidation) P0; projects/laravel-admin/handoffs/2026-10-12-T001-workpackages.json meta.excluded |

## needs-backend (49)

| id | proposal | recommended default | area · pages | helper | source |
|---|---|---|---|---|---|
| PR-001 | Per-staff prefs store (saved views, column presets, density, recent/pinned across devices, My home, import mapping memory) | Ship saved views on URL state + browser storage now (UI-only); add GET/PUT /admin/me/prefs/{key} (H01, S) for per-person sync. *PUT /admin/me/preferences stores only {locale, timezone}. Orders status-tab customisation (ORDERS-R1 I2) rides on the same store.* | shell · `/admin/orders`, `/admin/tickets`, shell | H01 | phase-1/powerups/POWERUPS.md #05/#04/#15; phase-1/powerups/advanced/ADVANCED.md #08/#18; phase-1/powerups/advanced/BACKEND-HELPERS.md H01; phase-0/COMPONENT-INVENTORY.md P2/saved-views; phase-3/flagships/orders/ORDERS-R1.md I2/I3 |
| PR-003 | Record-wide history / activity / audit store (activity panel, time-travel, design + pricing undo, bulk-run before-values) | Design nothing beyond existing scoped audits (payload audits, email-template versions, API-key audit, request logs) until GET /admin/records/{type}/{id}/history (H02, L) exists; start it day one. *GET /admin/audit-logs is 404. Pricing change log (before/after, actor) and design undo both need it.* | shell · shell, `/admin/orders/{order}`, `/admin/designs`, `/admin/designs/create`, `/admin/designs/{design}/edit`, `/admin/designs/bulk-hub`, `/admin/pricing`, `/admin/pricing/create` | H02 | phase-1/powerups/POWERUPS.md #13; phase-1/powerups/advanced/ADVANCED.md #11; phase-1/powerups/advanced/BACKEND-HELPERS.md H02; phase-0/COMPONENT-INVENTORY.md P1 / audit-row / M05; phase-2/truth/TRUTH-DESIGNS.md G7; phase-2/truth/TRUTH-PRICING.md P-G2 |
| PR-005 | One search across orders, accounts, fabric codes, tickets, designs (⌘K beyond orders) | ⌘K ships on admin.me.menu + admin.dashboard.quick-search (orders) now; add GET /admin/search (H04, M). | shell · shell, `/admin/dashboard` | H04 | phase-1/powerups/POWERUPS.md #01; phase-1/powerups/advanced/ADVANCED.md #05; phase-1/powerups/advanced/BACKEND-HELPERS.md H04; phase-2/archetypes/ARCHETYPES.md A05 ghost |
| PR-006 | Say it in ⌘K (sentence -> filter or action) | Later wave; POST /admin/search/parse (H05, M) after H04 + H09; never writes. | shell · shell | H05 | phase-1/powerups/advanced/ADVANCED.md #06; phase-1/powerups/advanced/BACKEND-HELPERS.md H05 |
| PR-007 | Counts for the filtered set (totals strip) | GET /admin/orders/counts?<list filters> (H06, S); until then show tab counts only where the status catalogue gives them. | orders · `/admin/orders` | H06 | phase-1/powerups/advanced/ADVANCED.md #21; phase-1/powerups/advanced/BACKEND-HELPERS.md H06 |
| PR-008 | Who else is here (presence + soft edit lock) | POST/DELETE /admin/presence (H07, S, Redis TTL 30 s, poll 10 s); hard guard stays the If-Match check (PR-004). | shell · `/admin/orders/{order}`, `/admin/designs/{design}/edit` | H07 | phase-1/powerups/advanced/ADVANCED.md #01; phase-1/powerups/advanced/BACKEND-HELPERS.md H07 |
| PR-009 | Names-only admin picker (for @mentions and ticket assignee) | GET /admin/pickers/admins?q= (H08, S). | shell · shell, `/admin/tickets`, `/admin/tickets/{ticket}` | H08 | phase-1/powerups/advanced/ADVANCED.md #02; phase-1/powerups/advanced/BACKEND-HELPERS.md H08 |
| PR-010 | Comments and @mentions on any record | GET/POST /admin/records/{type}/{id}/comments (H10, M); order notes and ticket comments stay as they are. | shell · shell | H10 | phase-1/powerups/advanced/ADVANCED.md #02; phase-1/powerups/advanced/BACKEND-HELPERS.md H10 |
| PR-011 | Watch a record -> notification inbox | POST/DELETE/GET /admin/watches (H11, M); the bell already reads admin.notifications.*. | shell · shell, `/admin/orders/{order}`, `/admin/tickets`, `/admin/tickets/{ticket}` | H11 | phase-1/powerups/advanced/ADVANCED.md #03; phase-1/powerups/advanced/BACKEND-HELPERS.md H11 |
| PR-012 | While you were away (shift hand-over digest) | GET /admin/me/digest?since= (H12, M) after H11 + H02. | shell · shell | H12 | phase-1/powerups/advanced/ADVANCED.md #04; phase-1/powerups/advanced/BACKEND-HELPERS.md H12 |
| PR-013 | Stuck-in-phase timers (phase ages + targets) | GET /admin/orders/phase-ages?ids= + GET/PUT /admin/settings/phase-targets (H09, M). | orders · `/admin/orders`, `/admin/gantt` | H09 | phase-1/powerups/advanced/ADVANCED.md #09; phase-1/powerups/advanced/BACKEND-HELPERS.md H09 |
| PR-014 | Why is this order here? (one composed explain read) | GET /admin/orders/{order}/explain (H13, M). | orders · `/admin/orders/{order}` | H13 | phase-1/powerups/advanced/ADVANCED.md #10; phase-1/powerups/advanced/BACKEND-HELPERS.md H13 |
| PR-015 | Restore one value from history | POST /admin/records/{type}/{id}/history/{change}/restore (H14, M) after H02. | shell · shell | H14 | phase-1/powerups/advanced/ADVANCED.md #11; phase-1/powerups/advanced/BACKEND-HELPERS.md H14 |
| PR-016 | Do it later (scheduled actions; allow-listed, never money) | POST/GET/DELETE /admin/scheduled-actions (H15, M). | shell · shell | H15 | phase-1/powerups/advanced/ADVANCED.md #12; phase-1/powerups/advanced/BACKEND-HELPERS.md H15 |
| PR-017 | Dry-run impact preview on the four bulk writes | dry_run=1 on accounts bulk-features / bulk-permissions, accessory-codes/bulk, api-keys/bulk-revoke (H16, S). | users · `/admin/users`, `/admin/users/bulk-permissions`, `/admin/accessory-codes`, `/admin/access` | H16 | phase-1/powerups/advanced/ADVANCED.md #13; phase-1/powerups/advanced/BACKEND-HELPERS.md H16 |
| PR-018 | Undo a whole bulk run (10-minute window) | GET /admin/bulk-runs/{id} + POST .../revert (H17, M). | shell · `/admin/designs/bulk-hub`, `/admin/users` | H17 | phase-1/powerups/advanced/ADVANCED.md #14; phase-1/powerups/advanced/BACKEND-HELPERS.md H17 |
| PR-020 | See the admin as someone else's role | as_admin={id} on GET /admin/me and /admin/me/menu, super admin only, writes refused (H20, S). | access · shell | H20 | phase-1/powerups/advanced/ADVANCED.md #16; phase-1/powerups/advanced/BACKEND-HELPERS.md H20 |
| PR-021 | Paste from Excel into an import (JSON rows on import preview) | Accept {rows, columns} on the existing import preview endpoints (H21, S). | materials · `/admin/fabric-codes/import`, `/admin/pt-colors/import`, `/admin/accessory-codes` | H21 | phase-1/powerups/advanced/ADVANCED.md #17; phase-1/powerups/advanced/BACKEND-HELPERS.md H21 |
| PR-022 | Trends inside the table (metric series sparklines) | GET /admin/metrics/series (H22, M), read-only, nightly cache. | users · `/admin/users`, `/admin/factories` | H22 | phase-1/powerups/advanced/ADVANCED.md #19; phase-1/powerups/advanced/BACKEND-HELPERS.md H22 |
| PR-023 | Scan a QR to open the record | GET /admin/qr/resolve?code= (H23, S). | shell · shell | H23 | phase-1/powerups/advanced/ADVANCED.md #22; phase-1/powerups/advanced/BACKEND-HELPERS.md H23 |
| PR-024 | Keeps working when Wi-Fi drops (Idempotency-Key honoured on floor writes) | 24 h Idempotency-Key middleware on vision-check resolve, QC checks, order checkpoints (H24, M). | vision-checks · `/admin/vision-checks/results` | H24 | phase-1/powerups/advanced/ADVANCED.md #23; phase-1/powerups/POWERUPS.md #20; phase-1/powerups/advanced/BACKEND-HELPERS.md H24 |
| PR-025 | Ping me when it's done (Web Push) | Upgrade only; polling + in-tab notification off admin.notifications.unread-count works today (H25, M). | shell · shell | H25 | phase-1/powerups/advanced/ADVANCED.md #25; phase-1/powerups/advanced/BACKEND-HELPERS.md H25 |
| PR-026 | Ticket summary + suggested next step (AI summary mode, explicit button) | mode:'summary' on admin.tickets.ai.suggest (H26, S); explicit button only, never automatic (AI costs money). | tickets · `/admin/tickets/{ticket}` | H26 | phase-1/powerups/advanced/ADVANCED.md #26; phase-1/powerups/advanced/BACKEND-HELPERS.md H26; phase-2/FEEDBACK-B-r1.md A11 |
| PR-027 | Anomaly flags on orders | GET /admin/orders/flags?ids= (H19, M), read-only rules. | orders · `/admin/orders` | H19 | phase-1/powerups/advanced/ADVANCED.md #27; phase-1/powerups/advanced/BACKEND-HELPERS.md H19 |
| PR-028 | Health strip for super admins | GET /admin/health/summary (H27, S), top administrator only (T003 #45). | ops · `/admin/failed-jobs`, `/admin/job/batches`, `/admin/schedule-monitor` | H27 | phase-1/powerups/advanced/ADVANCED.md #28; phase-1/powerups/advanced/BACKEND-HELPERS.md H27 |
| PR-029 | Out of stock? closest cloths in stock | GET /admin/fabric-intelligence/similar (H28, M). | fabrics · `/admin/fabric-codes` | H28 | phase-1/powerups/advanced/ADVANCED.md #29; phase-1/powerups/advanced/BACKEND-HELPERS.md H28 |
| PR-033 | Cancel a queued print job (G1) | Hide cancel until POST /admin/orders/print-jobs/{job}/cancel exists (dispatch_status=queued only). | orders · `/admin/orders/print-jobs` | — | PROPOSALS.md (pre-consolidation) G1; phase-2/archetypes/ARCHETYPES.md A06 |
| PR-034 | Resolve several vision results at once (G2) | Bulk bar stays hidden on A08 until a bulk resolve (≤100 ids, PASS/FAIL) exists. | vision-checks · `/admin/vision-checks/results` | — | PROPOSALS.md (pre-consolidation) G2; phase-2/archetypes/ARCHETYPES.md A08; phase-1/powerups/advanced/ADVANCED.md #24 |
| PR-035 | Ticket assignee + 'Mine' view + routed notifications (G3) | Rename today's 'Owner' to Shop (retailer account); assignee needs assignee_id, a filter and notification routing. | tickets · `/admin/tickets`, `/admin/tickets/{ticket}` | — | PROPOSALS.md (pre-consolidation) G3; phase-2/truth/TRUTH-TICKETS.md §7 / §10.1; phase-1/menu/MENU-OPTIONS.md badge |
| PR-036 | Internal (staff-only) ticket note (G4) | is_internal on tickets_comments, excluded from email and the retailer view. | tickets · `/admin/tickets/{ticket}` | — | PROPOSALS.md (pre-consolidation) G4; phase-2/truth/TRUTH-TICKETS.md §10.2 |
| PR-037 | Persist the last AI suggestion per ticket (no re-billing on reopen) | Cache the last suggestion with a timestamp; the 'Get AI suggestion' button stays explicit. | tickets · `/admin/tickets/{ticket}` | — | phase-2/truth/TRUTH-TICKETS.md §10.3; phase-2/FEEDBACK-B-r1.md A11 |
| PR-039 | CN labels for ticket statuses, severities and categories | DB data backfill (EN only today); show EN until present. | tickets · `/admin/tickets`, `/admin/tickets/{ticket}`, `/admin/tickets/status`, `/admin/tickets/severity`, `/admin/tickets/categories` | — | phase-2/truth/TRUTH-TICKETS.md §10.5 |
| PR-040 | Attachment count on ticket list/show payloads | Add attachments_count; no paperclip in the list until then. | tickets · `/admin/tickets`, `/admin/tickets/{ticket}` | — | phase-2/truth/TRUTH-TICKETS.md §10.6 |
| PR-042 | Order filter on the tickets index | Only has_order + search exist; add order_id filter (also feeds the order Issues tab). | tickets · `/admin/tickets`, `/admin/orders/{order}` | — | phase-3/flagships/orders/ORDERS-R1.md could-not-verify / D13 |
| PR-043 | Order status-history read (Activity tab) | Add an order_status history read; until then Activity shows payload audits, fitting-validation logs and print/agent jobs only. | orders · `/admin/orders/{order}` | — | phase-3/flagships/orders/ORDERS-R1.md D14 |
| PR-057 | gantt-grid rows: factory_due_at + current_step | Add both to gantt-grid rows; otherwise one phase-summary call per row. | orders · `/admin/gantt` | — | phase-3/flagships/gantt/GANTT-R1.md §4.1 |
| PR-058 | gantt-grid rolling window (from/to across months) | Add from/to; fallback stitches two month calls client-side. | orders · `/admin/gantt` | — | phase-3/flagships/gantt/GANTT-R1.md §4.2 |
| PR-059 | Express flag on gantt rows | Add express to gantt-grid rows (it exists on the index). | orders · `/admin/gantt` | — | phase-3/flagships/gantt/GANTT-R1.md §4.3 |
| PR-060 | Factory capacity per day | Until it exists, load heat is relative to each factory's own peak. | factory · `/admin/gantt`, `/admin/factories` | — | phase-3/flagships/gantt/GANTT-R1.md §4.4 |
| PR-061 | /orders/due horizon beyond 3 days | Raise horizon_days cap to 14 (or derive from factory due) for +7/+14 views. | orders · `/admin/orders/due`, `/admin/dashboard` | — | phase-3/flagships/gantt/GANTT-R1.md §4.5 |
| PR-062 | Design create silently drops the surcharge (extra_meter) | Persist extra_meter (design + popup rows) on create (web + API store), or remove the inputs from create. | designs · `/admin/designs/create` | — | phase-2/truth/TRUTH-DESIGNS.md §8 G1 |
| PR-063 | Camera frame and Supplier on the design create form | Add both to create (StoreDesignRequest already accepts camera_frame; supplier needs the store to accept it). | designs · `/admin/designs/create` | — | phase-2/truth/TRUTH-DESIGNS.md §8 G2 |
| PR-064 | 'Retailers carrying this design / priced?' panel on the design page | Read endpoint over user_main_product_design by design_id; read-only panel. | designs · `/admin/designs/{design}/edit` | — | phase-2/truth/TRUTH-DESIGNS.md §8 G3 |
| PR-066 | Align design 'info' validation (max:1000 on the edit path) | Align the web edit path with store/API. | designs · `/admin/designs/{design}/edit` | — | phase-2/truth/TRUTH-DESIGNS.md §8 G5 |
| PR-068 | Ungated web pricing writes | New UI calls the API only (update pricing + pricing:write); retire the ungated web writes. | pricing · `/admin/pricing`, `/admin/pricing/create` | — | phase-2/truth/TRUTH-PRICING.md P-G1 |
| PR-070 | Retailer pricing cell write by ids, not localized display name | Accept fabric_code_id / combination_id on the cell write so the grid never depends on locale. | pricing · `/admin/pricing/create` | — | phase-2/truth/TRUTH-PRICING.md P-G4 |
| PR-072 | Menu badge counts (optional integer badge per link) | Optional permission-scoped badge (tickets open, vision results awaiting review, failed print jobs), cached or via /me/menu/badges; nothing drawn when absent. | shell · shell | — | phase-1/menu/MENU-OPTIONS.md needs-backend 2; phase-1/powerups/POWERUPS.md note |
| PR-073 | Backfill cn labels for the menu (90 missing)  | Add cn keys in resources/lang/cn.json; EN fallback until then. | shell · shell | — | phase-1/menu/MENU-OPTIONS.md needs-backend 1 |
| PR-082 | Spec permission metadata drift on orders/tickets lists | x-permission / x-token-scope on GET /admin/orders and /admin/tickets list extra requirements the live API does not enforce; fix the spec so permission-shaped UI is not over-restrictive. | orders · `/admin/orders`, `/admin/tickets` | — | projects/laravel-admin/handoffs/2026-10-16-T012-RETURN.md §6 |

## UI-only (11)

| id | proposal | recommended default | area · pages | helper | source |
|---|---|---|---|---|---|
| PR-004 | Version check on measurement writes ('someone else changed this') | Build against the spec: admin.orders.measurement-check returns version + ETag, admin.orders.measurements.update takes If-Match / expected_version -> 409 version_conflict. Verify the 409 on staging before build (H03). | orders · `/admin/orders/{order}`, `/admin/orders/{order}/edit`, `/admin/orders/measurement/edit/{order}` | H03 | phase-1/powerups/POWERUPS.md #17; PROPOSALS.md (pre-consolidation) decision-B correction; phase-1/powerups/advanced/BACKEND-HELPERS.md H03; phase-0/COMPONENT-INVENTORY.md VC |
| PR-030 | Do that again (⌘.) | Adopt; last action kept in this tab only. | shell · shell | — | phase-1/powerups/advanced/ADVANCED.md #07 |
| PR-031 | Compare two records side by side | Adopt as a later UI pattern; two normal GETs diffed in the browser (M05). | shell · `/admin/designs/{design}/edit`, `/admin/pricing` | — | phase-1/powerups/advanced/ADVANCED.md #20 |
| PR-041 | Show the ticket creator | Adopt; the API already returns creator. | tickets · `/admin/tickets/{ticket}` | — | phase-2/truth/TRUTH-TICKETS.md §10.7 |
| PR-065 | Blockers active toggle on the design edit form | Use the API field blockers.*.is_active (UpdateDesignRequest accepts it); confirm web parity. | designs · `/admin/designs/{design}/edit` | — | phase-2/truth/TRUTH-DESIGNS.md §8 G4 |
| PR-071 | No master-pricing screen anywhere; retire /admin/pricing/master | Do not design; propose retiring the route (403, L1033/L1034). | pricing · `/admin/pricing/master` | — | phase-2/truth/TRUTH-PRICING.md P-G5; PROPOSALS.md (pre-consolidation) P0 |
| PR-076 | One shared internal kit package @rj/admin-kit for DTC + Laravel admins | Adopt: tokens (theme layer per app), shadcn/Radix primitives, F1 composites; no home-built chart/grid/table libraries. | stack · shell | — | PROPOSALS.md (pre-consolidation) stack; phase-0/STACK-AND-PACKAGES.md §5 |
| PR-077 | Package picks (grid react-datasheet-grid after spike; Gantt on CSS grid + @tanstack/react-virtual; no paid licences) | Frontend team confirms; full map in STACK-AND-PACKAGES §3–§4. | stack · shell | — | phase-0/STACK-AND-PACKAGES.md §3–§4; PROPOSALS.md (pre-consolidation) stack |
| PR-078 | Dev port: mock allows localhost:5173, Next defaults to :3000 | Run next dev -p 5173 or add :3000 to the mock's allowed origins. | stack · shell | — | PROPOSALS.md (pre-consolidation) stack |
| PR-080 | Materials onboarding draft stays browser-only (no server draft endpoints) | Keep wizard draft client-side (T001 Q24); unsaved-guard must warn on tab close. | materials · `/admin/materials/onboard` | — | phase-0/COMPONENT-INVENTORY.md unsaved-guard; T001 Q24 |
| PR-081 | Job batch live updates by polling, not websockets | Poll admin.dashboard.job-batches every few seconds (T001 Q2); no broadcasting auth endpoint. | ops · `/admin/job/batches`, shell | — | T001 Q2; phase-0/COMPONENT-INVENTORY.md M01 |

## Backend helper build order

Unchanged from `phase-1/powerups/advanced/BACKEND-HELPERS.md`: 1) H01 prefs · H02 history (long pole) · H03 verify 409 → 2) H04 search · H23 · H16 · H27 · H26 · H07 · H21 · H06 · H20 · H08 → 3) H09 → H13, H19 · H11 · H10 · H24 → 4) H05 · H12 · H14 · H17 · H15 · H22 · H28 · H25 → 5) H18 after the threshold decision. Page-specific needs-backend items (PR-033…PR-070) are independent of that order.


## Decided after consolidation

> Decisions taken after the consolidation above; carried in `phase-3/waves/proposals_data.py` (`DECIDED_AFTER`) so a rebuild keeps them.

| id | proposal | status | area · pages | decided | source |
|---|---|---|---|---|---|
| — | Retire the on-screen fabric pricing hypergrid (retailer-hypergrid.js / per-cell update) in the new admin — decided by Frank 2026-10-18: export/import only | **decided** | pricing · `/admin/pricing/create` (type=combinations) | Frank in chat, 2026-10-18: "Export/import only." · "we don't allow for a view of the file, we just allow export and import". Fabric combination pricing = queued Export (recent files + download) and Import (upload → check/map → diff-summary preview → typed confirm → run → result). The web grid's per-cell `admin/pricing/retailer/update` (PricingController::updateRetailerPricing) and the API `admin.pricing.retailer.update` are not called by the new UI; PR-070 (cell write by ids) is moot for this page. | `phase-3/flagships/pricing/PRICING-R3.md` |
