cjmellor/approval
Laravel package to stage and review model changes before they’re persisted. It stores pending/new or amended data (approve/reject states) so you can build your own approval workflow. Includes migrations and configurable states/tables.
ModelApproved, ModelRejected, ApprovalExpired) align well with Laravel’s ecosystem, enabling seamless integration with queues, notifications, or custom business logic.ApprovalStatus enum for type safety and extensibility, supporting both default (pending, approved, rejected) and custom states. This reduces boilerplate for state transitions.composer require cjmellor/approval).approvals table with polymorphic fields (approvalable_type, approvalable_id), requiring minimal migration effort. Schema changes in v2.x are documented in UPGRADE.md.MustBeApproved trait to models, with optional configuration (e.g., approvalAttributes to whitelist fields). No need for base class inheritance.approved(), rejected(), pending()) and custom state queries, reducing custom Eloquent logic.new_data/original_data as JSON may impact database size and query performance. Mitigation: Use approvalAttributes to limit tracked fields.approvals table could slow down queries if not optimized (e.g., indexing approvalable_type + approvalable_id).setState()), but complex state machines may need additional layers.approval:process-expired). Misconfiguration could lead to missed expirations or duplicate processing.rollback(bypass: false)). This could lead to unintended data persistence if not handled carefully.spatie/laravel-activitylog + custom states) may be needed.new_data/original_data JSON fields a concern for GDPR/compliance? If so, consider encrypting sensitive fields or using Laravel’s encrypt cast.lockForUpdate() or similar.approvals table be handled?ModelApproved → send email).Notifiable events for state changes.GET /posts/{id} → { "status": "pending" }).ApprovalStateScope to build dashboards (e.g., "Pending Posts" list).spatie/laravel-activitylog to audit approval changes.ModelApproved events to trigger external webhooks (e.g., Slack alerts).Post) to test the trait, scopes, and events.new_data/original_data for your use case.php artisan vendor:publish --tag="approval-migrations").approvals table for performance:
CREATE INDEX approvals_approvalable_idx ON approvals(approvalable_type, approvalable_id);
CREATE INDEX approvals_state_idx ON approvals(state);
php artisan vendor:publish --tag="approval-config") and customize:
author_id instead of user_id).in_review, needs_info).approve()/reject()).expiresIn(hours: 24)->thenReject()).ModelApproved → notify user).// app/Listeners/ApprovePostListener.php
public function handle(ModelApproved $event) {
if ($event->approval->approvalable_type === Post::class) {
Post::find($event->approval->approvalable_id)
->user
->notify(new PostApprovedNotification());
}
}
laravel/breeze, spatie/laravel-permission).MustBeApproved trait to models.approvalAttributes if needed.approval:process-expired command (e.g., every 5 minutes).ApprovalExpired events to track missed expirations.approvals table growth (archive old records if needed).composer why-not cjmellor/approval to check for outdated versions.approvals table to audit state transitions. Example query:
SELECT * FROM approvals
WHERE approvalable_type = 'App\Models\Post'
ORDER BY created_at DESC
LIMIT 10;
ModelApproved/ModelRejected entries.user_id) during creation.new_data/original_data serialization (e.g., avoid circular references in model attributes).approval:process-expired command runs (check Laravel scheduler logs).approved(), pending()) are efficient with proper indexing.How can I help you explore Laravel packages today?