Implementa lógica de negócio em Laravel usando Actions (lorisleiva/laravel-actions), Events, Listeners, Jobs e Observers. Use quando precisar criar actions, despachar eventos, jobs em background, ou implementar padrões event-driven em projetos Laravel.
From laravel-toolkitnpx claudepluginhub aronpc/ai --plugin laravel-toolkitThis skill is limited to using the following tools:
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Implementa lógica de negócio usando Actions, Events, Jobs e Observers.
| Skill | Quando usar junto |
|---|---|
architecture | Para usar Actions na arquitetura limpa |
realtime | Para broadcasting de events |
testing | Para testar Actions e Events |
exceptions | Para tratamento de erros em Actions |
coder | Para implementar Actions |
Use esta skill sempre que:
lorisleiva/laravel-actionsShouldQueuephp artisan make:action CreateBusiness
<?php
declare(strict_types=1);
namespace App\Actions\Business;
use App\DataObjects\Business\CreateBusinessData;
use App\Models\Business;
use App\Models\Tenant;
use Lorisleiva\Actions\Concerns\AsAction;
final class CreateBusinessAction
{
use AsAction;
/**
* Execute action.
*/
public function handle(Tenant $tenant, CreateBusinessData $data): Business
{
// Check limits
if (!$tenant->isWithinLimit('businesses')) {
throw new \Exception('Business limit exceeded');
}
// Create business
$business = $tenant->businesses()->create($data->toArray());
// Increment usage
$tenant->incrementUsage('businesses');
// Dispatch event
event(new BusinessCreated($business));
return $business;
}
/**
* Use as controller (optional).
*/
public function asController(StoreBusinessRequest $request): Business
{
$data = CreateBusinessData::fromRequest($request->validated());
return $this->handle(auth()->user()->tenant, $data);
}
/**
* Run as queued job (optional).
*/
public function asJob(Tenant $tenant, CreateBusinessData $data): void
{
$this->handle($tenant, $data);
}
}
// Run sincronamente
CreateBusinessAction::run($tenant, $data);
// Run em background (queued)
CreateBusinessAction::dispatch($tenant, $data);
// Run com delay
CreateBusinessAction::dispatch($tenant, $data)->delay(now()->addMinutes(5));
// Run em fila específica
CreateBusinessAction::dispatch($tenant, $data)->onQueue('high');
CRÍTICO: Actions DEVEM usar Value Objects - NUNCA passe arrays crusos.
✅ Type Safety - Detecta erros em tempo de compilação
✅ Suporte IDE - Autocompletion
✅ Validação Centralizada - Em um lugar
✅ Imutabilidade - Previne mutações
✅ Self-Documenting - Contrato claro
✅ Reusabilidade - Use across Actions/Jobs/Events
❌ Single primitive values
❌ Eloquent models
❌ Collections
<?php
declare(strict_types=1);
namespace App\DataObjects\Business;
final readonly class CreateBusinessData
{
public function __construct(
public string $name,
public string $type,
public ?string $email = null,
public ?string $phone = null,
public ?array $settings = null,
) {}
public static function fromRequest(array $data): self
{
return new self(
name: $data['name'],
type: $data['type'],
email: $data['email'] ?? null,
phone: $data['phone'] ?? null,
settings: $data['settings'] ?? null,
);
}
public function toArray(): array
{
return [
'name' => $this->name,
'type' => $this->type,
'email' => $this->email,
'phone' => $this->phone,
'settings' => $this->settings ?? [],
];
}
}
✅ Action parameters (sempre para inputs complexos)
✅ Service methods
✅ API responses
✅ Event payloads
✅ Jobs data
❌ Single primitive values
❌ Eloquent models
❌ Collections
Event:
<?php
namespace App\Events;
use App\Models\Business;
use Illuminate\Foundation\Events\Dispatchable;
final class BusinessCreated
{
use Dispatchable;
public function __construct(public Business $business) {}
}
Listener (as Action):
<?php
namespace App\Listeners;
use App\Events\BusinessCreated;
use Lorisleiva\Actions\Concerns\AsAction;
final class SendBusinessWelcomeEmail
{
use AsAction;
public function handle(BusinessCreated $event): void
{
// Send welcome email
}
}
php artisan make:observer BusinessObserver --model=Business
<?php
namespace App\Observers;
use App\Models\Business;
final class BusinessObserver
{
public function creating(Business $business): void
{
$business->slug = Str::slug($business->name);
}
public function created(Business $business): void
{
event(new BusinessCreated($business));
}
public function updating(Business $business): void
{
if ($business->isDirty('name')) {
$business->slug = Str::slug($business->name);
}
}
}
Registrar em AppServiceProvider:
public function boot(): void
{
Business::observe(BusinessObserver::class);
}
laravel-architecture para estrutura completa de Actions e Value Objectslaravel-i18n para traduções de Events e mensagens de sistemalaravel-exceptions para criar exceções customizadas em Actionslaravel-testing-pest para testes de Actions, Jobs e Eventsdocs/07-actions-events-jobs.md - Documentação completa