fix(map): apply per-node position override on multi-source nodes endpoint#3559
Conversation
…3551) The multi-source dashboard map fetches nodes via GET /api/sources/:id/nodes, which returns raw DB rows. Unlike /api/poll those rows never pass through enhanceNodeForClient, so the per-node position override was never applied — the map kept rendering the raw (potentially spoofed) GPS position and ignored the override. Apply getEffectiveDbNodePosition to the flat latitude/longitude/altitude the map reads, and set positionIsOverride so the misleading GPS accuracy circle is suppressed. Mirror enhanceNodeForClient's privacy semantics: private overrides are honored only for callers with nodes_private read, and the override coords are stripped from the response for everyone else. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job PR Review: fix(map): apply per-node position override on multi-source nodes endpointTasks:
Review SummaryThis is a clean, well-scoped bug fix. The root cause analysis is accurate and the implementation is sound. Here are my observations: Correctness ✅The fix correctly identifies the gap: Privacy Semantics ✅The private-override handling mirrors
One subtle behavioral difference vs. Minor ObservationsWrapper function const getEffectivePosition = (node: any) => getEffectiveDbNodePosition(node);This one-liner module-level wrapper is a thin indirection with no added value. It's likely a leftover artifact. Consider removing it and calling
const canViewPrivate = user?.isAdmin
? true
: (user ? await hasPermission(user, 'nodes_private', 'read') : false);The
Test Coverage ✅Five tests covering:
One gap: There's no test for the MeshCore branch (lines 941-974). MeshCore nodes are returned early before the override logic, so the override is not applied to them — this is probably intentional since MeshCore contacts don't have the same DB schema. A test or comment documenting this intent would be a nice addition, but it's not a regression risk for this PR. Performance ✅The VerdictApproved with minor suggestions. The fix is correct and well-tested. The only actionable suggestion is removing the redundant |
…ypass Address review feedback on #3559: - Remove the thin getEffectivePosition wrapper and call getEffectiveDbNodePosition directly at both call sites (nodes + neighbor-info). - Document that MeshCore sources return early and intentionally skip the position-override logic, since MeshCore contacts have no override columns. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job PR Review: fix(map): apply per-node position override on multi-source nodes endpointTasks:
Review SummaryThis is a clean, correct, and well-tested fix. The root cause is accurately identified and the patch is minimal and focused. Correctness ✅The fix correctly closes the gap: The previous review flagged a redundant Privacy Semantics ✅The private-override handling faithfully mirrors
One small behavioral difference to note (not a bug, but worth being aware of): MeshCore Early Return (Documented) ✅The MeshCore branch (lines 934-973) returns early before the override logic. This is intentional and is now documented with a comment explaining that MeshCore contacts don't have override columns. The previous review noted this as a gap — it's been addressed. ✅ Test Coverage ✅Five targeted tests covering all key scenarios:
The test for the MeshCore early-return path was noted as a gap in the prior review — it's still absent, but this is low risk since MeshCore nodes have a fundamentally different data shape (no override columns at all). Minor Observations
VerdictApproved. The fix is correct, well-scoped, and the earlier feedback (redundant wrapper, MeshCore comment) has been addressed. Ready to merge. |
Summary
The per-node position override was being saved correctly but never appeared on the map. The multi-source DashboardPage map fetches nodes via
GET /api/sources/:id/nodes, which returns raw DB rows. Unlike/api/poll(which runs nodes throughenhanceNodeForClient), this endpoint never applied the override, so the map kept rendering the raw — potentially spoofed — GPS position. This fixes #3551 by surfacing the effective (override) coordinates on that endpoint.Changes
src/server/routes/sourceRoutes.ts—GET /:id/nodesnow appliesgetEffectiveDbNodePositionto each node, overwriting the flatlatitude/longitude/altitudethe map reads and settingpositionIsOverride: true(which suppresses the misleading GPS accuracy circle).enhanceNodeForClient's privacy semantics: private overrides are honored only for callers withnodes_privateread, and the override coordinates are stripped from the response for everyone else.src/server/routes/sourceRoutes.positionOverride.test.tscovering: override applied to flat coords, no-override left untouched, incomplete override ignored, admin sees private override, and non-admin gets the private override hidden + coords stripped.Issues Resolved
Fixes #3551. Unblocks the "Hide from Map" workaround discussed in #3549 (which depends on the override working).
Documentation Updates
No documentation changes needed — this restores already-documented override behavior on a second endpoint.
Testing
tsconfig.server.jsontypechecks cleanly for the changed filesnodes_privateread (marker stays at raw GPS, no*Overridefields in the API response)🤖 Generated with Claude Code