Commit Graph

149 Commits

Author SHA1 Message Date
Daniel Pupius cb04054d18 Add compact attribution to NodeLocationMap and NetworkMap
Both were missing attributionControl so they rendered MapLibre's
default (full text). Now consistent with LocationMap.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 23:35:44 +00:00
Daniel Pupius bd09beff40 Fix __publicField polyfill via index.html instead of vite define
esbuild's define only accepts literals/identifiers, not arrow functions.
Inject the polyfill as a plain script tag before the module entry point
so it is available when any pre-compiled dependency uses it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 23:33:35 +00:00
Daniel Pupius 602a20cfc1 Fix several UI issues in packet stream and maps
- Fix __publicField runtime error from pre-compiled npm packages by
  defining the helper in vite optimizeDeps esbuildOptions
- Compact attribution control on LocationMap thumbnails so it doesn't
  dominate small maps
- Remove duplicate accuracy overlay in MapReportPacket (caption +
  accuracy div both at bottom-0 overlapping); accuracy still shown
  in the KeyValuePair section below
- Fix NodeLocationMap height: min-h-[300px] doesn't give ReactMap a
  resolved height, changed to h-[300px]
- Add short name lookup to TraceroutePacket hops (same pattern as
  NeighborInfoPacket)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 20:37:50 +00:00
Daniel Pupius 8130158c1e feat(cache): priority-based eviction with age protection and Bélády approximation
Replace the flat circular buffer with NodeAwareCache, a smarter eviction
strategy for historical mesh packet data:

- Packets younger than 1 hour are never evicted (recent traffic preserved)
- Under pressure, evict from the lowest-priority type first (neighbor-info
  outlasts node-info; chat messages outlast everything)
- Within a priority tier, evict from the most recently active source node —
  that node will resend soonest, so its old packet is cheapest to lose
  (Bélády approximation; protects flaky/distant node history)
- Node retention window still applies: silent nodes' packets are excluded
  from GetAll and pruned proactively before priority eviction runs

Also:
- Add --cache-retention flag (default 3h) and raise --cache-size default to 5000
- Fix decoder error strings (replace verbose Go errors with short codes)
- Add HTTP security headers middleware to server
- Fix broker dispatchLoop deadlock on source channel close
- Fix make gen-proto scanning web/node_modules for .proto files
- Fix tools target always reinstalling protoc-gen-go (handles stale arch binary)
- Move server port from 8080 to 5446; update Dockerfile, docker-compose, moat.yaml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 20:23:50 +00:00
Daniel Pupius d95a74c1d7 refactor(web): replace Google Maps with MapLibre, clean up map components
- Migrate all three map components (Map, GoogleMap, NetworkMap) to MapLibre GL JS
- Extract shared CARTO_DARK_STYLE constants into lib/mapStyle.ts
- Move buildCircleCoords to lib/mapUtils.ts (was duplicated across components)
- Rename exports: Map → LocationMap, GoogleMap → NodeLocationMap
- Remove dead props (width, height, nightMode) from LocationMap interface
- Lazy-mount GL contexts via IntersectionObserver to prevent WebGL exhaustion
- Fix Math.spread RangeError in NetworkMap bounds calculation
- Remove showLinks conditional render in favour of visibility layout property
- Remove cursor state; set canvas cursor style directly on map interactions
- Remove Google Maps API key env vars from .env.example and .env.local
- Move Vite dev server to port 5747 (avoids cached redirect on 3000)
- Fix CORS/404: set VITE_API_BASE_URL="" so browser uses Vite proxy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 20:22:12 +00:00
Daniel Pupius 6e650a7c57 chore: mark completed todos as complete 2026-03-15 16:45:23 +00:00
Daniel Pupius e8e1a112ab feat(topology): track mesh node connections and render as map polylines
Add passive topology tracking from four sources with confidence ranking:
- Zero-hop MQTT observations (continuous, per-gateway, highest frequency)
- Traceroute replies (RouteDiscovery, full path + SNR data)
- NeighborInfo packets (self-reported neighbor SNR)
- relay_node inferred links (1-hop packets with known relay)

Backend: add rx_snr (field 62) and rx_rssi (field 63) to meshstream Data
proto; extract from MeshPacket in decoder.go; regenerate Go bindings.

Frontend:
- topologySlice: LinkObservation model, per-direction confidence merge,
  24h TTL pruning, 2000-edge cap, Redux-pure (timestamp from payload)
- aggregatorSlice: add hopsFromGateway to NodeData
- __root.tsx: dispatch processTopologyPacket after each SSE message
- NetworkMap: render polylines colored by SNR (green/yellow/red/gray),
  dimmed at 0.4 opacity for viaMqtt edges; Links toggle button in legend
- NodeDetail: Connections section showing per-edge SNR, source badge,
  viaMqtt badge, and last-seen time

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-15 16:43:48 +00:00
Daniel Pupius 8779da32a8 refactor(map): extract useCallback hooks and fix XSS in NetworkMap
Convert plain function declarations inside component body to useCallback
with correct deps, eliminating the eslint-disable-react-hooks banner.
Extract buildMarkerContent to module level (pure, no state/refs).
Reorder fitMapToBounds before resetAutoZoom to avoid TDZ reference.
Replace innerHTML SVG in marker with DOM-API construction.
Replace showInfoWindow innerHTML template with .textContent DOM APIs
to eliminate XSS risk from node name/status fields.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-15 16:35:04 +00:00
Daniel Pupius 1d61a89505 fix: remove dead code, SSE error handling, bounded dedup maps
- Remove unused mustParseDuration from main.go
- Replace http.Error calls after SSE headers with plain returns;
  skip bad packets instead of killing the stream on marshal error
- Change processedPackets/seenPackets from boolean to timestamp values
  and prune entries older than 24h on each packet to prevent unbounded
  memory growth in long-running sessions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 16:27:57 +00:00
Daniel Pupius 9e5fd5bcae Add code review findings as todos
Security and architecture review of current codebase. 11 findings:
- 3 P1 (XSS, hardcoded creds, unbounded memory growth)
- 4 P2 (SSE protocol, broker deadlock, NetworkMap architecture, CORS)
- 4 P3 (security headers, error leakage, dead code, binary payload)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 15:41:24 +00:00
Daniel Pupius 3e24e6aea4 Add node topology tracking design spec
Covers link inference from traceroute, zero-hop MQTT, NeighborInfo,
and relay_node fields. Includes multi-gateway correlation, hop bounding,
SNR-colored polyline rendering on the map, and node detail connections.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 15:31:27 +00:00
Daniel Pupius e69fad97cb Add moat config 2026-03-14 20:30:11 -07:00
Daniel Pupius 69a31ca406 Split routers and extend mesh traffic retention (#1)
* Split routers on dashboard and extend retention periods

- Add Router node type with 12-hour stale timeout (vs 30 min for regular nodes)
- Create RouterList component to display router nodes separately
- Update NodeList to filter out routers (similar to gateways)
- Add yellow color scheme for router nodes to distinguish from gateways (green) and nodes (blue)
- Extend mesh traffic retention across the board:
  - Client-side packet age filter: 12h → 24h
  - Broker cache size: 50 → 200 packets
  - Messages per channel: 100 → 500

* Update regular node activity threshold to 60 minutes

* Fix TypeScript errors in router filtering logic

* Fix docker-build to use buildx explicitly with --load flag

* Add default empty value for MESHSTREAM_GOOGLE_MAPS_API_KEY in docker-build

* Restructure docker buildx command to fix path argument parsing

* Remove trailing backslash before build context path in docker-build

* Quote build args and separate path argument in docker-build
2026-01-06 12:25:34 -08:00
Daniel Pupius 245911a450 Remove duplicative block 2025-07-03 14:09:20 -07:00
Daniel Pupius 88dd1fc663 Tweak gateway visualization and card headers 2025-07-03 12:38:23 -07:00
Daniel Pupius f8c0e0d591 Render admin packets differently 2025-07-03 11:08:09 -07:00
Daniel Pupius dc36070355 Better error cards for private messages, neighbor info rendering 2025-06-23 09:47:14 -07:00
Daniel Pupius a83f4feddb Longer test timeout for broker test 2025-05-22 14:37:57 -07:00
Daniel Pupius bc3104f59c go fmt 2025-05-22 14:35:02 -07:00
Daniel Pupius ee20a1ea46 Better loading state for node page 2025-05-22 14:32:51 -07:00
Daniel Pupius 61a83bafca Better retry and reconnection logic 2025-05-21 14:35:10 -07:00
Daniel Pupius 0feb2591ef Remove stats listener since it is noisy in prod 2025-05-19 11:00:10 -07:00
Daniel Pupius 26ebc2a6f5 Ignore old packets 2025-05-07 11:32:44 -07:00
Daniel Pupius fc72e9f65a Mobile layout tweaks 2025-05-05 09:42:19 -07:00
Daniel Pupius 15e6047708 Color and layout tweaks 2025-05-05 09:12:51 -07:00
Daniel Pupius 84f8cdfe5c MQTT SetOrderMatters(false) 2025-05-04 16:12:32 -07:00
Daniel Pupius df7df6dbd6 Unique client id and fix graceful shutdown 2025-05-04 13:26:13 -07:00
Daniel Pupius 3ce8889786 Debugging prod failures 2025-05-04 10:15:42 -07:00
Daniel Pupius 92c08c0d6b Hack for handling env with spaces 2025-05-02 15:43:57 -07:00
Daniel Pupius c53486414f Fix static style serving in prod 2025-05-02 15:31:14 -07:00
Daniel Pupius ba9c8d9221 Channel name cleanup 2025-05-02 15:21:50 -07:00
Daniel Pupius 0279d5fcd4 Static file fallback for entry pages in prod 2025-05-02 15:15:48 -07:00
Daniel Pupius 2692b2e9af Track active connections 2025-05-02 14:39:57 -07:00
Daniel Pupius 5b8bee8736 Script for building and pushing docker to ECR 2025-05-02 14:39:38 -07:00
Daniel Pupius 908c851f02 Remove accidentally checked in proto generator 2025-05-02 13:57:35 -07:00
Daniel Pupius 4f6ee2ffde go fmt 2025-05-02 13:50:28 -07:00
Daniel Pupius 29e0b752ec Make clean hack 2025-05-02 13:25:43 -07:00
Daniel Pupius 23deefe061 More fixes for CI/CD 2025-05-02 13:20:57 -07:00
Daniel Pupius 5cae8fd5cf Another try at fixing proto in CI 2025-05-02 13:06:39 -07:00
Daniel Pupius 622e37ae53 Another try at fixing proto in CI 2025-05-02 13:04:56 -07:00
Daniel Pupius 1c7bfcd330 Another try at fixing proto in CI 2025-05-02 12:32:09 -07:00
Daniel Pupius 2ef4cf1166 Debug proto in CI 2025-05-02 12:28:04 -07:00
Daniel Pupius 06a81686a2 Install eslint 2025-05-02 12:24:48 -07:00
Daniel Pupius 6675c50e97 GitHub actions 2025-05-02 12:22:45 -07:00
Daniel Pupius 92313be6cd Screenshots and readme 2025-05-02 12:02:18 -07:00
Daniel Pupius e9fa0104e3 Docker set up and fixes for build 2025-05-01 15:34:16 -07:00
Daniel Pupius 68fc353673 Info page 2025-04-30 15:08:03 -07:00
Daniel Pupius e2ced4e939 packets --> stream 2025-04-30 13:11:27 -07:00
Daniel Pupius b7359339d3 Yet more map tweaks 2025-04-30 13:10:40 -07:00
Daniel Pupius ae496ace52 Makefile to make it easier to monitor bay mesh 2025-04-30 12:59:37 -07:00