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 companiondata-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 feature | Applies to Line/Bar/Pie/Table/KPI here? |
|---|---|---|
| 1 | Discover options (get_sankey_dimensions) | No — Sankey-specific (multi-dim contingency table); the impact metrics are fixed. |
| 2 | Fetch via a dedicated tool | Yes — get_impact_report (extended). |
| 3 | Render inline as an interactive spec | Yes — Line (new), Bar/Pie/Metric (done), Table (existing component). |
| 4 | Drill-down to tickets | No (defaulted) — Sankey keeps its own; not built for these. |
| 5 | Deep-link to Impact Dashboard | Yes — link to /reports/impact-dashboard + date range (no arbitrary-chart reconstruction; the metric charts are fixed). |
| 6 | Period-over-period comparison | Yes — two get_impact_report calls; also powers KPI deltas. |
| 7 | Configurable dimensions | No — Sankey-specific (see #1). |
| 8 | Graceful load/empty states | Yes — reuse the shimmer/fallback the registry entries already have. |
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: addLineDefinitiontocatalog.ts+linePropsSchematojson-render-props.ts(mirrorbarPropsSchema:{ data: [{ day, …series }], keys, … }) + a registry entry inregistry.tsx. Reuse a Recharts line chart via the hooseChartContainer(@open/hoose/ui) and the existing reports color ramp; if aReportLineChartdoesn’t exist, add a minimal one in.../impact-dashboard/_components/common/ReportLineChart.tsxmirroringReportStackedBarChart.tsx. No new shared abstractions beyond that one chart component.Metricdelta: extend the existingMetricDefinitionprops with an optionaldelta({ 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; commitui-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-dashboardwith the same date range so the user can see it on the dashboard. - KPI delta: call
get_impact_reportfor 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— assertautomation_rate_dailyis present, one entry per day in range, eachautomation_ratematches the per-day formula overresolutions_daily, ordering + zero-fill on empty days, empty window, assist-mode opted-out org (consistent withresolutions_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).