Turned on :error_handling, :underspecs, and :unmatched_returns in mix.exs dialyzer config. The 97 warnings this surfaced were fixed in place rather than suppressed: - unmatched_return (79): explicit discard with `_ = ...` for fire-and-forget side effects (Process.cancel_timer, :ets.new, send/2), and pattern-matched `:ok = ...` for control-plane Phoenix.PubSub subscribe/unsubscribe/broadcast calls so a future return-shape change fails loud. - contract_supertype (18): tightened @spec arg and return types on data_builder, historical_loader, url_params, packet_utils, encoding_utils, aprs_symbol, weather_controller, packet_replay to match each function's actual success typing. No behavioural change. mix compile clean, 1008 tests pass, dialyzer count is now 0.
76 lines
2 KiB
Elixir
76 lines
2 KiB
Elixir
defmodule AprsmeWeb.BadPacketsLive.Index do
|
|
@moduledoc false
|
|
use AprsmeWeb, :live_view
|
|
|
|
import Ecto.Query
|
|
|
|
alias Aprsme.BadPacket
|
|
alias Aprsme.Repo
|
|
|
|
@impl true
|
|
def mount(_params, _session, socket) do
|
|
if connected?(socket) do
|
|
# Subscribe to Postgres notifications for bad packets
|
|
:ok = Phoenix.PubSub.subscribe(Aprsme.PubSub, "postgres:aprsme_events")
|
|
# Load initial bad packets
|
|
bad_packets = fetch_bad_packets()
|
|
# Extra safeguard to ensure we never show more than 100
|
|
limited_packets = Enum.take(bad_packets, 100)
|
|
|
|
{:ok,
|
|
assign(socket,
|
|
bad_packets: limited_packets,
|
|
loading: false,
|
|
last_updated: DateTime.utc_now()
|
|
)}
|
|
else
|
|
{:ok, assign(socket, bad_packets: [], loading: false, last_updated: nil)}
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def handle_params(params, _url, socket) do
|
|
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
|
|
end
|
|
|
|
defp apply_action(socket, :index, _params) do
|
|
assign(socket, :page_title, "Bad Packets")
|
|
end
|
|
|
|
@impl true
|
|
def handle_event("refresh", _params, socket) do
|
|
send(self(), :do_refresh)
|
|
{:noreply, assign(socket, loading: true)}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info({:postgres_notify, _payload}, socket) do
|
|
# Optionally filter payload for bad packet events
|
|
send(self(), :do_refresh)
|
|
{:noreply, socket}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info(:do_refresh, socket) do
|
|
bad_packets = fetch_bad_packets()
|
|
# Extra safeguard to ensure we never show more than 100
|
|
limited_packets = Enum.take(bad_packets, 100)
|
|
|
|
{:noreply,
|
|
assign(socket,
|
|
bad_packets: limited_packets,
|
|
loading: false,
|
|
last_updated: DateTime.utc_now()
|
|
)}
|
|
end
|
|
|
|
defp fetch_bad_packets(limit \\ 100) do
|
|
# Hard cap at 100 to prevent showing too many records
|
|
actual_limit = min(limit, 100)
|
|
|
|
BadPacket
|
|
|> order_by([b], desc: b.attempted_at)
|
|
|> limit(^actual_limit)
|
|
|> Repo.all()
|
|
end
|
|
end
|