Mobus.Stepwise.Capabilities (mobus_stepwise v0.2.0)

Copy Markdown View Source

Configurable capability runner adapter for the stepwise engine.

When adapter is nil (default), capability execution returns {:ok, %{context: %{}}} (no-op). This allows the package to work for form-only wizards (e.g. Atrapos tenant creation) without requiring a capability runner.

Configure via :mobus_stepwise application config:

config :mobus_stepwise, :capability_runner_adapter, MyApp.CapabilityRunner

:strict mode

Some consumers (e.g. workflow_stem with its own adapter plumbing) prefer strict semantics where a nil adapter signals a misconfiguration rather than silently succeeding. Enable via:

config :mobus_stepwise, :capability_runner_strict, true

When strict is true, calling execute/3 with no adapter configured returns {:error, :capability_runner_disabled} instead of the default no-op success. Default: false (backwards compatible).

Summary

Functions

Returns the configured capability runner adapter module, or nil if none is set.

Returns true if a capability runner adapter is configured and exports execute/3.

Executes a capability via the configured adapter, or returns a no-op result.

Returns true when :capability_runner_strict mode is active.

Functions

adapter()

@spec adapter() :: module() | nil

Returns the configured capability runner adapter module, or nil if none is set.

Reads from application config key :mobus_stepwise, :capability_runner_adapter.

Examples

Capabilities.adapter()
#=> MyApp.CapabilityRunner

# When unconfigured:
Capabilities.adapter()
#=> nil

enabled?()

@spec enabled?() :: boolean()

Returns true if a capability runner adapter is configured and exports execute/3.

Checks that the adapter is a non-nil atom module with an execute/3 function exported.

Examples

Capabilities.enabled?()
#=> true

execute(tenant_id, capability_handle, input)

@spec execute(String.t(), String.t() | atom(), map()) ::
  {:ok, term()} | {:error, term()}

Executes a capability via the configured adapter, or returns a no-op result.

When no adapter is configured, returns {:ok, %{context: %{}}} (no-op). Otherwise delegates to adapter.execute(tenant_id, capability_handle, input).

Parameters

  • tenant_id — tenant identifier string
  • capability_handle — capability name (string or atom), e.g. "myapp.validate"
  • input — execution input map with event context, payload, and state

Returns

  • {:ok, result} — successful execution with context updates and/or artifacts
  • {:error, reason} — capability execution failed

Examples

Capabilities.execute("tenant-1", "myapp.validate", %{payload: %{email: "a@b.com"}})
#=> {:ok, %{context: %{valid: true}}}

strict?()

@spec strict?() :: boolean()

Returns true when :capability_runner_strict mode is active.

When true, execute/3 returns {:error, :capability_runner_disabled} if no adapter is configured instead of silently succeeding. Consumers that always configure an adapter (e.g. workflow_stem) should set this to true so accidental nil-adapter calls are caught as errors.

Examples

Capabilities.strict?()
#=> false

# After config:
#   config :mobus_stepwise, :capability_runner_strict, true
Capabilities.strict?()
#=> true