Skip to main content

Companion data-analyst — line charts, KPI deltas, tables (feature-parity pass 2)

Date: 2026-07-02 Branch: aziz/feat/companion-data-analyst-charts (continues PR #1423) Status: approved-by-default (Aziz said “continue”; recommended options chosen — overridable)

Goal

Extend the companion data-analyst skill (shipped in #1423 with Sankey + Pie + Bar + Metric) so it can also render line charts, a data table, and KPI cards with a period-over-period delta inline in chat — the “basic necessities for a data analyst” — each carrying as much of the Sankey/flow-analyst feature set as cheaply applies, plus a link into the Impact Dashboard.

Feature set being ported (from Sankey / conversation-flow-analyst)

#Sankey featureApplies to Line/Bar/Pie/Table/KPI here?
1Discover options (get_sankey_dimensions)No — Sankey-specific (multi-dim contingency table); the impact metrics are fixed.
2Fetch via a dedicated toolYesget_impact_report (extended).
3Render inline as an interactive specYes — Line (new), Bar/Pie/Metric (done), Table (existing component).
4Drill-down to ticketsNo (defaulted) — Sankey keeps its own; not built for these.
5Deep-link to Impact DashboardYes — link to /reports/impact-dashboard + date range (no arbitrary-chart reconstruction; the metric charts are fixed).
6Period-over-period comparisonYes — two get_impact_report calls; also powers KPI deltas.
7Configurable dimensionsNo — Sankey-specific (see #1).
8Graceful load/empty statesYes — reuse the shimmer/fallback the registry entries already have.
Out of scope (defaulted; follow-ups): ticket drill-down for these charts, dashboard chart reconstruction, CSV export, Area chart (redundant), CSAT time-series, slicing the fixed metrics by channel/dimension.

Work items

1. Backend — one additive field for the automation-rate line

File: backend/src/public-api/controllers/impact-report.public.controller.ts. Add automation_rate_daily: [{ day, automation_rate }] to ImpactReportResponseSchema, derived per-day from the already-computed resolutions_daily (same assist-filtered source), using the same automation-rate formula the endpoint already uses for the scalar automation_rate. Additive only — existing fields unchanged. Resolutions/sentiments lines reuse the existing resolutions_daily / sentiments_daily; no new fields for those. Regenerate the mcp-server client types; update the get_impact_report tool description (dashboard/packages/mcp-server/src/tools/impact-report.ts) to mention automation_rate_daily.

2. Dashboard json-render — new Line spec component + Metric delta

  • Line: add LineDefinition to catalog.ts + linePropsSchema to json-render-props.ts (mirror barPropsSchema: { data: [{ day, …series }], keys, … }) + a registry entry in registry.tsx. Reuse a Recharts line chart via the hoose ChartContainer (@open/hoose/ui) and the existing reports color ramp; if a ReportLineChart doesn’t exist, add a minimal one in .../impact-dashboard/_components/common/ReportLineChart.tsx mirroring ReportStackedBarChart.tsx. No new shared abstractions beyond that one chart component.
  • Metric delta: extend the existing MetricDefinition props with an optional delta ({ value, direction: 'up'|'down'|'flat', label? } or a signed percent — pick the shape the existing Metric render can show with the smallest change) so a KPI card can show change vs the previous period. Update the Metric registry render to display it. Keep it optional so existing Metric usages are unaffected.
  • Table: already a spec component — no new component. Only documented in the skill.
  • Run pnpm -C dashboard/apps/dashboard gen:companion-prompt; commit ui-prompt.generated.ts.

3. Skill — teach data-analyst the new surfaces

File: backend/src/companion/skills/.claude/skills/data-analyst/SKILL.md.
  • Chart-choice guidance: Line for trends over time (resolutions/sentiments/automation rate from the daily arrays), Bar for stacked composition by day, Pie for share of a total, Table for exact underlying numbers, KPI card (Metric + delta) for a single headline number with change vs the previous period.
  • Automation-rate line ← automation_rate_daily; resolutions line ← resolutions_daily; sentiments line ← sentiments_daily (consistent with the existing Pie/Bar source rules).
  • Deep-link: always offer a link to {dashboardBaseUrl}/reports/impact-dashboard with the same date range so the user can see it on the dashboard.
  • KPI delta: call get_impact_report for the current and previous window, compute the delta, pass it to the Metric card.

4. Tests (real e2e, exhaustive)

  • Backend: extend impact-report.public.controller.spec.ts — assert automation_rate_daily is present, one entry per day in range, each automation_rate matches the per-day formula over resolutions_daily, ordering + zero-fill on empty days, empty window, assist-mode opted-out org (consistent with resolutions_daily), and existing fields unchanged (regression). Multi-tenant isolation already covered — extend it to the new field.
  • json-render: rely on pnpm type-check + the CI prompt-drift gate; add a focused test only if a pure helper is introduced.

Verification

cd backend && pnpm tsgo + scoped lint; cd dashboard && pnpm type-check + scoped lint; pnpm -C dashboard/apps/dashboard gen:companion-prompt; regenerate mcp-server types; run the backend spec green. Do NOT run backend pnpm lint (its --fix glob reformats unrelated files — lint touched files directly with npx eslint, no --fix).

Defaulted decisions (Aziz can override)

  • Line metrics: resolutions + sentiments + automation-rate (CSAT deferred).
  • Necessities: Table + KPI-with-delta (no Area, no CSV).
  • No ticket drill-down for these charts.
  • Deep-link = link + date range (no chart reconstruction).