Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Action Approvals Laravel Package

coringawc/filament-action-approvals

Filament Action Approvals adds configurable approval workflows to Filament actions, letting users submit, approve, or reject requests with multi-step chains, role-based permissions, and audit history. Integrates directly into your existing Filament resources and actions.

View on GitHub
Deep Wiki
Context7

Getting Started

The package adds a maker–checker (approval) workflow to Filament actions: instead of executing immediately, an action creates a pending approval record, and an authorised approver later approves or rejects it.

  1. Install and publish assets:
    composer require coringawc/filament-action-approvals
    php artisan vendor:publish --tag="filament-action-approvals-migrations"
    php artisan migrate
    
    Publish the config tag too if you need to change table names, approver resolution, or notification behaviour.
  2. Look first at, in this order:
    • config/filament-action-approvals.php — the model/table names, approver resolution, and notification classes.
    • The published migration — the approvals table shape tells you exactly what's persisted (action identity, subject, payload, requester, status, approver, timestamps).
    • The trait/model concern the README instructs you to add to your approvable models.
    • Your panel provider — the plugin (or approvals page/resource) must be registered there or the review UI won't appear.
  3. First use case: a destructive table action on a resource — DeleteAction, a refund, a "force sync", a status transition. Gate it behind approval, submit one as a normal user, then approve it as a second user and confirm the side effect only happens on approval.
  4. v3.8.2 ships Laravel Boost guidance (AI/agent conventions for this package). If you use Boost, run php artisan boost:install (or re-run it) so your assistant picks up the package's trait, config, and action-API conventions. This is developer tooling only — it has no runtime effect.

Implementation Patterns

Start with one high-risk action, not everything. Wire approval onto a single action, verify the full round trip (submit → notify → approve → side effect → audit row), then roll out. Retrofitting approvals across a whole panel at once makes failures hard to attribute.

Capture intent, execute later. The approval row should record enough to replay the action (subject type + key, action identifier, scalar arguments). Keep the decision data in the record and the execution logic in your action class — don't put business logic in the approval handler.

Two separate authorisations. Model them as distinct gates/policies: canRequestApproval (usually your normal resource update permission) and canApprove (a supervisor/ops role). Separation of duties is the whole point — enforce "requester ≠ approver" explicitly if your compliance context requires it, since it is not always the default.

Approver workflow UI. Either surface pending approvals as a dedicated Filament page/resource with a status filter and nav badge, or as a relation manager on the subject record ("Approvals" tab). The resource approach suits central ops teams; the relation-manager approach suits record owners. Many teams ship both, sharing one query scope.

Notifications are part of the contract. Queue submission, approval, and rejection notifications. In tests, use Notification::fake() and assert the right people were notified — silent approvals are the most common production complaint.

Reuse the same service outside Filament. Scheduled jobs, artisan commands, and API endpoints should create approvals through the same entry point as the Filament action, so the audit trail is uniform. Don't hand-insert rows into the approvals table.

Testing pattern. Two assertions per case:

// submitting does not perform the side effect
livewire(ManageOrders::class)->callTableAction('refund', $order);
$this->assertDatabaseHas('approvals', ['status' => 'pending']);
$this->assertNull($order->fresh()->refunded_at);

// approving does
$this->actingAs($supervisor);
// approve via the package's UI/service
$this->assertNotNull($order->fresh()->refunded_at);

Gotchas and Tips

  • Publish migrations before migrate, not after. On existing apps, check for a table-name collision (approvals is generic) and override it in config before running.
  • Config caching bites. Changing approver resolution or notification classes has no effect until php artisan config:clear (and on deployed environments, a fresh config:cache).
  • Registration in the panel provider is easy to miss. Correct composer install + migrate with no visible review screen almost always means the plugin wasn't registered on that panel.
  • Payload serialisation. Store IDs and scalars, never closures or Eloquent models directly. If an action's signature or expected arguments change after approvals are pending, old records can fail on replay — version your action identifiers or invalidate stale pending rows in the migration.
  • Make actions idempotent. Approval replays the action; a user retrying, a double-click, or a queued replay can run it twice. Wrap execution in a transaction and guard with "already applied" checks on the subject.
  • Handle replay failures loudly. If the action throws during approval, the approval must not silently flip to "approved". Log the failure with the approval ID and keep the record in a failed/pending state your UI can surface.
  • Stale pending approvals. Add a pruning command or scheduled task for approvals on deleted subjects, and clean up when the underlying record is force-deleted.
  • Don't rely on UI hiding. Approve/reject buttons being invisible is not authorisation — enforce the approver gate in the action/service layer too.
  • Debugging checklist: approvals table rows (status, requester, approver), laravel.log for replay exceptions, queue workers running for notifications, and the panel provider registration. Those four cover most "it didn't work" reports.
  • Laravel Boost note. The v3.8.2 guidance improves AI-assisted code generation for this package, but assistant suggestions are only as good as your published config — re-run the Boost install after upgrading so the guidance matches v3.8.2 conventions.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle