Files
meshcore-analyzer/BUILD_PLAN.md
T

139 lines
5.2 KiB
Markdown

# MeshCore Analyzer — Build Plan
## What Is This
Open-source, self-hosted MeshCore mesh network packet analyzer. Community alternative to the closed-source `analyzer.letsmesh.net`.
**Live instance:** https://analyzer.00id.net
## Tech Stack
- **Frontend**: SPA, vanilla HTML/CSS/JS, Leaflet maps, WebSocket live feed, Canvas animations
- **Backend**: Node.js + Express + better-sqlite3 + ws + mqtt
- **Decoder**: Custom `decoder.js` (from MeshCore Packet.h spec)
- **Data**: SQLite, MQTT ingestion, REST API, manual packet injection
## Architecture
### Custom Decoder
The `@michaelhart/meshcore-decoder` npm library has a path parsing bug — treats `path_length` as raw byte count. Per `Packet.h`, it encodes `hash_size` (top 2 bits) + `hash_count` (lower 6 bits). We wrote `decoder.js` from scratch.
### Packet Ingestion
- MQTT subscriber (configurable broker/topic)
- Companion bridge (BLE → MQTT via `meshcore_observer.py`)
- POST `/api/packets` for manual injection
- WebSocket broadcast to all connected clients
### Channel Decryption
- Hashtag channel keys derived via `sha256("#name")[:16]`
- 1-byte channel hash means collisions — must verify by successful decryption
- Known PSKs configurable in `config.json`
## Completed Milestones
### M1: Custom Packet Decoder ✅
### M2: SQLite Schema ✅
### M3: Server + MQTT + WebSocket + API ✅
### M4: SPA Shell + Packets Page ✅
- Grouped/ungrouped views, detail panel, color-coded byte breakdown
- Resizable columns with localStorage persistence
- Packet hash click → detail with hex dump, field table
### M5: Map Page ✅
- Leaflet dark tiles, node markers by role, clustering
- Last-heard filters, region quick-jump
- Click marker → popup with node info
### M6: Channels Page ✅
- Chat-style UI with channel sidebar, message feed
- Decryption using known PSKs, @mention highlighting
- Hash collision filtering (encrypted packets excluded from named channels)
### M7: Nodes Page ✅
- Searchable directory with role tabs, detail panel
- QR code sharing, advert timeline
- Node health cards with status reasoning
- Favorites system (localStorage stars, "Your Nodes" home section)
- Responsive mobile layout, full-screen single-node detail via `#/nodes/PUBKEY`
- Prefix search dropdown on home page
### M8: Trace Routes ✅
### M9: Observer Status ✅
### M10: Polish ✅
- Dark mode toggle, global search (Ctrl+K)
- Config file support, README
### M11: Synthetic Packet Generator ✅
### M12: End-to-End Validation ✅
### M13: Frontend Smoke Tests ✅
### M14: Accessibility ✅
- Semantic HTML, ARIA attributes, keyboard navigation
- WCAG AA contrast verification on map and channel screens
- Proper focus management, screen reader landmarks
### M15: Dark Mode Overhaul ✅
- Explicit `data-theme` attribute (never remove — `prefers-color-scheme` trap)
- Consistent dark theme across all pages
### M16: Loading States & Visual Polish ✅
### M17: Mobile Responsive ✅
- Fully responsive layout, hamburger menu
- Touch-friendly controls, viewport fixes
### M18: Home Page ✅
- Hero section, node health cards, prefix search dropdown
- "Your Nodes" favorites section, "View packets" filtered link
### M19: Analytics Dashboard ✅
- Deep mesh network insights, charts, activity heatmaps
### M20: Live Page ✅
- Real-time animated map with contrail trails and shockwave pulses
- Traveling dots along hop paths, ghost hop interpolation
- Sound effects per packet type (toggleable)
- Heat map overlay, packet feed with detail cards
- Replay button on feed cards
- Auto-hide nav bar on inactivity
- Nav bar height-aware layout with Leaflet invalidateSize
### M21: VCR Controls ✅
- Pause/Play/Rewind/Speed (1x/2x/4x/8x)
- Buffer-based architecture — WS always stores, display consumes from playhead
- Option C unpause: "You missed N packets. [▶ Replay] [⏭ Skip to live]"
- Timeline scrubber with density sparkline, red playhead, click-to-seek
- Scope selector: 1h / 6h / 12h / 24h
- Rewind fetches from DB, prepends to buffer
- Replay uses real timestamp gaps (capped 2s) / speed multiplier
## File Structure
```
meshcore-analyzer/
├── package.json
├── config.json (MQTT broker, channel keys, regions)
├── server.js (Express + WS + MQTT + API)
├── decoder.js (custom packet decoder)
├── db.js (SQLite schema + queries)
├── data/
│ └── meshcore.db
├── public/
│ ├── index.html (SPA shell + nav)
│ ├── style.css (global theme)
│ ├── app.js (router, WS client, utils)
│ ├── home.js/css (home page)
│ ├── packets.js (packets browser)
│ ├── map.js (Leaflet map)
│ ├── channels.js (channel chat)
│ ├── nodes.js (node directory)
│ ├── traces.js (packet traces)
│ ├── observers.js (observer status)
│ ├── analytics.js (analytics dashboard)
│ ├── live.js/css (live view + VCR)
│ └── vendor/ (third-party libs)
└── tools/
├── generate-packets.js
├── e2e-test.js
└── frontend-test.js
```
## Default Test Data
Public channel key: `8b3387e9c5cdea6ac9e5edbaa115cd72`