- Remove auto-confirmation on registration (register_user and register_user_with_organization)
- Add deliver_user_confirmation_instructions/2 and confirm_user/1 to Accounts context
- Add verify_email_token_query/2 and by_user_and_contexts_query/2 to UserToken
- Make deliver_confirmation_email public in UserNotifier
- Send confirmation email after registration in both flows
- Block unconfirmed users at password login with helpful message
- Add UserConfirmationController with confirm/resend routes
- Add resend confirmation link to login page
- Update test fixtures to confirm users after registration
- nix.md: TimescaleDB now enabled for both dev and test databases
- nix.md: added troubleshooting section for TimescaleDB reinitialization
- New: docs/features/organization-settings.md (tabbed interface, all tabs documented)
- New: docs/features/device-monitoring.md (schema field reference, activity feed fields, SNMP socket management)
- Organization changeset: name length, SNMP port range, version enum, SNMPv3 fields
- Integration changeset: sync interval validation, provider enum
- Settings LiveView: tab routing with garbage params, arbitrary name/port/community input
- All capped at max_runs: 10-50 for fast execution
- Use postgresql_16.withPackages to include timescaledb extension
- Add shared_preload_libraries to PostgreSQL config
- Enable TimescaleDB for both dev and test databases
- Disable TimescaleDB telemetry in dev
These CRDs are not available for FluxCD dry-run validation, causing the
kustomization to fail. Apply certificate.yaml and ingressroute.yaml
manually instead.
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