Class: Yes::Core::CommandHandling::CommandHandler

Inherits:
Object
  • Object
show all
Includes:
OpenTelemetry::Trackable
Defined in:
lib/yes/core/command_handling/command_handler.rb

Overview

Handles the complete command execution flow for aggregates This class orchestrates command preparation, execution, and read model updates

Examples:

handler = CommandHandler.new(aggregate)
response = handler.call(:approve_documents, { document_ids: '123', another: 'value' })

Instance Method Summary collapse

Constructor Details

#initialize(aggregate) ⇒ CommandHandler

Initializes a new CommandHandler

Parameters:



19
20
21
22
23
# File 'lib/yes/core/command_handling/command_handler.rb', line 19

def initialize(aggregate)
  @aggregate = aggregate
  @command_utilities = aggregate.send(:command_utilities)
  @read_model = aggregate.read_model if aggregate.class.read_model_enabled?
end

Instance Method Details

#call(command_name, payload, guards: true, metadata: nil) ⇒ Yes::Core::Commands::Response

Executes a command and updates the aggregate state

Parameters:

  • command_name (Symbol)

    The name of the command to execute

  • payload (Hash)

    The command payload

  • guards (Boolean) (defaults to: true)

    Whether to evaluate guards (default: true)

  • metadata (Hash) (defaults to: nil)

    Optional custom metadata to add to the event

Returns:



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/yes/core/command_handling/command_handler.rb', line 32

def call(command_name, payload, guards: true, metadata: nil)
  prepared_payload = prepare_payload(command_name, payload, )
  cmd = command_utilities.build_command(command_name, prepared_payload)

  guard_evaluator_class = command_utilities.fetch_guard_evaluator_class(command_name)

  ReadModelRecoveryService.check_and_recover_with_retries(read_model, aggregate:) if aggregate.class.read_model_enabled?

  response = CommandExecutor.new(aggregate).
             call(cmd, command_name, guard_evaluator_class, skip_guards: !guards)

  ReadModelUpdater.new(aggregate).call(response.event, prepared_payload, command_name) if aggregate.class.read_model_enabled? && response.success?

  response
end