DoubleEntryLedger.Stores.CommandStoreHelper (double_entry_ledger v0.2.0)
View SourceHelper functions for command processing in the Double Entry Ledger system.
This module provides reusable utilities for working with commands, focusing on common operations like building changesets, retrieving related commands and transactions, and creating multi operations for use in Ecto transactions.
Key Functionality
- Changeset Building: Create Command changesets from TransactionCommandMaps or AccountCommandMaps
- Command Relationships: Look up related commands by source identifiers
- Transaction Linking: Find transactions and accounts associated with commands
- Ecto.Multi Integration: Build multi operations for atomic database transactions
- Status Management: Create changesets to update command status and error information
Usage Examples
Building a changeset from a CommandMap:
event_changeset = CommandStoreHelper.build_create(command_map)Adding a step to get a create command's transaction:
multi =
Ecto.Multi.new()
|> CommandStoreHelper.build_get_create_transaction_command_transaction(:transaction, update_command)
|> Ecto.Multi.update(:event, fn %{transaction: transaction} ->
CommandStoreHelper.build_mark_as_processed(update_command, transaction.id)
end)Implementation Notes
This module is primarily used internally by CommandStore and CommandWorker modules to share common functionality and reduce code duplication.
Summary
Functions
Builds an Command changeset from a TransactionCommandMap or AccountCommandMap.
Builds an Ecto.Multi step to get a create-transaction command's transaction.
Retrieves a command by its action and source identifiers with preloaded associations.
Gets the transaction associated with a create-transaction command.
Functions
@spec base_account_query(Ecto.UUID.t()) :: Ecto.Query.t()
@spec base_transaction_query(Ecto.UUID.t()) :: Ecto.Query.t()
@spec build_create( DoubleEntryLedger.Command.TransactionCommandMap.t() | DoubleEntryLedger.Command.AccountCommandMap.t(), Ecto.UUID.t() ) :: Ecto.Changeset.t(DoubleEntryLedger.Command.t())
Builds an Command changeset from a TransactionCommandMap or AccountCommandMap.
Creates a new Command changeset suitable for database insertion, converting the provided command map structure into the appropriate Command attributes.
Parameters
command_map- Either a TransactionCommandMap or AccountCommandMap struct containing command data
Returns
Ecto.Changeset.t(Command.t())- A changeset for creating a new Command
@spec build_get_create_transaction_command_transaction( Ecto.Multi.t(), atom(), DoubleEntryLedger.Command.t() | atom() ) :: Ecto.Multi.t()
Builds an Ecto.Multi step to get a create-transaction command's transaction.
This function adds a step to an Ecto.Multi that retrieves the transaction associated with the create command corresponding to an update command. Handles error cases by wrapping exceptions in the result tuple.
Parameters
multi- The Ecto.Multi instance to add the step tostep- The atom representing the step name in the Multicommand_or_step- Either a Command struct or the name of a previous step in the Multi
Returns
Ecto.Multi.t()- The updated Multi instance with the new step added
@spec get_command_by(atom(), String.t(), String.t(), Ecto.UUID.t()) :: DoubleEntryLedger.Command.t() | nil
Retrieves a command by its action and source identifiers with preloaded associations.
This function looks up a command using its action,
command_map
|> TransactionCommandMap.to_map()
|> Map.put(:instance_id, instance_id)
|> Mts action, source system identifier,source-specific identifier, and instance ID. The returned command includes preloaded associations for command_queue_item, account, and transaction with its entries.
Parameters
action: The command action atom (e.g.,:create_transaction,:create_account)source: The source system identifier (e.g., "accounting_system", "api")source_idempk: The source-specific identifier (e.g., "invoice_123", "tx_456")instance_id: The instance UUID that groups related events
Returns
Command.t() | nil: The found command with preloaded associations, or nil if not found
Preloaded Associations
The returned command includes:
:command_queue_item- Processing status and retry information:account- Associated account (for account-related events)transaction: [entries: :account]- Transaction with its entries and accounts
@spec get_create_transaction_command_transaction(DoubleEntryLedger.Command.t()) :: {:ok, {DoubleEntryLedger.Transaction.t(), DoubleEntryLedger.Command.t()}} | {:error | :pending_error, String.t(), DoubleEntryLedger.Command.t() | nil}
Gets the transaction associated with a create-transaction command.
This function finds the original create transaction command corresponding to an update command and returns its associated transaction. Used primarily when processing update events to locate the original transaction to modify.
Parameters
update_command- A Command struct containing source, source_idempk, and instance_id
Returns
{:ok, {Transaction.t(), Command.t()}}- The transaction and create command if found and processed- Raises
UpdateCommandErrorif the create command doesn't exist or isn't processed
@spec transaction_events_for_account_query(Ecto.UUID.t()) :: Ecto.Query.t()