Skip to content

feat(ui): add findings-by-category/severity breakdown card to analytics (#2195) - #4748

Merged
JSONbored merged 1 commit into
JSONbored:mainfrom
dhgoal:feat/ui-findings-breakdown-card
Jul 10, 2026
Merged

feat(ui): add findings-by-category/severity breakdown card to analytics (#2195)#4748
JSONbored merged 1 commit into
JSONbored:mainfrom
dhgoal:feat/ui-findings-breakdown-card

Conversation

@dhgoal

@dhgoal dhgoal commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

What

Adds the findings-by-category/severity breakdown card to the operator analytics dashboard (Closes #2195): AI-review findings grouped by category, each split by severity tier (blocker / warning / advisory / nit) as a stacked-count card with a proportional per-category bar.

Display slice — it reads an optional findingsBreakdown shape off the operator-dashboard payload and degrades cleanly:

  • "No findings in window" when the breakdown is present but empty (the issue's explicit empty-state deliverable), and
  • "Not yet available" until the backend aggregation is wired into the payload,

so it ships safely ahead of the feed and lights up automatically once the data lands. No src/** change.

Changes

  • findings-breakdown-card.tsx (new) — FindingsBreakdownCard + FindingsBreakdown / FindingSeverityTier types. Per category: a proportional stacked bar (guards total === 0, no divide-by-zero) + colored severity counts, ordered blocker→nit. Reuses the shared AnalyticsCardShell (feat(ui): shared analytics-card empty + loading skeleton states #2200) and StatusPill; severity colors via token classes only (bg-danger/bg-warning/bg-mint/bg-muted-foreground), no hardcoded hex.
  • findings-breakdown-card.test.tsx (new) — 4 tests: multi-category populated, single-category (zero-count severity omitted), present-but-empty, and absent-field — covering both arms of the count > 0 guards.
  • app.analytics.tsx — optional findingsBreakdown?: FindingsBreakdown on the dashboard type + renders <FindingsBreakdownCard findings={data.findingsBreakdown} /> after the acceptance-rate card.

Verification

ui:typecheck ✓ · ui:test (4/4) ✓ · ui:build ✓ · eslint 0 errors · prettier clean.

Screenshots

Net-new card — no findings-by-category card existed on /app/analytics before. Shown in both the live empty ("not yet available") and populated forms, across desktop + mobile, light + dark.

State Desktop (light) Desktop (dark) Mobile
After — populated
ready · light

ready · dark

ready · mobile
After — empty (live today)
empty · light

empty · dark

empty · mobile

Closes #2195

…cs (JSONbored#2195)

Group AI-review findings by category, each split by severity tier
(blocker/warning/advisory/nit) as a stacked-count card. Display slice:
it reads an optional findingsBreakdown shape off the operator-dashboard
payload, shows 'no findings in window' when the window is empty, and
'not yet available' until the backend aggregation is wired — so it ships
safely ahead of the feed and lights up once it lands. Reuses the shared
AnalyticsCardShell + StatusPill; severity colors via token classes only.
@dhgoal
dhgoal requested a review from JSONbored as a code owner July 10, 2026 22:11
@superagent-security superagent-security Bot added the contributor:flagged Contributor flagged for review by trust analysis. label Jul 10, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

🚨 Contributor flagged. Click here for more info: Superagent Dashboard

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 10, 2026
@loopover-orb

loopover-orb Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Tip

🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩

✅ Gittensory review result - approve/merge recommended

Review updated: 2026-07-10 22:15:31 UTC

3 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · unstable

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
Adds a new, self-contained FindingsBreakdownCard for the operator analytics dashboard: a stacked-bar view of AI-review findings grouped by category and split by severity tier, wired into app.analytics.tsx via an optional findingsBreakdown field. The component correctly guards divide-by-zero on total===0, omits zero-count severities from both the bar and the label row, and cleanly distinguishes 'not yet available' (field absent) from 'no findings in window' (field present, empty categories) — both states are exercised in the 4 included tests. This is a pure display slice with no backend wiring yet, matches the issue's explicit empty-state deliverable, and is scoped entirely to apps/gittensory-ui (no src/** coverage impact).

Nits — 5 non-blocking
  • findings-breakdown-card.tsx:1-8 — the multi-line block comment largely restates the PR description; the repo convention favors terse comments only where the WHY is non-obvious (e.g. just keep the 'blocker→nit ordering' rationale on SEVERITY_ORDER).
  • findings-breakdown-card.tsx CategoryRow uses row.category as the React key with no dedupe/uniqueness guard — fine if the backend always emits unique categories, but worth a one-line note on that assumption since nothing here validates it.
  • The component trusts that bySeverity counts sum to total without validation; if the backend ever sends a mismatched payload the bar segments will silently misrepresent proportions — acceptable for a display slice but worth flagging as a known assumption.
  • Stylistic inconsistency with CycleTimeCard's pattern in app.analytics.tsx (which handles the empty/absent case at the call site) vs. this component and AcceptanceRateCard, which handle it internally — not wrong, just worth confirming that's the established convention going forward.
  • Consider a short inline comment on the total-sum assumption for bySeverity so a future backend change that violates it is easier to trace.
Flagged checks (non-blocking)
  • Contributor trust — Contributor flagged for review
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #2195
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 94 registered-repo PR(s), 53 merged, 8 issue(s).
Contributor context ✅ Confirmed Gittensor contributor dhgoal; Gittensor profile; 94 PR(s), 8 issue(s).
Gate result ✅ Passing No configured blocker found.
Linked issue satisfaction

Partially addressed
The PR delivers the card UI, token-based severity colors, empty/unavailable states, StatusPill window label, wiring into app.analytics.tsx, and a matching Vitest suite, but it explicitly does not wire the card to src/review/stats.ts's StatsPayload as the issue requires ('No src/** change'), instead reading a placeholder field that always renders 'Not yet available' until a backend feed lands. This

Review context
  • Author: dhgoal
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 94 PR(s), 8 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/app/analytics desktop before /app/analytics after /app/analytics
/app/analytics mobile before /app/analytics (mobile) after /app/analytics (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@JSONbored
JSONbored merged commit 384d859 into JSONbored:main Jul 10, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor:flagged Contributor flagged for review by trust analysis. gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. manual-review Gittensor contributor context

Development

Successfully merging this pull request may close these issues.

feat(ui): findings-by-category/severity breakdown card

2 participants