This week’s DEV Community digest highlighted something interesting:
Laravel developers are moving beyond “fat controllers” toward clean architecture and enterprise-grade systems.
That’s exactly what I’ve been working on.
⚠️ The Problem (We All Faced)
If you've built any of these:
- Leave approval
- Expense approval
- Purchase workflows
You already know the reality:
- Business logic inside controllers
- Role checks everywhere
- Email spam for approvals
- Hard to scale, harder to maintain
And every project?
You rebuild the same workflow logic again.
💸 Why Most Teams Get It Wrong
Typical solutions:
- SaaS tools
- Zapier automation
- Email-based approvals
Which leads to:
- Recurring cost
- Limited customization
- Poor visibility
- No real control
🧠 What I Built Instead
I didn’t build another feature.
I built a reusable approval workflow engine:
- Multi-level approval pipelines
- Role-based access (IAM-ready)
- Event-driven lifecycle
- Token-based approvals (no login required)
- Smart notification batching
🧩 The Architecture (This Is the Key)
Adapters (API / CLI / Queue)
↓
Workflow Manager
↓
Workflow Engine (Pure Logic)
↓
Domain Models (State)
↓
Events → Listeners → Notifications
Key Idea:
The engine knows nothing about HTTP, UI, or SaaS.
🔥 What Makes It Different
1. Headless Workflow Engine
$manager->start('requisition', $payload);
$manager->approve($workflowId, $userId);
No controller dependency. Works anywhere.
2. IAM-Ready (But Decoupled)
- Engine does NOT handle auth
- It only receives
user_id - IAM handles permissions externally
👉 Clean separation = scalable system
3. Token-Based Approval (Game Changer)
POST /api/v1/approvals/token/approve
- Secure
- Expiring
- Single-use
👉 Approve directly from email / Slack
👉 No login required
4. Smart Notification Batching
Instead of:
10 approvals → 10 emails ❌
You get:
10 approvals → 1 email ✅
5. Idempotent Workflow Execution
hash('sha256', payload)
Prevents duplicate workflows on retries.
6. Extensible Plugin System (One of My Favorite Parts)
One thing I really wanted was flexibility.
So I added a plugin system:
- Hook into workflow events
- Add integrations (Slack, email, APIs)
- Extend behavior without touching core
Example:
class SlackPlugin extends BasePlugin
{
public function boot(): void
{
$this->listen(WorkflowCompleted::class, function ($event) {
// send slack notification
});
}
}
🧪 Built Like a Real System
- Full lifecycle testing
- Authorization validation
- Event-driven consistency
- Duplicate protection
💼 Real-World Direction
This system is designed for:
- SaaS platforms
- Banking workflows
- Enterprise approval pipelines
- Internal automation systems
🔗 Open Source
👉 https://github.com/apurba-labs/laravel-approval-engine
🤝 Let’s Talk
If you're building:
- Workflow systems
- Approval pipelines
- RBAC / IAM architectures
📩 LinkedIn: https://www.linkedin.com/in/apurba-narayan-singh/
📧 apurbansinghdev@gmail.com
💬 I’d Love Your Feedback
- How are you handling approvals today?
- Are you using SaaS tools or building in-house?
- What’s the biggest pain in your workflow systems?
Let’s discuss 👇
Top comments (0)