Skip to main content

Quickstart

This walks through defining a workflow in code, storing it, and running it. For the interactive terminal alternative, see Building workflows.

1. Define a workflow

A workflow is data. Build it with Workflow::fromArray() and hand it to the repository:

use Qanna\WorkflowEngine\Engine\Nodes\Logic\ConditionNode;
use Qanna\WorkflowEngine\Engine\Nodes\Action\LogNode;
use Qanna\WorkflowEngine\Engine\Nodes\Model\ModelUpdateNode;
use Qanna\WorkflowEngine\Engine\Triggers\ManualTrigger;
use Qanna\WorkflowEngine\Models\Workflow;
use Qanna\WorkflowEngine\Storage\Contracts\WorkflowRepositoryContract;

$workflow = Workflow::fromArray([
'id' => 'flag-large-orders',
'name' => 'Flag large orders for review',
'trigger' => ['type' => ManualTrigger::type(), 'config' => []],
'nodes' => [
[
'id' => 'check-total',
'type' => ConditionNode::type(),
'config' => ['field' => '{{ trigger.total }}', 'operator' => '>=', 'value' => '1000'],
],
[
'id' => 'flag',
'type' => ModelUpdateNode::type(),
'config' => [
'model' => \App\Models\Order::class,
'key' => 'id',
'value' => '{{ trigger.order_id }}',
'attributes' => ['status' => 'needs_review'],
],
],
[
'id' => 'log-small',
'type' => LogNode::type(),
'config' => ['level' => 'info', 'message' => 'Order {{ trigger.order_id }} auto-approved'],
],
],
'edges' => [
['from' => 'trigger', 'to' => 'check-total', 'branch' => 'main'],
['from' => 'check-total', 'to' => 'flag', 'branch' => 'true'],
['from' => 'check-total', 'to' => 'log-small', 'branch' => 'false'],
],
]);

app(WorkflowRepositoryContract::class)->create($workflow);

Key points:

  • The first edge always starts at from: 'trigger'.
  • ConditionNode exposes two branches, true and false. The engine only walks the branch that matched.
  • {{ trigger.total }} reads from the payload you pass at run time. {{ nodes.<id>.* }} reads a previous node's output. See Context & expressions.

2. Run it

use Qanna\WorkflowEngine\Facades\Workflow;

$execution = Workflow::run('flag-large-orders', [
'order_id' => 42,
'total' => 1499.00,
]);

$execution->status; // ExecutionStatus::Succeeded
$execution->output; // the final node's output
$execution->logs; // per-node timeline

Workflow::run() executes synchronously in the current process and returns a WorkflowExecution. To run it on a queue instead:

Workflow::dispatch('flag-large-orders', ['order_id' => 42, 'total' => 1499.00]);

3. Run it from the CLI

php artisan workflow:run flag-large-orders --payload='{"order_id": 42, "total": 1499}'

Without --payload, the command prompts you for the trigger's inputs interactively and prints the execution timeline. See the CLI reference.

Next steps

  • Concepts — how definitions, execution, context, and branching actually work.
  • Node reference — every built-in node, its config, and its output.
  • Testing — assert on workflow behaviour with Workflow::fake().
  • Extending — write your own nodes and triggers.