resources/boost/skills/events/SKILL.md
Decoupled communication between application layers. Events are plain data objects describing what happened; listeners react to those events with a single, specific side effect.
npx skillsauth add codebar-ag/coding-guidelines eventsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
app/Events/; listener classes live in app/Listeners/.InvoicePaid, UserRegistered, OrderShipped.SendInvoicePaidNotification, UpdateInventory.EventServiceProvider.ShouldQueue for deferrable listeners and provide failed() for critical paths.// Event — data container only
namespace App\Events;
use App\Models\Invoice;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class InvoicePaid
{
use Dispatchable, SerializesModels;
public function __construct(
public readonly Invoice $invoice,
) {}
}
// Listener — one reaction
namespace App\Listeners;
use App\Events\InvoicePaid;
use App\Notifications\InvoicePaidNotification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Log;
class SendInvoicePaidNotification implements ShouldQueue
{
public function handle(InvoicePaid $event): void
{
$event->invoice->user->notify(new InvoicePaidNotification($event->invoice));
}
public function failed(InvoicePaid $event, \Throwable $exception): void
{
Log::error('Invoice paid notification listener failed.', [
'invoice_id' => $event->invoice->id,
'message' => $exception->getMessage(),
]);
}
}
// Dispatching from an Action after successful state change
namespace App\Actions;
use App\Events\InvoicePaid;
use App\Models\Invoice;
use Illuminate\Support\Facades\DB;
class MarkInvoiceAsPaid
{
public function execute(Invoice $invoice): void
{
DB::transaction(function () use ($invoice): void {
$invoice->update(['paid_at' => now()]);
InvoicePaid::dispatch($invoice);
});
}
}
// Registration — one event, many listeners
protected $listen = [
InvoicePaid::class => [
SendInvoicePaidNotification::class,
UpdateAccountingRecords::class,
NotifyAccountManager::class,
],
];
// Anti-pattern: listener bundles multiple unrelated reactions
class HandleInvoicePaid implements ShouldQueue
{
public function handle(InvoicePaid $event): void
{
$event->invoice->user->notify(new InvoicePaidNotification($event->invoice));
app(UpdateAccountingRecords::class)->execute($event->invoice);
}
}
ShouldQueue.failed().failed() on queued listeners for critical side effectsActions/SKILL.md — events should be dispatched from ActionsObservers/SKILL.md — for model lifecycle reactionstesting
Translation and localization conventions for Laravel. Use when adding user-facing strings, creating translation files, or working with lang/ directory.
tools
Reusable behaviour shared across multiple unrelated classes. Traits provide shared Eloquent scopes, accessors, lifecycle hooks, and small stateless helper methods.
development
Tailwind CSS v4 styling conventions. Use when working with CSS, Tailwind utilities, or customizing the theme in Laravel projects.
development
Orchestration classes that coordinate multiple Actions, external APIs, or domain operations into a cohesive workflow. Services own transaction boundaries and third-party API integrations.