Fixes three critical issues affecting agent-based SNMP polling:
1. MikroTik gauge sensors incorrectly showing 10x values (223°C instead of 22.3°C)
- Root cause: get_int_value() rejected zero values, causing mtxrGaugeUnit
to be treated as nil and bypassing divisor logic
- Fixed: Accept zero values and apply correct divisor=10 for temp/voltage/current/power
2. Empty SNMP community strings sent to agents causing authentication failures
- Root cause: Devices with source="device" but null community weren't falling
back to organization/site inheritance
- Fixed: Enhanced resolve_snmp_community() to fall back to inheritance chain
even when source="device" but community is empty
3. Continuous MikroTik API commands sent every 60s instead of once per 24h
- Root cause: MikroTik jobs built on every poll cycle, not just discovery
- Fixed: Only build MikroTik jobs during discovery phase
Migrations update existing data to fix incorrect divisor values and community
source tracking. Added comprehensive debug logging to diagnose future issues.
Migrates consent prompt component strings to gettext for internationalization:
- Updated Policies modal title
- Policy review message
- Policy acceptance checkbox labels (Privacy Policy, Terms of Service)
- Consent disclaimer text
- Accept button text
All strings now use gettext() for translation support.
Migrates all admin-related flash messages to gettext for internationalization:
- Admin.UserLive.Index: user deletion messages
- Admin.OrgLive.Index: organization deletion messages
- UserAuth: impersonation start/stop messages
Adds Gettext backend and helpers import to UserAuth module to support translations.
All admin and auth tests passing (87 tests).
- Update UserNotifier to use t_email() helper for all email content
- Extract 4 email subjects and 4 email bodies to emails domain:
* Update email instructions
* Log in instructions
* Confirmation instructions
* Reset password instructions
- Replace string interpolation with Gettext bindings (%{email}, %{url})
- Auto-populate English translations (msgstr = msgid)
- All emails now ready for future internationalization
First module migration complete per design plan.
Critical fixes:
- Renamed controller actions to follow Phoenix conventions (verify→new, create→verify)
- Added sudo mode check in GET action using last_sudo_at timestamp
- Added TOTP enrollment check in GET action with redirect
- Changed default return path from /orgs to /users/settings
- Updated route paths from /users/sudo/verify to /users/sudo-verify (dash separator)
- Added success flash message "Identity verified."
Implementation details:
- new/2 (GET): Checks recently_verified_sudo?/1 helper that examines last_sudo_at
instead of authenticated_at to distinguish sudo verification from regular login
- verify/2 (POST): Adds info flash and defaults to /users/settings
- recently_verified_sudo?/1: Private helper checking last_sudo_at within 10 minutes
- Updated all routes, templates, and tests to use new paths and action names
Tests:
- Added tests for already-in-sudo-mode redirect behavior
- Added test for TOTP enrollment requirement
- Updated all test assertions for new route paths and success messages
- All 15 controller tests passing
- Full test suite passing (4076 tests, 0 failures)
- Add UserSudoController with GET and POST /users/sudo/verify routes
- Create verify.html.heex template for TOTP verification form
- Only accept TOTP codes (6 numeric digits), reject recovery codes
- Update grant_sudo_mode to set authenticated_at virtual field
- Exclude /users/sudo paths from return_to overwriting
- Add comprehensive controller tests (12 test cases)
- Verify redirect behavior, error handling, and session management
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>