Open source
Approvals for Laravel
composer require roundly-consulting/approvals-for-laravelOverview
Approvals, rejections and multi-approver sign-off between any two Eloquent models. Any model can act as an actor that decides and any model can be approvable; every decision carries an explicit status, an optional reason and an optional expiry. On top of single decisions you get requests that only their named approvers can decide, with unanimous, quorum, any-one or weighted rules, sequential staged pipelines, time-windowed delegation and named workflow presets — and every transition fires an event. It all runs through one Approvals facade, an injectable manager or plain actions. Native Laravel, MIT-licensed, with no third-party runtime dependencies beyond two small Roundly helper packages.
What you get
Real decision states
Pending, approved, rejected, cancelled and expired — with reasons, timestamps and a guarded state machine.
Multi-approver rules
Unanimous, quorum, any-one or weighted requests that only their named approvers can decide — and that resolve themselves.
Facade, DI or actions
One API three ways — the Approvals facade, an injected ApprovalsManager or plain actions — plus a recording Approvals::fake().
Staged pipelines
Engineering, then product, then finance — each stage opens only when the previous one clears.
Delegation
Hand your authority to a deputy for a time window; their decisions count as yours and record who acted.
Workflow presets
Define a payout or release sign-off once in config and open it by name anywhere in your app.
Events & Gate checks
Twelve events including one umbrella event, plus an optional Gate ability on every decision path.
Documentation
Installation
Install via Composer, publish and run the six publish-only migrations, and optionally publish the config.
Configuration
Every config key and its default — swappable models, morph key type, authorization gate, expiry and workflow presets.
Model traits
GivesApprovals for the actor, HasApprovals for the approvable and RequiresApproval for multi-approver subjects — plus interfaces.
The Approvals facade
The whole Approvals facade — decisions, multi-approver requests, reads, delegation and expiry — with every method and builder.
DI and actions
Skip the facade: inject ApprovalsManager or call the action classes directly — with the complete facade-method-to-action map.
Fluent builders
PendingApproval and PendingApprovalRequest in practice — pinning to a request, the approvals() helper, absolute expiry and incomplete builders.
Actions & DTOs
Every action class with its execute() signature, plus the DecisionData and ApprovalRequestData DTOs the actions take.
Decisions & statuses
Ask, approve, reject, cancel or toggle — the five statuses, one live decision per slot and what each call records.
Multi-approver requests
Open a request that only its named approvers can decide, under a unanimous, quorum, any-one or weighted rule — it resolves itself.
Weighted thresholds
Resolve on the summed weight of approvals instead of a head-count — per actor via ProvidesApprovalWeight or per decision.
Staged pipelines
Run sign-off as ordered stages — each opens only when the previous one clears, with stage events and a progress snapshot.
Delegation
Hand approval authority to another model for a time window — the delegate’s decisions count as yours and record who acted.
Workflow presets
Define a rule, quorum, stage and expiry setup once in config and open requests from it by name — flat or staged.
Authorization
Gate every decision path through a Laravel Gate ability your app defines — denied actors get UnauthorizedApprovalException.
Expiry
Give asks, approvals and requests a deadline — they stop counting once it passes, and expire() or approvals:expire records the lapse.
Blade directives
@approved, @rejected and @pendingApproval conditionals for your views — they work with any model, trait or not.
Events
Twelve events cover every transition — plus the umbrella ApprovalStatusChanged to observe all of them from one listener.
Enums
ApprovalStatus and ApprovalRule — domain helpers, labels, select options and validation rules that stay in sync with the cases.
Models & schema
The four Eloquent models, their tables, relations and scopes, the morph key type, and how to swap in your own subclasses.
Exceptions
One ApprovalsException base class and eight specific exceptions — what triggers each and how to catch them.
Testing
Approvals::fake() records every operation for assertions, plus Pest expectations, an approver test trait and factories for every model.
Requirements
PHP 8.4+, Laravel 12 or 13, and two small Roundly packages that Composer installs for you.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.