Skip to content

Architecture

Overview

Voodflow is structured as a standard FilamentPHP plugin. The core execution engine is decoupled from the UI and can be driven by queue workers, scheduled commands, or HTTP controllers.


Execution Pipeline

1. Trigger Resolution

Execution begins when one of the following events occurs:

TriggerMechanism
ScheduleLaravel scheduler runs voodflow:schedule-run every minute (schedule:run via cron or long-lived schedule:work / voodflow:work)
EventA Laravel Event::dispatch() is intercepted by Voodflow's listener
WebhookAn HTTP request hits the Voodflow webhook controller
ManualUser clicks "Run" in the Filament UI

2. Graph Traversal

Voodflow represents a workflow as a directed graph:

  • Nodes (voodflow_nodes) — processing units with a type and config JSON column
  • Edges (voodflow_edges) — directed connections with a source handle and a target handle

The engine performs a depth-first traversal starting from the trigger node. For branching nodes (If, Switch), only the branch whose condition is satisfied is traversed.

3. ExecutionContext

The ExecutionContext is the single source of truth during a workflow run. It carries:

php
// Key properties available to every node
$context->input        // Output from the previous node (array)
$context->config       // This node's configuration (array)
$context->sourceData   // Original trigger payload (array)
$context->execution    // The Execution model instance
$context->node         // The Node model instance
$context->vars         // Global workflow variables (mutable)

Nodes interact with the context exclusively through this object. They must not access the database or services directly except through the context API.

4. Node Execution

Each node implements NodeInterface:

php
interface NodeInterface
{
    public static function type(): string;
    public static function name(): string;
    public static function metadata(): array;
    public static function defaultConfig(): array;
    public static function definition(): array;
    public function execute(ExecutionContext $context): ExecutionResult;
}

The engine calls execute(), receives an ExecutionResult (success or failure with data), and passes the result's data as input to the next node(s).

5. Result Propagation

Node A::execute() → ExecutionResult::success(['users' => [...]])

                          ▼  (input for next node)
Node B::execute($context)  // $context->input = ['users' => [...]]

6. Persistence

After every node execution, Voodflow writes an ExecutionNode record to the database containing:

  • status (success / failed / skipped)
  • input (the data this node received)
  • output (the data this node produced)
  • started_at / finished_at
  • error_message (if any)

This gives full audit trail per node, per execution.


Hybrid Data Flow

Voodflow implements a hybrid sequential + broadcast data model:

PatternPropertyUse Case
Sequential$context->inputEach node receives the output of its immediate predecessor
Broadcast$context->sourceDataEvery node can access the original trigger payload
Global Variables$context->getVar()Set Variable node writes; any downstream node reads
Node Results$context->getNodeResult()Access the output of any named node in the graph

Queue Architecture

Voodflow supports two execution modes:

Synchronous (VOODFLOW_EXECUTE_SYNC=true)

The entire workflow executes inline, in the same PHP process as the trigger. Best for:

  • Local development
  • Simple, fast workflows
  • Environments without a queue worker

Warning: Long-running workflows will block the HTTP request or console command.

Asynchronous (VOODFLOW_EXECUTE_SYNC=false)

Each workflow execution is dispatched as a Laravel Job. The job is picked up by a queue worker and runs in a separate process.

HTTP Request / Event → Dispatch Job → Queue → Worker Process → Execute Workflow

Queue connection is configured via VOODFLOW_QUEUE (defaults to Laravel's default queue connection).


Credential Security

Credentials are stored in the voodflow_credentials table with encrypted:array cast. This means all credential values are encrypted at rest using Laravel's application encryption key (APP_KEY).

Access to credentials is mediated by the CredentialProxy service, which logs every access in voodflow_credential_access_logs.


Extension Points

Extension PointDescription
Custom Node classImplement NodeInterface or extend AbstractNode
Custom Model bindingRegister any Eloquent model via Model Integrations
Custom Message LayoutsHTML/WhatsApp templates with {{tag}} interpolation
Config overridesconfig/voodflow.php exposes all table names and class bindings

Release Notes

Proprietary software — source-available. All rights reserved.