Artisan commands
| Command | Does |
|---|---|
tickets:install {--force} | Publish the config and every migration, print the key types and the next steps. |
tickets:doctor {--json} | Check the installation; exit 1 on any error. |
tickets:sweep | Flag overdue and due-soon tickets — schedule every five minutes. |
tickets:prune-fields {--dry-run} {--chunk=200} | Forget orphaned custom field values. |
The provider registers the commands but puts nothing on the scheduler:
// routes/console.php
use Illuminate\Support\Facades\Schedule;
Schedule::command('tickets:sweep')->everyFiveMinutes(); // overdue and due-soon flags
Schedule::command('lifecycle:sweep')->everyMinute(); // closes resolved tickets after 7 daystickets:install
- Publishes tickets-config, then media-, likes-, reports-, approvals-, comments-, lifecycle-, attributes- and tickets-migrations (sluggable’s slug-history table is not needed).
- Shows the six key-type settings to align before migrating — tickets.primary_key_type, tickets.key_type, lifecycle.key_type, lifecycle.actor_key_type, comments.key_type, attributes.key_type — with their current values (INVALID for a junk one).
- Prints the next steps: migrate, the user model as an assignee, the Gate abilities, the two scheduler lines, tickets:doctor — and, while the doctor would report guest_links, the three ways to settle it — plus how to serve and customise the API. The route file is never published by the installer.
- Idempotent: published files are kept unless --force, and a republished migration lands on the file it landed on before.
tickets:doctor
Read-only checks, by section. Each has a section, a code, a level (ok, warning, error) and a message; the exit code is 1 when any check is an error:
php artisan tickets:doctor # exit 1 on any error
php artisan tickets:doctor --json # {ok, checks: [{section, code, level, message}]}| Section | Codes | Level | Checks |
|---|---|---|---|
keys | alignment | ok / error | Every key-type setting valid and the pairs equal. |
keys | user_model | warning | The default guard’s user model is keyed differently from tickets.key_type. |
lifecycle | contract, not_a_definition, not_status_attribute, state_not_ticket_state, automation_* | ok / error | The configured lifecycle satisfies the ticket contract. |
lifecycle | lifecycle.<code> | error / warning / ok | lifecycle-for-laravel’s own validation; the shipped close/dismiss ambiguous_target pair is ok, with a note. |
lifecycle | conveniences | ok / warning | Which named conveniences the lifecycle supports; a warning when not all eight. |
priority | enum, stored | ok / error / warning | The enum and default are usable; how many tickets hold a value the enum no longer has. |
authorization | abilities | ok / warning / error | The abilities are defined (Gate::has); undefined is a warning because a Gate::before is invisible to it. |
aliases | maps, requesters, assignables, watchables, projects | ok / error | Each alias map valid; assignables implement Assignee, projects TicketProject. |
guests | fields | ok / error | The guest field definitions are valid. |
conversation | meta, comments_authorization | ok / error / warning | The comments table has the meta column; a warning while comments.authorization is on. |
attachments | disk, temporary_urls | ok / warning / error | The attachments disk is not the web-served public disk; download URLs can be minted. |
api | policy, routes, guest_links | ok / warning / error | The policy class is valid; routes sit behind an auth* middleware; guest links can be minted — an error while guests are notified. |
notifications | enabled, types, url | ok / error | Notifications on or off, every type a packaged class, a subclass or false, the URL http(s). |
due | soon_window, auto_close, schedule | ok / error | The durations parse; the reminder to schedule both sweeps. |
config | keys | ok / warning | A published config still holds routes.enabled, guests.enabled and attachments.mimes. |
A fresh install exits 1 until it is configured: guest notifications are on by default and the default guest-link generator needs the guest routes, which ship off. Fix it with TICKETS_ROUTES=on, your own Contracts\GuestLinkGenerator, or TICKETS_NOTIFY_GUESTS=off.
tickets:sweep
Calls Tickets::sweep() and prints the counts. Each ticket is flagged at most once per due date, concurrent sweeps included; it never auto-closes — that is lifecycle:sweep:
php artisan tickets:sweep
# 3 tickets became overdue.
# 1 ticket is due soon.tickets:prune-fields
Forgets the custom field values no field of their ticket accounts for any more; values of an inactive field are kept. The one step that cannot be undone:
| Option | Meaning |
|---|---|
--dry-run | Count only (5 orphaned field values would be forgotten.). |
--chunk=200 | Tickets per chunk, a whole number from 1 to 999999 (anything else exits with an error). |
php artisan tickets:prune-fields --dry-run
php artisan tickets:prune-fields --chunk=500Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.