Filament is a useful fit for a Laravel admin panel when the work centers on records, forms, tables and explicit actions. It can give a support or operations team a consistent interface, but it does not decide who may change a record or what a business transition means.
This guide uses a proposed report-review panel: staff find a customer's failed report, inspect its history, add an internal note and request a retry. It is a design exercise, not a completed client implementation. Package references use Filament 5 documentation; the panel and its installation commands have not been executed for this article.
Choose Filament for the work people actually do
A structured internal tool is a different problem from a public website or a highly customized customer workspace. First sketch the busiest operation and its awkward cases. If a staff member can complete it through a list, detail view and a few carefully defined actions, a resource-oriented panel is a plausible starting point. If the work depends on a spatial canvas, offline operation or complex real-time collaboration, prototype that interaction before committing to a panel framework.
| Workflow | Likely starting point | Question to settle |
|---|---|---|
| Search records and edit a few fields | Filament resource | Which fields and records can each role read or change? |
| Approve or retry a business operation | Resource plus explicit action | What checks and audit evidence must the action require? |
| Customer-facing branded workspace | Custom UI or a separately evaluated panel | Does the navigation and interaction model fit the customer? |
| Existing SaaS already handles the task | Evaluate integration before custom development | What concrete constraint justifies owning another tool? |
Our Laravel CRM guide addresses the broader customer-data model. Filament can implement part of that interface; adding an admin framework is not the same as delivering a CRM.
Install against an explicit version baseline
The Filament 5 installation guide lists PHP 8.2+, Laravel 11.28+ and Tailwind CSS 4.1+ requirements. Check the selected release's Composer constraints, existing Livewire integration and plugins too. An older tutorial's resource signatures or component imports may not match the installed major version.
In a disposable branch of a compatible application, the panel-builder installation begins with:
composer require filament/filament:"^5.0"
php artisan filament:install --panels
Review the generated panel provider and confirm its registration. Retain the dependency lockfile. Do not run a full frontend scaffold over a customized application simply to obtain an admin page. Resolve how the panel's assets fit the existing frontend before accepting generated changes.
For an existing Report Eloquent model, php artisan make:filament-resource Report creates a starting structure. The resource documentation describes optional generation from database columns. Generated fields should be reviewed as a draft: a column's existence does not establish that a staff member may edit it.
Separate panel entry from record permissions
Define panel access through the documented FilamentUser contract and canAccessPanel method. Base it on a controlled staff permission or role. A successful local login does not establish production access behavior, and an email address alone should not silently grant operational authority.
Next define Laravel model policies for the resource operations. Admission to the panel answers “may this person enter?”; a policy answers “may they perform this operation on this record?”. A hidden menu item is not evidence that a direct URL or action request is denied.
| Actor | Visible information | Permitted changes |
|---|---|---|
| Customer | Own report through the customer interface | No access to the internal panel. |
| Support reader | Assigned customer reports and public status | None; internal note creation can be a separately granted permission. |
| Operations reviewer | Reports within the approved support scope | Add notes; request a retry only for eligible failures. |
| Administrator | Explicitly assigned wider scope | Manage staff access; exceptional actions still need an audit trail. |
Translate this proposed matrix into executable allow and deny tests. Do not use role labels without listing the actual operations they permit. If staff serve several customer organizations, test scoped lists, detail links, relation selectors, search and exports with two organizations and deliberately similar records.
Filament's tenancy tools support tenant-aware panels, but the application still owns its access model. A scoped main table does not automatically prove that a custom lookup or background export respects the same boundary. Carry the authorized scope into each operation instead of trusting a hidden tenant field supplied by the browser.
Make “Retry report” a business action
A retry should not be an ordinary editable status dropdown. In the proposed workflow, the action checks the current record, confirms the user can retry it, requires a reason, and records a new attempt identity. The service should reject an already-running report or a stale request, even if an old browser tab still shows the button.
Keep this rule in application code that can also be called safely from an API or command. Within a transaction, re-read or conditionally update the expected state and create the attempt record. After commit, enqueue the work. Record the staff actor and reason with the attempt; do not rely on a temporary success toast as the only history.
The Filament security guide makes custom-action authorization the application's responsibility. In this design, the action handler invokes the relevant authorization check before calling the retry service. Confirmation text explains the consequence; it does not replace a server-side check.
If the customer starts a new attempt while staff are viewing the old one, the UI should show a conflict and reload current state. Repeated clicks must not create repeated external side effects. For a failed third-party operation, inspect the previous attempt before retrying it; “the request timed out” does not necessarily mean the provider did nothing.
Design the smallest useful resource
The first list needs a report reference, customer identity within permitted scope, status, last attempt time and owner. Its default filters should surface actionable failures. A detail view can show the attempt timeline and internal notes. Avoid adding every database column, a chart or unrestricted bulk action merely because the generator makes it easy.
For a read-only field, consider whether it should be included in the editable form at all. Protect ownership, internal state and audit fields on the server as well. A disabled control is presentation, not a complete data-integrity boundary. Keep uploads private when their contents are private, and authorize any download or export destination.
Large lists need realistic data during review. Examine the query count, selected columns and relationship loading for the actual table. Measure an expensive search or export before adding caches; a cache keyed without its customer scope can create a worse problem than a slow query.
Review the operation, including failure
| Case | Expected result | Evidence to keep |
|---|---|---|
| Customer or revoked staff account opens panel | Access denied | HTTP/action response under a non-local environment. |
| Staff guesses another customer record URL | No unauthorized record or fields | List, detail, relation and export checks. |
| Two staff retry the same failure | One accepted attempt; clear conflict for the other | Attempt records, request results and queue evidence. |
| Queue is unavailable after a request | Visible pending/failure state and recovery path | Recorded operation identity and reconciliation procedure. |
| Permission changes while a page is open | Next operation is checked against current permission | Direct action test, not only a hidden button. |
Use the Laravel delivery acceptance workbook to assign a reviewer, expected response and evidence location for each case. These are proposed checks, not claimed results for a deployed panel. Filament's testing documentation supplies the framework-specific helpers.
When the retry becomes a background job, continue with our Horizon queue guide. If the customer needs live progress, the Reverb private-channel guide covers that separate delivery path. A useful brief for our Laravel team names one staff operation, its access boundary and the evidence needed to accept it.
