Add background workers to regularly poll SNMP sensors and interfaces:
- Create PollerWorker GenServer to poll SNMP devices
- Poll all sensors for temperature, voltage, CPU, memory, etc.
- Poll all interfaces for bandwidth, errors, and discards
- Save time-series data to snmp_sensor_readings and snmp_interface_stats
- Integrate with monitoring supervisor to auto-start pollers
- Use same interval as connectivity checks (minimum 30 seconds)
- Add list_snmp_enabled_equipment function to Equipment context
Pollers start automatically on app boot for all SNMP-enabled equipment
and run independently of connectivity monitoring.
- Remove delete buttons from show pages
- Add 'Danger Zone' section to edit pages with delete functionality
- Improves UX by keeping destructive actions on edit pages
- Add clear warnings about deletion consequences
- After creating a site, redirect to site detail page instead of list
- Show helpful empty state on site page with instructions to add equipment
- Flash message guides user to add their first device
- Dashboard shows welcome wizard when no sites exist
- Equipment page redirects to site creation when no sites exist
- Equipment form redirects users to create a site if none exist
- Equipment list hides "New Equipment" button when no sites exist
- Update layouts to accept nil current_organization for org-less pages
- Change /orgs to use Layouts.authenticated instead of Layouts.app
- Update authenticated layout to show user menu without organization
- Menu button shows org name when in org, 'Menu' on org list page
- Always show Settings and Log out options
- Wrap /orgs page in Layouts.app to include header/footer
- Make entire org box clickable by using .link component
- Remove 'Open' button - entire card is now the link
- Add cursor-pointer for better UX
Create HealthController that returns 200 OK for health checks.
Route is outside browser pipeline to avoid SSL redirect and
authentication requirements.
- Convert snmp_sensor_readings to standard table
- Convert snmp_interface_stats to standard table
- Disable snmp_sensor_aggregates (continuous aggregates)
- Disable snmp_interface_aggregates (continuous aggregates)
All TimescaleDB commercial features (hypertables, continuous aggregates,
retention/compression policies) are disabled. Using standard PostgreSQL
tables with proper indexing instead.
Commented out retention and compression policies which require
TimescaleDB commercial license. Apache-licensed version only supports
basic hypertable functionality.
- Migrations now run in Application.start/2 before starting services
- Ecto's advisory locks prevent concurrent migrations in clustered setup
- Simplified deployment - no separate migration job needed
- Removed migrate-job.yaml manifest
- Set runAsNonRoot and runAsUser to 65534 (nobody)
- Disable privilege escalation
- Drop all Linux capabilities
- Use RuntimeDefault seccomp profile
- Applies to both migration job and main deployment
- Create Kubernetes Job to run migrations before deployment
- Update GitLab CI to execute migration job and wait for completion
- Ensures migrations run once per deployment in clustered environment
- Migration job uses PostgreSQL advisory locks to prevent race conditions
- Add real-time updates with 10-second refresh and PubSub integration
- Implement pure SVG charts: response time sparkline and uptime gauge
- Create compact dashboard layout with status cards, metrics, and graphs
- Add relative time display (e.g., '5s ago') for last check
- Redesign SNMP data display: compact device info, sensors grid, interfaces table
- Calculate and display uptime percentage and average response time
- Update tests to match new compact layout
- Explicitly discard return value from trigger_check call
- The return value is not needed for this fire-and-forget operation
- Resolves unmatched_return warning at line 58
- Explicitly discard return value from Endpoint.broadcast call
- Broadcast is fire-and-forget, return value not needed
- Resolves unmatched_return warning at line 54
- Create changeset before Multi pipeline for better type inference
- Pass changeset directly to Multi.insert instead of using function form
- Resolves call_without_opaque warning at line 97
- Replace catch-all pattern with explicit :unknown status handling
- Makes status transitions more explicit and type-safe
- Resolves pattern_match_cov warning at line 174
- Organization names can now be freely duplicated
- Slugs are generated as random 8-character lowercase alphanumeric IDs
- Provides ~218 trillion possible combinations
- Updated tests to not rely on name-based slug patterns
- Update LiveView tests to match actual redirect behavior
- Fix equipment and site form redirect test expectations
- Update organization tests to reflect slug-based uniqueness
- All datetime truncation fixes for Ecto :utc_datetime fields
- Add active_page attribute to authenticated layout
- Update nav_link component to show active state with border and text styling
- Update all LiveView templates to pass active_page parameter
- Fix datetime truncation issues in tests and schemas for :utc_datetime fields
- Fix dashboard test assertions for equipment status text