Documentation
Complete guide to building flexible approval workflows in your Laravel application.
π°π Stand with Cambodia β’ ααααα»ααΆ
ποΈ Cambodia Needs Peace ποΈ
With heavy hearts, we stand with our brave soldiers defending Cambodia's land and dignity.
We seek no conflictβonly peace, justice, and respect for our sovereignty.
π ααααα»ααΆααααΌαααΆαααααα·ααΆα β’ Together to protect Cambodia's sovereignty.
What is Laravel Approval Workflow?
A flexible, domain-driven approval workflow engine designed for enterprise Laravel applications. Build multi-step approval processes with role-based assignments, SLA tracking, and comprehensive audit trails.
Features
- Multiple Workflow Versions: Define and evolve workflows over time without breaking existing instances
- Dynamic Assignment: Assign tasks to users, roles (Spatie Permission integration), or managers
- Flexible Modes: Support for 'any' (one person approves) or 'all' (consensus required) modes
- SLA Monitoring: Built-in support for task deadlines and breach recording
- Delegation: Automatic redirection of tasks based on user availability (vacation/out-of-office)
- Audit Trail: Detailed event logging (started, assigned, acted, breached, completed) for every action
- Conditional Transitions: Override default flow based on actions (approve/reject/changes_requested)
- Team / Department Scoping: Optionally scope workflows, tasks, and approvers by team_id
- UI & API Agnostic: No controllers, routes, views, or APIs are enforced. Each application decides how workflows are exposed
Installation
Requirements
- PHP 8.2 or higher (PHP 8.4+ recommended)
- Laravel 12.x
- Composer
- Spatie Laravel Permission (optional, for role-based assignment)
Step 1: Install via Composer
composer require putheakhem/approval-workflow
Step 2: Publish Configuration
php artisan vendor:publish --tag=approval-workflow-config
This publishes the configuration file to config/approval-workflow.php
Step 3: Publish Migrations
php artisan vendor:publish --tag=approval-workflow-migrations
Step 4: Run Migrations
php artisan migrate
Configuration
The configuration file is published to config/approval-workflow.php
return [
// Enable SLA checking command
'sla_command' => env('APPROVAL_WORKFLOW_SLA_COMMAND', false),
// Default SLA hours for approval steps
'default_sla_hours' => 24,
// Team scoping
'enable_team_scoping' => true,
];
Basic Usage
Make a Model Approvable
Use the HasWorkflow trait on any Eloquent model:
use PutheaKhem\ApprovalWorkflow\Concerns\HasWorkflow;
class Term extends Model
{
use HasWorkflow;
}
β οΈ What This Package Does Not Do
- Controllers or API routes
- UI or view components
- Notification delivery
These concerns are intentionally handled by the consuming application.
Workflow Definitions
Define workflows using PHP arrays or JSON format with versioning support:
[
'steps' => [
['key' => 'start', 'type' => 'start', 'next' => 'review'],
[
'key' => 'review',
'type' => 'approval',
'mode' => 'any',
'sla_hours' => 24,
'assignment' => [
'type' => 'role',
'roles' => ['reviewer'],
],
'next' => 'end',
],
['key' => 'end', 'type' => 'end'],
],
'transitions' => [
['from' => 'review', 'on' => 'reject', 'to' => 'end'],
],
]
Starting Workflows
Initialize a workflow instance for your subject model:
$instance = $service->startWorkflow(
workflowKey: 'service-approval',
context: [
'team_id' => 1,
'requester_id' => auth()->id(),
],
teamId: 1,
startedBy: auth()->id(),
);
Approving & Rejecting Tasks
Approve
use PutheaKhem\ApprovalWorkflow\Services\ApprovalService;
$approval = app(ApprovalService::class);
$approval->approve(
instance: $instance,
taskId: $taskId,
userId: auth()->id(),
notes: 'Approved with conditions'
);
Reject
$approval->reject(
instance: $instance,
taskId: $taskId,
userId: auth()->id(),
notes: 'Missing required documents'
);
Request Changes
$approval->requestChanges(
instance: $instance,
taskId: $taskId,
userId: auth()->id(),
notes: 'Please provide additional details'
);
API Reference
Complete list of available services and methods.
WorkflowEngine::start()
PublicStarts a new workflow instance for the given subject.
$subject
β’
Model
β’
Eloquent model to attach workflow
$workflowKey
β’
string
β’
Workflow definition key
$context
β’
array
β’
Workflow context data
$teamId
β’
?int
β’
Team ID for scoping
$startedBy
β’
?int
β’
User ID who started workflow
WorkflowInstance
ApprovalService::approve()
PublicApproves a workflow task.
$instance
β’
WorkflowInstance
β’
Workflow instance
$taskId
β’
int
β’
Task ID to approve
$userId
β’
int
β’
User ID performing approval
$notes
β’
?string
β’
Optional approval notes
void
ApprovalService::reject()
PublicRejects a workflow task.
$instance
β’
WorkflowInstance
β’
Workflow instance
$taskId
β’
int
β’
Task ID to reject
$userId
β’
int
β’
User ID performing rejection
$notes
β’
?string
β’
Optional rejection notes
void
ApprovalService::requestChanges()
PublicRequests changes on a workflow task.
$instance
β’
WorkflowInstance
β’
Workflow instance
$taskId
β’
int
β’
Task ID for change request
$userId
β’
int
β’
User ID requesting changes
$notes
β’
?string
β’
Required change description
void
DelegationService::delegate()
PublicDelegates approval authority to another user.
$fromUserId
β’
int
β’
Delegating user ID
$toUserId
β’
int
β’
Delegate user ID
$validFrom
β’
Carbon
β’
Delegation start date
$validUntil
β’
Carbon
β’
Delegation end date
Delegation
Events
The package emits the following domain events:
-
WorkflowStartedFired when a workflow instance is created
-
TaskAssignedFired when a task is assigned to users
-
TaskApprovedFired when a task is approved
-
TaskRejectedFired when a task is rejected
-
WorkflowCompletedFired when a workflow completes
-
SlaBreachedFired when SLA deadline is exceeded
Audit Trail
All workflow actions are recorded in the workflow_events table for transparency and compliance.
Event Types
-
workflow_started -
task_created -
task_assigned -
assignee_acted -
task_finished -
workflow_completed -
sla_breached
SLA Support
Enable SLA checking to monitor approval deadlines.
Enable SLA Command
APPROVAL_WORKFLOW_SLA_COMMAND=true
Run SLA Check
php artisan workflow:check-sla
Schedule in Kernel
// In routes/console.php or app/Console/Kernel.php
Schedule::command('workflow:check-sla')->hourly();