🔴 Laravel с Claude Code
Полное руководство по работе с Laravel 11 через Claude Code: MCP-инструменты, архитектурные паттерны, Pest TDD, Artisan, Telescope, Horizon и стандарты кода.
🔌 laravel-boost MCP — суперсила для Laravel
laravel-boost — MCP-сервер, который запускается внутри Laravel-контейнера и предоставляет Claude Code прямой доступ к роутам, моделям, событиям, конфигурации и Artisan — без необходимости читать файлы вручную.
// .mcp.json для Laravel-проекта:
{
"mcpServers": {
"laravel-boost": {
"command": "docker",
"args": [
"exec", "-i",
"phone-rosveb-ru-backend-1", // имя контейнера Laravel
"php", "artisan", "boost:mcp"
]
}
}
}
Что даёт laravel-boost
| Инструмент | Что делает |
|---|---|
boost_routes | Список всех роутов с методом, URI, контроллером, middleware |
boost_models | Структура Eloquent-моделей: fillable, casts, relations |
boost_events | События и листенеры |
boost_config | Конфигурация (без secrets) |
boost_artisan | Запуск безопасных Artisan-команд |
boost_queue | Статус очередей и джобов |
Экономия контекста: вместо чтения 50+ PHP файлов, Claude получает структурированные данные через один вызов. Это экономит тысячи токенов на каждый запрос.
🏗️ Архитектурные паттерны
Claude должен следовать этим паттернам при написании Laravel-кода:
Controller — только HTTP-слой
<?php
declare(strict_types=1);
namespace App\Http\Controllers\Api;
use App\Http\Requests\StorePaymentRequest;
use App\Http\Resources\PaymentResource;
use App\Services\PaymentService;
final class PaymentController
{
// DI через конструктор — тестируемость
public function __construct(
private readonly PaymentService $paymentService
) {}
public function store(StorePaymentRequest $request): PaymentResource
{
// Валидация — в FormRequest, логика — в Service
$payment = $this->paymentService->create($request->validated());
return new PaymentResource($payment);
}
}
Service — бизнес-логика
<?php
declare(strict_types=1);
namespace App\Services;
use App\Models\Payment;
use Illuminate\Support\Facades\DB;
final class PaymentService
{
public function __construct(
private readonly PaymentRepository $repository,
private readonly NotificationService $notifications
) {}
public function create(array $data): Payment
{
return DB::transaction(function () use ($data) {
$payment = $this->repository->create($data);
$this->notifications->paymentCreated($payment);
return $payment;
});
}
}
🧪 Pest TDD — тесты как первый класс
Структура Feature-теста
<?php
// tests/Feature/PaymentTest.php
uses(Tests\TestCase::class, Illuminate\Foundation\Testing\RefreshDatabase::class);
describe('Payment creation', function () {
it('creates payment for authenticated user', function () {
// Arrange
$user = User::factory()->create();
$payload = ['amount' => 1000, 'currency' => 'RUB'];
// Act
$response = $this
->actingAs($user)
->postJson('/api/v1/payments', $payload);
// Assert
$response->assertCreated()
->assertJsonStructure(['data' => ['id', 'amount', 'status']]);
$this->assertDatabaseHas('payments', [
'user_id' => $user->id,
'amount' => 1000,
]);
});
it('requires authentication', function () {
$this->postJson('/api/v1/payments', [])->assertUnauthorized();
});
});
Запуск тестов
// Через Docker MCP:
mcp__docker__docker_exec({
container: "phone-rosveb-ru-backend-1",
command: "./vendor/bin/pest --parallel"
})
// Только изменённые тесты:
mcp__docker__docker_exec({
container: "phone-rosveb-ru-backend-1",
command: "./vendor/bin/pest tests/Feature/PaymentTest.php"
})
⚡ Artisan — полезные команды
| Команда | Когда использовать | Безопасно? |
|---|---|---|
php artisan route:list | Просмотр роутов | ✅ |
php artisan model:show User | Структура модели | ✅ |
php artisan queue:work --once | Обработать 1 джоб | ✅ |
php artisan cache:clear | Очистить кэш | ✅ |
php artisan telescope:clear | Очистить Telescope логи | ✅ |
php artisan migrate | Накатить миграции | ⚠️ Проверить! |
php artisan migrate:status | Статус миграций | ✅ |
php artisan migrate:fresh | 🚫 УДАЛИТ ВСЕ ДАННЫЕ | ❌ Заблокировано |
php artisan db:wipe | 🚫 УНИЧТОЖИТ БД | ❌ Заблокировано |
🔭 Telescope & Horizon
Telescope — отладка через MCP
Laravel Telescope записывает все запросы, очередные задачи, исключения, запросы к БД. Claude Code может читать Telescope данные через laravel-boost или запросы к БД.
-- Последние медленные запросы через postgres-mcp:
SELECT
content->>'slow_query' AS query,
content->>'time' AS ms
FROM telescope_entries
WHERE type = 'query'
AND (content->>'time')::float > 100
ORDER BY created_at DESC
LIMIT 20;
Horizon — мониторинг очередей
// Просмотр статуса Horizon через laravel-boost:
boost_artisan({ command: "horizon:status" })
boost_artisan({ command: "horizon:list" })
// Приостановить обработку для отладки:
boost_artisan({ command: "horizon:pause" })
// Возобновить:
boost_artisan({ command: "horizon:continue" })
📏 Стандарты кода Laravel
pint.json — форматирование
{
"preset": "psr12",
"rules": {
"declare_strict_types": true,
"single_quote": true,
"ordered_imports": { "sort_algorithm": "alpha" },
"no_unused_imports": true,
"final_class": true,
"trailing_comma_in_multiline": true
}
}
✅ final class везде
Service, Controller, FormRequest — все
final. Наследование запрещено без явного обоснования.✅ readonly properties
Параметры конструктора помечать
readonly. Иммутабельность — главное правило DI.❌ $request->all()
Запрещено! Использовать
$request->validated() только. Иначе mass assignment уязвимость.❌ Eloquent в Controller
Контроллер не должен знать про Eloquent. Только Service/Repository → Controller.
✅ DB::transaction()
Любая операция с несколькими записями — в транзакции. Автоматический rollback при Exception.
✅ FormRequest + Resource
Входные данные — через FormRequest (валидация). Выходные — через JsonResource (сериализация).
📦 CMS на базе Laravel
Filament (Admin Panel)
// Работа с Filament через Claude:
// 1. Читать ресурсы через Serena (LSP понимает PHP)
// 2. Artisan для генерации:
boost_artisan({ command: "make:filament-resource Payment --generate" })
// 3. Telescope показывает N+1 запросы при загрузке таблиц
// 4. Правило: withRelationships() для всех relation columns
Nova / Voyager
// Nova — аналогично Filament. Ресурсы генерируются Artisan:
boost_artisan({ command: "nova:resource Payment" })
// Главное правило при работе с CMS:
// НЕ модифицировать vendor-пакеты напрямую
// Использовать service providers и extension points
CMS + Claude: Context7 MCP автоматически загружает документацию Filament/Nova при запросах. Убедись, что
context7 есть в .mcp.json.🔐 Sanctum — API аутентификация
<?php
// routes/api.php — правильная структура:
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('payments', PaymentController::class);
Route::apiResource('subscriptions', SubscriptionController::class);
});
// Публичные роуты:
Route::post('/auth/login', [AuthController::class, 'login']);
Route::post('/auth/register', [AuthController::class, 'register']);
Sanctum + Reverse Proxy: при работе за Caddy нужно настроить
SANCTUM_STATEFUL_DOMAINS или переключиться на Bearer token аутентификацию для SPA. Без этого CSRF-проверки не пройдут.