defmodule Towerops.Agents.AgentAssignment do @moduledoc """ Schema for assigning devices to remote agents. Each device can only be assigned to one agent at a time (unique constraint on device_id). This ensures that polling is not duplicated across multiple agents. """ use Ecto.Schema import Ecto.Changeset alias Ecto.Association.NotLoaded alias Towerops.Agents.AgentToken alias Towerops.Devices.Device @primary_key {:id, :binary_id, autogenerate: true} @foreign_key_type :binary_id schema "agent_assignments" do field :enabled, :boolean, default: true belongs_to :agent_token, AgentToken belongs_to :device, Device timestamps(type: :utc_datetime) end @type t :: %__MODULE__{ id: Ecto.UUID.t(), enabled: boolean(), agent_token_id: Ecto.UUID.t(), agent_token: NotLoaded.t() | AgentToken.t(), device_id: Ecto.UUID.t(), device: NotLoaded.t() | Device.t(), inserted_at: DateTime.t(), updated_at: DateTime.t() } @doc """ Changeset for creating and updating agent assignments. ## Examples iex> changeset(%AgentAssignment{}, %{agent_token_id: token_id, device_id: equip_id}) %Ecto.Changeset{valid?: true} """ def changeset(assignment, attrs) do assignment |> cast(attrs, [:agent_token_id, :device_id, :enabled]) |> validate_required([:agent_token_id, :device_id]) |> unique_constraint([:device_id]) |> foreign_key_constraint(:agent_token_id) |> foreign_key_constraint(:device_id) end end