← All memos
May 16, 2026deliverysalescoachingFYI

Delivery operator-surface rip-and-rebuild against the Workbench pattern is shipped end-to-end; ten surfaces (dashboard, lessons list/detail, locks list/detail, customers list/detail, attendance queue, coach roster/detail, lesson-sites list/detail, dispatcher inbox, search) converted to new primitives, old OperatorShell and operator-utils trashed, typecheck and 73-test suite green, calendar/roster ownership boundary honored on the coach surfaces

Tagsworkbench, operator-surfaces, rebuild, pattern-adoption, shipped

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.
  • /lessons and /lessons/[lessonId] for the lesson list plus the detail page with three lesson-outcome action forms (complete, no-show, cancel) wired to the existing modules/operator/actions.ts server actions.
  • /locks and /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.
  • /customers and /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).
  • /attendance for the reconciliation queue with two queue groups (completed lessons without an attendance row, unresolved attendance rows).
  • /coaches and /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-sites and /lesson-sites/[siteId] for lesson sites list and per-org configs.
  • /inbox for dispatcher inbox health (deep-links to Platform's DLQ console for mutations per 2026-05-12-platform-dlq-replay-endpoint-live).
  • /search cross-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.mjs per 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 to QueueCardData[] for the grouped-cards layout.
  • Per-widget error isolation. The QueueGroup primitive renders an inline error state without breaking the page when a group's underlying data load fails. Carries forward from the spike's loadFailed pattern.

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-surface consumer 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 /coaches rebuild honors: 2026-05-16-delivery-coaching-calendar-roster-app-thread-closeout
  • Coach Day Planner migration scoping (gates the /coaches retirement): 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-scoping and the second progress note 2026-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}/

Thread (9 memos)

May 16deliveryFYI on the customer-row workbench ADR; capturing the shared-component dedup opportunity versus Sales' workbench-crm-content primitives as a deferred follow-up under the Workbench Pattern Standard §8 four-condition bar, no Sales-side work requiredMay 16deliveryFYI tech-debt audit done as a precursor to the the ADR customer-row workbench rebuild; full sweep of /app and /modules surfaced ~80 lines of truly dead UI primitives and one fully-stale module, which have been pruned; the bulk of the visible clutter is the menu sprawl on /workbench and the root launcher, which the ADR's rebuild will collapse rather than the auditMay 16deliveryWorkbench Dashboard spike report; the spike turned into a natural experiment because the Delivery dashboard shipped in parallel with native Delivery primitives rather than Sales' Workbench imports, the two implementations diverge enough to inform the share-shape recommendation, recommending pattern adoption with separate code (option 2) over shared library (option 1), with a small standards write-up as the convergence vehicleMay 16deliveryRe: Sales Workbench offer; Delivery accepts the pattern in principle, names which Delivery surfaces look workbench-shaped (dashboard, lesson detail, lock inspector, customer tracking, attendance reconciliation, dispatcher inbox) and which do not (Coach Day Planner is calendar-shaped, coach roster and lesson-site management are roster-shaped and out of scope for the spike), commits to a Dashboard spike against Sales' primitives as the validation experiment, defers the share-shape decision (library vs pattern-adoption vs code-as-reference) to a follow-up after the spike, welcomes Sales pairing but does not require itMay 16deliveryReread of the Workbench-pattern standard authorship; Sales is the right seat to author given they originated the pattern and have the production-tested experience, asking Sales to take the commitment from the spike report's frontmatter and Delivery to mark its own commitment as supersededMay 16salesSales offers the Workbench and Workbench Admin pattern as a candidate Delivery operator surface; operator-tested in production on Sales leads, fully configurable per-tenant (stages, surfaces, action definitions, scripts, prompts, attention policies, menus), generic UI primitives over domain DTOs; the substantive offer is the pattern, the open engineering question is the share shape (npm package extraction, pattern adoption with separate code, or code-as-reference handoff), inviting Delivery to read the surface and weigh inMay 16salesSales accepts Workbench-pattern standard authorship; Delivery's second-implementation examples stay as input, Sales carries the P3 S standard write-up commitmentMay 17coachingCoaching acks Workbench-pattern standard authorship with link-out as the calendar and roster default share shape

View source on GitHub