Skip to content

fix(dashboard): replace per-miner mirror fan-out with single bulk call#1134

Merged
entrius merged 2 commits into
testfrom
feat/dashboard-module
May 14, 2026
Merged

fix(dashboard): replace per-miner mirror fan-out with single bulk call#1134
entrius merged 2 commits into
testfrom
feat/dashboard-module

Conversation

@anderdc
Copy link
Copy Markdown
Collaborator

@anderdc anderdc commented May 14, 2026

Summary

Replaces the dashboard's N parallel mirror.gittensor.io/api/v1/miners/<id>/issues calls (one per active miner, ~25+ on a typical mount) with a single call to the new /api/v1/dashboard/issues endpoint. Eliminates the rate-limit pressure visible as a cascade of 304s in DevTools on /dashboard. Also fixes #1125 (Issues Resolved trend always 0) by switching the resolved-issue predicate to the correct conjunction.

Depends on entrius/das-github-mirror#93 — must be merged + deployed first.

Architectural shape

Layer Knows about
Mirror (das-github-mirror) GitHub state only — issues, PRs. Roster-blind.
gittensor backend (api.gittensor.io) Subnet roster, miner evaluations, scoring outputs.
Frontend (this repo) Blends both — calls useAllMiners() for the roster, calls useMirrorDashboardIssues() for raw GitHub trend data, filters/buckets client-side.

Resolved predicate fix (#1125)

Old: state === 'CLOSED' && state_reason === 'COMPLETED' — missed every issue that was closed by a merged PR but not flagged COMPLETED. Trend series rendered as flat 0.

New: state === 'CLOSED' && state_reason === 'COMPLETED' && !!solving_pr?.merged_at — the conjunction matches the "Solved" definition used elsewhere in the app. Bucketing also moves from closed_at to solving_pr.merged_at so the bar reflects when the PR landed.

Changes

New files

  • src/api/models/MirrorDashboard.tsMirrorDashboardIssue, MirrorDashboardIssuesResponse
  • src/api/MirrorDashboardApi.tsuseMirrorDashboardIssues(since, enabled?) hook (single-call via useMirrorApiQuery)

Edits

  • src/api/index.ts and src/api/models/index.ts — barrel exports
  • src/pages/dashboard/dashboardData.ts:
  • src/pages/dashboard/useDashboardData.ts:
    • Replaced useMinersIssues fan-out with single useMirrorDashboardIssues call, since pinned at module load to keep the React Query cache key stable across renders/remounts
    • Dropped hasIssueActivity + activeMinerGithubIds
    • Added minerGithubIdSet memo built from minersQuery.data
    • Added blend step: dashboardIssues.filter(i => minerGithubIdSet.has(i.author_github_id))

Related Issues

Fixes #1125

Type of Change

  • Bug fix
  • New feature
  • Refactor
  • Documentation
  • Other

Screenshots

Before — DevTools Network tab on /dashboard:

After:

Test plan

  • /dashboard mounts and the Contribution Trends chart renders all four series.
  • DevTools → Network: only one mirror.gittensor.io/api/v1/dashboard/issues?since=... request fires per dashboard mount (no /miners/<id>/issues requests from the dashboard route).
  • Switching range buttons (1D / 7D / 35D / All) fires zero new mirror requests.
  • Issues Resolved trend line is non-zero on ranges where solved issues exist (Dashboard "Issues resolved" trend series is always 0 (wrong resolved-issue predicate) #1125 fixed).
  • Issues Solved KPI card matches the Issues Resolved series total for the active range.
  • Issues Opened, Merged PRs, PRs Opened series unchanged.
  • Watchlist and Miner Details pages still work — they continue to use the per-miner endpoint and are not affected by this change.

Checklist

  • New components are modularized/separated where sensible
  • Uses predefined theme (e.g. no hardcoded colors) — N/A, pure data layer
  • Responsive/mobile checked — no UI changes
  • Tested against the test API
  • npm run format and npm run lint:fix have been run
  • npm run build passes
  • Screenshots included for any UI/visual changes — added once mirror PR is deployed and Network tab is verifiable

Out of scope

  • 1D range still uses day-granularity bucketing from a daily series — works visually but loses the 3-hour resolution. If we need it back we can either add bucket=hour to the mirror endpoint or compute hourly buckets client-side from the same dataset.
  • Watchlist and Miner Details continue to use useMinersIssues per-miner — N is small there, no rate-limit pressure.

Replaces N parallel mirror.gittensor.io/api/v1/miners/<id>/issues calls
on every dashboard mount with a single call to /api/v1/dashboard/issues
(see entrius/das-github-mirror#93). Eliminates the rate-limit cascade of
304s on /dashboard.

Also fixes #1125 (Issues Resolved trend always 0): the resolved-issue
predicate is now the conjunction (state=CLOSED, state_reason=COMPLETED,
solving_pr.merged_at not null) and the resolved bucket uses
solving_pr.merged_at instead of closed_at.

Architecture: mirror is roster-blind, gittensor backend owns the miner
roster, frontend blends. Watchlist and Miner Details continue to use the
per-miner endpoint (low N, page-scoped).
@xiao-xiao-mao xiao-xiao-mao Bot added the bug Something isn't working label May 14, 2026
# Conflicts:
#	src/pages/dashboard/dashboardData.ts
#	src/pages/dashboard/useDashboardData.ts
@entrius entrius merged commit 5b26ccb into test May 14, 2026
2 checks passed
@entrius entrius deleted the feat/dashboard-module branch May 14, 2026 02:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dashboard "Issues resolved" trend series is always 0 (wrong resolved-issue predicate)

2 participants