fix(traceroute): scope traceroute history to the active source#3566
Conversation
The Traceroute History modal called the history endpoint without a sourceId, so the backend defaulted to unscoped (withSourceScope returns no filter when sourceId is undefined) and merged rows from every source. Viewing the Meshtastic (radio/TCP) source would mix in MQTT broker/bridge sources, which record many flood-relayed copies of the same reply — the "50 entries at the same time" symptom. Thread the active sourceId from useSource() through the modal and ApiService.getTracerouteHistory into the existing ?sourceId query param. Backend already scopes via withSourceScope once the param is present. - api.ts: getTracerouteHistory accepts sourceId, appends &sourceId= - TracerouteHistoryModal: new sourceId prop, refetch on change - App.tsx: pass sourceId from useSource() - tests: assert sourceId is forwarded (+ updated existing call assertions) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job PR Review: fix(traceroute): scope traceroute history to the active source
Overall: This is a clean, minimal, correct fix that follows the codebase's established source-scoping patterns. No backend changes were necessary — the infrastructure was already there; this PR simply threads the Code Review
The implementation is consistent with how other methods in this file handle the // Current
const sourceQuery = sourceId ? `&sourceId=${encodeURIComponent(sourceId)}` : '';
const response = await fetch(`...?limit=${limit}${sourceQuery}`);
// Consistent with the rest of the file would be:
const params = new URLSearchParams({ limit: String(limit) });
if (sourceId) params.set('sourceId', sourceId);
const response = await fetch(`...?${params}`);
The
Straightforward. Bug / Potential Issue
The existing test calls But with the new code, passing Test CoverageThe new test in The one gap is there's no test that verifies the API service actually appends Summary
|
The previous commit put sourceId before limit in getTracerouteHistory, which broke the existing api.test.ts caller getTracerouteHistory(111,222,20) — 20 was reinterpreted as sourceId. Reorder to (from,to,limit?,sourceId?) so the existing positional limit caller stays correct; the modal passes undefined for limit to keep the default. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job PR Review: fix(traceroute): scope traceroute history to the active source
Overall: Clean, minimal, correct fix. The infrastructure was already in place on the backend; this PR simply threads Code Review
|
| Test | File | Status |
|---|---|---|
sourceId forwarded to API when provided |
TracerouteHistoryModal.test.tsx:157 |
✅ New regression test |
No sourceId → called with undefined |
TracerouteHistoryModal.test.tsx:112,280 |
✅ Updated to match new 4-arg signature |
| Existing node direction / loading / error / empty tests | TracerouteHistoryModal.test.tsx |
✅ All pass |
api.test.ts existing limit test |
api.test.ts:805 |
✅ Still valid (no change needed) |
API-level test: &sourceId= appended in URL |
api.test.ts |
The one genuine gap is there's no test in api.test.ts verifying that a non-null sourceId appends &sourceId=... to the request URL. This is a minor omission — the behavior is covered at the component level — but an API-service-level test for it would be a small improvement for future maintainability.
Summary
The fix is correct and follows all established patterns. No blocking issues. The optional improvements are:
- Add an
api.test.tstest case for thesourceIdURL parameter (minor) - Consider
URLSearchParamsfor consistency with other methods inapi.ts(cosmetic)
Problem
Viewing a node's Traceroute History while on the Meshtastic (radio/TCP) source showed entries from all sources merged together — including the MQTT broker/bridge sources, which record many flood-relayed copies of the same reply. This surfaced as "~50 entries all at the same time."
Root cause
The history endpoint (
GET /api/traceroutes/history/:from/:to) already supports a?sourceId=query param and scopes viawithSourceScope. But the frontend never sent it:TracerouteHistoryModal→ApiService.getTracerouteHistory(from, to)(no sourceId)ApiService.getTracerouteHistorydidn't accept or forward a sourceIdreq.query.sourceId=undefined→withSourceScope(table, undefined)returns no filter → all sources mergedInvestigation against live data confirmed the radio/TCP source records exactly 1 traceroute row per exchange, while the MQTT broker source records 5–10 rows (flood copies), and the unscoped query merged them.
Fix
Thread the active
sourceId(fromuseSource()) through the whole chain into the existing query param. No backend change required.src/services/api.ts—getTracerouteHistory(from, to, sourceId?, limit)appends&sourceId=src/components/TracerouteHistoryModal.tsx— newsourceIdprop; refetch when it changessrc/App.tsx— passsourceIdfromuseSource()Tests
sourceIdis forwarded to the APITracerouteHistoryModal,tracerouteRoutes, andsourceRoutes.traceroutes; changed files are tsc-cleanScope / follow-up
This fixes cross-source mixing. The separate behavior where the MQTT source itself stores multiple flood copies per traceroute is intentionally left as-is (useful for later mesh-path analysis).
🤖 Generated with Claude Code