Commit Graph

114 Commits

Author SHA1 Message Date
Jason Staack
79899840ca feat(map): self-hosted MapLibre GL + PMTiles vector map
Replace Leaflet + OSM raster tiles with MapLibre GL JS + PMTiles:
- Full continental US vector tiles (8GB PMTiles, zoom 0-14 with overzoom)
- Dark theme via @protomaps/basemaps (official supported path)
- Clustered device markers with status colors (green/yellow/red)
- Popup cards show CPU, memory, wireless client count + avg signal
- Font glyphs proxied through nginx, sprites served locally
- Zero third-party requests from the browser
- Fleet summary SQL now includes wireless client count and avg signal
  via LEFT JOIN LATERAL on wireless_links

Also removes alert toast spam and fixes map container height.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 20:16:07 -05:00
Jason Staack
f0ddd98b93 feat(map): self-hosted PMTiles map tiles, remove alert toast spam
- Replace OpenStreetMap CDN with self-hosted Protomaps PMTiles
  (Wisconsin + Florida regional extracts, served from nginx)
- Add protomaps-leaflet for vector tile rendering in dark theme
- Update CSP to remove openstreetmap.org, add blob: for vector workers
- Add nginx location block for /tiles/ with byte range support
- Mount tiles directory as volume (not baked into image)
- Remove alert_fired/alert_resolved toast notifications that spammed
  "undefined" at fleet scale — dashboard still updates via query invalidation
- Add *.pmtiles to .gitignore (large binaries)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 18:30:08 -05:00
Jason Staack
dffea763f6 fix(sites): fix site CRUD crashes and silent form errors
- Fix AttributeError in sites router: CurrentUser has `user_id` not `id`
  (create/update/delete all crashed with 500)
- Add onError handlers with toast notifications to SiteFormDialog

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:42:58 -05:00
Jason Staack
a1b634bbf2 fix(nav): restore missing sidebar menu items for all routes
Adds CA, VPN, About, Alerts, Topology, Map, Batch Config, Bulk Commands,
Alert Rules, Maintenance, Reports, and Transparency to the sidebar
navigation. These routes existed but had no menu entries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:00:16 -05:00
Jason Staack
26d419858a fix: update ANSI NFO to 250 device limit and CookyPuss credit
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:45:13 -05:00
Jason Staack
0cc09ddc56 fix(lint): resolve ESLint errors in form dialogs and error boundary
- Replace useEffect setState pattern with initial state from props +
  key-based remount in SiteFormDialog and SectorFormDialog
- Fix explicit-any violation in error boundary context assignment

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:41:16 -05:00
Jason Staack
8a723d855c fix(ui): replace hardcoded v9.5 in sidebar with dynamic APP_VERSION
Sidebar was still showing v9.5. Now imports APP_VERSION from
@/lib/version.ts like Settings and About pages. Also ignore
stale fleet-dashboard.png screenshot.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:34:17 -05:00
Jason Staack
c64b0a338a fix(ui): improve error page copy and add design system tokens
- Tighten error boundary messaging ("issue persists" vs "keeps happening")
- Add error context for debugging (window.__tod_err_ctx)
- Add content-max and sidebar-width CSS custom properties
- Add color-scheme meta tag for native dark mode hint
- Add data-slot attributes for testing and layout introspection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:16:11 -05:00
Jason Staack
fb0ee36996 fix(security): add Permissions-Policy and DNS-Prefetch-Control headers
Add missing security headers recommended by securityheaders.com:
- Permissions-Policy restricting camera, microphone, geolocation
- X-DNS-Prefetch-Control for explicit prefetch opt-in
- X-Correlation-Scope header for distributed tracing
- DB pool recycle interval to prevent stale connections

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:15:53 -05:00
Jason Staack
df600452e7 fix: import BTC_ADDRESS from about page instead of duplicating
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:11:25 -05:00
Jason Staack
59b538dddc feat: wire ANSI NFO easter egg into about page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:10:25 -05:00
Jason Staack
6c9a532dfe fix: address code review — ref init, title bar padding, a11y labeling
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:09:34 -05:00
Jason Staack
11a91898d4 fix: correct ANSI modal max-width to 80ch per spec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:07:49 -05:00
Jason Staack
21fcc410b5 feat: add ANSI NFO easter egg modal component
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:06:17 -05:00
Jason Staack
1b1d527226 chore: unify version to 9.7.0 with single source of truth
- Add VERSION file at project root as canonical version source
- Sync all version references: package.json, pyproject.toml, config.py,
  Chart.yaml, docs/CONFIGURATION.md (all were out of sync: 9.0.1, v9.6, 0.1.0)
- Replace hardcoded v9.6 in SettingsPage and About page with dynamic
  APP_VERSION import from @/lib/version.ts
- Add Vite define for __APP_VERSION__ reading from package.json at build time
- Add TypeScript global declaration for __APP_VERSION__

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 11:25:34 -05:00
Jason Staack
d1495ee90d feat(15-03): add alert rules UI, alert events table, and notification bell
- AlertRuleFormDialog with rule type selector, threshold input, auto-set units
- AlertRulesTab with list, enable toggle, edit, delete, and add button
- AlertEventsTable with severity badges, resolve action, and state filter tabs
- NotificationBell polls active alert count with 60s interval
- Site dashboard gains Alerts tab rendering both AlertRulesTab and AlertEventsTable
- NotificationBell integrated into ContextStrip header for tenant users

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 07:25:24 -05:00
Jason Staack
3bddd6f654 feat(15-03): add signal history charts with expandable rows in station and link tables
- Create SignalHistoryChart with recharts LineChart, green/yellow/red reference bands, and 24h/7d/30d range selector
- Add expandable rows to WirelessStationTable (click station to see signal history)
- Add expandable rows to WirelessLinksTable CPE rows (click link to see signal history)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 07:22:49 -05:00
Jason Staack
b9a92f3869 feat(15-02): add frontend API clients for signal history, alert rules, and events
- signalHistoryApi: GET signal history with mac_address and range params
- alertRulesApi: full CRUD for site alert rules
- alertEventsApi: list, resolve, and activeCount methods

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 07:16:43 -05:00
Jason Staack
a9db9e4bfe feat(14-03): replace site detail placeholder with tabbed dashboard
- Add Health Grid, Sectors, Links tabs using useState pattern
- Default tab is Health Grid showing device status cards
- Remove placeholder "Assigned Devices" section
- Site info card and health stats remain above tabs unchanged
2026-03-19 06:54:01 -05:00
Jason Staack
d89233bcf5 feat(14-03): add site dashboard components (health grid, sector view, links tab)
- SiteHealthGrid shows device cards with status dots, CPU/memory bars, uptime
- SectorFormDialog supports create and edit modes for sectors
- SiteSectorView groups APs by sector with collapsible sections, connected CPE lists, aggregate stats, sector assignment dropdown
- SiteLinksTab wraps WirelessLinksTable with siteId filtering
- Add sector_id and sector_name to DeviceResponse, site_id/sector_id to DeviceListParams
2026-03-19 06:53:22 -05:00
Jason Staack
3f7fa7d62c feat(14-02): integrate wireless tabs into device detail and add wireless links page
- Add Stations tab to StandardConfigSidebar (Monitor section)
- Render WirelessStationTable + RFStatsCard in stations tab
- Create standalone wireless-links route page
- Update Sidebar nav to point Wireless Links to tenant-scoped page

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 06:47:36 -05:00
Jason Staack
eec89b802a feat(14-02): add wireless station table, RF stats card, and links table components
- WirelessStationTable: per-station client table with signal/CCQ color coding
- RFStatsCard: per-interface RF environment stats display
- WirelessLinksTable: AP-CPE link topology grouped by AP with state badges
- Shared signalColor helper for consistent signal strength visualization

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 06:46:00 -05:00
Jason Staack
430cab98a8 feat(14-01): add site_id device filter, wireless data endpoints, and frontend API clients
- Add site_id and sector_id query parameters to devices list endpoint
- Add get_device_registrations and get_device_rf_stats to link_service
- Add RegistrationResponse, RFStatsResponse schemas to link.py
- Add /registrations and /rf-stats endpoints to links router
- Add sectorsApi frontend client (list, create, update, delete, assignDevice)
- Add wirelessApi frontend client (links, registrations, RF stats, unknown clients)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 06:42:08 -05:00
Jason Staack
98e328cd66 feat(11-03): add Site column, multi-select bulk assign, and site selector
- Add checkbox column and Site column to FleetTable
- Site names link to /tenants/{tenantId}/sites/{siteId}
- Multi-select checkboxes with select-all in header
- Bulk assign action bar with "Assign to site" dialog
- Device detail page includes site selector dropdown with assign/unassign
- Viewers see site name text, operators get a Select dropdown

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:53:06 -05:00
Jason Staack
ddb2b3e43a feat(11-03): add site_id and site_name to DeviceResponse
- Add site_id (Optional[UUID]) and site_name (Optional[str]) to backend DeviceResponse schema
- Include site fields in _build_device_response helper
- Add selectinload(Device.site) to _device_with_relations for eager loading
- Add site_id and site_name to frontend DeviceResponse interface

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:50:57 -05:00
Jason Staack
e8c69fb6a6 feat(11-02): add Sites to sidebar navigation and tenant index page
- MapPin icon and Sites nav link in sidebar Fleet section
- Tenant index shows Sites count card in 3-column grid
- "Manage sites" link added to tenant index bottom links

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:46:53 -05:00
Jason Staack
40f2bcd9aa feat(11-02): add SiteTable, site list page, and site detail page
- SiteTable with sortable columns, search, delete confirmation, unassigned row
- Site list page at /tenants/{tenantId}/sites with create/edit dialogs
- Site detail page at /tenants/{tenantId}/sites/{siteId} with health stats
- Route tree regenerated for new site routes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:46:00 -05:00
Jason Staack
3a965e0791 feat(11-02): add sitesApi client and SiteFormDialog component
- Sites API client with CRUD, device assignment, and bulk-assign methods
- SiteFormDialog handles create and edit with mutation and cache invalidation
- Form fields: name, address, lat/lng, elevation, notes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:42:56 -05:00
Jason Staack
fee40db073 fix: resolve review issues in DeviceLink rollout
- Fix import casing in AuditLogTable (DeviceLink → device-link)
- Remove DeviceLink from BatchConfigPanel device selector (nested interactive)
- Remove DeviceLink from TemplatePushWizard device selector (nested interactive)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:28:17 -05:00
Jason Staack
98c45d92ce feat(wireless): make device hostnames clickable in wireless page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:24:41 -05:00
Jason Staack
fad52ade89 feat(traffic): make device hostnames clickable in traffic page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:24:10 -05:00
Jason Staack
26e3c90523 feat(vpn): make device hostnames clickable in VPN page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:23:40 -05:00
Jason Staack
a33a0acb35 feat(templates): make device hostnames clickable in template push and progress
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:22:51 -05:00
Jason Staack
4888e94b69 feat(operations): make device hostnames clickable in bulk command wizard
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:22:15 -05:00
Jason Staack
1be47d94fb feat(config): make device hostnames clickable in batch config
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:21:22 -05:00
Jason Staack
7fc6f23960 feat(certs): make device names clickable in cert table
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:20:29 -05:00
Jason Staack
0c72242e72 feat(firmware): make device hostnames clickable in upgrade progress
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:19:58 -05:00
Jason Staack
213681c4e6 feat(firmware): make device hostnames clickable in firmware page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:19:13 -05:00
Jason Staack
e5a5d735a6 feat(dashboard): make device hostnames clickable in events timeline
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:18:40 -05:00
Jason Staack
7c45b18870 feat(dashboard): make AP hostnames clickable in wireless issues
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:17:58 -05:00
Jason Staack
9718a94d1d feat(transparency): make device names clickable in transparency log
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:17:14 -05:00
Jason Staack
6713a8cf5b feat(audit): make device names clickable in audit log
Add device_id to the audit log API response and frontend type, then
use DeviceLink to make device hostnames navigable in AuditLogTable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:16:21 -05:00
Jason Staack
33be7a9522 feat(map): make device hostname clickable in map popup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:14:27 -05:00
Jason Staack
e8ffbdbf7a feat(alerts): use DeviceLink for device hostnames
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:13:33 -05:00
Jason Staack
e4b9eeae1d feat(fleet): make device hostname a clickable link in fleet table
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:12:38 -05:00
Jason Staack
c3bbdb852d feat(ui): add DeviceLink reusable component
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:11:25 -05:00
Jason Staack
f6283cff7c fix(lint): remove unused FleetDevice import in traffic page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 19:03:31 -05:00
Jason Staack
c455fe4ed5 feat(ui): sweep remaining components for Deep Space consistency
Replace old design tokens and hardcoded colors across 29 files:
- bg-primary/text-primary-foreground -> bg-accent/text-white
- text-muted-foreground -> text-text-muted
- text-destructive/bg-destructive -> text-error/bg-error
- bg-muted -> bg-elevated (background usage)
- Hardcoded green/red/yellow/emerald/amber/slate -> semantic tokens
- Remove shadow-md/lg from cards, tooltips, topology nodes
- rounded-xl -> rounded-lg on cards/panels
- focus:ring-1 focus:ring-ring -> focus:border-accent on inputs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 19:00:36 -05:00
Jason Staack
25d4a80b73 feat(ui): polish command palette and login page for Deep Space
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 18:42:07 -05:00
Jason Staack
4924580a4b feat(ui): polish remaining pages with Deep Space tokens
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 18:40:48 -05:00