docs/adr/.issue-177-body.md
RuView is a WiFi-based human pose estimation system built on ESP32 CSI (Channel State Information). Today, managing a RuView deployment requires juggling 6+ disconnected CLI tools: esptool.py for flashing, provision.py for NVS configuration, curl for OTA and WASM management, cargo run for the sensing server, a browser for visualization, and manual IP tracking for node discovery. There is no single tool that provides a unified view of the entire deployment — from ESP32 hardware through the sensing pipeline to pose visualization.
This issue tracks the implementation of RuView Desktop — a Tauri v2 cross-platform desktop application that replaces all of these tools with a single, cohesive interface. The application is designed as the control plane for the RuView platform, managing the full lifecycle: discover, flash, provision, OTA, load WASM, observe sensing.
| Requirement | Why Desktop is Required |
|---|---|
| Serial port access | Browser/PWA cannot touch COM/tty ports for firmware flashing |
| Raw UDP sockets | Node discovery via broadcast probes requires raw socket access |
| Filesystem access | Firmware binaries, WASM modules, model files live on local disk |
| Process management | Sensing server runs as a managed child process (sidecar) |
| Small binary | Tauri ~20 MB vs Electron ~150 MB |
| Rust integration | Shares crates with existing workspace |
The frontend uses a Foundation Book design scheme with Unity Editor-inspired UI panels. Think: clean typographic hierarchy, structured panels with dockable regions, monospaced data displays, and a professional dark theme with accent colors for status indicators. Powered by rUv.
The full architecture is documented in ADR-052 with a companion DDD bounded contexts appendix.
The desktop app is a new Rust crate (wifi-densepose-desktop) in the existing workspace, sharing types with the sensing server and hardware crate. The frontend uses React + Vite + TypeScript with a Foundation Book / Unity-inspired design system.
| Group | Commands | Bounded Context |
|---|---|---|
| Discovery | discover_nodes, get_node_status, watch_nodes | Device Discovery |
| Flash | list_serial_ports, flash_firmware, read_chip_info | Firmware Management |
| OTA | ota_update, ota_status, ota_batch_update | Firmware Management |
| WASM | wasm_list, wasm_upload, wasm_control | Edge Module |
| Server | start_server, stop_server, server_status | Sensing Pipeline |
| Provision | provision_node, read_nvs | Configuration |
| Page | Purpose |
|---|---|
| Dashboard | Node count (online/offline), server status, quick actions, activity feed |
| Node Detail | Single node deep-dive: firmware, health, TDM config, WASM modules |
| Flash Firmware | 3-step wizard: select port, select firmware, flash with progress bar |
| WASM Modules | Drag-and-drop upload, module list with start/stop/unload |
| Sensing View | Live CSI heatmap, pose skeleton overlay, vital signs |
| Mesh Topology | Force-directed graph: TDM slots, sync drift, node health |
| Settings | Server ports, bind address, OTA PSK, UI theme |
6 bounded contexts with 9 aggregates, 25+ domain events, and 3 anti-corruption layers. See the DDD appendix for full details.
| Context | Aggregate Root(s) | Key Events |
|---|---|---|
| Device Discovery | NodeRegistry | NodeDiscovered, NodeWentOffline, ScanCompleted |
| Firmware Management | FlashSession, OtaSession, BatchOtaSession | FlashProgress, OtaCompleted, BatchOtaCompleted |
| Configuration | ProvisioningSession | NodeProvisioned, ConfigReadBack |
| Sensing Pipeline | SensingServer, WebSocketSession | ServerStarted, FrameReceived |
| Edge Module (WASM) | ModuleRegistry | ModuleUploaded, ModuleStarted |
| Visualization | Query model (no aggregate) | Consumes all upstream events |
Stored in ~/.ruview/nodes.db (SQLite). On startup, previously known nodes load as Offline and reconcile against fresh discovery. The app remembers the mesh across restarts.
The TdmSafe rolling update strategy updates even-slot nodes first, then odd-slot nodes, ensuring adjacent nodes are never offline simultaneously during mesh-wide firmware updates.
| Platform | Concern | Solution |
|---|---|---|
| macOS | USB serial drivers need signing on Sequoia+ | Document driver requirements |
| Windows | COM port naming, UAC | Auto-detect via registry |
| Linux | Serial port permissions | Bundle udev rules installer |
| Phase | Scope | Priority |
|---|---|---|
| 1. Skeleton | Tauri scaffolding, workspace integration, React window | P0 |
| 2. Discovery | Serial ports, node discovery, dashboard cards | P0 |
| 3. Flash | espflash integration, flashing wizard | P0 |
| 4. Server | Sidecar sensing server, log viewer | P1 |
| 5. OTA | HTTP OTA with PSK auth, batch TdmSafe | P1 |
| 6. Provisioning | NVS GUI form, read-back, mesh presets | P1 |
| 7. WASM | Module upload/list/control | P2 |
| 8. Sensing | WebSocket, live charts, pose overlay | P2 |
| 9. Mesh View | Topology graph, TDM visualization | P2 |
| 10. Polish | App signing, auto-update, onboarding wizard | P3 |
Total estimated effort: ~11 weeks for a single developer.
Powered by rUv