Logistiki.Event behaviour (logistiki v0.1.0)

Copy Markdown View Source

Behaviour implemented by business events.

Applications publish business events. Logistiki decides whether and how those events become accounting entries. An event must be able to report its type and normalize itself into a Logistiki.Event.Normalized struct.

Defining events

Use the defevent macro to declare a business event struct with the common normalized fields and an automatic Logistiki.Event implementation:

defmodule Logistiki.Event.DepositReceived do
  use Logistiki.Event, type: "deposit_received"

  defevent do
    field :cash_account_code, :string
  end
end

Common fields provided by defevent

Every event struct built with defevent includes: id, source_system, source_id, actor_id, occurred_at, effective_date, amount, currency, entity_id, account_id, account_code, counterparty_id, product_code, jurisdiction, entity_type, metadata. Additional event-specific fields are declared inside the defevent do ... end block.

Dispatchers

Logistiki.Event.event_type/1 and Logistiki.Event.normalize/1 dispatch to the event struct's implementation so callers don't need to know the module.

Summary

Callbacks

Returns the string event type used by the knowledge layer.

Normalizes the event into a Logistiki.Event.Normalized struct.

Functions

Injects the Logistiki.Event behaviour and the event_type/1 implementation into the calling module. Used with use Logistiki.Event, type: "...".

Declares the event struct fields (beyond the common normalized fields) and generates a normalize/1 implementation that flattens the event into a Logistiki.Event.Normalized struct.

Dispatches to the event struct's event_type/1 implementation.

Dispatches to the event struct's normalize/1 implementation.

Callbacks

event_type(struct)

@callback event_type(struct :: term()) :: String.t()

Returns the string event type used by the knowledge layer.

Callback arguments

  • struct — the event struct (e.g. %Logistiki.Event.DepositReceived{}).

Returns

  • String.t() — e.g. "deposit_received".

normalize(struct)

@callback normalize(struct :: term()) ::
  {:ok, Logistiki.Event.Normalized.t()} | {:error, term()}

Normalizes the event into a Logistiki.Event.Normalized struct.

Callback arguments

  • struct — the event struct.

Returns

  • {:ok, %Logistiki.Event.Normalized{}} — the flattened event.
  • {:error, term()} — normalization failed.

Functions

__using__(opts)

(macro)

Injects the Logistiki.Event behaviour and the event_type/1 implementation into the calling module. Used with use Logistiki.Event, type: "...".

Options

  • :typeString.t — the event type string used by the knowledge layer (e.g. "deposit_received", "fee_assessed").

Example

use Logistiki.Event, type: "deposit_received"

defevent(list)

(since 0.1.0) (macro)

Declares the event struct fields (beyond the common normalized fields) and generates a normalize/1 implementation that flattens the event into a Logistiki.Event.Normalized struct.

Arguments

  • block — a do block containing Ecto.Schema.field/3 declarations for event-specific fields (e.g. field :cash_account_code, :string).

Generated code

The macro builds an embedded_schema with the common fields plus any declared fields, and a normalize/1 function that constructs a %Logistiki.Event.Normalized{} from the event struct, merging in any extra event-specific fields (like cash_account_code).

Example

defevent do
  field :cash_account_code, :string
  field :fee_income_account_code, :string
end

event_type(event)

(since 0.1.0)
@spec event_type(struct()) :: String.t()

Dispatches to the event struct's event_type/1 implementation.

Arguments

Returns

  • String.t() — the event type (e.g. "deposit_received").

Examples

iex> Logistiki.Event.event_type(%Logistiki.Event.DepositReceived{})
"deposit_received"

normalize(event)

(since 0.1.0)
@spec normalize(struct()) :: {:ok, Logistiki.Event.Normalized.t()} | {:error, term()}

Dispatches to the event struct's normalize/1 implementation.

Arguments

Returns

  • {:ok, %Logistiki.Event.Normalized{}} — the flattened event.
  • {:error, term()} — normalization failed.

Examples

iex> {:ok, normalized} = Logistiki.Event.normalize(%Logistiki.Event.DepositReceived{id: "evt_1"})
iex> normalized.type
"deposit_received"