Commit Graph

333 Commits

Author SHA1 Message Date
Jason Staack
7147b15e13 feat(13-02): add device_interfaces table migration and ORM model
- Migration 032 creates device_interfaces with RLS, MAC index, unique(device_id, name)
- DeviceInterface SQLAlchemy model with all columns and device relationship

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 06:01:22 -05:00
Jason Staack
4b5bb949e9 test(13-01): add failing tests for InterfaceInfo collector
- InterfaceInfo struct field compilation test
- MAC address lowercasing test
- Running bool parsing test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 06:01:12 -05:00
Jason Staack
caa33ca8d7 feat(12-01): add RF monitor collector, WIRELESS_REGISTRATIONS stream, wire into poll cycle
- RFMonitorStats struct for per-interface RF data (noise floor, channel width, TX power)
- CollectRFMonitor with v6/v7 RouterOS version routing
- WIRELESS_REGISTRATIONS NATS stream with 30-day retention (separate from DEVICE_EVENTS)
- WirelessRegistrationEvent type and PublishWirelessRegistrations method
- Poll cycle collects per-client registrations and RF stats, publishes combined event

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 05:38:14 -05:00
Jason Staack
390c4c1297 feat(12-02): add NATS subscriber for wireless registrations and wire into lifespan
- wireless_registration_subscriber.py: consumes wireless.registrations.> from WIRELESS_REGISTRATIONS stream
- Inserts per-client rows into wireless_registrations hypertable
- Inserts RF monitor data into rf_monitor_stats hypertable
- Uses AdminAsyncSessionLocal to bypass RLS for cross-tenant writes
- Durable consumer: api-wireless-reg-consumer with retry logic
- Wired into FastAPI lifespan with non-fatal startup and graceful shutdown

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 05:37:12 -05:00
Jason Staack
23d6b38a4d feat(12-01): add per-client wireless registration collector and signal parser
- RegistrationEntry struct for per-client wireless data (MAC, signal, CCQ, rates, distance)
- ParseSignalStrength handles all RouterOS format variations (-67, -67@5GHz, -67@HT40)
- CollectRegistrations with v6/v7 RouterOS version routing
- Unit tests for ParseSignalStrength covering 10 cases

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 05:36:08 -05:00
Jason Staack
d12e9e280b feat(12-02): create wireless_registrations and rf_monitor_stats hypertables
- wireless_registrations hypertable with per-client columns (mac, signal, rates, uptime)
- rf_monitor_stats hypertable for RF environment data (noise floor, channel width, tx power)
- RLS tenant_isolation with super_admin bypass on both tables
- Composite indexes: device+time, mac+time (for Phase 13 link discovery)
- 30-day retention policies on both hypertables
- GRANTs for app_user and poller_user

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 05:35:56 -05:00
Jason Staack
1858c88e8b docs(11-03): complete device-site assignment UI plan
- SUMMARY.md with task commits, decisions, and metrics
- STATE.md updated: Phase 11 complete (3/3 plans)
- ROADMAP.md progress updated
- Requirements SITE-03, SITE-04, SITE-05 marked complete

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:54:46 -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
6ccccb3902 docs(11-02): complete frontend site list and detail pages plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:48:51 -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
7afd918e2f feat(11-01): create site service, router, and wire into app
- Add site_service with CRUD, health rollup, device assignment functions
- Add sites router with 8 endpoints (CRUD + assign/unassign/bulk-assign)
- RBAC: viewer for reads, operator for writes, tenant_admin for delete
- Wire sites_router into main.py with /api prefix
- Health rollup computes device_count, online_count, online_percent per site

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:38:54 -05:00
Jason Staack
f7e678532c feat(11-01): create sites table migration, model, and schemas
- Add migration 030 with sites table, RLS policy, and device site_id FK
- Add Site SQLAlchemy model with tenant isolation
- Add site_id nullable FK and relationship to Device model
- Add sites relationship to Tenant model
- Register Site in models __init__.py
- Add SiteCreate, SiteUpdate, SiteResponse, SiteListResponse schemas

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:37:08 -05:00
Jason Staack
0693e0898b fix(website): make site-nav--light dark for Deep Space, bump cache
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 18:12:55 -05:00
Jason Staack
81a0bac97d fix(website): cache-bust style.css for Deep Space deploy
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 17:52:09 -05:00
Jason Staack
cf11b29f49 fix(website): replace remaining Outfit font references in blog inline styles
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 17:42:59 -05:00
Jason Staack
2eddc545d2 feat(website): replace screenshots with fresh 100-device fleet images
Swap 9 old screenshots for 8 new ones showing fleet dashboard, traffic,
firmware management, config templates, device detail, interface
utilization, device health, and traffic analytics. Update carousel
markup with Deep Space card styling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 17:42:20 -05:00
Jason Staack
4f8ab7f0d0 feat(website): retheme to Deep Space design system with local fonts
Replace CSS variables, hardcoded colors, font families, syntax token
colors, and banner styling. Swap Google Fonts for self-hosted Manrope
and IBM Plex Mono woff2 files. Update theme-color meta tags and remove
testing-banner--light variant across all 19 HTML files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 17:41:17 -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
8d8779951c feat(website): retake all screenshots with 100-device demo data
12 hours of mock device polling produced rich metrics data.
Dashboards show real bandwidth, device counts, and events.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 07:29:59 -05:00
Jason Staack
3c3ddb8487 chore: remove docs/superpowers/ from tracking
These are local-only planning docs, already in .gitignore.
Files were committed before the gitignore entry was added.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 06:42:11 -05:00
Jason Staack
e7af5e85ab feat(seo): add 6 targeted SEO pages for high-intent search phrases
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 06:39:48 -05:00
Jason Staack
31d224ca58 feat(seo): add open source MikroTik management page, update sitemap
New SEO page targeting "open source mikrotik management" keyword.
Added to sitemap with 0.8 priority. Cross-linked from existing
centralized management page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 06:25:46 -05:00
Jason Staack
b925d534bc feat(seo): add open source keywords, update sitemap, add cross-links
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 06:23:12 -05:00
Jason Staack
67caecd52c blog: add "Found a Bug Running 100 Simulated Routers"
Fourth blog post covering a NATS JetStream memory issue found
during 100-device simulation testing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 06:14:30 -05:00
Jason Staack
05e5595c2b fix(poller): add 64MB cap on DEVICE_EVENTS NATS stream
Without a byte limit, the stream grows unbounded within its 24h
max_age window. At 101 devices polling every 60s, it hits 128MB
in ~10 hours and OOMs the NATS container.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 05:52:09 -05:00
Jason Staack
556545cf9c chore: gitignore tools/dev/ for local dev tooling
Mock RouterOS server and screenshot automation live here
but should not be in the public repo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 20:11:50 -05:00
Jason Staack
0c8a473796 fix(website): retake config editor screenshot with device selected
Shows gw-bowling-alley config tree with RouterOS menu hierarchy.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 19:57:29 -05:00
Jason Staack
412f9c2530 feat(website): update screenshots for Deep Space theme with new tenants
Replace all screenshots with Deep Space dark theme captures.
New tenants: Lebowski Lanes, MXC Studios, Irken Empire.
Login screenshot now shows Secret Key fields.
Remove old Stranger's Ranch screenshot.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 19:49:26 -05:00
Jason Staack
ddcea97dd0 blog: add "What You Can Do With It Today (And What You Can't)"
Third blog post covering current capabilities, limitations, and
design philosophy. Factual inventory of what works, what's rough,
and what's missing entirely.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 19:06:22 -05:00
Jason Staack
517eb944d7 docs: update for Helm chart and telemetry changes
Add Kubernetes/Helm deployment section to DEPLOYMENT.md, telemetry
environment variables to CONFIGURATION.md, telemetry privacy details
to SECURITY.md, telemetry bullet to README quick start, and fix Go
version from 1.24 to 1.25 in docs/README.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 19:00:46 -05:00