Switch deployment pipeline from GitLab Agent kubectl to FluxCD image
automation. CI now only builds and pushes tagged images to Forgejo
registry; FluxCD detects new tags and updates the deployment manifest.
Fix Ecto.MultipleResultsError on /dashboard when a device has multiple
Preseem access point records by using limit(1) instead of Repo.get_by.
get_bulk, set, and get_multi used 'with' chains that skipped
close_socket when the operation failed, leaking file descriptors.
Over time this exhausted the fd limit causing EMFILE crashes.
Switched to case + try/after to guarantee socket cleanup.
- Activity feed: use schema modules instead of string table names in Ecto
queries to fix UUID encoding (Postgrex expected binary, got string)
- Changelog parser: remove plain hyphen from separator character class
to prevent splitting on date hyphens (2026-02-13)
- Fix broken route paths in dashboard (/discovery, /subscribers/trace, /config-changes)
- Fix insights empty state settings link (org-scoped route)
- Add underscores to all 86400 literals across 6 files
- Alphabetize aliases in search.ex and agent_channel.ex
- Extract changelog parser helper to reduce nesting
- Extract dashboard impact calculation to reduce nesting
- Refactor agent_channel config change detection (pattern match, extract function)
- Combine double Enum.reject into single call in trace.ex
- Fix line length in trace.ex search query
- Replace length/1 > 0 with != [] in trace_live
- Run mix format on all files
- ChangelogParser: parses priv/static/changelog.txt into structured entries
- ChangelogLive: timeline view with DaisyUI styling
- Route at /changelog in authenticated scope
- What's New link in org dropdown menu
- Group alerts by site (tower/location) with collapsible sections
- Show alert count badges per site, critical count highlighted
- Color-code alerts by severity and age (red >1h, orange >15m, yellow new)
- Add Resolve button with confirmation dialog
- Show subscriber impact from Gaiia inventory at site and alert level
- Filter tabs: Unresolved, Critical, All, Resolved with counts
- Sort options: Severity (default), Oldest First, Subscriber Impact
- Sites with most critical alerts and highest subscriber impact sort first
- Use DaisyUI collapse, badge, tab, and btn components
- Add summary stat cards (subscribers, MRR, device count, alerts)
- Add QoE summary with capacity bar (qoe_color, qoe_bg, capacity_bar_color)
- Device health grid with status dots and response times (status_dot_class, format_response_time)
- Active alerts panel with urgency icons (insight_urgency_class, insight_urgency_icon, time_ago)
- Config changes panel with size labels (change_size_label, change_size_color, time_ago)
- Preseem insights panel with urgency styling
- Keep existing latency chart
- Use DaisyUI card/badge components throughout
- Health status dot (green/yellow/red/gray) from worst-case check state
- Relative 'last seen' with color-coded staleness thresholds
- Response time badge from latest monitoring check
- Subscriber count badge from Gaiia inventory items
- Batch queries to avoid N+1: Monitoring.get_device_health_summary/1,
Monitoring.get_device_latest_response_times/1,
Gaiia.get_device_subscriber_counts/1
Replace inline cache with dedicated buildcache tag that stores all
intermediate builder layers. Unchanged stages like deps and compile
will be pulled from cache instead of rebuilt.
Add node:22-bookworm container image since ubuntu:latest lacks Node.js
required by JavaScript-based actions. Update checkout to v6 and
build-push-action to v6.
- Promote Insights to top-level nav at /insights with source/urgency/status filters
- Unified insights page shows all sources (Preseem, Gaiia, SNMP, System)
- Bulk select/dismiss support
- Integration pages now show sync schedule and next sync estimate
- Expose sync_interval_minutes as editable config field
- Add tab navigation between integration sub-pages
- Dashboard insights section links to /insights
- Integration 'Network Insights' link now points to /insights?source=preseem
- Add product roadmap (ROADMAP.md)