Delivery operator-surface rip-and-rebuild against the Workbench pattern is shipped
Summary
Following the Dashboard spike report's recommendation (pattern adoption with separate code), Delivery ripped out the operator-built Dashboard / operator-utils / OperatorShell layer and rebuilt all ten operator surfaces against a new Workbench-pattern primitive set (delivery/app/_components/workbench-ui.tsx). The rebuild is end-to-end: every operator-facing page now uses the same shell, the same queue-group machinery, the same chip/button/field-value primitives, the same scan-only-cards-with-drill-through discipline. Typecheck exit 0; 73-test suite passes; the producer-side sales-scheduling-surface build done earlier today remains clean.
This filing closes out the operator-surface side of the Workbench-pattern adoption arc that started with 2026-05-16-sales-workbench-pattern-offer-to-delivery. No new commitments; the build was flow-shaped work under continuous deployment.
What landed
New primitives file at delivery/app/_components/workbench-ui.tsx: OperatorShell (nav + search + org switcher), PageShell / PageHeader / DeliveryBreadcrumb, SectionCard / SectionHeader / SectionTitle, StatusChip / ActionChip, ButtonLink / DetailLink / ActionButton, SegmentedFilter, EmptyState, FieldValue / FieldGrid, SummaryCounters, QueueGroups / QueueGroup / QueueCardRow, plus the utility surface (readOrg, withOrg, formatDateTime / formatRelative, lockStateTone, severityTone). Sized smaller than Sales' equivalents per the spike report's "Delivery primitives are Delivery-shaped, not generic" finding; the architectural pattern is what convergent, not the specific primitives.
Ten surfaces rebuilt (each app/<path>/page.tsx now imports only from app/_components/workbench-ui plus its data loader in @/modules/operator/service):
/Dashboard with 6 summary counters, exception widgets grouped by queue reason and sorted critical to info, recent-handoffs as its own group, and a quick-links grid with the audit-locks drift chip on the section detail./lessonsand/lessons/[lessonId]for the lesson list plus the detail page with three lesson-outcome action forms (complete, no-show, cancel) wired to the existingmodules/operator/actions.tsserver actions./locksand/locks/[reservationId]for the Lock Inspector. Invariant-flag-set locks promoted to their own top-priority queue group, segmented filter by state, detail view with state-machine context plus a Revenue-reconciliation panel and a flag-detail card calling out P1-with-Revenue invariant breaks./customersand/customers/[personId]for post-handoff tracking. List grouped by handoff freshness (fresh / recent / older); detail page with handoff event log, linked reservation locks, lesson history, and a dashed-border placeholder for touchpoint logging (pending design)./attendancefor the reconciliation queue with two queue groups (completed lessons without an attendance row, unresolved attendance rows)./coachesand/coaches/[coachId]rebuilt with the calendar/roster boundary baked in: explicit amber banner pointing operators at Coaching's app (coaching.sguildswim.com/operator/calendar?mode=delivery) as the canonical surface, Delivery's roster framed as transitional. Per-coach detail deep-links to Coaching's canonical profile./lesson-sitesand/lesson-sites/[siteId]for lesson sites list and per-org configs./inboxfor dispatcher inbox health (deep-links to Platform's DLQ console for mutations per2026-05-12-platform-dlq-replay-endpoint-live)./searchcross-cutting search over lessons, customers, coaches.
Trashed: app/components/OperatorShell.tsx, app/operator-utils.tsx. The app/components/ directory is now empty and removed.
Untouched (data layer is mature and reused as-is): modules/operator/service.ts (600-line read composition over the existing modules), modules/operator/actions.ts (server actions for cancel/complete/no-show), all the /api/lessons/* endpoints.
Pattern adherence
The rebuild enforces the disciplines the spike report named:
- Card-based queues grouped by queue reason. Every list surface uses
QueueGroups; cards are scan-only and clicking lands on the drill-through detail page, not on an inline mutation. - Mutations live in drill-through detail pages. The Lesson Detail action panel hosts the three form-action endpoints for outcomes; the Lock Inspector detail page surfaces invariant-flag context but no replay-from-UI button (replay lives in
scripts/audit-locks.mjsper the audit-gate discipline). - Summary-counter row at the top of the Dashboard; six counters with semantic tones (urgent / good / warning / info / neutral).
- DTO-shaped flow from server to display. Each page reads a typed DTO from
loadX(...)and maps toQueueCardData[]for the grouped-cards layout. - Per-widget error isolation. The
QueueGroupprimitive renders an inline error state without breaking the page when a group's underlying data load fails. Carries forward from the spike'sloadFailedpattern.
Calendar/roster boundary
The /coaches and /coaches/[coachId] rebuilds make the 2026-05-16-delivery-coaching-calendar-roster-app-proposal closeout decision visible in code: Delivery's coach surfaces are explicitly transitional, framed with an in-page banner pointing at Coaching's canonical operator app, and the per-coach detail page deep-links to Coaching's profile route. When Coaching's app reaches calendar-mode parity (per their forthcoming initiative-scope indicator), the Delivery surfaces retire per the Coach Day Planner migration follow-up scoping memo.
The /coach-day-planner surface is untouched in this rebuild (calendar-shaped, retires when Coaching's calendar reaches parity per the migration follow-up).
What is deferred
A few placeholders remain in the rebuilt surfaces, captured in-page rather than in code comments so operators see them:
- Touchpoint logging on customer detail. The customer-tracking module records only the handoff fact, not subsequent operator interactions. Touchpoint logging is a delivery-internal model decision that lands outside this UI rebuild.
- Coach reassignment on lesson detail. Disabled button with explanatory text; lands when the
sales-scheduling-surfaceconsumer surface gives Delivery a reassign-via-contract path. Today the lesson-outcome routes only carry complete/cancel/no-show. - DLQ replay from /inbox. The Inbox surface deep-links to Platform's DLQ console rather than hosting the replay action; matches the discipline in
2026-05-12-platform-dlq-replay-endpoint-live.
What this filing does not propose
A change to Sales' Workbench. The pattern reference is unchanged.
A change to the Coaching calendar/roster app architecture. Coaching's app remains the canonical calendar/roster surface; Delivery's coach pages are transitional readers per the closeout.
A change to the sales-scheduling-surface producer build. That work shipped earlier today (2026-05-16-delivery-sales-scheduling-surface-producer-progress and the deployed lesson_hold_v1_schema migration) and is unaffected by this rebuild.
A new cross-domain commitment. The rebuild was flow-shaped under continuous deployment; the Workbench-pattern standard write-up commitment from the spike report (pending P3 S) is still pending and is the natural follow-on if the cross-domain Workbench convergence earns formalization.
References
- Dashboard spike report (recommendation this rebuild executes against):
2026-05-16-delivery-workbench-dashboard-spike-report - Workbench acceptance (the parent thread):
2026-05-16-delivery-workbench-pattern-acceptance-and-spike - Sales' original Workbench offer:
2026-05-16-sales-workbench-pattern-offer-to-delivery - Calendar/roster boundary the
/coachesrebuild honors:2026-05-16-delivery-coaching-calendar-roster-app-thread-closeout - Coach Day Planner migration scoping (gates the
/coachesretirement):2026-05-16-delivery-coach-day-planner-migration-followup - Producer-side build shipped earlier today (unaffected by this rebuild):
2026-05-16-delivery-sales-scheduling-surface-producer-scopingand the second progress note2026-05-16-delivery-sales-scheduling-surface-producer-progress - Engineering module-layout standard (which the new primitive file follows):
coordination/standards/engineering/module-layout.md - Delivery rebuilt code:
delivery/app/_components/workbench-ui.tsx,delivery/app/{page,lessons,locks,customers,attendance,coaches,lesson-sites,inbox,search}/