module Flow

A callback driven approach to wrap business logic within database transaction.

Callbacks provide an extensible mechanism for hooking into a Flow.

Accepts input representing the arguments and options which define the initial state.

When `#trigger` is called on a Flow, `#execute` is called on Operations sequentially in their given order.

Operations are an ordered list of the behaviors which are executed with (and possibly change) the Flow's state.

The Flow status is a summary of what has occurred during the runtime, used mainly for analysis and program flow.

Flows where no operation should be persisted unless all are successful should use a transaction.

Triggering a Flow executes all its operations in sequential order (see `Flow::Flux`) iff it has a valid state.

A Flow is a collection of procedurally executed Operations sharing a common State.

Callbacks provide an extensible mechanism for hooking into a Operation.

Operations take a state as input.

When an exception is raised during execution, but a handler can rescue, it causes a failure instead.

Operations define a `#behavior` that occurs when `#execute` is called.

When `#execute` is unsuccessful, expected problems are failures and unexpected problems are Exceptions.

The Operation status is used by the Flow calling it to determine what to do next; continue on or stop and rollback.

Operations which modify several persisted objects together should use a transaction.

An Operation is a service object which is executed with a State.

RSpec matcher for making assertions on the state of a Flow or Operation after it has been run.

class ExampleOperation

def behavior
  state.foo = "some data"
  state.bar = "some other data"
end

end

class ExampleFlow

operations [ ExampleOperation ]

end

RSpec.describe ExampleOperation, type: :operation do

subject { operation.execute }

it { is_expected.to have_on_state foo: "some data" }
it { is_expected.to have_on_state foo: instance_of(String) }
it { is_expected.to have_on_state foo: "some data", bar: "some other data" }

end

RSpec.describe ExampleFlow, type: :operation do

subject { flow.trigger }

it { is_expected.to have_on_state foo: "some data" }
it { is_expected.to have_on_state foo: instance_of(String) }
it { is_expected.to have_on_state foo: "some data", bar: "some other data" }

end

A State is an aggregation of input and derived data.

A StateProxy adapts a State to an Operation through an Operation's `state_*` accessors.

Constants

VERSION