lib/openagents/repositories/repository_publication.ex

58e6347eeb72 · 2 KB

defmodule OpenAgents.Repositories.RepositoryPublication do
  @moduledoc "Records one idempotent publication from a chat workspace to Forge."

  use Ecto.Schema
  import Ecto.Changeset

  @primary_key {:id, :binary_id, autogenerate: true}
  @foreign_key_type :binary_id
  @timestamps_opts [type: :utc_datetime_usec]
  @states ~w(requested committing pushing accepted uncertain failed nothing_to_publish)

  schema "repository_publications" do
    belongs_to :repository, OpenAgents.Repositories.Repository
    belongs_to :owner_user, OpenAgents.Accounts.User
    field :conversation_id, :binary_id
    field :tool_call_id, :string
    field :workspace_ref, :string
    field :idempotency_key, :string
    field :argument_digest, :string
    field :message, :string
    field :expected_workspace_digest, :string
    field :observed_workspace_digest, :string
    field :branch, :string
    field :source_oid, :string
    field :expected_previous_oid, :string
    field :published_oid, :string
    field :state, :string, default: "requested"
    field :wal_seq, :integer
    field :result, :map
    field :error_code, :string
    timestamps()
  end

  def changeset(publication, attrs) do
    publication
    |> cast(attrs, [
      :repository_id,
      :owner_user_id,
      :conversation_id,
      :tool_call_id,
      :workspace_ref,
      :idempotency_key,
      :argument_digest,
      :message,
      :expected_workspace_digest,
      :observed_workspace_digest,
      :branch,
      :source_oid,
      :expected_previous_oid,
      :published_oid,
      :state,
      :wal_seq,
      :result,
      :error_code
    ])
    |> validate_required([
      :repository_id,
      :owner_user_id,
      :workspace_ref,
      :idempotency_key,
      :argument_digest,
      :message,
      :branch,
      :state
    ])
    |> validate_inclusion(:state, @states)
    |> validate_length(:message, min: 1, max: 2_000)
    |> validate_length(:idempotency_key, is: 64)
    |> validate_length(:argument_digest, is: 64)
    |> unique_constraint(:idempotency_key)
    |> foreign_key_constraint(:repository_id)
    |> foreign_key_constraint(:owner_user_id)
    |> check_constraint(:state, name: :repository_publications_state_check)
  end
end