Quality
laravel-refactor
Refactors code for SOLID/DRY compliance
Overview
The laravel-refactor agent improves code quality by applying SOLID principles, eliminating duplication (DRY), extracting services, and following Laravel best practices. It uses Pint for styling and PHPStan for static analysis.
Responsibilities
- SOLID Compliance - Single responsibility, dependency inversion, etc.
- DRY Extraction - Extract duplicated code into reusable components
- Service Extraction - Move business logic from controllers to services
- Code Style - Apply Laravel Pint formatting
- Static Analysis - Fix PHPStan issues
- Simplification - Reduce complexity, improve readability
SOLID Principles Applied
| Principle | What Agent Does |
|---|---|
| S - Single Responsibility | Extracts classes doing too much into focused services |
| O - Open/Closed | Uses interfaces and strategy patterns |
| L - Liskov Substitution | Ensures proper inheritance hierarchies |
| I - Interface Segregation | Splits fat interfaces into focused ones |
| D - Dependency Inversion | Injects dependencies via constructor |
Refactoring Examples
// BEFORE: Fat controller with business logic
class OrderController extends Controller
{
public function store(Request $request)
{
$validated = $request->validate([...]);
// Business logic in controller (bad!)
$order = new Order($validated);
foreach ($request->items as $item) {
$product = Product::find($item['id']);
if ($product->stock < $item['quantity']) {
return back()->withErrors(['Insufficient stock']);
}
$product->decrement('stock', $item['quantity']);
$order->items()->create([...]);
}
$order->save();
// More business logic...
Mail::send(new OrderConfirmation($order));
return redirect()->route('orders.show', $order);
}
}
// AFTER: Thin controller with service
class OrderController extends Controller
{
public function __construct(
private OrderService $orderService
) {}
public function store(StoreOrderRequest $request)
{
try {
$order = $this->orderService->create(
auth()->user(),
$request->validated()
);
return redirect()
->route('orders.show', $order)
->with('success', 'Order placed!');
} catch (InsufficientStockException $e) {
return back()->withErrors(['stock' => $e->getMessage()]);
}
}
}
DRY Extraction Example
// BEFORE: Duplicated query logic
class UserController
{
public function index()
{
$users = User::where('active', true)
->where('role', 'admin')
->orderBy('name')
->get();
}
}
class ReportController
{
public function admins()
{
$users = User::where('active', true)
->where('role', 'admin')
->orderBy('name')
->get(); // Same query!
}
}
// AFTER: Query scope in model
class User extends Model
{
public function scopeActiveAdmins($query)
{
return $query->where('active', true)
->where('role', 'admin')
->orderBy('name');
}
}
// Usage
$users = User::activeAdmins()->get();
Laravel Pint Configuration
{
"preset": "laravel",
"rules": {
"simplified_null_return": true,
"blank_line_before_statement": {
"statements": ["return", "throw", "try"]
},
"concat_space": {
"spacing": "one"
},
"method_argument_space": {
"on_multiline": "ensure_fully_multiline"
}
}
}
PHPStan Configuration
# phpstan.neon
parameters:
level: 8
paths:
- app
ignoreErrors:
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Builder#'
checkMissingIterableValueType: false
Common Refactoring Patterns
- Extract Service - Move business logic from controllers
- Extract Action - Create single-purpose classes
- Extract Query Scope - Reusable query logic in models
- Extract Trait - Share behavior across models
- Extract Interface - Define contracts for swappable implementations
- Extract Value Object - Encapsulate related data
Invoked By Commands
- /laravel-agent:refactor - Analyze and refactor code
Guardrails
The refactor agent follows strict rules:
- ALWAYS run tests before and after refactoring
- ALWAYS extract after 2nd occurrence (Rule of Three)
- ALWAYS keep methods under 20 lines
- NEVER refactor without test coverage
- NEVER change behavior while refactoring
- NEVER create god classes or services
See Also
- laravel-review - Code review agent
- laravel-service-builder - Creates extracted services