towerops/lib/towerops/devices
Graham McIntire 247bbe58da refactor: address audit recommendations from results.md
Applies the 11 recommendations from the codebase optimization review.

Module decomposition:
- Extract Towerops.Topology.InferenceEngine: pulls device-role inference
  (capability rules, vendor matching, evidence merging) out of the topology
  context. Topology now delegates merge_confidence/2,
  infer_role_from_capabilities/1, and infer_device_role/1.
- Extract Towerops.Accounts.TOTP: TOTP secret/QR generation, multi-device
  verification, recovery code lifecycle, and sudo MFA logic. Accounts
  delegates the public TOTP API for backwards compatibility.
- Extract Towerops.Accounts.Sessions: browser session create/list/touch/
  revoke/anonymize/expire. Accounts delegates the public session API.
- Extract Towerops.Snmp.Queries: time-series read paths
  (sensor readings, interface stats, latest-per-id batches).
- Extract Towerops.Snmp.Monitoring: time-series write paths
  (sensor/interface/processor reading inserts, batch inserts via
  Repo.insert_all). Snmp.ex shrinks from 2985 to 2742 lines.

DRY refactoring:
- Add per-schema Query modules (Devices.DeviceQuery, Alerts.AlertQuery)
  with composable for_organization/for_site/with_status/etc filters;
  refactor list_site_devices, count_organization_devices,
  count_site_devices, count_site_devices_down, count_organization_alerts
  to compose them.
- Introduce create_discovered_checks/6 helper in Snmp; collapses 4 nearly
  identical Enum.reduce blocks for sensors/interfaces/processors/storage.
- Unify MAC and ARP evidence collectors behind collect_lookup_evidence/3
  (lldp/cdp were already factored).

Pattern matching:
- Replace cond block in infer_role_from_capabilities/1 with a declarative
  @role_rules table consulted via Enum.find_value (Elixir 1.19 forbids `in`
  with runtime lists in guards, so multi-clause functions weren't an option).
- Replace inline `if since` in get_sensor_readings/2 with a maybe_filter_since
  pipe helper.

Performance:
- Replace Enum.each + Repo.insert per evidence row in upsert_link with a
  single Repo.insert_all batch (truncates :observed_at to seconds).

Human-centric:
- Decompose build_device_lookup/1 into fetch_lookup_devices, map_ips_to_ids,
  map_names_to_ids, map_macs_to_ids.
- Adopt Towerops.Result.map/2 in Snmp.Client.do_get_multiple_sequential
  (kept narrow; `with` is preferred over Result.and_then for chained
  operations and is already used widely).

CLAUDE.md updates:
- Replace stale main→staging / production-branch deployment notes with the
  current flow: PRs deploy to Dokku staging, push to main runs the
  ExUnit gate then builds an image; argocd-image-updater rolls production.
- Refresh data-model diagram and references from "Equipment" to "Device"
  (post equipment→devices rename migration).
- Correct stale architecture facts: Hammer → in-tree Towerops.RateLimit,
  Rust NIF → C NIF (libnetsnmp), gitlab-registry → forgejo-registry,
  expand the Oban queue and cron lists, list actual implemented Ecto types.

All 10,228 tests pass.
2026-04-30 12:33:41 -05:00
..
mikrotik_backups dialyzer: fix remaining 88 warnings — clean dialyzer run 2026-04-21 10:32:42 -05:00
backup_request.ex handle mikrotik ssh 2026-02-02 16:42:18 -06:00
backup_requests.ex handle mikrotik ssh 2026-02-02 16:42:18 -06:00
credential_resolver.ex Replace conditionals with functional pattern matching 2026-02-10 17:11:37 -06:00
device.ex feat: simplify device type to manual-only with 6 options (#109) 2026-03-22 11:24:53 -05:00
device_firmware_history.ex Add firmware tracking database schema 2026-02-01 10:13:16 -06:00
device_query.ex refactor: address audit recommendations from results.md 2026-04-30 12:33:41 -05:00
event.ex add sensor value change events for all sensor types 2026-02-11 15:06:55 -06:00
event_logger.ex perf: LiveView event batching & PubSub optimization (TOW-26) 2026-03-15 14:08:27 -05:00
firmware.ex dialyzer: fix all unmatched_return warnings (154 → 0) 2026-04-21 10:03:55 -05:00
firmware_release.ex Add firmware tracking database schema 2026-02-01 10:13:16 -06:00
mikrotik_backup.ex Mikrotik backup and gettext start 2026-02-02 09:11:22 -06:00
mikrotik_backups.ex handle mikrotik ssh 2026-02-02 16:42:18 -06:00
version_comparator.ex refactor: convert 6 Gleam modules to idiomatic Elixir with TDD (#196) 2026-03-28 09:52:07 -05:00