lc-generate-action
Create a Laractions action class with proper boilerplate.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Create a Laractions action class with proper boilerplate.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Create a Larascraper scraper (v2 or v3) for a target website, chaining browser actions (click, type, wait, scroll), conditional flow (when/repeatUntil), captcha solving, and file/PDF downloads. Detects the installed major and generates the matching style.
Add or edit a Laracrate file collection in config/laracrate.php with the correct anatomy (disk, access, types, variants, previews, extract/embed, flags, per-model scoping).
Runtime-verified Laravel inspection using the Laravel Boost MCP server (Tinker, Database Query/Schema, Last Error) instead of static grep. Falls back to Docker/Tinker if Boost is not installed.
Scaffold spatie/laravel-permission setup - add the HasRoles trait to a model and generate a roles & permissions seeder.
Audit spatie/laravel-permission usage - permissions used in code but undefined, defined but unused, unprotected routes, guard mismatches, and cache pitfalls.
Extract business logic from a controller or Livewire component method into a Laractions Action class.
| name | lc:generate-action |
| description | Create a Laractions action class with proper boilerplate. |
| argument-hint | [Model/ActionName] |
| user-invocable | true |
| allowed-tools | Read Grep Bash Edit Write Glob |
Create a Laractions action class following the project's conventions, and register it in the corresponding model.
| Subcommand | Description |
|---|---|
| (no argument) | Prompt for model name and action name, then generate. |
[Model/ActionName] | Generate the specified action class and register it in the model. |
This is a generator skill -- it always creates files. There is no analyze-only or fix mode.
Grep to check if edulazaro/laractions exists in composer.json.Laractions is not installed. Install it with:
composer require edulazaro/laractions
Read the installed Action.php from vendor to understand the current API:
Read to load vendor/edulazaro/laractions/src/Action.php.create(), run(), dispatch(), handle()queue(), delay(), retry()actor(), on(), with()trace(), enableLogging(), log()$rules for validation$tries, $delay, $queue class propertiesvendor/edulazaro/laractions/src/Concerns/HasActions.php to understand the trait.The argument should be in the format Model/ActionName (e.g., Property/ToggleShowcase, Client/CreateCopyForGroup).
/, split into model name and action name./ is provided, ask the user for both the model name and the action name.Derive the following:
PropertyToggleShowcaseAction (append Action suffix if not already present)toggle_showcase (snake_case of the action name without the Action suffix)app/Actions/{Model}/{ActionClass}.phpGlob to find existing actions in app/Actions/{Model}/ directory.Read to examine one or two to understand:
$rules, trace(), enableLogging(), etc.app/Models/{Model}.php) to understand:
$actions array (existing action registrations)HasActions)Create the file using Write at app/Actions/{Model}/{ActionClass}.php:
<?php
namespace App\Actions\{Model};
use App\Models\{Model};
use EduLazaro\Laractions\Action;
class {ActionClass} extends Action
{
protected {Model} ${model};
public function handle(): void
{
// Action logic here
}
}
Key requirements:
App\Actions\{Model}EduLazaro\Laractions\Actionprotected Property $property)use statements, never inline qualified class names.text() helper for any translatable strings (Laratext, not __())IMPORTANT: Generate only the clean skeleton by default. Do NOT add $rules, $tries, $delay, $queue, trace(), enableLogging(), or log() unless the user explicitly asks for them. The generated action should be minimal:
class {ActionClass} extends Action
{
protected {Model} ${model};
public function handle(): void
{
//
}
}
Validation rules (user asks for validation):
protected array $rules = [
'email' => 'required|email',
'name' => 'required|string|max:255',
];
Queue configuration (user asks for async/queue support):
protected int $tries = 3;
protected int $delay = 0;
protected string $queue = 'default';
Logging (user asks for logging):
$this->log('Starting operation', ['id' => $this->{model}->id]);
Read to load the model file at app/Models/{Model}.php.$actions array property.Edit to add the new action registration:protected array $actions = [
// ... existing actions
'action_key' => ActionClass::class,
];
use import for the new action class at the top of the model file if not already present.If the model does not have:
use EduLazaro\Laractions\Concerns\HasActions; trait -- add it$actions array property -- create itRead to verify the action class file was created correctly.Read to verify the model was updated correctly.php -l on both files to check syntax (Docker-aware: detect container from docker-compose.yml).EduLazaro\Laractions\Action$actions is snake_caseuse import is present in the model fileHasActions trait is used in the modelAfter successful creation, show how to use the action:
// Synchronous execution
$result = ${model}->action('action_key')->run($param1, $param2);
// With named parameters
$result = ${model}->action('action_key')
->with(['param1' => $value1])
->run();
// Asynchronous execution (queued)
${model}->action('action_key')
->queue('default')
->dispatch($param1, $param2);
// With delay and retries
${model}->action('action_key')
->queue('default')
->delay(60)
->retry(3)
->dispatch($param1);
// With actor tracking
$user->act(ActionClass::class)
->on(${model})
->run($param1);
// With audit trail
${model}->action('action_key')
->trace()
->run($param1);
// With logging enabled
${model}->action('action_key')
->enableLogging()
->run($param1);
Based on common patterns in the project, here are templates for different action types:
public function handle(array $data): void
{
$this->{model}->update($data);
}
public function handle(Organization|int|string $organization, int|string|null $officeId = null): {Model}
{
$orgInstance = $organization instanceof Organization ? $organization : Organization::find($organization);
return {Model}::create([
'organization_id' => $orgInstance->id,
'office_id' => $officeId,
// ... copy fields from $this->{model}
]);
}
public function handle(): void
{
$this->{model}->update([
'active' => !$this->{model}->active,
]);
}
protected array $rules = [
'name' => 'required|string',
];
public function handle(): array
{
$errors = [];
if (!$this->{model}->name) {
$errors[] = text('name_required', 'Name is required');
}
return $errors;
}
public function handle(array $oldValues, array $newValues): void
{
foreach ($newValues as $field => $newValue) {
$oldValue = $oldValues[$field] ?? null;
if ($oldValue !== $newValue) {
Activity::create([
'activitable_type' => '{model}',
'activitable_id' => $this->{model}->id,
'field' => $field,
'old_value' => $oldValue,
'new_value' => $newValue,
]);
}
}
}
protected int $tries = 3;
protected int $delay = 0;
protected string $queue = 'default';
public function handle(): void
{
$this->log('Starting heavy operation', ['id' => $this->{model}->id]);
// ... heavy logic (API calls, file processing, etc.) ...
$this->log('Operation completed');
}
public function handle(string $reason = ''): void
{
$this->{model}->update(['status' => 'approved']);
// Actor is available via $this->actor if set
}
Actions can be dispatched to a queue for asynchronous processing:
// Basic queue dispatch
$model->action('action_name')->dispatch($param1);
// Specify queue name
$model->action('action_name')->queue('emails')->dispatch($param1);
// With delay (seconds)
$model->action('action_name')->delay(120)->dispatch($param1);
// With retry attempts
$model->action('action_name')->retry(5)->dispatch($param1);
// Full configuration
$model->action('action_name')
->queue('high')
->delay(60)
->retry(3)
->dispatch($param1, $param2);
No special code is needed in the action class itself for basic queue support. Laractions wraps the action in an ActionJob (implements ShouldQueue) automatically.
For actions that should always run on a specific queue, set class-level defaults:
protected int $tries = 3;
protected int $delay = 0;
protected string $queue = 'emails';
protected Property $property, protected Client $client).__invoke(), so they can be used as callables: $action($param) is equivalent to $action->run($param).HasActions support mockAction() to replace actions with mocks.