From d0160f7d8ae147a294bc1f82b8ba91c7021b7ec8 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sun, 14 Jun 2026 08:27:57 -0500 Subject: [PATCH] credo fixes --- .credo.exs | 20 +++---- lib/snmpkit/snmp_lib/asn1.ex | 4 +- lib/snmpkit/snmp_mgr/bulk.ex | 6 +- lib/towerops/accounts.ex | 7 +-- lib/towerops/admin.ex | 17 ++---- lib/towerops/agents.ex | 3 +- lib/towerops/billing.ex | 4 +- lib/towerops/coverages/antenna.ex | 6 +- lib/towerops/devices.ex | 13 +---- lib/towerops/gaiia/sync.ex | 7 +-- lib/towerops/monitoring.ex | 5 +- lib/towerops/preseem.ex | 3 +- lib/towerops/preseem/fleet_intelligence.ex | 6 +- lib/towerops/preseem/sync.ex | 3 +- lib/towerops/proto/tuple_decode.ex | 3 +- lib/towerops/snmp.ex | 24 +++----- lib/towerops/snmp/discovery.ex | 9 +-- lib/towerops/snmp/profiles/dynamic.ex | 13 +---- lib/towerops/workers/alert_digest_worker.ex | 3 +- lib/towerops/workers/check_worker.ex | 4 +- lib/towerops/workers/device_monitor_worker.ex | 6 +- lib/towerops/workers/device_poller_worker.ex | 4 +- lib/towerops/workers/gaiia_insight_worker.ex | 13 ++--- lib/towerops_native.ex | 4 +- lib/towerops_web/channels/agent_channel.ex | 27 +++------ lib/towerops_web/components/layouts.ex | 3 +- .../controllers/admin_controller.ex | 8 +-- .../api/v1/coverages_controller.ex | 4 +- .../api/v1/escalation_policies_controller.ex | 4 +- .../controllers/health_controller.ex | 6 +- .../live/account_live/totp_enrollment.ex | 11 +--- .../live/admin/monitoring_live.ex | 6 -- lib/towerops_web/live/admin/org_live/index.ex | 3 +- lib/towerops_web/live/agent_live/index.ex | 37 ------------- lib/towerops_web/live/alert_live/index.ex | 28 ---------- lib/towerops_web/live/changelog_live.ex | 2 +- .../live/check_live/form_component.ex | 26 +-------- .../components/global_search_component.ex | 3 - lib/towerops_web/live/config_timeline_live.ex | 2 +- lib/towerops_web/live/coverage_live/form.ex | 1 - lib/towerops_web/live/dashboard_live.ex | 12 +--- lib/towerops_web/live/device_live/form.ex | 11 +--- lib/towerops_web/live/device_live/index.ex | 1 - lib/towerops_web/live/device_live/show.ex | 42 ++------------ .../live/escalation_policy_live/form.ex | 2 +- .../live/escalation_policy_live/index.ex | 1 - .../live/escalation_policy_live/show.ex | 1 - lib/towerops_web/live/graph_live/show.ex | 6 -- lib/towerops_web/live/help_live/index.ex | 1 - lib/towerops_web/live/insights_live/index.ex | 4 +- .../live/maintenance_live/form.ex | 3 +- lib/towerops_web/live/mobile_qr_live.ex | 4 +- .../live/org/integrations_live.ex | 1 - lib/towerops_web/live/org/settings_live.ex | 24 +++----- lib/towerops_web/live/schedule_live/form.ex | 2 +- lib/towerops_web/live/schedule_live/index.ex | 1 - lib/towerops_web/live/schedule_live/show.ex | 2 - lib/towerops_web/live/site_live/index.ex | 3 +- lib/towerops_web/live/trace_live/index.ex | 9 +-- .../live/user_registration_live.ex | 7 +-- .../live/user_reset_password_live.ex | 1 - lib/towerops_web/live/user_settings_live.ex | 18 ------ lib/towerops_web/permissions.ex | 4 +- lib/towerops_web/plugs/webhook_auth.ex | 4 +- lib/towerops_web/telemetry.ex | 9 +-- lib/towerops_web/user_auth.ex | 5 +- test/integration/snmp_integration_test.exs | 7 +-- test/snmpkit/snmp_lib/cache_test.exs | 6 +- test/snmpkit/snmp_lib/config_test.exs | 4 +- test/snmpkit/snmp_lib/dashboard_test.exs | 10 +++- test/towerops/accounts_test.exs | 3 +- test/towerops/admin_test.exs | 17 ++---- test/towerops/alerts/storm_detector_test.exs | 6 +- test/towerops/alerts_test.exs | 9 +-- test/towerops/coverages/raster_test.exs | 3 +- .../devices/device_firmware_history_test.exs | 11 ++-- test/towerops/devices_test.exs | 55 ++----------------- test/towerops/sites_test.exs | 4 +- test/towerops/snmp/discovery_sync_test.exs | 17 ++---- test/towerops/snmp/discovery_test.exs | 6 +- test/towerops/snmp/mib_translator_test.exs | 2 + test/towerops/snmp/mib_validation_test.exs | 5 ++ .../snmp/profiles/vendors/registry_test.exs | 42 ++++++++++---- test/towerops/snmp/wireless_clients_test.exs | 2 +- test/towerops/snmp_test.exs | 3 +- test/towerops/topology_test.exs | 18 ++---- .../workers/alert_digest_worker_test.exs | 3 +- .../device_poller_transceiver_test.exs | 2 +- .../workers/discovery_worker_test.exs | 5 +- .../workers/job_health_check_worker_test.exs | 1 + .../agent_channel_extra_coverage_test.exs | 3 +- .../channels/agent_channel_test.exs | 3 +- .../api/mobile_controller_test.exs | 15 +---- .../agent_release_webhook_controller_test.exs | 5 +- .../graphql/resolvers/check_test.exs | 3 +- .../live/admin/org_live/index_test.exs | 3 +- .../live/coverage_live/index_test.exs | 4 +- .../live/coverage_live/map_test.exs | 3 +- .../live/coverage_live/show_test.exs | 5 +- .../live/device_live/form_test.exs | 7 +-- .../helpers/chart_builders_test.exs | 4 +- .../live/device_live/index_test.exs | 3 +- .../live/device_live/show_test.exs | 31 +++-------- .../live/help_live/index_test.exs | 4 +- .../live/insights_live_events_test.exs | 17 +++--- test/towerops_web/live/live_helpers_test.exs | 32 ++--------- .../live/trace_live/index_test.exs | 4 +- .../live/user_registration_live_test.exs | 4 +- .../live/weathermap_live_events_test.exs | 2 +- 109 files changed, 273 insertions(+), 656 deletions(-) diff --git a/.credo.exs b/.credo.exs index dab1765b..70c94369 100644 --- a/.credo.exs +++ b/.credo.exs @@ -188,16 +188,16 @@ # {:erlang, :binary_to_term, "Use Plug.Crypto.non_executable_binary_to_term/2 instead."} # ] # ]}, - {Jump.CredoChecks.LiveViewFormCanBeRehydrated} - # {Jump.CredoChecks.UndeclaredExternalResource}, - # {Jump.CredoChecks.PreferChangeOverUpDownMigrations, [start_after: "20250101000000"]}, - # {Jump.CredoChecks.PreferTextColumns, [start_after: "20250101000000"]}, - # {Jump.CredoChecks.SafeBinaryToTerm}, - # {Jump.CredoChecks.TestHasNoAssertions, - # [custom_assertion_functions: [:assert_has, :refute_has, :assert_eventually]]}, - # {Jump.CredoChecks.TooManyAssertions, [max_assertions: 20]}, - # {Jump.CredoChecks.TopLevelAliasImportRequire}, - # {Jump.CredoChecks.UnusedLiveViewAssign, [ignored_assigns: [:active_path, :current_scope]]}, + {Jump.CredoChecks.LiveViewFormCanBeRehydrated}, + {Jump.CredoChecks.UndeclaredExternalResource}, + {Jump.CredoChecks.PreferChangeOverUpDownMigrations, [start_after: "20250101000000"]}, + {Jump.CredoChecks.PreferTextColumns, [start_after: "20250101000000"]}, + {Jump.CredoChecks.SafeBinaryToTerm}, + {Jump.CredoChecks.TestHasNoAssertions, + [custom_assertion_functions: [:assert_has, :refute_has, :assert_eventually]]}, + {Jump.CredoChecks.TooManyAssertions, [max_assertions: 20]}, + {Jump.CredoChecks.TopLevelAliasImportRequire}, + {Jump.CredoChecks.UnusedLiveViewAssign, [ignored_assigns: [:active_path, :current_scope, :current_token]]} # {Jump.CredoChecks.UseObanProWorker}, # {Jump.CredoChecks.VacuousTest, # [ diff --git a/lib/snmpkit/snmp_lib/asn1.ex b/lib/snmpkit/snmp_lib/asn1.ex index 1131aac2..794c45e2 100644 --- a/lib/snmpkit/snmp_lib/asn1.ex +++ b/lib/snmpkit/snmp_lib/asn1.ex @@ -68,6 +68,8 @@ defmodule SnmpKit.SnmpLib.ASN1 do import Bitwise + require Logger + @type tag :: non_neg_integer() @type length :: non_neg_integer() @type content :: binary() @@ -154,8 +156,6 @@ defmodule SnmpKit.SnmpLib.ASN1 do end def encode_octet_string(value) when not is_binary(value) do - require Logger - Logger.error("encode_octet_string received non-binary value: #{inspect(value)}") {:error, {:invalid_type, value}} end diff --git a/lib/snmpkit/snmp_mgr/bulk.ex b/lib/snmpkit/snmp_mgr/bulk.ex index 2e14d96d..e04d7d76 100644 --- a/lib/snmpkit/snmp_mgr/bulk.ex +++ b/lib/snmpkit/snmp_mgr/bulk.ex @@ -10,6 +10,8 @@ defmodule SnmpKit.SnmpMgr.Bulk do alias SnmpKit.SnmpMgr.Core alias SnmpKit.SnmpMgr.Format + require Logger + @default_max_repetitions 30 @default_non_repeaters 0 @@ -232,8 +234,6 @@ defmodule SnmpKit.SnmpMgr.Bulk do end defp bulk_walk_subtree(target, current_oid, root_oid, acc, remaining, opts) when remaining > 0 do - require Logger - max_repetitions = min(remaining, Keyword.get(opts, :max_repetitions, @default_max_repetitions)) @@ -290,8 +290,6 @@ defmodule SnmpKit.SnmpMgr.Bulk do end defp filter_table_results(results, root_oid) do - require Logger - in_scope_results = Enum.filter(results, fn # Only accept 3-tuple format with proper type information diff --git a/lib/towerops/accounts.ex b/lib/towerops/accounts.ex index ae2c493e..2e90e0e9 100644 --- a/lib/towerops/accounts.ex +++ b/lib/towerops/accounts.ex @@ -17,6 +17,8 @@ defmodule Towerops.Accounts do alias Towerops.Accounts.UserNotifier alias Towerops.Accounts.UserToken alias Towerops.Admin.AuditLogger + alias Towerops.Organizations.Membership + alias Towerops.Organizations.Organization alias Towerops.Repo require Logger @@ -489,11 +491,8 @@ defmodule Towerops.Accounts do Used to check if a user can safely delete their account without orphaning organizations. """ - @spec sole_owner_organizations(String.t()) :: [Towerops.Organizations.Organization.t()] + @spec sole_owner_organizations(String.t()) :: [Organization.t()] def sole_owner_organizations(user_id) do - alias Towerops.Organizations.Membership - alias Towerops.Organizations.Organization - user_owner_org_ids = Membership |> where([m], m.user_id == ^user_id and m.role == :owner) diff --git a/lib/towerops/admin.ex b/lib/towerops/admin.ex index 1cc0cc20..a9d094c4 100644 --- a/lib/towerops/admin.ex +++ b/lib/towerops/admin.ex @@ -8,8 +8,12 @@ defmodule Towerops.Admin do alias Towerops.Accounts.User alias Towerops.Admin.AuditLog + alias Towerops.Billing + alias Towerops.Billing.StripeClient alias Towerops.Organizations.Organization alias Towerops.Repo + alias Towerops.Settings + alias Towerops.Settings.ApplicationSetting require Logger @@ -403,11 +407,6 @@ defmodule Towerops.Admin do Returns {:ok, migration_report} or {:error, reason}. """ def update_global_pricing(attrs, superuser_id, ip_address) do - alias Towerops.Billing - alias Towerops.Billing.StripeClient - alias Towerops.Settings - alias Towerops.Settings.ApplicationSetting - with {:ok, validated} <- validate_pricing_attrs(attrs), old_values = get_current_pricing(), {:ok, new_price_id, migration_report} <- maybe_update_stripe_price(validated, old_values), @@ -454,8 +453,6 @@ defmodule Towerops.Admin do end defp get_current_pricing do - alias Towerops.Settings - %{ free_devices: Settings.get_setting("default_free_devices"), price: Settings.get_setting("default_price_per_device") @@ -463,9 +460,6 @@ defmodule Towerops.Admin do end defp maybe_update_stripe_price(validated, old_values) do - alias Towerops.Billing - alias Towerops.Billing.StripeClient - price_changed = validated.price && validated.price != old_values.price if price_changed do @@ -483,9 +477,6 @@ defmodule Towerops.Admin do end defp update_pricing_settings(validated, new_price_id) do - alias Towerops.Settings - alias Towerops.Settings.ApplicationSetting - if validated.free_devices do Settings.update_setting("default_free_devices", validated.free_devices) end diff --git a/lib/towerops/agents.ex b/lib/towerops/agents.ex index e65a72bb..abe40ed9 100644 --- a/lib/towerops/agents.ex +++ b/lib/towerops/agents.ex @@ -14,6 +14,7 @@ defmodule Towerops.Agents do alias Towerops.Agents.AgentTokenQuery alias Towerops.Agents.ReleaseChecker alias Towerops.Devices.Device + alias Towerops.Preseem.Insight alias Towerops.Repo require Logger @@ -237,8 +238,6 @@ defmodule Towerops.Agents do end defp dismiss_agent_offline_insights(agent_token_id) do - alias Towerops.Preseem.Insight - now = Towerops.Time.now() {count, _} = diff --git a/lib/towerops/billing.ex b/lib/towerops/billing.ex index 6e203565..f5169827 100644 --- a/lib/towerops/billing.ex +++ b/lib/towerops/billing.ex @@ -6,6 +6,8 @@ defmodule Towerops.Billing do Pricing: $2/device/month after first 10 free devices (configurable via ApplicationSettings). """ + import Ecto.Query, warn: false + alias Towerops.Billing.StripeClient alias Towerops.Organizations.Organization alias Towerops.Organizations.SubscriptionLimits @@ -240,8 +242,6 @@ defmodule Towerops.Billing do - failures: list of {:error, org, reason} tuples """ def migrate_all_subscriptions_to_price(new_price_id) do - import Ecto.Query - orgs = Repo.all( from o in Organization, diff --git a/lib/towerops/coverages/antenna.ex b/lib/towerops/coverages/antenna.ex index c4ac4dca..6295286f 100644 --- a/lib/towerops/coverages/antenna.ex +++ b/lib/towerops/coverages/antenna.ex @@ -14,6 +14,8 @@ defmodule Towerops.Coverages.Antenna do alias Towerops.Coverages.AntennaCatalog + require Logger + @enforce_keys [:slug, :model, :h_pattern, :v_pattern, :gain_dbi] defstruct [ :slug, @@ -187,8 +189,6 @@ defmodule Towerops.Coverages.Antenna do Map.put(acc, antenna.slug, antenna) {:error, reason} -> - require Logger - Logger.warning("Failed to synthesize antenna #{spec.slug}: #{inspect(reason)}") acc end @@ -314,8 +314,6 @@ defmodule Towerops.Coverages.Antenna do Map.put(acc, slug, antenna) {:error, reason} -> - require Logger - Logger.warning("Failed to parse antenna #{filename}: #{inspect(reason)}") acc end diff --git a/lib/towerops/devices.ex b/lib/towerops/devices.ex index c275f31d..6e88640e 100644 --- a/lib/towerops/devices.ex +++ b/lib/towerops/devices.ex @@ -15,11 +15,14 @@ defmodule Towerops.Devices do alias Towerops.Organizations alias Towerops.Organizations.Organization alias Towerops.Organizations.SubscriptionLimits + alias Towerops.Preseem.Insight alias Towerops.Repo alias Towerops.Sites alias Towerops.Workers.DeviceMonitorWorker alias Towerops.Workers.DiscoveryWorker + require Logger + @device_preloads [:organization, site: :organization] @doc """ @@ -270,8 +273,6 @@ defmodule Towerops.Devices do # Guard against NotLoaded to prevent crashes if association isn't preloaded case device.organization do %Ecto.Association.NotLoaded{} -> - require Logger - Logger.error( "Organization not preloaded for device #{device.id} in get_org_default_agent", device_id: device.id @@ -554,8 +555,6 @@ defmodule Towerops.Devices do * `:bypass_limits` - When true, bypasses subscription device limits (for superusers) """ def create_device(attrs, opts \\ []) do - require Logger - bypass_limits = Keyword.get(opts, :bypass_limits, false) changeset = build_device_changeset(attrs) @@ -787,8 +786,6 @@ defmodule Towerops.Devices do # Log warning if community is empty defp log_empty_community(device, community) when community in [nil, ""] do - require Logger - Logger.warning("Empty SNMP community resolved for device", device_id: device.id, device_name: device.name, @@ -964,8 +961,6 @@ defmodule Towerops.Devices do end defp dismiss_poll_gap_insights(device_id) do - alias Towerops.Preseem.Insight - now = Towerops.Time.now() {count, _} = @@ -974,8 +969,6 @@ defmodule Towerops.Devices do |> Repo.update_all(set: [status: "dismissed", dismissed_at: now]) if count > 0 do - require Logger - Logger.info("Auto-dismissed #{count} poll gap insight(s) for device #{device_id}") end diff --git a/lib/towerops/gaiia/sync.ex b/lib/towerops/gaiia/sync.ex index dede5550..827da252 100644 --- a/lib/towerops/gaiia/sync.ex +++ b/lib/towerops/gaiia/sync.ex @@ -13,6 +13,8 @@ defmodule Towerops.Gaiia.Sync do alias Towerops.Gaiia.Client alias Towerops.Gaiia.SubscriberMatching alias Towerops.Integrations + alias Towerops.Repo + alias Towerops.Sites.Site require Logger @@ -119,11 +121,6 @@ defmodule Towerops.Gaiia.Sync do end defp find_matching_site_id(org_id, gaiia_name) when is_binary(gaiia_name) and gaiia_name != "" do - import Ecto.Query - - alias Towerops.Repo - alias Towerops.Sites.Site - search = "%#{Towerops.QueryHelpers.sanitize_like(gaiia_name)}%" Repo.one( diff --git a/lib/towerops/monitoring.ex b/lib/towerops/monitoring.ex index 1a00b698..1cdeb0b4 100644 --- a/lib/towerops/monitoring.ex +++ b/lib/towerops/monitoring.ex @@ -14,6 +14,8 @@ defmodule Towerops.Monitoring do alias Towerops.Monitoring.CheckResult alias Towerops.Monitoring.MonitoringCheck alias Towerops.Repo + alias Towerops.Snmp.SensorReading + alias Towerops.Workers.CheckExecutorWorker alias Towerops.Workers.PollingOffset ## Checks @@ -254,8 +256,6 @@ defmodule Towerops.Monitoring do Queues a CheckExecutorWorker job with polling offset to distribute load. """ def schedule_check(%Check{} = check) do - alias Towerops.Workers.CheckExecutorWorker - offset = PollingOffset.calculate_offset(check.id, check.interval_seconds) %{check_id: check.id} @@ -355,7 +355,6 @@ defmodule Towerops.Monitoring do # If SNMP check with source_id, also query old snmp_sensor_readings for backfill historical_results = if check.check_type == "snmp_sensor" && check.source_id do - alias Towerops.Snmp.SensorReading # Find earliest check_result timestamp to avoid overlap earliest_check_result = recent_results diff --git a/lib/towerops/preseem.ex b/lib/towerops/preseem.ex index dc8a20aa..1ebbba59 100644 --- a/lib/towerops/preseem.ex +++ b/lib/towerops/preseem.ex @@ -5,6 +5,7 @@ defmodule Towerops.Preseem do import Ecto.Query + alias Towerops.Devices alias Towerops.Preseem.AccessPoint alias Towerops.Preseem.Insights alias Towerops.Preseem.SubscriberMetric @@ -126,8 +127,6 @@ defmodule Towerops.Preseem do Returns a map with average QoE, latency, capacity info, and per-AP breakdowns. """ def get_site_qoe_summary(site_id) do - alias Towerops.Devices - device_ids = site_id |> Devices.list_site_devices() diff --git a/lib/towerops/preseem/fleet_intelligence.ex b/lib/towerops/preseem/fleet_intelligence.ex index 6d80b57c..e6b40a70 100644 --- a/lib/towerops/preseem/fleet_intelligence.ex +++ b/lib/towerops/preseem/fleet_intelligence.ex @@ -9,10 +9,10 @@ defmodule Towerops.Preseem.FleetIntelligence do alias Towerops.Preseem.FleetProfile alias Towerops.Repo + require Logger + @doc "Compute fleet profiles for all matched APs in an organization." def compute_fleet_profiles(organization_id) do - require Logger - now = Towerops.Time.now() matched_aps = @@ -94,8 +94,6 @@ defmodule Towerops.Preseem.FleetIntelligence do # PostgreSQL treats NULLs as distinct in unique indexes, so ON CONFLICT won't match # rows with NULL firmware_version. Ecto's get_by also rejects nil values. defp upsert_fleet_profile(organization_id, attrs) do - require Logger - full_attrs = Map.put(attrs, :organization_id, organization_id) existing = diff --git a/lib/towerops/preseem/sync.ex b/lib/towerops/preseem/sync.ex index cdac1c31..a7796627 100644 --- a/lib/towerops/preseem/sync.ex +++ b/lib/towerops/preseem/sync.ex @@ -10,6 +10,7 @@ defmodule Towerops.Preseem.Sync do alias Towerops.Preseem.AccessPoint alias Towerops.Preseem.Client alias Towerops.Preseem.DeviceMatcher + alias Towerops.Preseem.SubscriberMetric alias Towerops.Preseem.SyncLog alias Towerops.Repo @@ -75,8 +76,6 @@ defmodule Towerops.Preseem.Sync do Inserts a subscriber metric record for the given access point. """ def insert_metrics(access_point_id, metrics_data) do - alias Towerops.Preseem.SubscriberMetric - recorded_at = case metrics_data["recorded_at"] do nil -> Towerops.Time.now() diff --git a/lib/towerops/proto/tuple_decode.ex b/lib/towerops/proto/tuple_decode.ex index 7ca7786f..16fe324a 100644 --- a/lib/towerops/proto/tuple_decode.ex +++ b/lib/towerops/proto/tuple_decode.ex @@ -4,6 +4,7 @@ defmodule Towerops.Proto.TupleDecode do Converts Elixir structs to tagged tuples for backward compatibility. """ + alias Towerops.Agent.AgentJob alias Towerops.Agent.MikrotikCommand alias Towerops.Agent.MikrotikDevice alias Towerops.Agent.SnmpDevice @@ -211,8 +212,6 @@ defmodule Towerops.Proto.TupleDecode do # Convert from Types.AgentJob to Agent.AgentJob defp types_job_to_agent_job(%Types.AgentJob{} = j) do - alias Towerops.Agent.AgentJob - %AgentJob{ job_id: j.job_id, job_type: j.job_type, diff --git a/lib/towerops/snmp.ex b/lib/towerops/snmp.ex index 88c89f45..3ec4b5c0 100644 --- a/lib/towerops/snmp.ex +++ b/lib/towerops/snmp.ex @@ -138,8 +138,6 @@ defmodule Towerops.Snmp do end defp create_sensor_check(device, sensor) do - alias Towerops.Monitoring - attrs = %{ organization_id: device.organization_id, device_id: device.id, @@ -156,10 +154,10 @@ defmodule Towerops.Snmp do } } - case Monitoring.create_check(attrs) do + case Towerops.Monitoring.create_check(attrs) do {:ok, check} -> # Schedule first execution - _ = Monitoring.schedule_check(check) + _ = Towerops.Monitoring.schedule_check(check) {:ok, check} error -> @@ -168,8 +166,6 @@ defmodule Towerops.Snmp do end defp create_interface_check(device, interface) do - alias Towerops.Monitoring - name = interface.if_alias || interface.if_name || interface.if_descr || "Interface #{interface.if_index}" attrs = %{ @@ -187,9 +183,9 @@ defmodule Towerops.Snmp do } } - case Monitoring.create_check(attrs) do + case Towerops.Monitoring.create_check(attrs) do {:ok, check} -> - _ = Monitoring.schedule_check(check) + _ = Towerops.Monitoring.schedule_check(check) {:ok, check} error -> @@ -198,8 +194,6 @@ defmodule Towerops.Snmp do end defp create_processor_check(device, processor) do - alias Towerops.Monitoring - attrs = %{ organization_id: device.organization_id, device_id: device.id, @@ -215,9 +209,9 @@ defmodule Towerops.Snmp do } } - case Monitoring.create_check(attrs) do + case Towerops.Monitoring.create_check(attrs) do {:ok, check} -> - _ = Monitoring.schedule_check(check) + _ = Towerops.Monitoring.schedule_check(check) {:ok, check} error -> @@ -226,8 +220,6 @@ defmodule Towerops.Snmp do end defp create_storage_check(device, storage) do - alias Towerops.Monitoring - name = storage.description || storage.device_name || "Storage #{storage.storage_index}" attrs = %{ @@ -245,9 +237,9 @@ defmodule Towerops.Snmp do } } - case Monitoring.create_check(attrs) do + case Towerops.Monitoring.create_check(attrs) do {:ok, check} -> - _ = Monitoring.schedule_check(check) + _ = Towerops.Monitoring.schedule_check(check) {:ok, check} error -> diff --git a/lib/towerops/snmp/discovery.ex b/lib/towerops/snmp/discovery.ex index 7c7f1e7f..6f00e0ca 100644 --- a/lib/towerops/snmp/discovery.ex +++ b/lib/towerops/snmp/discovery.ex @@ -27,12 +27,15 @@ defmodule Towerops.Snmp.Discovery do alias Towerops.Snmp.EntityPhysical alias Towerops.Snmp.Interface alias Towerops.Snmp.IpAddress + alias Towerops.Snmp.Mempool alias Towerops.Snmp.NeighborDiscovery + alias Towerops.Snmp.PrinterSupply alias Towerops.Snmp.Processor alias Towerops.Snmp.Profiles.Base alias Towerops.Snmp.Profiles.Dynamic alias Towerops.Snmp.Sensor alias Towerops.Snmp.Storage + alias Towerops.Snmp.Transceiver alias Towerops.Snmp.Vlan # alias Towerops.Topology # Commented out - auto-inference disabled alias Towerops.Workers.DiscoveryWorker @@ -1387,8 +1390,6 @@ defmodule Towerops.Snmp.Discovery do Sync memory pools from discovery/polling results to database. """ def sync_mempools(device, discovered_mempools) do - alias Towerops.Snmp.Mempool - # Get existing mempools for this device, indexed by mempool_index existing_mempools = from(m in Mempool, where: m.snmp_device_id == ^device.id) @@ -1463,8 +1464,6 @@ defmodule Towerops.Snmp.Discovery do Creates, updates, or deletes transceiver entries to match discovered state. """ def sync_transceivers(snmp_device, discovered_transceivers) do - alias Towerops.Snmp.Transceiver - # Get existing transceivers for this device, indexed by port_index existing_transceivers = from(t in Transceiver, where: t.snmp_device_id == ^snmp_device.id) @@ -1521,8 +1520,6 @@ defmodule Towerops.Snmp.Discovery do - Deletes supplies that are no longer discovered """ def sync_printer_supplies(snmp_device, discovered_supplies) do - alias Towerops.Snmp.PrinterSupply - # Get existing supplies for this device, indexed by supply_index existing_supplies = from(s in PrinterSupply, where: s.snmp_device_id == ^snmp_device.id) diff --git a/lib/towerops/snmp/profiles/dynamic.ex b/lib/towerops/snmp/profiles/dynamic.ex index fee88bf7..ba5b7a54 100644 --- a/lib/towerops/snmp/profiles/dynamic.ex +++ b/lib/towerops/snmp/profiles/dynamic.ex @@ -6,6 +6,9 @@ defmodule Towerops.Snmp.Profiles.Dynamic do alias Towerops.Snmp.Client alias Towerops.Snmp.Discovery + alias Towerops.Snmp.Profiles.Base + alias Towerops.Snmp.Profiles.Vendors.Arista + alias Towerops.Snmp.Profiles.Vendors.Powervault alias Towerops.Snmp.Profiles.Vendors.Registry, as: VendorRegistry require Logger @@ -66,8 +69,6 @@ defmodule Towerops.Snmp.Profiles.Dynamic do @spec discover_sensors(map(), Client.connection_opts()) :: {:ok, [Discovery.sensor_data()]} def discover_sensors(profile, client_opts) do - alias Towerops.Snmp.Profiles.Base - # Always discover ENTITY-SENSOR-MIB sensors (most devices support this) {:ok, base_sensors} = Base.discover_sensors(client_opts) @@ -119,8 +120,6 @@ defmodule Towerops.Snmp.Profiles.Dynamic do @spec discover_interfaces(map(), Client.connection_opts()) :: {:ok, [Discovery.interface_data()]} def discover_interfaces(_profile, client_opts) do - alias Towerops.Snmp.Profiles.Base - Base.discover_interfaces(client_opts) end @@ -540,20 +539,14 @@ defmodule Towerops.Snmp.Profiles.Dynamic do case name do "arista_eos" -> # Apply Arista-specific enhancements - alias Towerops.Snmp.Profiles.Vendors.Arista - Arista.post_process_sensors(sensors, client_opts) "arista-mos" -> # Apply Arista-specific enhancements - alias Towerops.Snmp.Profiles.Vendors.Arista - Arista.post_process_sensors(sensors, client_opts) "dell-powervault" -> # Parse text-based sensor messages from FCMGMT-MIB - alias Towerops.Snmp.Profiles.Vendors.Powervault - Powervault.post_process_sensors(sensors, client_opts) _ -> diff --git a/lib/towerops/workers/alert_digest_worker.ex b/lib/towerops/workers/alert_digest_worker.ex index ac824862..8d164654 100644 --- a/lib/towerops/workers/alert_digest_worker.ex +++ b/lib/towerops/workers/alert_digest_worker.ex @@ -11,6 +11,8 @@ defmodule Towerops.Workers.AlertDigestWorker do queue: :notifications, max_attempts: 3 + import Ecto.Query + alias Towerops.Alerts alias Towerops.Alerts.NotificationRateLimiter @@ -19,7 +21,6 @@ defmodule Towerops.Workers.AlertDigestWorker do @impl Oban.Worker def perform(%Oban.Job{args: %{"user_id" => "__cron__"}}) do # Cron mode: find all pending digests and enqueue delivery - import Ecto.Query pending = Towerops.Repo.all( diff --git a/lib/towerops/workers/check_worker.ex b/lib/towerops/workers/check_worker.ex index 90c99c75..63282273 100644 --- a/lib/towerops/workers/check_worker.ex +++ b/lib/towerops/workers/check_worker.ex @@ -13,6 +13,8 @@ defmodule Towerops.Workers.CheckWorker do states: [:available, :scheduled, :executing, :retryable, :suspended] ] + import Ecto.Query + alias Towerops.Agents alias Towerops.Alerts alias Towerops.Monitoring @@ -114,8 +116,6 @@ defmodule Towerops.Workers.CheckWorker do Stops executing a check by cancelling its jobs. """ def stop_check(check_id) do - import Ecto.Query - Oban.cancel_all_jobs( from(j in Oban.Job, where: j.worker == "Towerops.Workers.CheckWorker", diff --git a/lib/towerops/workers/device_monitor_worker.ex b/lib/towerops/workers/device_monitor_worker.ex index d3a9b1fa..b320ce93 100644 --- a/lib/towerops/workers/device_monitor_worker.ex +++ b/lib/towerops/workers/device_monitor_worker.ex @@ -19,6 +19,8 @@ defmodule Towerops.Workers.DeviceMonitorWorker do available: [:scheduled_at] ] + import Ecto.Query + alias Towerops.Agents alias Towerops.Alerts alias Towerops.Alerts.StormDetector @@ -105,8 +107,6 @@ defmodule Towerops.Workers.DeviceMonitorWorker do Stops monitoring for a device by cancelling its jobs. """ def stop_monitoring(device_id) do - import Ecto.Query - Oban.cancel_all_jobs( from(j in Oban.Job, where: j.worker == "Towerops.Workers.DeviceMonitorWorker", @@ -227,8 +227,6 @@ defmodule Towerops.Workers.DeviceMonitorWorker do :ok {:error, reason} -> - require Logger - Logger.error("Failed to create device up alert for #{device.name}: #{inspect(reason)}", device_id: device.id ) diff --git a/lib/towerops/workers/device_poller_worker.ex b/lib/towerops/workers/device_poller_worker.ex index 7a0ce753..03a03dbd 100644 --- a/lib/towerops/workers/device_poller_worker.ex +++ b/lib/towerops/workers/device_poller_worker.ex @@ -25,6 +25,8 @@ defmodule Towerops.Workers.DevicePollerWorker do available: [:scheduled_at] ] + import Ecto.Query + alias Towerops.Agents alias Towerops.Devices alias Towerops.Gaiia.SubscriberMatching @@ -129,8 +131,6 @@ defmodule Towerops.Workers.DevicePollerWorker do Stops polling for a device by cancelling its jobs. """ def stop_polling(device_id) do - import Ecto.Query - Oban.cancel_all_jobs( from(j in Oban.Job, where: j.worker == "Towerops.Workers.DevicePollerWorker", diff --git a/lib/towerops/workers/gaiia_insight_worker.ex b/lib/towerops/workers/gaiia_insight_worker.ex index 00cd50d2..4a6a1ed7 100644 --- a/lib/towerops/workers/gaiia_insight_worker.ex +++ b/lib/towerops/workers/gaiia_insight_worker.ex @@ -8,9 +8,15 @@ defmodule Towerops.Workers.GaiiaInsightWorker do use Oban.Worker, queue: :maintenance use Gettext, backend: ToweropsWeb.Gettext + import Ecto.Query + alias Towerops.Gaiia.Reconciliation alias Towerops.Integrations + alias Towerops.Preseem.Insight alias Towerops.Preseem.Insights + alias Towerops.Repo + + require Logger @impl Oban.Worker def perform(%Oban.Job{}) do @@ -39,11 +45,6 @@ defmodule Towerops.Workers.GaiiaInsightWorker do defp maybe_dismiss_resolved_insights(organization_id, dedup_key, current_items) do # If the issue is resolved (no items), dismiss any active insights if Enum.empty?(current_items) do - import Ecto.Query - - alias Towerops.Preseem.Insight - alias Towerops.Repo - now = Towerops.Time.now() {count, _} = @@ -57,8 +58,6 @@ defmodule Towerops.Workers.GaiiaInsightWorker do |> Repo.update_all(set: [status: "dismissed", dismissed_at: now]) if count > 0 do - require Logger - Logger.info( "Auto-dismissed #{count} reconciliation_finding insight(s) for #{dedup_key} in org #{organization_id}" ) diff --git a/lib/towerops_native.ex b/lib/towerops_native.ex index bdcf5dae..c73885c1 100644 --- a/lib/towerops_native.ex +++ b/lib/towerops_native.ex @@ -12,6 +12,8 @@ defmodule ToweropsNative do - Throughput: ~50,000-100,000 resolutions/second per core """ + require Logger + @on_load :load_nif def load_nif do @@ -22,8 +24,6 @@ defmodule ToweropsNative do :ok {:error, _reason} -> - require Logger - Logger.warning("ToweropsNative NIF not available, using stubs") :ok end diff --git a/lib/towerops_web/channels/agent_channel.ex b/lib/towerops_web/channels/agent_channel.ex index ef74f609..de334906 100644 --- a/lib/towerops_web/channels/agent_channel.ex +++ b/lib/towerops_web/channels/agent_channel.ex @@ -50,7 +50,11 @@ defmodule ToweropsWeb.AgentChannel do alias Towerops.Monitoring alias Towerops.Snmp alias Towerops.Snmp.AgentDiscovery + alias Towerops.Snmp.ArpDiscovery alias Towerops.Snmp.Discovery + alias Towerops.Snmp.MacDiscovery + alias Towerops.Snmp.NeighborDiscovery + alias Towerops.Snmp.Profiles.Base, as: SnmpProfiles alias Towerops.Snmp.SensorChangeDetector alias Towerops.Snmp.SensorScale alias Towerops.Topology @@ -2042,11 +2046,6 @@ defmodule ToweropsWeb.AgentChannel do Task.Supervisor.start_child(Towerops.TaskSupervisor, fn -> try do - alias Towerops.Snmp.ArpDiscovery - alias Towerops.Snmp.MacDiscovery - alias Towerops.Snmp.NeighborDiscovery - alias Towerops.Snmp.Profiles.Base - # Fetch interfaces once for reuse across multiple operations interfaces = Snmp.list_interfaces(snmp_device_id) @@ -2082,8 +2081,6 @@ defmodule ToweropsWeb.AgentChannel do end defp process_neighbors(client_opts, device_id, interfaces_with_device_id) do - alias Towerops.Snmp.NeighborDiscovery - case NeighborDiscovery.discover_neighbors(client_opts, interfaces_with_device_id) do {:ok, neighbors} when neighbors != [] -> Discovery.save_neighbors(device_id, neighbors) @@ -2094,8 +2091,6 @@ defmodule ToweropsWeb.AgentChannel do end defp process_arp_entries(client_opts, device_id, interfaces) do - alias Towerops.Snmp.ArpDiscovery - case ArpDiscovery.discover_arp_table(client_opts) do {:ok, arp_entries} when arp_entries != [] -> Discovery.save_arp_entries(device_id, arp_entries, interfaces) @@ -2106,8 +2101,6 @@ defmodule ToweropsWeb.AgentChannel do end defp process_mac_addresses(client_opts, device_id, interfaces) do - alias Towerops.Snmp.MacDiscovery - case MacDiscovery.discover_mac_table(client_opts) do {:ok, mac_addresses} when mac_addresses != [] -> Snmp.upsert_mac_addresses(device_id, mac_addresses, interfaces) @@ -2118,9 +2111,7 @@ defmodule ToweropsWeb.AgentChannel do end defp process_ip_addresses(client_opts, device_id, interfaces) do - alias Towerops.Snmp.Profiles.Base - - case Base.discover_all_ip_addresses(client_opts) do + case SnmpProfiles.discover_all_ip_addresses(client_opts) do {:ok, ip_addresses} when ip_addresses != [] -> discovered_device = %{ device_id: device_id, @@ -2135,9 +2126,7 @@ defmodule ToweropsWeb.AgentChannel do end defp process_processors(client_opts, snmp_device_id) do - alias Towerops.Snmp.Profiles.Base - - case Base.discover_processors(client_opts) do + case SnmpProfiles.discover_processors(client_opts) do {:ok, processors} when processors != [] -> discovered_device = %{id: snmp_device_id} Discovery.sync_processors(discovered_device, processors) @@ -2148,9 +2137,7 @@ defmodule ToweropsWeb.AgentChannel do end defp process_storage(client_opts, snmp_device_id) do - alias Towerops.Snmp.Profiles.Base - - case Base.discover_storage(client_opts) do + case SnmpProfiles.discover_storage(client_opts) do {:ok, storage} when storage != [] -> discovered_device = %{id: snmp_device_id} Discovery.sync_storage(discovered_device, storage) diff --git a/lib/towerops_web/components/layouts.ex b/lib/towerops_web/components/layouts.ex index c469c266..6baca897 100644 --- a/lib/towerops_web/components/layouts.ex +++ b/lib/towerops_web/components/layouts.ex @@ -9,6 +9,7 @@ defmodule ToweropsWeb.Layouts do alias ToweropsWeb.Components.CookieConsent alias ToweropsWeb.Helpers.StatusHelpers alias ToweropsWeb.Live.Components.GlobalSearchComponent + alias ToweropsWeb.TimeHelpers # Embed all files in layouts/* within this module. # The default root.html.heex file contains the HTML @@ -988,8 +989,6 @@ defmodule ToweropsWeb.Layouts do attr :timezone, :string, default: "UTC" def footer(assigns) do - alias ToweropsWeb.TimeHelpers - build_time = Towerops.Application.build_timestamp() timezone = Map.get(assigns, :timezone, "UTC") diff --git a/lib/towerops_web/controllers/admin_controller.ex b/lib/towerops_web/controllers/admin_controller.ex index 2ec7a3ee..7ecdd3cd 100644 --- a/lib/towerops_web/controllers/admin_controller.ex +++ b/lib/towerops_web/controllers/admin_controller.ex @@ -4,8 +4,12 @@ defmodule ToweropsWeb.AdminController do """ use ToweropsWeb, :controller + import Ecto.Query + alias ToweropsWeb.UserAuth + require Logger + @doc """ Start impersonating a user. """ @@ -30,10 +34,6 @@ defmodule ToweropsWeb.AdminController do POST /admin/oban/flush?states=scheduled,retryable """ def flush_oban(conn, %{"states" => states_param}) do - import Ecto.Query - - require Logger - valid_states = ~w(scheduled retryable available) requested = states_param |> String.split(",") |> Enum.map(&String.trim/1) states = Enum.filter(requested, &(&1 in valid_states)) diff --git a/lib/towerops_web/controllers/api/v1/coverages_controller.ex b/lib/towerops_web/controllers/api/v1/coverages_controller.ex index 8c786edb..cba709ce 100644 --- a/lib/towerops_web/controllers/api/v1/coverages_controller.ex +++ b/lib/towerops_web/controllers/api/v1/coverages_controller.ex @@ -17,6 +17,8 @@ defmodule ToweropsWeb.Api.V1.CoveragesController do alias Towerops.Coverages + require Logger + @doc """ GET /api/v1/coverages @@ -199,8 +201,6 @@ defmodule ToweropsWeb.Api.V1.CoveragesController do |> json(%{error: "Coverage is not ready yet"}) {:error, reason} -> - require Logger - # Log the underlying reason server-side so we can debug, but don't # leak filesystem paths / zip errors / IO details to the caller. Logger.error("Failed to build KMZ for coverage: #{inspect(reason)}") diff --git a/lib/towerops_web/controllers/api/v1/escalation_policies_controller.ex b/lib/towerops_web/controllers/api/v1/escalation_policies_controller.ex index 7e61333b..e5056d7a 100644 --- a/lib/towerops_web/controllers/api/v1/escalation_policies_controller.ex +++ b/lib/towerops_web/controllers/api/v1/escalation_policies_controller.ex @@ -17,6 +17,8 @@ defmodule ToweropsWeb.Api.V1.EscalationPoliciesController do alias ToweropsWeb.Api.ParamFilter alias ToweropsWeb.ScopedResource + require Logger + # --- Policy CRUD --- @doc "GET /api/v1/escalation_policies" @@ -238,8 +240,6 @@ defmodule ToweropsWeb.Api.V1.EscalationPoliciesController do json(conn, %{success: true}) {:error, reason} -> - require Logger - Logger.error("Failed to delete escalation target #{target_id}: #{inspect(reason)}") conn |> put_status(:internal_server_error) |> json(%{error: "Failed to delete escalation target"}) end diff --git a/lib/towerops_web/controllers/health_controller.ex b/lib/towerops_web/controllers/health_controller.ex index 551ce1b6..a092c1e7 100644 --- a/lib/towerops_web/controllers/health_controller.ex +++ b/lib/towerops_web/controllers/health_controller.ex @@ -6,6 +6,8 @@ defmodule ToweropsWeb.HealthController do alias Ecto.Adapters.SQL alias Towerops.Repo + require Logger + # Liveness probe: confirms the BEAM/web stack is responsive. Deliberately does # NOT touch the database or redis — liveness failure causes k8s to kill the # pod, so it must not react to transient dependency outages. Dependency health @@ -18,8 +20,6 @@ defmodule ToweropsWeb.HealthController do end def index(conn, _params) do - require Logger - db_status = check_database() redis_status = check_redis() @@ -61,8 +61,6 @@ defmodule ToweropsWeb.HealthController do end defp check_redis do - require Logger - redis_config = Application.get_env(:towerops, :redis, []) if Keyword.has_key?(redis_config, :host) do diff --git a/lib/towerops_web/live/account_live/totp_enrollment.ex b/lib/towerops_web/live/account_live/totp_enrollment.ex index 23e4de8d..e058600b 100644 --- a/lib/towerops_web/live/account_live/totp_enrollment.ex +++ b/lib/towerops_web/live/account_live/totp_enrollment.ex @@ -8,10 +8,10 @@ defmodule ToweropsWeb.AccountLive.TotpEnrollment do alias Towerops.Accounts + require Logger + @impl true def mount(_params, _session, socket) do - require Logger - user = socket.assigns.current_scope.user # If user already has TOTP enabled, redirect them @@ -45,9 +45,7 @@ defmodule ToweropsWeb.AccountLive.TotpEnrollment do |> assign(:page_title, t("Set Up Two-Factor Authentication")) |> assign(:secret_base32, secret_base32) |> assign(:qr_code, qr_code) - |> assign(:code, "") |> assign(:error, nil) - |> assign(:enrollment_complete, false) |> assign(:recovery_codes, []) |> assign(:show_recovery_codes, false) @@ -60,9 +58,7 @@ defmodule ToweropsWeb.AccountLive.TotpEnrollment do |> assign(:page_title, t("Set Up Two-Factor Authentication")) |> assign(:secret_base32, nil) |> assign(:qr_code, nil) - |> assign(:code, "") |> assign(:error, nil) - |> assign(:enrollment_complete, false) |> assign(:recovery_codes, []) |> assign(:show_recovery_codes, false) @@ -73,8 +69,6 @@ defmodule ToweropsWeb.AccountLive.TotpEnrollment do @impl true def handle_event("verify_code", %{"code" => code}, socket) do - require Logger - user = socket.assigns.current_scope.user secret_base32 = socket.assigns.secret_base32 @@ -123,7 +117,6 @@ defmodule ToweropsWeb.AccountLive.TotpEnrollment do # Show recovery codes to user - they can only be displayed once {:noreply, socket - |> assign(:enrollment_complete, true) |> assign(:recovery_codes, codes) |> assign(:show_recovery_codes, true)} diff --git a/lib/towerops_web/live/admin/monitoring_live.ex b/lib/towerops_web/live/admin/monitoring_live.ex index f994fb83..9b784d61 100644 --- a/lib/towerops_web/live/admin/monitoring_live.ex +++ b/lib/towerops_web/live/admin/monitoring_live.ex @@ -31,10 +31,7 @@ defmodule ToweropsWeb.Admin.MonitoringLive do |> assign(:active_jobs, []) |> assign(:executing_jobs, []) |> assign(:stuck_jobs, []) - |> assign(:stuck_jobs_count, 0) |> assign(:failed_jobs, []) - |> assign(:failed_jobs_count, 0) - |> assign(:recent_jobs, []) |> assign(:recent_events, []) |> assign(:metrics, %{}) |> assign(:health_metrics, %{}) @@ -77,10 +74,7 @@ defmodule ToweropsWeb.Admin.MonitoringLive do socket |> assign(:executing_jobs, executing_jobs) |> assign(:stuck_jobs, stuck_jobs) - |> assign(:stuck_jobs_count, length(stuck_jobs)) |> assign(:failed_jobs, failed_jobs) - |> assign(:failed_jobs_count, length(failed_jobs)) - |> assign(:recent_jobs, recent_jobs) |> assign(:recent_events, recent_jobs) |> assign(:metrics, metrics) |> assign(:health_metrics, metrics) diff --git a/lib/towerops_web/live/admin/org_live/index.ex b/lib/towerops_web/live/admin/org_live/index.ex index d2ceed44..dc4ac52f 100644 --- a/lib/towerops_web/live/admin/org_live/index.ex +++ b/lib/towerops_web/live/admin/org_live/index.ex @@ -9,6 +9,7 @@ defmodule ToweropsWeb.Admin.OrgLive.Index do alias Towerops.Admin alias Towerops.Billing alias Towerops.Organizations.Organization + alias Towerops.Repo on_mount {ToweropsWeb.UserAuth, :require_superuser} @@ -262,8 +263,6 @@ defmodule ToweropsWeb.Admin.OrgLive.Index do end defp count_active_subscriptions do - alias Towerops.Repo - Repo.one( from o in Organization, where: o.subscription_status == "active" and not is_nil(o.stripe_subscription_id), diff --git a/lib/towerops_web/live/agent_live/index.ex b/lib/towerops_web/live/agent_live/index.ex index 4b9e585f..3cc06764 100644 --- a/lib/towerops_web/live/agent_live/index.ex +++ b/lib/towerops_web/live/agent_live/index.ex @@ -8,7 +8,6 @@ defmodule ToweropsWeb.AgentLive.Index do alias Towerops.Accounts.Scope alias Towerops.Agents - alias Towerops.Agents.Stats alias Towerops.Settings @impl true @@ -45,11 +44,6 @@ defmodule ToweropsWeb.AgentLive.Index do %{} end - # Get organization-wide agent health statistics - agent_health_stats = Stats.get_organization_agent_health(organization.id) - assignment_breakdown = Stats.get_device_assignment_breakdown(organization.id) - offline_agents = Stats.get_offline_agents(organization.id) - # Get agent image URL from config or use default agent_image = Application.get_env( @@ -72,9 +66,6 @@ defmodule ToweropsWeb.AgentLive.Index do |> assign(:selected_global_default, global_default_cloud_poller_id || "") |> assign(:device_counts, equipment_counts) |> assign(:cloud_poller_counts, cloud_poller_counts) - |> assign(:agent_health_stats, agent_health_stats) - |> assign(:assignment_breakdown, assignment_breakdown) - |> assign(:offline_agents, offline_agents) |> assign(:agent_image, agent_image) |> assign(:new_token, nil) |> assign(:show_token_modal, false) @@ -223,10 +214,6 @@ defmodule ToweropsWeb.AgentLive.Index do equipment_counts = calculate_device_counts(agent_tokens) cloud_poller_counts = calculate_device_counts(cloud_pollers) - agent_health_stats = Stats.get_organization_agent_health(organization.id) - assignment_breakdown = Stats.get_device_assignment_breakdown(organization.id) - offline_agents = Stats.get_offline_agents(organization.id) - success_message = get_success_message(is_cloud_poller) {:noreply, @@ -238,9 +225,6 @@ defmodule ToweropsWeb.AgentLive.Index do |> assign(:has_cloud_pollers, cloud_pollers != []) |> assign(:device_counts, equipment_counts) |> assign(:cloud_poller_counts, cloud_poller_counts) - |> assign(:agent_health_stats, agent_health_stats) - |> assign(:assignment_breakdown, assignment_breakdown) - |> assign(:offline_agents, offline_agents) |> assign(:new_token, %{agent_token: agent_token, token: token}) |> assign(:agent_form, to_form(%{"name" => "", "is_cloud_poller" => false})) |> put_flash(:info, success_message) @@ -338,10 +322,6 @@ defmodule ToweropsWeb.AgentLive.Index do equipment_counts = calculate_device_counts(agent_tokens) cloud_poller_counts = calculate_device_counts(cloud_pollers) - agent_health_stats = Stats.get_organization_agent_health(organization.id) - assignment_breakdown = Stats.get_device_assignment_breakdown(organization.id) - offline_agents = Stats.get_offline_agents(organization.id) - socket |> stream(:agent_tokens, agent_tokens, reset: true) |> assign(:has_agents, agent_tokens != []) @@ -350,9 +330,6 @@ defmodule ToweropsWeb.AgentLive.Index do |> assign(:has_cloud_pollers, cloud_pollers != []) |> assign(:device_counts, equipment_counts) |> assign(:cloud_poller_counts, cloud_poller_counts) - |> assign(:agent_health_stats, agent_health_stats) - |> assign(:assignment_breakdown, assignment_breakdown) - |> assign(:offline_agents, offline_agents) end defp maybe_update_agent(socket, agent_token_id, organization_id) do @@ -388,14 +365,7 @@ defmodule ToweropsWeb.AgentLive.Index do end defp update_health_stats(socket) do - organization = socket.assigns.current_scope.organization - - agent_health_stats = Stats.get_organization_agent_health(organization.id) - offline_agents = Stats.get_offline_agents(organization.id) - socket - |> assign(:agent_health_stats, agent_health_stats) - |> assign(:offline_agents, offline_agents) end defp agent_authorized_for_deletion?(socket, agent_token) do @@ -429,10 +399,6 @@ defmodule ToweropsWeb.AgentLive.Index do equipment_counts = calculate_device_counts(agent_tokens) cloud_poller_counts = calculate_device_counts(cloud_pollers) - agent_health_stats = Stats.get_organization_agent_health(organization.id) - assignment_breakdown = Stats.get_device_assignment_breakdown(organization.id) - offline_agents = Stats.get_offline_agents(organization.id) - {:noreply, socket |> stream(:agent_tokens, agent_tokens, reset: true) @@ -444,9 +410,6 @@ defmodule ToweropsWeb.AgentLive.Index do |> assign(:selected_global_default, global_default_cloud_poller_id || "") |> assign(:device_counts, equipment_counts) |> assign(:cloud_poller_counts, cloud_poller_counts) - |> assign(:agent_health_stats, agent_health_stats) - |> assign(:assignment_breakdown, assignment_breakdown) - |> assign(:offline_agents, offline_agents) |> put_flash( :info, t_equipment("Agent deleted successfully. Devices now fall back to site/org defaults or cloud polling.") diff --git a/lib/towerops_web/live/alert_live/index.ex b/lib/towerops_web/live/alert_live/index.ex index 95c990be..d2ceded8 100644 --- a/lib/towerops_web/live/alert_live/index.ex +++ b/lib/towerops_web/live/alert_live/index.ex @@ -196,7 +196,6 @@ defmodule ToweropsWeb.AlertLive.Index do site_subscribers = load_site_subscribers(filtered_alerts) sorted_alerts = sort_alerts(filtered_alerts, socket.assigns.sort_by, site_subscribers) - grouped = group_by_site(sorted_alerts, site_subscribers) counts = %{ all: Alerts.count_organization_alerts(organization_id), @@ -208,7 +207,6 @@ defmodule ToweropsWeb.AlertLive.Index do socket |> assign(:alerts, sorted_alerts) |> assign(:site_subscribers, site_subscribers) - |> assign(:grouped_alerts, grouped) |> assign(:counts, counts) end @@ -245,32 +243,6 @@ defmodule ToweropsWeb.AlertLive.Index do def severity_weight(%{alert_type: "device_down"}), do: 1 def severity_weight(_alert), do: 2 - defp group_by_site(alerts, site_subscribers) do - alerts - |> Enum.group_by(fn alert -> - if alert.device.site do - {alert.device.site.id, alert.device.site.name} - else - {nil, "No Site"} - end - end) - |> Enum.map(fn {{site_id, site_name}, site_alerts} -> - sub_info = if site_id, do: site_subscribers[site_id] - critical_count = Enum.count(site_alerts, &(&1.alert_type == "device_down" and is_nil(&1.resolved_at))) - - %{ - site_id: site_id, - site_name: site_name, - alerts: site_alerts, - total_count: length(site_alerts), - critical_count: critical_count, - subscriber_info: sub_info, - total_subscribers: get_site_subscriber_count(sub_info) - } - end) - |> Enum.sort_by(fn group -> {-group.critical_count, -group.total_subscribers, -group.total_count} end) - end - @doc false def get_site_subscriber_count(%{account_count: count}) when is_integer(count), do: count def get_site_subscriber_count(_), do: 0 diff --git a/lib/towerops_web/live/changelog_live.ex b/lib/towerops_web/live/changelog_live.ex index 4f8f7512..ae65db90 100644 --- a/lib/towerops_web/live/changelog_live.ex +++ b/lib/towerops_web/live/changelog_live.ex @@ -5,7 +5,7 @@ defmodule ToweropsWeb.ChangelogLive do @impl true def mount(_params, _session, socket) do entries = ToweropsWeb.ChangelogParser.parse() - {:ok, assign(socket, entries: entries, page_title: "What's New", active_page: "changelog")} + {:ok, assign(socket, entries: entries, page_title: "What's New")} end @impl true diff --git a/lib/towerops_web/live/check_live/form_component.ex b/lib/towerops_web/live/check_live/form_component.ex index 78b57699..7875240e 100644 --- a/lib/towerops_web/live/check_live/form_component.ex +++ b/lib/towerops_web/live/check_live/form_component.ex @@ -309,16 +309,12 @@ defmodule ToweropsWeb.CheckLive.FormComponent do |> assign(assigns) |> assign(:action, action) |> assign(:selected_type, selected_type) - |> assign(:form, to_form(changeset)) - |> assign_default_config(selected_type)} + |> assign(:form, to_form(changeset))} end @impl true def handle_event("change_type", %{"check" => %{"check_type" => type}}, socket) do - socket = - socket - |> assign(:selected_type, type) - |> assign_default_config(type) + socket = assign(socket, :selected_type, type) # Auto-fill host from device IP for TCP and SSL checks socket = @@ -451,20 +447,6 @@ defmodule ToweropsWeb.CheckLive.FormComponent do def config_to_form_fields(_config, _type), do: %{} - defp assign_default_config(socket, type) do - assign(socket, :default_config, default_config_for_type(socket, type)) - end - - defp default_config_for_type(_socket, "http"), do: default_config_by_type("http", "") - - defp default_config_for_type(socket, "tcp"), do: default_config_by_type("tcp", device_host_from_socket(socket)) - - defp default_config_for_type(_socket, "dns"), do: default_config_by_type("dns", "") - - defp default_config_for_type(socket, "ssl"), do: default_config_by_type("ssl", device_host_from_socket(socket)) - - defp default_config_for_type(_socket, _type), do: %{} - @doc false def default_config_by_type("http", _host) do %{ @@ -489,10 +471,6 @@ defmodule ToweropsWeb.CheckLive.FormComponent do def device_host(%{ip_address: ip}), do: to_string(ip) def device_host(_), do: "" - defp device_host_from_socket(socket) do - device_host(socket.assigns[:device]) - end - @doc false def merge_config_params(check_params, type) do check_params diff --git a/lib/towerops_web/live/components/global_search_component.ex b/lib/towerops_web/live/components/global_search_component.ex index 621ac602..cea5a4d1 100644 --- a/lib/towerops_web/live/components/global_search_component.ex +++ b/lib/towerops_web/live/components/global_search_component.ex @@ -69,9 +69,6 @@ defmodule ToweropsWeb.Live.Components.GlobalSearchComponent do @impl true def render(assigns) do - flat = flat_results(assigns.results) - assigns = assign(assigns, flat_results: flat) - ~H"""