Replace binary passthrough in humanize_sync_error/1 across all 6 sync
modules (Gaiia, VISP, NetBox, Preseem, Splynx, Sonar) so that raw
Erlang/SSL error messages never surface in the UI. SSL/CA cert errors
get a clean message; all other raw strings are logged and replaced with
a generic user-facing message.
- Make insight messages more descriptive (explain what untracked/ghost/mismatch means)
- Clarify action button labels on insight cards
- Redesign Gaiia mapping page to be TowerOps-centric: devices/sites as primary rows, search Gaiia for what to link them to
- Add IP-based match suggestions and smart sorting (suggestions first, then unlinked, then linked)
- Add search_inventory_items/2 and search_network_sites/2 to Gaiia context
- Make IP addresses clickable links (http://<ip>)
- Add optional Gaiia App URL setting to enable deep links to inventory items and network sites
The server only sent polling/ping jobs to agents once on WebSocket join
and never re-dispatched them. After the first batch completed (~5-10s),
devices were never polled again until the agent reconnected.
:send_jobs now schedules a follow-up dispatch every 60s (configurable).
Unifies the timer management with :assignments_changed to prevent
accumulation.
Site compound nodes have IDs like "site_<uuid>" which can't be cast to
binary_id in Ecto queries. Add guard clause to get_node_detail/2 and
skip node_clicked events for site nodes in Cytoscape hook.
- fix bidirectional link queries to find links where device is source or target
- merge A→B and B→A edges into single link with combined confidence
- include interface speed in edge data for variable edge width
- infer discovered node roles from LLDP/CDP capabilities (router, switch, wireless, phone)
- store remote_capabilities in link metadata during evidence processing
- replace Cytoscape destroy-and-recreate with element diffing to preserve zoom/pan/positions
- add node detail slide-out panel with device info, connections, and confidence
- support ?node= URL param for deep-linking to selected nodes
- add site-based compound node grouping in Cytoscape
Tests for agents, alerts, integrations, organization, members, and
invitations controllers. Refactor alert filters to reduce complexity.
75 new tests, all passing.
REST endpoints for CRUD, scoped filtering (active/upcoming/past).
GraphQL queries and mutations for maintenance windows.
Fix agent edit test assertion message.
REST API v1 endpoints for schedules (14 endpoints) and escalation
policies (10 endpoints) with full CRUD for nested resources (layers,
members, overrides, rules, targets). GraphQL types, resolvers, and
schema mutations for both resource trees.
Built-in PagerDuty-equivalent system for on-call scheduling and alert
escalation. Users can now manage schedules, rotation layers, overrides,
and escalation policies directly in the app alongside PagerDuty.
- On-call schedules with rotation layers (daily/weekly/custom), member
management, and temporary overrides
- Escalation policies with ordered rules, timeout-based escalation,
and user/schedule targets
- Automatic escalation via Oban worker with configurable repeat count
- Email notifications via Swoosh for on-call alerts
- Resolver computes who's on-call from layer stacking and overrides
- AlertNotificationWorker integration: starts escalation alongside
PagerDuty, acknowledges/resolves incidents on alert state changes
- Device and organization schemas support escalation_policy_id
- Escalation policy picker on device form
- Schedules nav item with tabbed index (schedules + escalation policies)
- Full CRUD UI for schedules, layers, members, overrides, rules, targets
- 62 LiveView tests, 56 context/schema/resolver/escalation tests
- 26 E2E Playwright tests for smoke and critical path coverage
8 of 13 OIDs were pointing to wrong MIB columns:
- RSSI: was reading ubntWlStatSignal(.5), now ubntWlStatRssi(.6)
- Quality: was reading ubntWlStatSignal(.5), now ubntAirMaxQuality(.6.1.3)
- Tx Rate: was reading ubntWlStatSsid(.2), now ubntWlStatTxRate(.9)
- Rx Rate: was reading ubntWlStatHideSsid(.3), now ubntWlStatRxRate(.10)
- Capacity: was reading ubntWlStatTxRate(.9), now ubntAirMaxCapacity(.6.1.4)
- Distance: was reading ubntWlStatSecurity(.11), now ubntRadioDistance(.1.1.7)
- Utilization: was reading WDS/Repeater booleans(.12/.13), now ubntAirMaxAirtime(.6.1.7)
- Added Signal Level sensor from ubntWlStatSignal(.5)
All 7 OIDs were reading from wrong SNMP table/columns. Frequency and
power config values pointed at the status table instead of the config
table, and capacity/signal columns pointed at unrelated fields like
radio temperature and boolean flags.
Corrected OIDs to match UBNT-AirFIBER-MIB structure:
- Frequency/power: config table (.3.1) entries 5, 6, 9
- Signal: status table (.3.2) entries 11, 14
- Capacity: status table (.3.2) entries 5, 6 with 1M divisor
The test makes a real HTTP call to GitHub which can fail or return
different responses depending on network conditions, rate limits, etc.
Tagged as :integration to exclude from normal test runs, consistent
with other GitHub API tests in ReleaseCheckerTest.
- Prefix unused variables with underscore in subscriber_matching_test.exs
- Fix unused integration_id parameters in gaiia_fixtures.ex
- Remove duplicate site_fixture/1 from access_control_test.exs
- Use public site_fixture/2 from OrganizationsFixtures instead
- Remove unused Sites alias from access_control_test.exs
All 19 subscriber matching tests passing with no warnings.
- Made normalize_mac/1 public with comprehensive documentation
- Enhanced normalize_mac to handle:
- Binary MAC addresses (6 bytes) with proper hex conversion
- Short MAC addresses with zero-padding (e.g., 'A:B' -> '0a:0b')
- Colons, dashes, and no-separator formats
- Fixed refresh_links_for_device/1 to return :ok when device not found
(was returning nil, causing test failures)
- Fixed site fallback test to use assigned_network_site_gaiia_id
(string field) instead of network_site_id (FK)
- Simplified account lookup optimization test to remove
non-existent Repo.query_count/1 dependency
All 19 subscriber matching tests now passing:
- 7 normalize_mac/1 tests (binary, colons, dashes, padding, etc.)
- 12 refresh_device_links/1 tests (all match methods, prioritization,
cross-org isolation, etc.)
The ActivityFeed groups sync logs by minute, so when creating test data with
random timestamps, multiple logs could fall within the same minute and get
grouped together, causing the test to fail. Now ensures each sync log is
exactly 60 seconds apart (different minutes).
Add CapacityInsightWorker (every 15 min) that generates critical/warning
insights when backhaul utilization exceeds 90%/75% and auto-resolves
when it drops below 70%.
Add capacity and utilization columns to the device ports tab with
set/clear capacity controls. Add organization-level /capacity page
with summary cards and per-site capacity table. Add capacity summary
card to site show page. Add Capacity link to nav menu.
- Fix ApplicationSetting duplicate key constraint errors in BillingTest and AdminTest
by deleting existing records before inserting new ones in tests
- Increase timeouts for agent_channel debounce tests from 75ms to 200ms
to prevent flaky failures on slower systems (50ms debounce + processing time)
All 7633 tests now pass consistently across multiple runs.
Connection counts (IPv4/IPv6, DHCP leases) were showing as floats
(e.g. 1270.0) in executor output, change detection messages, and
chart tooltips/axes. Now displayed as integers everywhere.
Allow superadmins to override free device limits and per-device pricing
on a per-organization basis. Overrides cascade through subscription
limits, billing calculations, and user-facing settings display.
- Add custom_free_device_limit and custom_price_per_device to organizations
- Add billing_override_changeset with validation
- Update SubscriptionLimits.effective_device_limit to respect overrides
- Update Billing to use effective free count and price per device
- Add Admin.update_billing_overrides with audit logging
- Add override editing UI to /admin/organizations
- Update org settings page to show effective limits/pricing
- Test empty activity list
- Test preseem sync logs with correct DateTime format
- Test duration formatting with integer precision
- Test sync logs without duration
- Test grouping by minute
- Test sorting by timestamp descending
- Test limit parameter
- Test date range filtering
- Test organization isolation
- Test different sync statuses (success, failed, partial)
- Test count_by_type functionality