prop/lib/microwaveprop/radio/contact_common_volume_radar.ex
Graham McIntire d31e783776
Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 4m35s
fix: resolve 18 bugs across LiveViews, schemas, tests, and logic
- MonitorLive.Show: safe nil-guard on current_scope for anonymous access
- Admin.MonitorLive.Index: add phx-update=stream to enable stream ops
- ImportLive: require owner/admin authorization, not_found redirect
- MapLive: store timer refs in assigns, cancel before reschedule
- 10 schemas: add missing foreign_key_constraint on belongs_to
- Soundings: preload :station to eliminate N+1 in path analysis
- PathAnalysis: defensive preload of :station on soundings
- GridTaskEnqueuer: wrap reclaim_stale_running in Repo.transaction()
- HrdpsClient: replace String.to_atom with compile-time atom literals
- Contacts: fix extract_latlon false return for lon=0.0
- Tests: remove duplicate Mox.defmock, unblock swallowed task exits,
  bump refute_receive timeouts from 50ms to 200ms
2026-07-29 07:46:54 -05:00

48 lines
1.5 KiB
Elixir

defmodule Microwaveprop.Radio.ContactCommonVolumeRadar do
@moduledoc """
Aggregated n0q composite reflectivity statistics sampled inside the
common volume (lens-shaped intersection of two 400 km circles around
the endpoints) for a single contact, at the QSO time.
One row per contact. Feeds `Microwaveprop.Propagation.RainScatterClassifier`.
"""
use Ecto.Schema
import Ecto.Changeset
alias Microwaveprop.Radio.Contact
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "contact_common_volume_radar" do
belongs_to :contact, Contact
field :observed_at, :utc_datetime
field :common_volume_km2, :float
field :pixel_count, :integer, default: 0
field :rain_pixel_count, :integer, default: 0
field :heavy_rain_pixel_count, :integer, default: 0
field :core_pixel_count, :integer, default: 0
field :max_dbz, :float
field :mean_dbz, :float
field :coverage_pct, :float
timestamps(type: :utc_datetime)
end
@type t :: %__MODULE__{}
@required ~w(contact_id observed_at)a
@optional ~w(common_volume_km2 pixel_count rain_pixel_count heavy_rain_pixel_count
core_pixel_count max_dbz mean_dbz coverage_pct)a
@spec changeset(t() | Ecto.Changeset.t(), map()) :: Ecto.Changeset.t()
def changeset(row, attrs) do
row
|> cast(attrs, @required ++ @optional)
|> validate_required(@required)
|> foreign_key_constraint(:contact_id)
|> unique_constraint(:contact_id)
end
end