- How do I install and set up cjmellor/approval in a Laravel 12 project?
- Run `composer require cjmellor/approval`, publish the migrations with `php artisan vendor:publish --tag="approval-migrations"`, then execute `php artisan migrate`. For config, use `php artisan vendor:publish --tag="approval-config"`. The package supports Laravel 11–13 out of the box.
- Which Laravel models can use this approval system?
- Any Eloquent model can use the approval system via the `MustBeApproved` trait. The package uses polymorphic relationships, so it works with all models without requiring inheritance. Just add the trait and configure `approvalAttributes` if needed.
- Can I customize the approval states beyond 'pending', 'approved', and 'rejected'?
- Yes, the package supports custom states via the `states` config array. You can define additional states like 'needs_revision' or 'under_review' and extend the `ApprovalStatus` enum. Events are triggered for all state transitions.
- How does the package handle data rollback if a rejected model is edited again?
- By default, rejected models can be edited and re-submitted without re-approval. To enforce re-approval, set `rollback(bypass: false)` in your logic. The package stores original and new data as JSON for comparison.
- Will this package slow down my application if I have many pending approvals?
- The package adds minimal overhead for queries, but large-scale use may impact performance due to polymorphic joins. Optimize by indexing `approvalable_type` and `approvalable_id`, and limit tracked fields with `approvalAttributes`. Test under load.
- How do I trigger notifications when a model is approved or rejected?
- Use Laravel’s event system. The package dispatches `ModelApproved`, `ModelRejected`, and `ApprovalExpired` events. Listen to these events in your `EventServiceProvider` and dispatch notifications (e.g., `Notification::route()`) or queue jobs.
- Does this package support time-based expiration for pending approvals?
- Yes, you can set expiration times via `approve()->expiresAt($timestamp)`. Use the `approval:process-expired` Artisan command or schedule it as a job to handle expired approvals automatically.
- Can I integrate this with existing moderation tools or APIs?
- Absolutely. The package provides query scopes (`approved()`, `pending()`, etc.) and events for custom logic. You can build admin dashboards, webhooks, or API endpoints to sync with external tools. The data is stored in a single `approvals` table.
- What happens if I upgrade from v1.x to v2.x? Are there breaking changes?
- Version 2.x includes database schema changes. Follow the [UPGRADE.md guide](https://github.com/cjmellor/approval/blob/main/UPGRADE.md) to migrate safely. Key changes include new fields for expiration and improved polymorphic handling. Always back up your database before upgrading.
- How do I test approval workflows in my Laravel application?
- Use Laravel’s testing tools to simulate state transitions. Mock events (e.g., `ModelApproved`) and test query scopes. For end-to-end testing, verify database states and event listeners. The package includes unit tests, but you’ll need to write integration tests for custom logic.