DoubleEntryLedger.Command (double_entry_ledger v0.1.0)

View Source

Defines and manages commands in the Double Entry Ledger system.

The Command schema represents a request to create or update ledger data. Commands drive the asynchronous processing pipeline (queueing, retries, idempotency) and link to journal events once they have been processed.

Summary

Types

t()

Represents a command in the Double Entry Ledger system.

Functions

Creates a changeset for validating and creating/updating a Command.

Creates a changeset for marking a command as being processed.

Types

t()

@type t() :: %DoubleEntryLedger.Command{
  __meta__: term(),
  account: DoubleEntryLedger.Account.t() | Ecto.Association.NotLoaded.t(),
  command_map: map() | nil,
  command_queue_item:
    DoubleEntryLedger.CommandQueueItem.t() | Ecto.Association.NotLoaded.t(),
  id: Ecto.UUID.t() | nil,
  inserted_at: DateTime.t() | nil,
  instance: DoubleEntryLedger.Instance.t() | Ecto.Association.NotLoaded.t(),
  instance_id: Ecto.UUID.t() | nil,
  journal_event:
    DoubleEntryLedger.JournalEvent.t() | Ecto.Association.NotLoaded.t(),
  journal_event_command_link:
    DoubleEntryLedger.JournalEventCommandLink.t()
    | Ecto.Association.NotLoaded.t(),
  transaction:
    DoubleEntryLedger.Transaction.t() | Ecto.Association.NotLoaded.t(),
  updated_at: DateTime.t() | nil
}

Represents a command in the Double Entry Ledger system.

A command encapsulates a request to create or update a transaction, along with metadata about the processing state, source, and queue management information.

Fields

  • id: UUID primary key
  • command_map: map containing the command payload
  • instance: Association to the ledger instance
  • instance_id: Foreign key to the ledger instance
  • inserted_at: Creation timestamp
  • updated_at: Last update timestamp

Functions

changeset(command, attrs)

@spec changeset(t(), map()) :: Ecto.Changeset.t()

Creates a changeset for validating and creating/updating a Command.

This function builds an Ecto changeset for a command with appropriate validations and handling based on the action type and transaction data provided.

Parameters

  • command - The Command struct to create a changeset for
  • attrs - Map of attributes to apply to the command

Returns

  • An Ecto.Changeset with validations applied

Examples

# Create command changeset
iex> command_map = %{
...>   action: :create_transaction,
...>   source: "api",
...>   source_idempk: "order-123",
...>   instance_address: "instance1",
...>   payload: %{status: :pending, entries: [
...>     %{account_address: "account1", amount: 100, currency: :USD},
...>     %{account_address: "account2", amount: 100, currency: :USD}
...>   ]}
...> }
...> attrs = %{instance_id: Ecto.UUID.generate(), command_map: command_map}
iex> changeset = Command.changeset(%Command{}, attrs)
iex> changeset.valid?
true

# Error changeset is added
iex> command_map = %{
...>   action: :create_account,
...>   source: "api",
...>   source_idempk: "order-123",
...>   instance_address: "instance1",
...>   payload: %{type: :wrong, address: "wrong format"}
...> }
...> attrs = %{instance_id: Ecto.UUID.generate(), command_map: command_map}
iex> changeset = Command.changeset(%Command{}, attrs)
iex> changeset.valid?
false
iex> Map.has_key?(changeset, :command_map_changeset)
true
iex> changeset.command_map_changeset.valid?
false

processing_start_changeset(command, processor_id, retry_count)

@spec processing_start_changeset(t(), String.t(), non_neg_integer()) ::
  Ecto.Changeset.t()

Creates a changeset for marking a command as being processed.

This function prepares a changeset that updates a command to the :processing state, assigns a processor, and updates processing metadata such as start time and retry count.

Parameters

  • command - The Command struct to update
  • processor_id - String identifier for the processor handling the command

Returns

  • An Ecto.Changeset with processing status updates and optimistic locking

Fields Updated

  • status: Set to :processing
  • processor_id: Set to the provided processor_id
  • processing_started_at: Set to current UTC datetime
  • processing_completed_at: Set to nil
  • retry_count: Incremented by 1
  • next_retry_after: Set to nil
  • processor_version: Used for optimistic locking