lc-extract-action
Extract business logic from a controller or Livewire component method into a Laractions Action class.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Extract business logic from a controller or Livewire component method into a Laractions Action class.
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.
Create a Laractions action class with proper boilerplate.
| name | lc:extract-action |
| description | Extract business logic from a controller or Livewire component method into a Laractions Action class. |
| argument-hint | [file:method] |
| user-invocable | true |
| allowed-tools | Read Grep Bash Edit Write Glob |
Extract business logic from a controller method or Livewire component method into a standalone Laractions Action class. Replaces the original code with an action call.
| Subcommand | Description |
|---|---|
| (no argument) | Prompt for the file path and method name to extract from. |
[file:method] | Extract the specified method's logic into an action. Format: app/Http/Controllers/PropertyController.php:store or resources/views/livewire/properties/edit.blade.php:save. |
This is a refactoring skill -- it creates an action file and modifies the source file.
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.:).Read to load the source file.Analyze the method body to determine which model the action operates on:
$property->update(), Property::create(), $this->property->save()Glob to find existing actions in app/Actions/{Model}/ directory.Read to examine one or two to understand conventions:
$rules, trace(), enableLogging(), queue properties, etc.Analyze the method and separate:
$request->input(), $this->validate())$this->authorize())return redirect(), return view())session()->flash())$this->dispatch())Determine the action's interface:
store method on PropertyController -> CreatePropertyAction)$rulesCreate the action file at app/Actions/{Model}/{ActionName}.php:
<?php
namespace App\Actions\Property;
use App\Models\Property;
use EduLazaro\Laractions\Action;
class CreatePropertyAction extends Action
{
protected Property $property;
public function handle(array $data): Property
{
$this->property->update([
'name' => $data['name'],
'address' => $data['address'],
'price' => $data['price'],
]);
if (isset($data['tags'])) {
$this->property->tags()->sync($data['tags']);
}
return $this->property->fresh();
}
}
Use Write to create the file.
IMPORTANT: Do NOT add $rules, $tries, $delay, $queue, trace(), enableLogging(), or log() unless the user explicitly asks for them. Extract only the business logic into a clean action. These features are available but should only be added on request.
Read to load the model file.$actions array using Edit:
'create_property' => CreatePropertyAction::class,
use import for the action class.HasActions trait, add it:
use EduLazaro\Laractions\Concerns\HasActions; importuse HasActions; in the class bodyUse Edit to replace the business logic in the original method with the action call.
Before (controller):
public function store(Request $request, Property $property)
{
$validated = $request->validate([...]);
$property->update([
'name' => $validated['name'],
'address' => $validated['address'],
]);
if (isset($validated['tags'])) {
$property->tags()->sync($validated['tags']);
}
return redirect()->route('properties.show', $property)
->with('success', text('property_updated', 'Property updated'));
}
After (controller) -- synchronous:
public function store(Request $request, Property $property)
{
$validated = $request->validate([...]);
$property->action('create_property')->run($validated);
return redirect()->route('properties.show', $property)
->with('success', text('property_updated', 'Property updated'));
}
After (controller) -- asynchronous (for heavy operations):
public function store(Request $request, Property $property)
{
$validated = $request->validate([...]);
$property->action('create_property')
->queue('default')
->dispatch($validated);
return redirect()->route('properties.show', $property)
->with('success', text('property_queued', 'Property update queued'));
}
Before (Volt component):
public function save()
{
$this->validate();
$this->property->update([
'name' => $this->name,
'address' => $this->address,
]);
session()->flash('success', text('saved', 'Saved'));
}
After (Volt component):
public function save()
{
$this->validate();
$this->property->action('update_property')->run([
'name' => $this->name,
'address' => $this->address,
]);
session()->flash('success', text('saved', 'Saved'));
}
Read to verify the action class, model, and source file are all correct.php -l on all modified 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 model{path}{path} (action registered){path} (business logic replaced with action call)Show the user how to use the extracted action in different contexts:
// Synchronous (default)
${model}->action('action_key')->run($data);
// With named parameters
${model}->action('action_key')
->with(['key' => $value])
->run();
// Asynchronous (queued)
${model}->action('action_key')
->queue('default')
->dispatch($data);
// With delay and retries
${model}->action('action_key')
->queue('default')
->delay(60)
->retry(3)
->dispatch($data);
// With actor tracking
auth()->user()->act(ActionClass::class)
->on(${model})
->trace()
->run($data);
// As callable
$action = ${model}->action('action_key');
$action($data); // Same as ->run($data)
$rules in the action.text() helper.->queue()->dispatch() instead of ->run().->trace() for audit trail.use import for the action class in the model file.__invoke(), so they can be used as callables.HasActions support mockAction() to replace actions with mocks.