Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Flow Laravel Package

moffhub/flow

Database-driven state machine & workflow engine for Laravel. Build multi-step approval gates with role/permission guards, auditable transitions, actions, parallel states, scheduled transitions, and a visual builder + workflow visualization for complex business processes.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require moffhub/flow
    php artisan vendor:publish --provider="Moffhub\Flow\FlowServiceProvider" --tag="config"
    php artisan migrate
    
    • Publish the config and run migrations to set up the workflow tables.
  2. Define a Workflow: Create a workflow definition in a migration or seed:

    use Moffhub\Flow\Workflow;
    
    Workflow::create('tax_submission', [
        'states' => ['draft', 'submitted', 'under_review', 'approved', 'rejected'],
        'transitions' => [
            ['from' => 'draft', 'to' => 'submitted', 'action' => 'submit'],
            ['from' => 'submitted', 'to' => 'under_review', 'action' => 'review'],
            // ... other transitions
        ],
    ]);
    
  3. Attach to a Model: Use the HasFlow trait in your Eloquent model:

    use Moffhub\Flow\Concerns\HasFlow;
    
    class TaxSubmission extends Model
    {
        use HasFlow;
    
        protected $flowName = 'tax_submission';
    }
    
  4. First Transition: Trigger a transition via the model instance:

    $submission = TaxSubmission::find(1);
    $submission->flow()->transition('submit');
    

Where to Look First

  • Config: config/flow.php for default settings (e.g., audit trail retention, guard defaults).
  • Migrations: database/migrations/xxxx_create_flow_tables.php to understand the schema.
  • Facade: Flow:: for global workflow operations (e.g., Flow::getWorkflow('tax_submission')).
  • Model Integration: HasFlow trait and its methods (transition(), canTransition(), etc.).

First Use Case

Government Revenue Submission Workflow:

  1. Define a tax_submission workflow with states like draft, submitted, approved.
  2. Attach it to a TaxSubmission model.
  3. Use transition('submit') to move from draft to submitted.
  4. Add a role-based guard to restrict approve transitions to tax_officers.

Implementation Patterns

Core Workflows

  1. Linear Approval Chains:

    // Define in migration:
    Workflow::create('loan_application', [
        'states' => ['applied', 'reviewed', 'approved', 'rejected'],
        'transitions' => [
            ['from' => 'applied', 'to' => 'reviewed', 'action' => 'initiate_review'],
            ['from' => 'reviewed', 'to' => 'approved', 'action' => 'approve'],
            ['from' => 'reviewed', 'to' => 'rejected', 'action' => 'reject'],
        ],
    ]);
    
    • Use transition('initiate_review') to kick off the process.
  2. Parallel States (Split/Join):

    Workflow::create('inspection', [
        'states' => ['pending', 'legal_review', 'technical_review', 'approved'],
        'transitions' => [
            ['from' => 'pending', 'to' => ['legal_review', 'technical_review'], 'action' => 'split'],
            ['from' => ['legal_review', 'technical_review'], 'to' => 'approved', 'action' => 'join'],
        ],
    ]);
    
    • Trigger split to parallelize, then join to converge.
  3. Scheduled Transitions:

    $submission->flow()->transition('escalate', ['scheduled_at' => now()->addHours(24)]);
    
    • Useful for time-bound approvals (e.g., "escalate after 24 hours").

Integration Tips

  • Laravel Events: Bind to flow.transitioning and flow.transitioned events for side effects:
    event(new TaxSubmissionSubmitted($submission));
    
  • Notifications: Use transition() with notify option:
    $submission->flow()->transition('approve', [
        'notify' => ['taxpayer', 'auditor'],
    ]);
    
  • API Endpoints: Restrict transitions via middleware:
    Route::post('/submissions/{id}/approve', function ($id) {
        $submission = TaxSubmission::findOrFail($id);
        if ($submission->flow()->canTransition('approve')) {
            $submission->flow()->transition('approve');
            return response()->json(['status' => 'approved']);
        }
        abort(403);
    })->middleware('can:approve-submissions');
    

Guard Patterns

  1. Role-Based Guards:

    Workflow::transition('approve')
        ->guard('role:tax_officer');
    
    • Automatically checks auth()->user()->hasRole('tax_officer').
  2. Conditional Guards:

    Workflow::transition('approve')
        ->guard(function ($model, $transition) {
            return $model->amount <= 1000;
        });
    
    • Custom logic (e.g., "approve only if amount ≤ $1000").
  3. Permission Guards:

    Workflow::transition('reject')
        ->guard('permission:reject-tax-submissions');
    

Action Patterns

  1. Built-in Actions:

    • notify: Send notifications via Laravel Notifications.
    • log: Append to the audit trail.
    • update_attributes: Modify model attributes on transition.
  2. Custom Actions:

    class SendEmailAction implements ActionContract
    {
        public function handle($model, $transition, $data)
        {
            Mail::to($model->taxpayer_email)->send(new ApprovalEmail());
        }
    }
    

    Register in config:

    'actions' => [
        'send_email' => \App\Actions\SendEmailAction::class,
    ],
    

    Use in workflow:

    Workflow::transition('approve')
        ->action('send_email');
    

Gotchas and Tips

Pitfalls

  1. Circular References:

    • Avoid defining transitions that create loops (e.g., A → B → A). The package validates this but may throw cryptic errors if misconfigured.
    • Fix: Use Flow::validateWorkflow('workflow_name') in a migration.
  2. Guard Short-Circuiting:

    • Guards are evaluated in order (config → role → permission → condition). If a guard fails, later guards aren’t checked.
    • Tip: Use ->guard(...)->guard(...) to chain multiple guards explicitly.
  3. Audit Trail Bloat:

    • Every transition creates a record in flow_audit_trails. For high-volume systems, set audit_retention_days in config to auto-prune old entries.
  4. Parallel State Deadlocks:

    • If using split/join, ensure all parallel branches can eventually transition to the join state. Orphaned branches will block the workflow.
    • Tip: Add a timeout transition to force-complete stuck branches.
  5. Model Attribute Conflicts:

    • If your model has flow_name or flow_state attributes, they’ll conflict with the package’s reserved names. Rename them or exclude from mass assignment:
    protected $guarded = ['flow_name', 'flow_state'];
    

Debugging

  1. Transition Validation Errors:

    • Check flow_transitions table for valid from/to pairs. Use:
    dd(Flow::getWorkflow('tax_submission')->getValidTransitions());
    
  2. Guard Failures:

    • Enable debug mode in config:
    'debug' => [
        'guard_errors' => true,
    ],
    
    • This logs failed guard conditions to storage/logs/flow.log.
  3. Visualization Issues:

    • If the visual builder API (Flow::visualize('workflow_name')) returns malformed JSON, clear compiled views:
    php artisan view:clear
    

Extension Points

  1. Custom Guard Classes:

    class MinimumBalanceGuard implements GuardContract
    {
        public function check($model, $transition)
        {
            return $model->balance >= 1000;
        }
    }
    

    Register in config:

    'guards' => [
        'minimum_balance' => \App\Guards\MinimumBalanceGuard::class,
    ],
    

    Use in workflow:

    Workflow::transition('withdraw')
        ->guard('minimum_balance');
    
  2. Action Data Serialization:

    • Pass complex data to actions via the data option:
    $submission->flow()->transition('approve', [
        'data' => ['reason' => '
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky