Skip to content

Workbench Architecture

Purpose

Keep the proposal workbench maintainable by defining where logic belongs and where new logic must not go.

Parent Component

File: src/components/proposal-workbench.tsx

The parent is an orchestrator.

Should own: - Top-level proposal state - Route-triggered actions - Shared orchestration across panels - High-level effects: autosave, presence, keyboard shortcuts

Should NOT grow into: - A monolithic JSX file with multiple tab UIs inline - A dumping ground for formatting helpers - Repeated decision logic that could be pure/tested

Hooks

Files: - src/components/workbench/use-workbench-analysis.ts - src/components/workbench/use-workbench-collaboration.ts

Should own: - Grouped async workflows - Request state - Domain-specific local state - Reusable side-effect logic

Should NOT own: - Rendering concerns - Broad unrelated state bundles - Business rules better shared with server/service code

Panels

Examples: - proposal-editor-panel.tsx - proposal-preview-panel.tsx - proposal-collaboration-panel.tsx - proposal-management-panel.tsx - proposal-versions-panel.tsx - proposal-bom-panel.tsx - proposal-canvas-panel.tsx - proposal-toolbar.tsx

Should own: - A focused UI surface - Presentation wiring for one slice of the workbench - Local display-only state where appropriate

Should NOT own: - Cross-tab orchestration - Fetch logic that belongs in shared hooks - Route mutation logic spread across many components

Pure Helpers

Examples: - proposal-panel-utils.ts - proposal-management-utils.ts - proposal-editor-utils.ts

Should own: - Formatting - Small business or UI decisions - Deterministic computations worth testing directly

Helpers are the preferred home for: repeated inline decisions, date/label/status formatting, recommendation logic, tab-agnostic calculations.

Rules for Future Changes

  1. If logic is pure and reusable, extract it before adding more JSX around it.
  2. If UI state and async actions cluster around one concern, prefer a hook.
  3. If a tab is more than a small JSX fragment, it belongs in its own panel.
  4. Do not add new wide flat prop lists when grouped control objects are clearer.
  5. Do not put new business rules only in the client if they affect approvals, sharing, or exports.

Current Boundaries

Parent     → orchestrates
Hooks      → manage analysis/collaboration behaviour
Panels     → render focused workbench sections
Helpers    → cover decision logic that should be directly tested