{"slug":"architecture/WORKBENCH_QUICK_START","title":"Workbench Quick Start Guide","section":"architecture","sectionLabel":"Architecture","status":"unclassified","type":"document","path":"architecture/WORKBENCH_QUICK_START.mdx","bytes":7576,"description":null,"updated":null,"source":"integratewise/Integratewise-docs-wiki","content":"\n\n> **Tier C — Historical.** This document is a point-in-time snapshot preserved for reference. For current architecture, see [CANONICAL_PLATFORM_ARCHITECTURE.md](../architecture/CANONICAL_PLATFORM_ARCHITECTURE.md).\n\n## 30-Second Overview\n\nYou have a **Spine-first workbench system** with 12 department dashboards. Phase 1 (Sales/RevOps) is ready to deploy. Metrics compute from Spine data in real-time.\n\n---\n\n## Step 1: Import & Render\n\n```tsx\nimport {\n  SalesRevOpsWorkbench,\n  MetricEngine,\n  METRICS_BY_DOMAIN,\n} from '@integratewise/domain-shells/workbenches';\n\n  const spineRows = useSpineRows('sales_revops');\n\n  const metrics = METRICS_BY_DOMAIN.sales_revops.map(metric =>\n    MetricEngine.computeMetric(metric, spineRows)\n  );\n\n  const dataQuality = MetricEngine.assessDataQuality(\n    'sales_revops',\n    spineRows,\n    CANONICAL_FIELDS\n  );\n\n  return (\n    <SalesRevOpsWorkbench\n      metrics={metrics}\n      dataQuality={dataQuality}\n      onRefresh={() => revalidate()}\n      onConnectTools={() => router.push('/settings')}\n    />\n  );\n}\n```\n\n---\n\n## Step 2: Connect Spine Data\n\nYour Loader should:\n1. Read raw connector data (Salesforce, HubSpot, etc.)\n2. Map to `CANONICAL_FIELDS` (connector-agnostic names)\n3. Store in Spine tables (spine_deals, spine_accounts, etc.)\n4. MetricEngine queries these rows\n\nIf Spine is shallow (nulls), workbench shows \"Connect [tool]\" prompts automatically.\n\n---\n\n## Step 3: Customize Metrics\n\nEdit `metrics-definitions.ts`:\n\n```ts\n  {\n    metric_id: 'M-SALES-01',\n    metric_name: 'Total Pipeline Value',\n    formula: 'SUM(deal_amount)',\n    threshold_good: 1000000,  // ← Your threshold\n    threshold_warning: 500000, // ← Your threshold\n    ...\n  },\n  // Add more metrics here\n];\n```\n\n---\n\n## Step 4: Test\n\n```tsx\n\nconst metric = MetricEngine.computeMetric(\n  { formula: 'SUM(amount)', field_refs: ['amount'] },\n  [{ data: { amount: 100 } }, { data: { amount: 200 } }]\n);\n\nconsole.log(metric.value); // 300\nconsole.log(metric.status); // 'good' or 'warning' or 'critical'\n```\n\n---\n\n## Step 5: Scale\n\nCopy `sales-revops-workbench.tsx` pattern for all 11 other departments:\n\n```tsx\n// finance-workbench.tsx\n  return (\n    <div className=\"min-h-screen bg-slate-50 dark:bg-slate-950\">\n      \n      {dataQuality.overall_score < 80 && (\n        <DataGapPrompt status={dataQuality} onConnectClick={onConnectTools} />\n      )}\n      <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n        {metrics.map(m => <SpineCard key={m.metric_id} metric={m} />)}\n      </div>\n    </div>\n  );\n}\n```\n\n---\n\n## Key Components\n\n### SpineCard\nDisplays a single metric with status, trend, confidence score:\n```tsx\n<SpineCard metric={metric} showTrend={true} />\n```\n\n### DataGapPrompt\nShows missing data sources and what metrics they unlock:\n```tsx\n<DataGapPrompt status={dataQuality} onConnectClick={handleConnect} />\n```\n\n### MetricEngine\nComputes metrics from Spine rows:\n```tsx\nconst metric = MetricEngine.computeMetric(definition, spineRows, historical);\n```\n\n---\n\n## Phase 1 Domains\n\n| Domain | Metrics | Status |\n|--------|---------|--------|\n| Sales/RevOps | 5 (Pipeline, Win Rate, Cycle, Coverage, Velocity) | ✅ Ready |\n| Finance | 5 (MRR, DSO, Collections, Recognition, Overdue) | Template ready |\n| CSM | 5 (NRR, Health, Churn, Expansion, Adoption) | Template ready |\n| Engineering | 3 (MTTR, Critical Incidents, Deployment) | Template ready |\n| Marketing | 3 (CPA, MQL, ROI) | Template ready |\n\n---\n\n## Real Thresholds (Examples)\n\n```ts\n// Sales metrics\nthreshold_good: 1000000    // $1M+ pipeline = good\nthreshold_warning: 500000  // $500k-1M = warning\n\n// Finance metrics\nthreshold_good: 95   // 95%+ collections = good\nthreshold_warning: 85 // 85-95% = warning\n\n// CSM metrics\nthreshold_good: 110  // 110%+ NRR = good\nthreshold_warning: 100 // 100-110% = warning\n```\n\n---\n\n## Null Policy Handling\n\nMetrics automatically handle missing data:\n\n```ts\n// If required fields missing:\n{\n  status: 'insufficient_data',\n  value: null,\n  recommendation: 'Connect Salesforce to unlock Total Pipeline Value'\n}\n\n// If some optional fields missing:\n{\n  status: 'good',\n  value: 2500000,\n  confidence_score: 0.85  // 85% complete (down from 1.0)\n}\n```\n\n---\n\n## Dark Mode\n\nAll components support dark mode out-of-the-box:\n```tsx\n// Good in light AND dark\n<SpineCard metric={metric} />\n```\n\n---\n\n## Formula Support\n\nMetricEngine supports:\n- `SUM(field)` — sum all values\n- `AVG(field)` — average\n- `COUNT(field)` — count non-null\n- `RATE(numerator, denominator)` — percentage\n- `(formula1 - formula2) * 100` — arithmetic\n\n---\n\n## Performance\n\n- Metrics computation: O(n) per metric\n- Component rendering: memoized, no re-renders unless data changes\n- Trend calculation: cached with historical data\n- Recommended: Query Spine once per page load, cache with SWR\n\n---\n\n## Common Patterns\n\n### Show metrics for domain\n```tsx\nconst metrics = METRICS_BY_DOMAIN.sales_revops.map(metric =>\n  MetricEngine.computeMetric(metric, spineRows)\n);\n```\n\n### Filter by status\n```tsx\nconst critical = metrics.filter(m => m.status === 'critical');\n```\n\n### Group by category\n```tsx\nconst byCategory = {\n  deals: metrics.filter(m => m.metric_id.includes('deal')),\n  pipeline: metrics.filter(m => m.metric_id.includes('pipeline')),\n};\n```\n\n### Export to CSV\n```tsx\nconst csv = metrics.map(m => \n  `${m.metric_name},${m.value},${m.status}`\n).join('\\n');\n```\n\n---\n\n## Troubleshooting\n\n### Metrics showing \"insufficient_data\"\n**Check:** Are Spine fields being populated by Loader? Verify:\n- `CANONICAL_FIELDS` mapping is correct\n- Loader is running and normalizing data\n- Spine rows contain non-null values for required fields\n\n### Confidence score < 100%\n**Expected:** This is OK. Means some optional fields missing.\n- System still computes metric with available fields\n- Recommendation shows which tool to connect to complete it\n\n### Trend showing \"flat\"\n**Check:** Is historical data available?\n- Trends require multiple data points over time\n- First load always shows \"flat\" (no history)\n- Use `historicalMetrics` param: `MetricEngine.computeMetric(def, spineRows, historical)`\n\n---\n\n## Files to Know\n\n```\npackages/domain-shells/workbenches/\n├── foundation/\n│   ├── spine-types.ts      ← Type definitions\n│   ├── metric-engine.ts    ← Computation logic\n│   └── metrics-definitions.ts ← All metric definitions\n├── components/\n│   ├── spine-card.tsx      ← Metric display\n│   └── data-gap-prompt.tsx ← Missing data guidance\n├── sales-revops-workbench.tsx ← Example workbench (copy this pattern)\n└── index.ts                ← Exports everything\n```\n\n---\n\n## Next: Build Finance Workbench\n\n1. Copy `sales-revops-workbench.tsx` → `finance-workbench.tsx`\n2. Replace `METRICS_BY_DOMAIN.sales_revops` → `METRICS_BY_DOMAIN.finance`\n3. Swap domain name in title/header\n4. Add to exports in `index.ts`\n5. Deploy\n\nTotal time: ~20 minutes per workbench.\n\n---\n\n## Docs\n\n- **Full Guide:** `WORKBENCH_IMPLEMENTATION_GUIDE.md`\n- **System Overview:** `COMPLETE_SYSTEM_DELIVERY.md`\n- **Thresholds Reference:** `WORKBENCH_DELIVERY_COMPLETE.txt`\n\n---\n\n**You're ready. Deploy Sales/RevOps. Scale with the pattern. Go fast.**\n"}