A stability and data integrity release — fixing critical crashes, broken observer data, and WebSocket storms, while adding transport code visibility, geo-filtering, and a fully responsive navigation bar.
15 commits · 35 files · +1,659 / -229 · 3 contributors · 9 issues closed
🐛 Critical Fixes
Packets page crash on mobile (#326) — Number(null) silently set the time window to "All time", loading 50K+ packets and crashing iOS Safari/Edge. Fixed with proper guard, 1K packet cap on mobile, and restricted time window options.
Observer metadata broken since Go migration (#320, #321) — Battery, uptime, noise floor read at wrong nesting level; SNR/RSSI case-sensitive with no fallback. All fields now work with 10 regression tests.
Hash stats frozen on historical data (#303) — Reconfigured repeaters now show updated hash size immediately instead of requiring dozens of adverts to shift the statistical mode.
WebSocket replaying entire database (#349) — Corrupted DB caused the poller to start from ID 0, broadcasting 76K packets at ~2,000/sec. Poller now cross-checks against the in-memory store.
✨ Features
Transport code badge (#241) — "T" badge on packets using T_FLOOD / T_DIRECT routing — instant visibility into transport adoption across the mesh.
Geo-filter enforcement (#215) — Server-side polygon boundary filtering, automatic DB pruning for out-of-bounds nodes, and a visual geofilter-builder tool.
Responsive navigation (#322) — Hamburger menu at ≤1023px with drawer scroll, outside-click close, Escape key, and aria-expanded. Priority+ pattern on tablets (768–1023px): 5 primary tabs inline + "More ▾" dropdown for the rest.
🎨 Improvements
Side pane contrast (#334) — Card-style backgrounds on node detail side pane sections, fixing poor dark mode contrast.
WebSocket time filtering — WS packets now respect the selected time window instead of showing data from days ago.
CI runner cleanup (#333) — Automatic Docker image pruning after deploy. Runner was 100% full (18.8GB of dangling images).
Full changelog: v3.1.0...v3.2.0