Skip to content

EventFlowDocumentation That Runs

Your .flow file is the executable specification. One source generates runtime behavior, tests, and diagrams. No drift. No sync. Just truth.

EventFlow

Quick Example โ€‹

flow
machine: @order

scenario: checkout

  given:
    @customer is logged in
    cart has items

  on :checkout from @customer (api)
    ? cart is valid
      $order_id becomes uuid()
      order moves to #awaiting_payment

      emit :payment_request to @payment with:
        | field    | value     | validation                       |
        | order_id | $order_id | required, string, valid uuid     |
        | amount   | $total    | required, number, greater than 0 |

      reply 201 with:
        | id     | $order_id     |
        | status | current_state |

    otherwise
      reply 400 bad request with:
        | error | "CART_INVALID" |

  on :validation_failed
    reply 400 with:
      | errors | $errors |

  on :payment_success from @payment
    order moves to #confirmed
    emit async :send_confirmation to @notification

  expect:
    = order is in #confirmed
    = reply status is 201
flow
test: @order

  for scenario: checkout

    for :checkout:
      empty cart rejected:
        with scenario:
          cart is empty
        = order is not in #awaiting_payment

      invalid amount rejected:
        when:
          @customer sends :checkout with:
            | amount | -10 | required, number, greater than 0 |
        = :validation_failed was emitted

    payment fails then succeeds:
      after :checkout
      receive :payment_failed from @payment
      then :payment_success from @payment
      = order is in #confirmed
php
#[Guard('cart is valid')]
class CartIsValidGuard extends GuardBehavior
{
    public function __invoke(array $context): bool
    {
        return count($context['cart']['items'] ?? []) > 0;
    }
}
php
#[Action('send confirmation')]
class SendConfirmationAction extends ActionBehavior
{
    public function __invoke(array $context): void
    {
        Mail::to($context['customer']['email'])
            ->send(new OrderConfirmation($context['order_id']));
    }
}
php
#[ValidationRule('valid uuid')]
class ValidUuidRule implements Rule
{
    public function validate(mixed $value, Context $ctx): bool
    {
        return Uuid::isValid($value);
    }
}

Released under the MIT License.