lib/openagents/compensation/event.ex

58e6347eeb72 · 2 KB

defmodule OpenAgents.Compensation.Event do
  @moduledoc "One deduplicated compensation classification for an accepted invocation outcome."
  use Ecto.Schema
  import Ecto.Changeset

  @primary_key {:id, :binary_id, autogenerate: true}
  @foreign_key_type :binary_id
  @timestamps_opts [type: :utc_datetime_usec, updated_at: false]

  schema "compensation_events" do
    belongs_to :tool_step, OpenAgents.Conversations.ToolStep
    belongs_to :policy_receipt, OpenAgents.Compensation.PolicyReceipt
    belongs_to :outcome_decision, OpenAgents.Compensation.OutcomeDecision
    field :module_id, :string
    field :module_version, :integer
    field :artifact_digest, :string
    field :invocation_key, :string
    field :outcome_receipt_ref, :string
    field :technical_units, :integer
    field :eligible_units, :integer
    field :classification, :string
    field :reason_code, :string
    field :event_digest, :string
    timestamps()
  end

  @type t :: %__MODULE__{}

  def changeset(record, attributes) do
    record
    |> cast(
      attributes,
      ~w(tool_step_id policy_receipt_id outcome_decision_id module_id module_version artifact_digest invocation_key outcome_receipt_ref technical_units eligible_units classification reason_code event_digest)a
    )
    |> validate_required(
      ~w(tool_step_id policy_receipt_id outcome_decision_id module_id module_version artifact_digest invocation_key outcome_receipt_ref technical_units eligible_units classification reason_code event_digest)a
    )
    |> validate_inclusion(:classification, ~w(eligible ineligible))
    |> validate_number(:technical_units, greater_than_or_equal_to: 0)
    |> validate_number(:eligible_units, greater_than_or_equal_to: 0)
    |> validate_format(:artifact_digest, ~r/\A[0-9a-f]{64}\z/)
    |> validate_format(:invocation_key, ~r/\A[0-9a-f]{64}\z/)
    |> validate_format(:event_digest, ~r/\A[0-9a-f]{64}\z/)
    |> foreign_key_constraint(:tool_step_id)
    |> foreign_key_constraint(:policy_receipt_id)
    |> foreign_key_constraint(:outcome_decision_id)
    |> unique_constraint(:tool_step_id)
    |> unique_constraint(:invocation_key)
    |> unique_constraint(:outcome_receipt_ref)
  end
end