diff --git a/tmp_roadmap_patch.py b/tmp_roadmap_patch.py new file mode 100644 index 0000000..da941d3 --- /dev/null +++ b/tmp_roadmap_patch.py @@ -0,0 +1,75 @@ +new_section = """ +### Asset Location Tracking +MSP clients frequently ask "can you find this device if it's stolen?" — this feature makes the answer yes. +Primary use case is theft recovery and asset accountability, not real-time surveillance. + +#### Approach by device type + +**Laptops & desktops (Windows/macOS/Linux) — agent-based, no MDM required:** +Location is derived from visible WiFi networks (SSID + BSSID) sent to the Google or Microsoft +Geolocation API, which returns coordinates accurate to ~50-100m. Falls back to IP geolocation +(city-level) on wired-only or WiFi-disabled machines. No GPS hardware required. + +**Phones & tablets — mobile agent app:** +A lightweight GuruRMM Agent app (iOS App Store / Google Play) reports background location and +can receive remote lock commands via standard APNs/FCM push — no Apple MDM vendor certificate +required. This covers the "find my stolen iPad" use case without the full MDM enrollment stack. + +#### Agent (Windows/macOS/Linux) +- [ ] Collect visible WiFi networks (SSID, BSSID, signal strength) - P2 +- [ ] Send to geolocation API (Google or Microsoft, configurable); store lat/lng + accuracy radius - P2 +- [ ] IP geolocation fallback when WiFi scan returns empty - P2 +- [ ] Location reported on each inventory checkin (not continuous polling) - P2 +- [ ] Policy flag: location collection enabled/disabled per site or agent - P2 +- [ ] On-demand location request (server pushes LocationRequest, agent responds immediately) - P2 +- [ ] Platform WiFi scan implementations: + - [ ] Windows: `netsh wlan show networks mode=bssid` or `wlanapi` - P2 + - [ ] macOS: CoreWLAN CWInterface.scanForNetworks - P2 + - [ ] Linux: `iwlist scan` / nl80211 via netlink - P2 +- [ ] Agent platform parity: all three platforms in same release per parity rule - P1 + +#### Server +- [ ] `agent_locations` table (agent_id, recorded_at, lat, lng, accuracy_meters, source: wifi|ip|gps, raw_wifi_scan JSON) - P2 +- [ ] Location history — retain last N readings (configurable, default 30 days) - P2 +- [ ] `POST /api/agents/:id/location` ingest endpoint - P2 +- [ ] `GET /api/agents/:id/location` — current + history - P2 +- [ ] `POST /api/agents/:id/location/request` — on-demand location pull - P2 +- [ ] Fleet location endpoint: `GET /api/sites/:id/locations` (all agents for a site) - P2 + +#### Dashboard +- [ ] Location tab on Agent Detail page — map embed (Leaflet.js, OpenStreetMap tiles, no API key) with accuracy circle - P2 +- [ ] Last known location + timestamp in Agent Overview card - P2 +- [ ] Fleet map view — all online agents for a site pinned on one map - P3 +- [ ] Location history timeline (scroll through past readings) - P3 +- [ ] "Request Location Now" button — fires on-demand poll, updates map live - P2 +- [ ] Geofence alerts — notify if agent appears outside defined boundary - P3 + +#### Mobile App (iOS + Android) — future phase +- [ ] Lightweight GuruRMM Agent app distributed via App Store / Google Play - P3 +- [ ] Background location reporting (uses standard OS location APIs, not MDM) - P3 +- [ ] Remote lock via APNs/FCM push notification (guided access on iOS, device admin on Android) - P3 +- [ ] Enrollment via QR code / enrollment URL (same server, mobile-specific agent type) - P3 +- [ ] No Apple MDM vendor certificate required — standard app distribution - P3 + +#### Out of scope (v1) +- Real-time continuous GPS tracking (battery/privacy concerns; on-demand + checkin is sufficient) +- Full MDM profile management for iOS/Android (separate MDM integration feature if ever needed) +- Wired-only machines where WiFi is disabled and IP geolocation accuracy is unacceptable + +""" + +with open('/home/guru/gururmm/docs/FEATURE_ROADMAP.md', 'r') as f: + content = f.read() + +# Insert before the --- that separates Core Agent Features from Server/API Features +# That separator comes right after the tray security section ending at line ~183 +marker = "- [ ] Optional PIN/password for sensitive actions - P3\n\n---\n\n## Server/API Features" +replacement = "- [ ] Optional PIN/password for sensitive actions - P3\n" + new_section + "\n---\n\n## Server/API Features" + +if marker in content: + content = content.replace(marker, replacement, 1) + with open('/home/guru/gururmm/docs/FEATURE_ROADMAP.md', 'w') as f: + f.write(content) + print("inserted") +else: + print("MARKER NOT FOUND")