- Created new on_mount hook :load_default_organization that automatically loads user's first organization
- Moved sites and devices routes to root path (/ sites, /devices) instead of /orgs/:org_slug
- Updated all navigation links and route references throughout the app
- Dashboard, alerts, and agents still use org-specific routes (/orgs/:org_slug)
- Users can still switch organizations via org selector for other pages
- Pass range parameter to SensorChart hook via data-range attribute
- Calculate x-axis min/max dynamically based on selected range (1h, 6h, 12h, 24h, 7d, 30d)
- Show date + time on x-axis labels for ranges > 24 hours
- Show time only for ranges <= 24 hours
- Fixes issue where 7d and 30d graphs showed incorrect time range
- Add timezone to socket assigns in mount_current_scope
- Detect user timezone from browser using Intl.DateTimeFormat
- Auto-save detected timezone to user profile on first connection
- Update all templates to use TimeHelpers with timezone parameter
- Update agent helper functions to accept timezone parameter
- Templates updated:
- Alert list (triggered, acknowledged, resolved)
- Device list (last checked)
- Agent list and show (created, last seen, updated)
- Admin dashboard (impersonation logs)
- Admin org/user lists (created/joined dates)
- Main dashboard (alert times)
The token success modal was missing z-index classes that caused the modal
content to appear behind the grey backdrop. Users could only see the
checkmark icon and couldn't interact with the modal properly.
Changes:
- Added z-0 class to backdrop div
- Added relative z-10 classes to span and modal content div
- Added unique ID to modal (token-success-modal)
- Added unique ID to modal title (token-success-modal-title)
This matches the z-index structure used in the "add token" modal.
API token creation fix:
- Handle both nested (%{"token" => %{...}}) and flat params
- Support URL-encoded form data from LiveView
- Add validation for required name and organization_id fields
Rust agent raw ICMP ping implementation:
- New ping module with async ICMP echo request/reply
- Build ICMP packets manually with proper checksum calculation
- Use socket2 for raw socket creation (requires CAP_NET_RAW)
- Parse both raw ICMP and IP-wrapped responses
- Include unit tests for checksum and packet building
- Dependencies: socket2 v0.5, rand v0.8
- Compiles successfully with release profile optimizations
User deletion bug:
- Store client IP in socket assigns during mount
- Access stored IP during delete event instead of connect_info
- Fixes RuntimeError when attempting to delete users
Timezone support:
- Add timezone offset maps for common timezones (no external deps)
- Implement shift_timezone/2 helper using DateTime.add/3
- Add timezone-aware format_datetime/2, format_date/2, format_iso8601/2
- Keep backwards-compatible 1-arity versions defaulting to UTC
- Add comprehensive test coverage for timezone conversions
- All tests passing (23 tests, 0 failures)
Note: Timezone offsets are standard time only (no DST handling)
Common timezones supported: America/New_York, America/Los_Angeles,
Europe/London, Europe/Paris, Asia/Tokyo, Asia/Shanghai, Australia/Sydney
- Replace JavaScript modal handlers with LiveView event bindings
- Add phx-click events for show_add_token_modal and cancel_add_token
- Convert plain HTML form to LiveView form with phx-submit
- Remove outdated window.liveSocket.execJS JavaScript code
- Add timezone parameter support to TimeHelpers functions:
- format_datetime/2 now accepts timezone and shifts DateTime
- format_date/2 now accepts timezone and shifts DateTime
- format_iso8601/2 now accepts timezone and shifts DateTime
- All helper functions fallback to UTC if timezone is invalid or nil
- Add tab navigation UI with Personal, Account, Security, API, Notifications tabs
- Add active_tab state management in LiveView
- Add switch_tab event handler
- Show only active tab content (like Tailwind Plus template)
- Remove section prefixes since each is now on separate tab
- Default to Personal tab on mount
- Update user settings page to use Tailwind Plus 3-column grid layout
- Add API token management section to user settings
- Implement organization name display in navigation menu
- Update table component to use Tailwind Plus styling across all tables
- Update flash notifications with Tailwind Plus design
- Update dropdown menus and select inputs with custom chevron styling
- Fix authentication redirect to return to original page after login
- Preserve user_return_to session key across session renewal
- Add store_return_to_for_liveview plug to browser pipeline
- Add profiles.json to gitignore
When clicking 'Rediscover Device', navigate to the device details page
where the user can see live updates as discovery progresses.
The device show page already subscribes to PubSub discovery events and
will automatically refresh when discovery completes, showing updated
manufacturer, model, sensors, and interfaces.
- Configure Phoenix.PubSub to use Redis adapter for pod-resilient messaging
- Add PubSub broadcasts for sensor readings updates in PollerWorker
- Add PubSub broadcasts for interface stats updates in PollerWorker
- Add PubSub broadcasts for neighbor discovery updates in PollerWorker
- Add PubSub broadcasts for monitoring check updates in MonitorWorker
- Broadcast interface and sensor events to device-specific topics
- Add event handlers in DeviceLive.Show for all update types
- Device show page now updates in real-time without polling
- Updates survive pod restarts and work across multiple pods
Updated all references to use the more technically accurate term 'ICMP Latency'
instead of 'Ping Latency' in:
- Graph titles and labels
- HTML comments
- Test assertions
- Added comprehensive tests for GraphLive.Show to ensure:
* Page renders with correct assigns
* Uses @current_organization (not @organization)
* Latency, processor, memory, and traffic graphs work
* Time range selection works correctly
* All required assigns are present
- Reordered device show page so Overall Traffic appears above Ping Latency
Shows ping latency for all devices in the site over the last 24 hours.
Each device is displayed as a separate line on the graph with its name
as the label.
Graph only appears if there is latency data available for at least
one device in the site.
- Create DiscoveryWorker for handling SNMP device discovery
- Replace Task.start with Exq.enqueue for discovery operations
- Enqueue jobs to 'discovery' queue with device_id parameter
- Add enqueue_discovery/1 helper that falls back to Task.start in test
- Discovery jobs now persistent and retryable via Exq
- Triggered on: new device creation, device update, manual rediscover button
- Make device name field optional when SNMP is enabled (ICMP Only mode still requires name)
- Add database migration to make name column nullable
- Add conditional validation: name required only when snmp_enabled is false
- Update SNMP discovery to populate device name from sysName when empty
- Add helper text explaining SNMP name population behavior in form
- Add comprehensive tests for device name SNMP population
- Update test mocks to account for NetSnmp profile sensor discovery
- After creating a device, stay on /devices/new instead of navigating to device show page
- Display success flash message with creation confirmation
- Reset form to defaults (preserving selected site) for adding next device
- Allows users to quickly add multiple devices in a row without navigation
- Add tests for staying on page and adding multiple devices sequentially
- All 91 device-related tests passing with no Credo warnings
- Add tab selector in Monitoring Configuration section for choosing monitoring mode
- SNMP & ICMP mode: enables ICMP pings + SNMP discovery (default)
- ICMP Only mode: enables only ICMP ping monitoring, hides SNMP fields
- Monitoring mode controls snmp_enabled field automatically on save
- Test SNMP Connection button shows informational message when agent is configured
(agents handle SNMP testing during their polling cycle)
- Update all tests to use tab selector instead of setting snmp_enabled directly
- All 818 tests passing with no Credo warnings
- Add Monitoring.get_latency_data/2 to query successful checks with response times
- Support 'latency' sensor type in GraphLive.Show with configurable time ranges
- Add latency chart to device show page alongside other metric charts
- Add comprehensive tests for get_latency_data/2 (limit, since, failed checks)
- All 813 tests passing with no Credo warnings
Implemented hierarchical SNMP community string inheritance following TDD:
Schema changes:
- Updated Device.changeset to remove required validation for snmp_community
- Community string is now optional when SNMP is enabled
- Allows inheritance from site or organization level
Inheritance hierarchy:
- Device-level community (highest priority)
- Site-level community
- Organization-level community
- nil (no community set at any level)
Form updates:
- extract_snmp_config now resolves inherited community for SNMP testing
- validate_test_snmp_input provides clearer error message about inheritance
- SNMP test uses effective community from hierarchy
Tests:
- Added tests for creating devices with nil/empty community string
- Added comprehensive SNMP configuration inheritance tests
- Tests verify hierarchy: device > site > org > default
- All 28 device tests passing
All 808 tests passing (2 pre-existing alert notifier failures unrelated to this change)
No Credo warnings
Implemented ability to rename agents through a new edit page following TDD:
Backend changes:
- Added update_agent_token/2 in Agents context for updating agent names
- Added update_changeset/2 in AgentToken schema that only allows name updates
- Security: Token field cannot be changed, only name field is allowed
LiveView implementation:
- Created AgentLive.Edit module with mount, validate, and save handlers
- Created edit.html.heex template with form for renaming agents
- Added route /orgs/:org_slug/agents/:id/edit
- Added Edit button to agent show page header
- Validates organization ownership using Repo.get_by!
Tests:
- Added comprehensive context tests for update_agent_token/2
- Added LiveView tests for edit page functionality
- Tests cover: loading, validation, save/redirect, auth, and org ownership
All 801 tests passing, no Credo warnings.
Replace the revoke functionality with delete to properly clean up agent references.
When an agent is deleted:
- All direct device assignments are removed
- Agent is removed from site defaults
- Agent is removed from organization defaults
- Devices automatically fall back to site/org agents or cloud polling
This ensures no orphaned references and provides better clarity about
what happens to device monitoring when an agent is removed.
- Add delete_agent_token/1 function in Agents context
- Update LiveView to use delete_agent event instead of revoke_agent
- Update UI button from "Revoke" to "Delete" with clearer confirmation message
- Add comprehensive tests for delete functionality and fallback behavior
- All 792 tests passing, no Credo warnings