From 74f112642d47f00f816ad0dd2db9adcc8de401d9 Mon Sep 17 00:00:00 2001
From: Graham McIntie
Date: Sat, 14 Feb 2026 13:06:51 -0600
Subject: [PATCH] feat: make network insights actionable with affected device
links and metadata
---
lib/towerops/workers/gaiia_insight_worker.ex | 9 +++++-
.../live/insights_live/index.html.heex | 30 +++++++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/lib/towerops/workers/gaiia_insight_worker.ex b/lib/towerops/workers/gaiia_insight_worker.ex
index f26fef1e..1392f3a2 100644
--- a/lib/towerops/workers/gaiia_insight_worker.ex
+++ b/lib/towerops/workers/gaiia_insight_worker.ex
@@ -49,6 +49,7 @@ defmodule Towerops.Workers.GaiiaInsightWorker do
"dedup_key" => "untracked",
"finding_type" => "untracked",
"count" => count,
+ "device_ids" => untracked_devices |> Enum.map(& &1.device.id),
"device_names" => untracked_devices |> Enum.take(10) |> Enum.map(& &1.device.name)
}
})
@@ -97,7 +98,13 @@ defmodule Towerops.Workers.GaiiaInsightWorker do
metadata: %{
"dedup_key" => "mismatch",
"finding_type" => "mismatch",
- "count" => count
+ "count" => count,
+ "device_ids" => data_mismatches |> Enum.map(& &1.device.id) |> Enum.uniq(),
+ "device_names" =>
+ data_mismatches
+ |> Enum.map(& &1.device.name)
+ |> Enum.uniq()
+ |> Enum.take(10)
}
})
end
diff --git a/lib/towerops_web/live/insights_live/index.html.heex b/lib/towerops_web/live/insights_live/index.html.heex
index 6355375f..6466cd99 100644
--- a/lib/towerops_web/live/insights_live/index.html.heex
+++ b/lib/towerops_web/live/insights_live/index.html.heex
@@ -274,6 +274,36 @@
<% end %>
+ <%!-- Affected devices list (from metadata) --%>
+ <%= if insight.metadata["device_names"] && length(insight.metadata["device_names"]) > 0 do %>
+
+
+ Affected devices:
+
+
+ <%= for {name, idx} <- Enum.with_index(insight.metadata["device_names"]) do %>
+ <%= if insight.metadata["device_ids"] && Enum.at(insight.metadata["device_ids"], idx) do %>
+ <.link
+ navigate={~p"/devices/#{Enum.at(insight.metadata["device_ids"], idx)}"}
+ class="inline-flex items-center rounded-md bg-white px-2 py-0.5 text-xs font-medium text-indigo-700 ring-1 ring-inset ring-indigo-700/10 hover:bg-indigo-50 dark:bg-indigo-900/20 dark:text-indigo-400 dark:ring-indigo-400/20 dark:hover:bg-indigo-900/40"
+ >
+ {name || "Unnamed"}
+
+ <% else %>
+
+ {name || "Unnamed"}
+
+ <% end %>
+ <% end %>
+ <%= if insight.metadata["count"] && insight.metadata["count"] > length(insight.metadata["device_names"]) do %>
+
+ +{insight.metadata["count"] - length(insight.metadata["device_names"])} more
+
+ <% end %>
+
+
+ <% end %>
+
<%!-- Access point --%>
<%= if insight.preseem_access_point do %>