fix(miner-ui): reunify the portfolio view with the CLI's own richer dashboard - #5479
Conversation
…ashboard (JSONbored#4846) The portfolio view re-implemented its own narrower, global-only aggregation instead of reusing the CLI's own richer, per-repo `queue dashboard` output. The local API middleware now calls collectPortfolioDashboard directly (the same aggregator the CLI and the read-only MCP tool already use), and the view renders a per-repo table alongside the existing global summary cards.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-07-12 22:40:11 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 5 non-blocking
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk Gittensory a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands Visual preview
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.
|
Summary
{ total, counts }) instead of reusing the CLI's own richer, per-repoqueue dashboardoutput — a real functional regression, not just duplicated code, and the miner-ui and CLI maintained two separate data paths for the same underlyingminer_portfolio_queuestore.apps/gittensory-miner-ui/vite-portfolio-queue-api.ts(the local dev-server API middleware) now callspackages/gittensory-miner/lib/portfolio-dashboard.js's existingcollectPortfolioDashboard— the SAME pure aggregatorgittensory-miner queue dashboardand the read-onlygittensory_miner_get_portfolio_dashboardMCP tool already use — instead of a bespoke, narrower re-implementation. One shared data path now feeds the CLI, the MCP tool, and the UI.apps/gittensory-miner-ui/src/lib/portfolio-queue.ts'sPortfolioQueueSummarytype now matches the CLI's dashboard shape ({ total, byStatus, repos: [{repoFullName, byStatus, total}], oldestQueuedAgeMs }) instead of the old flat{ total, counts }.apps/gittensory-miner-ui/src/routes/portfolio.tsxnow renders a per-repo breakdown table (using the shared@jsonbored/gittensory-ui-kitTablecomponent, matching the existingrun-history.tsxroute's pattern) beneath the existing global summary cards, so the view shows the same per-repo detail the CLI'squeue dashboardalready shows — not just a global aggregate.identifier/priorityare).Fixes #4846
Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally — this change lives entirely underapps/gittensory-miner-ui/**(a separate vitest workspace covered byui:test, not the roottest:coverage/Codecov-measured slice) andpackages/gittensory-miner/**, which sits outside vitest'scoverage.includeglob today.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run build:minernpm run test:miner-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:testnpm run ui:buildnpm audit --audit-level=moderateRan the full
apps/gittensory-miner-uitest suite (33/33 passing, including 14 in the rewrittenportfolio-queue.test.tsx) plusnpm run ui:lint/ui:typecheck/ui:test/ui:buildat the root (all green). Also manually started the real dev server and curledGET /api/portfolio-queueagainst a fresh (no local state) install to confirm the live endpoint returns the new shape end-to-end ({"summary":{"total":0,"byStatus":{...},"repos":[],"oldestQueuedAgeMs":null}}), not just the unit-test doubles.Test coverage added/updated: per-repo table rendering (row-per-repo, correct per-status columns), the fresh-install/loading/error states unchanged, the API handler's wiring to the (now dynamically-imported, to avoid a
node:sqlite-via-portfolio-queue.jsbundling failure in the UI's client/test environment) dashboard aggregator, the fresh-install fast path (never initializes the store), a 500-on-store-failure path, and aoldestQueuedAgeMs: nullcase when nothing is queued. The aggregation algorithm's own correctness (sorting, per-repo grouping, oldest-queued-age math) is already exhaustively covered by the pre-existingtest/unit/miner-portfolio-dashboard.test.ts— this PR's tests verify the API handler's wiring/serialization, not re-derive that math.Safety
/api/portfolio-queuedev-server endpoint's response shape changed (documented above); no public API/OpenAPI/MCP surface is touched.UI Evidencesection below.UI Evidence
This is a local-only, loopback dev-server dashboard with no hosted/public deployment to screenshot from this environment (no browser screenshot tooling available here). Verified functionally instead:
npm run ui:test(33/33 passing, including full render assertions for the new per-repo table — column headers, one row per repo, correct per-status counts) and a livecurlagainst the real running dev server (see Validation above) confirming the endpoint's real response shape end-to-end on a fresh install.Notes
queue dashboardoutput leads with the same global totals before its per-repo table, so this mirrors that ordering.oldestQueuedAgeMsis now also surfaced end-to-end (part ofcollectPortfolioDashboard's existing output) even though not explicitly named in the issue's acceptance criteria — it comes for free from sharing the same aggregator and further closes the CLI/UI parity gap the issue is about; not yet rendered in the UI (kept the visible scope to the requested per-repo table) but available on the typed summary for a follow-up.