fix(dashboard): stabilize Unified source node count (#2805)#2806
Conversation
The Unified source card used two different formulas for its node count: the deduped merged count when Unified was selected, and a raw sum of per-source counts when it was not. Sum over-counted nodes shared between sources, and the fan-out hook is disabled when Unified is not the active source, so the displayed value drifted as the user clicked between individual sources. Add GET /api/unified/status returning a server-computed deduped count (COUNT(DISTINCT nodeNum) across readable sources) plus an aggregate connected flag. The dashboard now polls this on the same cadence as the per-source statuses and uses it as a single source of truth for the Unified card. The connected flag is computed across all sources (not permission scoped) so anonymous viewers see the correct connection dot — same approach as /api/unified/sources-status. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job Comprehensive Code ReviewI've thoroughly reviewed this PR which fixes the inconsistent Unified source node count (#2805). The implementation is solid with good architectural decisions and comprehensive testing. Here's my detailed analysis: ✅ StrengthsDatabase Layer (
API Endpoint (
React Integration
🔍 Technical AnalysisPerformance
Security
Maintainability
📋 Code Quality AssessmentDatabase Best Practices ✅
API Design ✅
React/TypeScript ✅
Testing ✅
🎯 Architectural AlignmentThis PR follows MeshMonitor's architectural principles:
🏆 Overall AssessmentThis is a well-executed fix that:
Verdict: ✅ Ready to merge The implementation correctly addresses issue #2805 with a clean, maintainable solution that integrates well with the existing codebase architecture. |
System Test ResultsMeshMonitor System Test ResultsTest Run: 2026-04-26 11:23:52 EDT Test Summary
✅ Overall Result: PASSEDAll deployment configurations are working correctly! Test DetailsConfiguration Import:
Quick Start Test:
Security Test:
V1 API Test:
Reverse Proxy Test:
Reverse Proxy + OIDC Test:
Virtual Node CLI Test:
Backup & Restore Test:
Database Migration Test:
DB Backing Consistency Test:
|
Summary
Fixes #2805. The Unified source card showed an inconsistent node count that drifted depending on which source was currently selected.
The card was computing its count two different ways:
unifiedSourceData.nodes.length).statusMap.nodeCount— over-counts any node present in multiple sources.Plus, anonymous viewers always saw "disconnected" because the connection check fell back to a
statusMapthat's gated bysources:read.Fix
GET /api/unified/statusreturns{ nodeCount, connected }.nodeCountisCOUNT(DISTINCT nodeNum)across the user's readable sources (permission-scoped).connectedreflects whether any source is currently up — not permission-scoped, matching the existing/api/unified/sources-status(operational signal, not user data).useUnifiedStatus()hook polls on the standard 15s dashboard cadence.DashboardPageandDashboardSidebarconsume this single source of truth for the Unified card. The previous live-merged length is kept only as a pre-poll fallback when Unified is selected.Files
src/db/repositories/nodes.ts— addedgetDistinctNodeCount(sourceIds)using DrizzlecountDistinct.src/server/routes/unifiedRoutes.ts— addedGET /status.src/hooks/useDashboardData.ts— addeduseUnifiedStatus()+UnifiedStatustype.src/components/Dashboard/DashboardSidebar.tsx— Unified dot prefersunifiedStatus.connected, falls back tostatusMap.src/pages/DashboardPage.tsx— single formula for Unified count, threadsunifiedStatusto the sidebar.Test plan
nodes.getDistinctNodeCountdedupes shared nodes across sources, handles empty list./api/unified/statusadmin all-sources, regular-user permission filter, no-readable-sources case.useUnifiedStatus.unifiedRoutes(42),useDashboardData(16),DashboardSidebar, andDashboardPagetests pass.🤖 Generated with Claude Code