llaski/nova-scheduled-jobs
A Laravel Nova package that brings your scheduled tasks into the Nova dashboard. View every scheduled job, inspect cron expressions and next run times, run jobs manually, and toggle them on or off without leaving your admin panel.
Bottom line: A single-purpose, read-only Laravel Nova tool that surfaces the application's registered scheduled jobs — command/closure descriptions, cron expressions, timezones, and next-run times — inside the admin panel. No migrations, no write path, no queue interaction, no external service. Adoption cost is roughly a day of engineering including the compatibility spike. The actual decision is whether a low-adoption, single-maintainer dependency belongs on your admin surface, and the answer is yes only as internal convenience tooling with a pinned version and a known exit path.
Architecture fit
NovaServiceProvider::tools(). It resolves Laravel's Schedule singleton and renders the event collection. There is no persistence layer, no event listener, and no queue interaction.Schedule::events() and not worth adopting as a dependency.Integration feasibility
composer require llaski/nova-scheduled-jobs, then register the tool in NovaServiceProvider::tools(). Optional config publish. No artisan migrate step, no seeding, no service provider gymnastics.tools() and running composer remove.Technical risk
routes/console.php / bootstrap/app.php, and the schedule loads during console bootstrap. If the web request does not load the schedule, the Nova page renders empty — a confusing failure that looks like a package bug. Compatibility with Laravel 11+ and Nova 5 is explicitly unverified in the available material.canSee() or a Nova policy. This is a configuration responsibility, not a package defect, but it will be missed if nobody owns it.Schedule:: calls across providers produce duplicate rows that read as a bug; jobs registered only in console context silently vanish from the page.withoutOverlapping(), onOneServer(), or runInBackground() flags, so a mutex-guarded job looks identical to an unguarded one. It also has no execution history. Teams that assume the panel answers "did it run?" will be wrong, and that misread is the most likely source of an incident narrative.Key questions
php artisan schedule:list match the Nova page on our actual stack, in staging, on the first deploy? Any divergence is a registration-context problem we must resolve before rollout.canSee() gating, and is admin-only the right default for our Nova user population?Stack fit
app/Console/Kernel.php (Laravel ≤10) or routes/console.php / bootstrap/app.php (Laravel 11+) following the Laravel convention.Migration path
schedule:list, add the page to the deploy runbook.->name() and optionally ->description() (unnamed closures render as anonymous rows), consolidate the schedule into a single source of truth so duplicate rows do not appear, and annotate operational behavior — overlap guards, single-server constraints — in ->description() since the package will not surface those flags for you.composer remove. If the project goes stale mid-life, fork; the component is a read-only Vue table over the scheduler's event collection, which is a contained port.Compatibility
composer.json at the installed tag for the laravel/nova and illuminate/* constraints before committing. Do not infer compatibility from the description.php artisan schedule:list; remediate by ensuring definitions live somewhere that boots on every request.app.timezone when a job sets ->timezone(...). Validate against schedule:list and the server clock rather than filing upstream bugs.Sequencing
php artisan schedule:list job-for-job. Explicit pass/fail. If we are on Laravel 11+/Nova 5, this step decides go/no-go.canSee() or a Nova policy, admin-only by default. Also decide per-environment registration — skipping it on staging or customer-facing dashboards where it is clutter.Kernel.php, a provider, and routes/console.php, or whose cron expression drifted.Maintenance
Support
Scaling
schedule_runs table — not extending this tool. Extension points are shallow by design.Failure modes
schedule:list; fix by relocating schedule definitions.Schedule:: registration across providers. Diagnose by grepping app/, package service providers, and routes/console.php.->name() / ->description(), not the package.app.timezone for jobs with explicit ->timezone().canSee() is not configured.Ramp-up
How can I help you explore Laravel packages today?