AshCommanded.Commanded.Transformers.GenerateAggregateModule (AshCommanded v0.1.0)

View Source

Generates an aggregate module based on the commands and events defined in the DSL.

For each resource, this transformer will generate an aggregate module that:

  1. Defines a struct representing the aggregate state
  2. Implements the execute/2 function for handling commands
  3. Implements the apply/2 function for applying events to the state

This transformer should run after the command and event module transformers.

Example

Given a resource with commands and events, this transformer will generate:

defmodule MyApp.UserAggregate do
  @moduledoc "Aggregate for User resource"
  
  # Define the aggregate state struct
  defstruct [:id, :email, :name, :status]
  
  # Command handlers
  def execute(%__MODULE__{} = aggregate, %MyApp.Commands.RegisterUser{} = command) do
    # Validate command - in this case, prevent duplicate registration
    if aggregate.id != nil do
      {:error, :user_already_registered}
    else
      # Return event(s) to be applied
      {:ok, %MyApp.Events.UserRegistered{
        id: command.id,
        email: command.email,
        name: command.name
      }}
    end
  end
  
  def execute(%__MODULE__{} = aggregate, %MyApp.Commands.UpdateEmail{} = command) do
    # Validate command - only allow updating existing user
    if aggregate.id == nil do
      {:error, :user_not_found}
    else
      # Return event(s) to be applied
      {:ok, %MyApp.Events.EmailChanged{
        id: command.id,
        email: command.email
      }}
    end
  end
  
  # Event handlers to update state
  def apply(%__MODULE__{} = state, %MyApp.Events.UserRegistered{} = event) do
    %__MODULE__{
      state |
      id: event.id,
      email: event.email,
      name: event.name,
      status: :active
    }
  end
  
  def apply(%__MODULE__{} = state, %MyApp.Events.EmailChanged{} = event) do
    %__MODULE__{
      state |
      email: event.email
    }
  end
end

Summary

Functions

Specifies that this transformer should run after the command and event module transformers.

Callback implementation for Spark.Dsl.Transformer.before?/1.

Builds the module name for an aggregate.

Transforms the DSL state to generate an aggregate module.

Functions

after?(arg1)

Specifies that this transformer should run after the command and event module transformers.

after_compile?()

Callback implementation for Spark.Dsl.Transformer.after_compile?/0.

before?(_)

Callback implementation for Spark.Dsl.Transformer.before?/1.

build_aggregate_module(resource_name, app_prefix)

Builds the module name for an aggregate.

Examples

iex> build_aggregate_module("User", MyApp)
MyApp.UserAggregate

build_aggregate_module_ast(resource_name, attribute_names, commands, events, command_modules, event_modules, dsl_state \\ nil)

Builds the AST (Abstract Syntax Tree) for an aggregate module.

Examples

iex> build_aggregate_module_ast("User", attribute_names, commands, events, command_modules, event_modules)
{:__block__, [], [{:@, [...], [{:moduledoc, [...], [...]}]}, ...]}

transform(dsl_state)

Transforms the DSL state to generate an aggregate module.

Examples

iex> transform(dsl_state)
{:ok, updated_dsl_state}