AshWorkflow.Entities.Step (AshWorkflow v0.7.1)

Copy Markdown View Source

Defines a workflow step entity with its configuration schema.

Summary

Functions

Finds the initial step from a list of steps.

Returns true if the step is a manual step — i.e., it has declared transitions and is not a terminal state.

Returns true if the step's on_success needs runtime evaluation to pick its target — i.e. it is more than a single unconditional route.

Returns true if on_success is statically guaranteed to match: it ends with an unconditional entry (no when), which validate_on_success_ordering already requires to be both trailing and unique.

Returns every step this step's on_success could reach, in declaration order. Returns [] if no on_success is declared.

Returns true if the step is an end state: nothing runs on entry and nothing leaves it.

Returns true if the step is a wait state — no action runs on entry and no caller-facing transition leaves it, so a timeout is its only exit.

Types

t()

@type t() :: %AshWorkflow.Entities.Step{
  __spark_metadata__: term(),
  action: atom() | nil,
  everys: [AshWorkflow.Entities.Every.t()],
  initial: boolean(),
  name: atom(),
  on_error: atom() | nil,
  on_success: [AshWorkflow.Entities.Route.t()],
  policy: term() | nil,
  retry: AshWorkflow.Entities.Retry.t() | nil,
  terminal: boolean(),
  timeouts: [AshWorkflow.Entities.Timeout.t()],
  transitions: [AshWorkflow.Entities.Transition.t()]
}

Functions

attribute_schema()

find_initial(steps)

Finds the initial step from a list of steps.

Returns the step with initial: true, or falls back to the first non-terminal step by declaration order.

manual?(step)

Returns true if the step is a manual step — i.e., it has declared transitions and is not a terminal state.

Manual-ness is derived from the step's fields: a step with transitions is manual; a step with an action is automatic; a step with nothing at all is an end state.

A step with neither transitions nor an action, whose only exit is a timeout, is a wait state — it is manual in the sense that nothing runs on entry, even though no caller can move it along either. A step whose only declarations are every entries is also manual in this sense: every never leaves the step, so such a step still needs a timeout with transition_to (or transitions) to have any way out at all.

on_success_conditional?(step)

Returns true if the step's on_success needs runtime evaluation to pick its target — i.e. it is more than a single unconditional route.

A single on_success entry with no when is unconditional and resolves to a plain transition_state. Anything else (any when present, or more than one entry) requires evaluating conditions against the record after the step's action runs.

on_success_exhaustive?(step)

Returns true if on_success is statically guaranteed to match: it ends with an unconditional entry (no when), which validate_on_success_ordering already requires to be both trailing and unique.

A step whose on_success is not exhaustive can, at runtime, run its action and have every route's when fail to match. AshWorkflow.Verifiers.ValidateWorkflow uses this to require on_error on such a step, since that is otherwise a failure the step has no declared way to handle.

on_success_targets(step)

Returns every step this step's on_success could reach, in declaration order. Returns [] if no on_success is declared.

terminal?(step)

Returns true if the step is an end state: nothing runs on entry and nothing leaves it.

Derived from the fields of the step. A step with no action, no transitions, no timeouts, no every, no on_success and no on_error has no way out, so it is terminal whether or not it says so. terminal: true is an assertion on top of that: AshWorkflow.Verifiers.ValidateWorkflow rejects a step that declares it and then declares something outgoing.

A step that is terminal by mistake — a name typo'd in one place and not the other — is caught by the reachability check rather than here, since an end state nothing transitions to is unreachable.

wait_state?(step)

Returns true if the step is a wait state — no action runs on entry and no caller-facing transition leaves it, so a timeout is its only exit.