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 Deleted Records Laravel Package

amjadiqbal/filament-deleted-records

A Filament plugin that adds a dedicated panel resource for browsing, filtering, and restoring soft-deleted Eloquent records. Quickly inspect trashed data, view deleted items, and restore or force-delete them without leaving the admin panel.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package with Composer and register the plugin in your Filament panel provider:

composer require amjadiqbal/filament-deleted-records
php artisan vendor:publish --tag="filament-deleted-records-config"
// app/Providers/Filament/AdminPanelProvider.php
->plugin(DeletedRecordsPlugin::make())

The first place to look is the published config file. Add the soft-deletable models you want exposed, and review the masking and authorization options before opening the page. The second place is the README/docs at https://amjad.com.pk/filament/plugins/filament-deleted-records, especially the v1.0.1 notes on defaults and limitations.

Your first use case should be: register one model, open the Deleted Records page, search for a known trashed record, preview it, and restore it. Before you let anyone else near the page, add a policy or callback for restore and permanent delete — the default is permissive.

v1.0.1 is a security release. Upgrade before exposing the page to non-admin panel users, because earlier versions allowed search to probe masked values.

Implementation Patterns

Register models deliberately. Only add models that use SoftDeletes and that you actually want panel users to see. The config is the source of truth for what appears in the page.

Authorize through policies, not hope. Define restore and forceDelete abilities on each model's policy. This is the cleanest extension point and keeps authorization auditable:

class InvoicePolicy
{
    public function restore(User $user, Invoice $invoice): bool
    {
        return $user->hasRole('admin');
    }

    public function forceDelete(User $user, Invoice $invoice): bool
    {
        return $user->hasRole('super-admin');
    }
}

Use config callbacks only when a policy is impractical. Prefer policies for anything long-lived.

Treat bulk actions as a reporting workflow. Bulk restore and bulk permanent delete now report records skipped for permission separately from failed restores. Surface both counts in your UI or logs. If you have tests asserting a single "restored" count, update them.

Configure masking for previews. Add sensitive attributes (password hashes, tokens, personal data) to the mask list. Understand that this is a display-layer control, not encryption or redaction at rest.

Handle tenancy explicitly. If your panel uses Filament tenancy, verify that the plugin scopes records to the current tenant. Test with a second tenant: can a user see, restore, or purge a record belonging to another tenant? The README covers tenancy but does not replace your own test.

Search behavior is now narrower and safer. Search matches configured keys/title attributes and never masked attributes. If users need richer search, add a dedicated searchable column or extend the page rather than reintroducing JSON-wide matching.

Test against your production database driver. The package runs its own suite on MySQL 9.7, Postgres 17, and SQLite via DB_TEST_DRIVER. Run your application tests on the same driver you deploy, because JSON and case-insensitive search behavior differ across databases.

Upgrade routine. Run composer update, then php artisan config:clear, review any republished config, and re-run tests covering search, masking, bulk actions, and tenancy.

Gotchas and Tips

  • Upgrade from earlier versions immediately. Pre-v1.0.1 search matched the entire stored JSON with LIKE, allowing a user to probe masked values such as password hashes. v1.0.1 fixes this.
  • Search results will change after upgrading. Searching for a masked value should now return nothing. Do not "fix" this by widening search; that reopens the leak.
  • Default permissions are open. Without a policy or callback, any panel user can restore and purge. This is now stated plainly in the README. Add authorization before deployment.
  • Masking is on screen only. The underlying database, exports, APIs, logs, and backups still contain the real value. Do not treat masking as a compliance control.
  • "Deleted by" has limits. It reflects the tracking data the package stores; it will not reliably capture impersonation, direct database deletes, or cascading deletes. Do not use it as a sole audit trail.
  • Tenancy can hide or expose the wrong records. Verify restore and purge behavior under tenant context, including records with null tenant identifiers.
  • Bulk action messaging changed. Permission-skipped records are now reported separately from failed restores. Update UI expectations, translations, and test assertions.
  • Clear config cache after upgrading. A stale cached config can make new defaults or keys appear not to work.
  • Prefer policies over config callbacks. Policies are easier to test, review, and audit. Use callbacks only for narrow, local exceptions.
  • The tested matrix is current: PHP 8.3–8.5, Laravel 12/13, Filament 4/5. If you are outside that matrix, budget extra verification time for search and bulk actions.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin