liberusoftware/scheduler-queues-filament
Filament panel integration for Liberu Software's scheduler and queue tooling. It adds admin screens to inspect scheduled tasks and queued jobs, review status and activity, and trigger or retry work directly from your dashboard, keeping background processing visible and manageable in Laravel apps.
This is a Filament presentation adapter — it is not a scheduler or queue implementation on its own. It is designed to sit on top of the matching domain module (liberusoftware/module-scheduler-queues) and render that module's scheduled tasks and queue/job state inside a Filament panel. If you install it standalone you will most likely get either a service-provider error or empty pages.
Minimal steps:
composer require liberusoftware/scheduler-queues-filament
php artisan vendor:publish --provider="Liberu\SchedulerQueuesFilament\SchedulerQueuesFilamentServiceProvider"
composer.json first. Before writing any code, check the require block to confirm (a) the exact core module package name and version constraint, (b) the supported filament/filament major (v3 vs v4 plugin APIs are not compatible), and (c) the PHP/Laravel floor. This package is at 0 stars / 0 dependents, so the constraint graph is your only reliable documentation.vendor/liberusoftware/scheduler-queues-filament/src/ and look for a *Plugin.php implementing Filament\Contracts\Plugin. That class, not the service provider, is what you register.app/Providers/Filament/AdminPanelProvider.php:public function panel(Panel $panel): Panel
{
return $panel
->plugin(\Liberu\SchedulerQueuesFilament\SchedulerQueuesFilamentPlugin::make());
}
php artisan migrate:status should show the scheduler/queue tables if the module is DB-backed). Then run php artisan filament:optimize-clear and reload the panel.First use case: open the panel, find the new navigation group (likely "Scheduler" / "Queues"), confirm the scheduled-task list matches php artisan schedule:list, then go to the failed-jobs page and retry one deliberately-failed job. That end-to-end pass tells you in two minutes whether the adapter is wired to real data or just a static shell.
Restrict to the admin/ops panel only. Register the plugin conditionally so it never leaks into customer-facing panels:
->plugin(
SchedulerQueuesFilamentPlugin::make()
->when(fn () => auth()->user()?->hasRole('ops'))
)
If no fluent when()/authorize() exists on the plugin, gate at the policy layer instead — see below.
Authorize at the policy/gate layer, not the nav layer. Filament hides navigation for resources whose canViewAny() returns false, but direct URLs and Livewire actions still resolve. Publish or define a policy and register it in a service provider:
Gate::define('viewSchedulerQueues', fn (User $u) => $u->hasAnyRole(['ops', 'super-admin']));
Then override canViewAny() / canRetry() / canDelete() on the package's Resource or Page subclasses.
Prefer subclassing pages over editing vendor files. The adapter almost certainly ships Filament Resources/Pages under a namespace you can extend. Add your own actions (retry, forget, "run now", export failed payload) in a subclass and swap it in:
// config/filament.php or a panel ->resources([...]) call
->resources([
App\Filament\Resources\FailedJobResource::class, // extends the package's
])
Treat scheduled-task definitions as code, the UI as observability. If the module is DB-backed and the adapter allows editing cron expressions, resist it. Keep routes/console.php / Kernel::schedule() as the source of truth and use the page to see next-run times and last-run outcomes. Editing schedules in a UI without version control is how you get a 3 a.m. page.
Pair, don't replace, Horizon. If you run Redis queues with Horizon, Horizon owns worker metrics and this package owns "which jobs are pending/failed and let me retry them." Point both at the same connection; don't let two tools own failed_jobs retention policy.
Add dashboard widgets for queue depth. Filament widgets compose well with this package — a small StatsOverview widget reading DB::table('jobs')->count() and failed_jobs gives you the at-a-glance number without opening the full page. Cache it for 30–60s; polling a big jobs table on every dashboard refresh is a classic own-goal.
Testing. These are Livewire components, so test them as such:
Livewire::actingAs($opsUser)
->test(FailedJobsPage::class)
->assertCanSeeTableRecords($failedJobs)
->callTableAction('retry', $failedJobs->first());
Queue::assertPushed(YourJob::class);
Use RefreshDatabase and Queue::fake() for the action assertions, and a real database queue connection in one integration test so you catch serialization issues the fakes hide.
Monorepo integration. If you develop against the module locally, add a path repository in composer.json and composer update liberusoftware/* after each module change — the adapter and module version-lock together and silently drift otherwise.
NOASSERTION. GitHub could not match a standard license file. Before this goes anywhere near a commercial product, open LICENSE in the repo and read it, or ask the maintainer. "No assertion" is not "permissive."composer.json and commit composer.lock.composer show -a liberusoftware/scheduler-queues-filament and a filesystem listing of vendor/ before pasting into a PanelProvider. A wrong plugin class throws an unhelpful BindingResolutionException.schedule:list and the database render in config('app.timezone'); Filament date columns may render in the user's timezone or raw UTC. When a task "should have run 10 minutes ago," check all three before debugging the scheduler itself.->call(fn () => ...) entry — it shows an empty command string. If your task list looks half-empty, that's why, not a bug in the adapter.sync shows nothing; database and redis are where this earns its keep. On sqs/beanstalkd you'll get push-only semantics and the retry/delete actions may behave differently or fail.requiresConfirmation() plus a policy check. Default Filament table bulk actions are easy to mis-click on a paginated list.php artisan filament:optimize-clear, php artisan optimize:clear, check the panel actually registers the plugin, check ->navigationGroup()/shouldRegisterNavigation() isn't hiding it, and check the panel's ->authGuard() matches the guard your User model uses.APP_DEBUG=true locally and read storage/logs/laravel.log — Filament swallows component exceptions into the modal. Nine times out of ten it's a missing policy or a null job row.--tag= names are in the service provider's publishes() array), Resource/Page subclassing, then finally a fork. Never patch vendor/.composer update breaking your admin panel.How can I help you explore Laravel packages today?