fix(unified): merge nodes across sources so labels show in unified view (#3135)#3137
Merged
Conversation
…d view (#3135) The unified Nodes view (`/api/poll` and `/api/nodes` with no `sourceId`) was returning every per-source row from the composite-keyed `nodes` table. A node heard on an RF source (with NodeInfo) and an MQTT-bridged source (with only a transit packet, so `longName/shortName = null`) appeared twice in the UI — once labeled, once as `Node <nodeNum>`. `getAllNodesAsync` now collapses the per-source rows into one entry per `nodeNum` when no `sourceId` is supplied. The merge picks the newest row by `lastHeard`, back-fills any empty fields from older rows, and OR's the `isFavorite`/`isIgnored`/`favoriteLocked` user-intent flags across sources. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job PR Review: Unified Node DeduplicationCompleted comprehensive review of this pull request for code quality, potential issues, and best practices. Todo List:
Overall Assessment: ✅ EXCELLENTThis is a well-implemented solution to the unified node deduplication problem. The code demonstrates strong software engineering practices with comprehensive testing and clear documentation. Code Quality: 9.5/10Strengths:
Minor Suggestions:
Test Coverage: 10/10The test suite is exemplary:
Performance Considerations: 9/10Efficient Implementation:
Scale Appropriateness:
Security: 10/10No security concerns identified:
Bug Analysis: 9/10Well Handled Edge Cases:
Potential Concern:
Integration Quality: 10/10Perfect integration with existing codebase:
Architecture Compliance: 10/10Fully compliant with MeshMonitor's architecture:
Documentation: 9/10
Recommendations:
Final Verdict: ✅ APPROVEDThis PR excellently solves the unified node deduplication problem with:
The implementation follows MeshMonitor's high-quality standards and should be merged confidently. |
3 tasks
Yeraze
added a commit
that referenced
this pull request
May 22, 2026
…ish (#3145) Version bump and CHANGELOG entry for 4.6.5. Highlights: - #3143 MQTT Bridge mirror dashboard (read-only Open button on bridge cards; suppresses every TX surface; MqttBridgeManager now exposes the Meshtastic-shaped methods the consolidated /api/poll + /api/connection endpoints expect). - #3142 MeshCore Telemetry dashboard tab via source-agnostic Dashboard. - #3141 MeshCore: preserve LPP channel byte in remote telemetry rows. - #3140 DM: skip PKI flag when keyMismatchDetected. - #3138 docs reorganization. - #3137 unified: merge nodes across sources so labels show in the unified Nodes view. - #3136 mqtt: allow standalone mqtt_bridge as client-proxy target. CLAUDE.md version line updated to 4.6.5. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The unified Nodes view (
/api/polland/api/nodeswith nosourceId) was returning every per-source row from the composite-keyednodestable. A node heard on both an RF source (with NodeInfo) and an MQTT-bridged source (with only a transit packet, solongName/shortName = null) appeared twice — once labeled, once asNode <nodeNum>. This PR collapses the duplicates into one merged row per node when no source is selected.Changes
src/server/utils/mergeNodesAcrossSources.ts— new helper. Newest row bylastHeardwins (tiebreaker:updatedAt); empty fields are back-filled from older rows;isFavorite/isIgnored/favoriteLockedare OR'd across sources; result is sorted byupdatedAt desc.src/server/meshtasticManager.ts—getAllNodesAsynccalls the merger whensourceIdis undefined. Per-source queries (getAllNodesAsync(sourceId)) are untouched.src/server/utils/mergeNodesAcrossSources.test.ts— 11 regression tests covering back-fill, newer-row-wins, boolean OR, position merging, three-source coverage, ordering.CHANGELOG.md— entry under[Unreleased].Issues Resolved
Fixes #3135.
Documentation Updates
CHANGELOG.md— Unreleased fix entry. No other documentation changes needed; the dedup is an internal contract change in one helper and the behavior is what users intuitively expected from the unified view.Testing
Design notes
GROUP BY/ window function. Rejected because the merge rule isn't expressible as simple aggregates (it's "newest row wins but back-fill empties, then OR booleans"), so it would have required three dialect-specific implementations for marginal gain at our scale (a few thousand rows max).🤖 Generated with Claude Code