Laravel Expert Assistant
All-in-one agent covering expert, laravel, development, assistant. Includes structured workflows, validation checks, and reusable patterns for development tools.
Laravel Expert Assistant
A world-class Laravel development agent with deep expertise in Laravel 12+ applications, helping you build elegant, maintainable, and production-ready applications following the framework's conventions and best practices.
When to Use This Agent
Choose Laravel Expert Assistant when:
- Building new Laravel features with Eloquent, Blade, or Livewire
- Implementing authentication, authorization, and middleware patterns
- Designing database schemas with migrations, seeders, and factories
- Writing tests for Laravel applications (Feature, Unit, Dusk)
- Optimizing Laravel application performance (queries, caching, queues)
Consider alternatives when:
- Building a non-Laravel PHP application (use a general PHP agent)
- Working on the frontend JavaScript separately from Laravel (use a frontend agent)
- Managing server infrastructure and deployments (use a DevOps agent)
Quick Start
# .claude/agents/laravel-expert-assistant.yml name: Laravel Expert Assistant description: Expert Laravel development and best practices model: claude-sonnet tools: - Read - Write - Edit - Bash - Glob - Grep
Example invocation:
claude "Create a complete CRUD resource for a blog post system with Eloquent model, migration, controller, form requests, and feature tests"
Core Concepts
Laravel Resource Structure
| Component | File Location | Responsibility |
|---|---|---|
| Model | app/Models/Post.php | Domain logic, relationships, scopes |
| Migration | database/migrations/*_create_posts_table.php | Schema definition |
| Controller | app/Http/Controllers/PostController.php | HTTP handling |
| FormRequest | app/Http/Requests/StorePostRequest.php | Validation |
| Resource | app/Http/Resources/PostResource.php | API response transformation |
| Policy | app/Policies/PostPolicy.php | Authorization |
| Factory | database/factories/PostFactory.php | Test data generation |
| Test | tests/Feature/PostTest.php | Feature verification |
Eloquent Model Best Practices
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Builder; class Post extends Model { use HasFactory; protected $fillable = [ 'title', 'slug', 'body', 'status', 'published_at', 'user_id', ]; protected $casts = [ 'published_at' => 'datetime', 'status' => PostStatus::class, // Enum cast ]; // Relationships public function author(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); } public function comments(): HasMany { return $this->hasMany(Comment::class); } // Scopes public function scopePublished(Builder $query): void { $query->where('status', PostStatus::Published) ->where('published_at', '<=', now()); } // Accessors protected function readingTime(): Attribute { return Attribute::get(fn () => (int) ceil(str_word_count(strip_tags($this->body)) / 200) ); } }
Service Pattern for Complex Logic
<?php namespace App\Services; use App\Models\Post; use App\Events\PostPublished; use Illuminate\Support\Facades\DB; class PostService { public function publish(Post $post): Post { return DB::transaction(function () use ($post) { $post->update([ 'status' => PostStatus::Published, 'published_at' => now(), ]); // Clear relevant caches cache()->tags(['posts'])->flush(); // Dispatch event for side effects PostPublished::dispatch($post); return $post->fresh(); }); } }
Configuration
| Parameter | Description | Default |
|---|---|---|
laravel_version | Target Laravel version | 12 |
php_version | PHP version | 8.3 |
frontend | Frontend approach (blade, livewire, inertia, api-only) | blade |
testing | Test framework (pest, phpunit) | pest |
database | Database engine (mysql, postgresql, sqlite) | mysql |
queue_driver | Queue backend (redis, database, sqs) | redis |
Best Practices
-
Use Form Requests for validation instead of validating in controllers. Form Requests encapsulate validation rules, authorization checks, and error messages into dedicated classes. This keeps controllers thin and makes validation rules reusable across multiple endpoints. The
authorize()method in Form Requests should handle authorization for the specific request, while Policies handle model-level authorization. -
Leverage Eloquent scopes and accessors instead of querying in controllers. Business logic like "get published posts" belongs in the model as a scope (
scopePublished), not as raw query conditions scattered across controllers. Accessors likereading_timecompute derived values consistently everywhere the model is used. This centralizes domain logic and prevents duplication. -
Use database transactions for operations that modify multiple tables. When creating an order with items, updating inventory, and recording payment in one operation, wrap everything in
DB::transaction(). If any step fails, all changes roll back automatically. Without transactions, a failure mid-operation leaves the database in an inconsistent state that requires manual cleanup. -
Write feature tests that hit the HTTP layer, not just unit tests. Laravel's
TestCasemakes it easy to test the full request lifecycle: authentication, validation, controller logic, database changes, and response format. Feature tests catch integration issues that unit tests miss. Use factories for test data and assertions likeassertDatabaseHas,assertJson, andassertRedirectfor precise verification. -
Use events and listeners for side effects instead of embedding them in services. When a post is published, you might need to send notifications, update search indexes, clear caches, and generate sitemap entries. Dispatching a
PostPublishedevent and handling each side effect in separate listeners keeps the core logic clean and makes side effects independently testable and toggleable.
Common Issues
N+1 query problem causes slow page loads. Loading posts with Post::all() then accessing $post->author->name in a loop triggers a query per post. Use eager loading: Post::with('author')->get(). Enable Laravel's Model::preventLazyLoading() in development to throw exceptions when lazy loading occurs, catching N+1 problems during development rather than production.
Mass assignment vulnerability from unprotected fillable attributes. Setting $guarded = [] (no protection) or including sensitive columns like role or is_admin in $fillable allows attackers to escalate privileges by including extra fields in form submissions. Explicitly list only user-editable fields in $fillable. For admin-only fields, set them explicitly in the service layer rather than through mass assignment.
Queue jobs fail silently without proper error handling. Jobs that throw exceptions are retried according to the $tries property, but failures may go unnoticed without monitoring. Implement the failed() method on every job to log or alert on permanent failures. Configure failed_jobs table and use php artisan queue:failed to monitor. Set up Horizon for Redis queues to get a dashboard with retry and monitoring capabilities.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
API Endpoint Builder
Agent that scaffolds complete REST API endpoints with controller, service, route, types, and tests. Supports Express, Fastify, and NestJS.
Documentation Auto-Generator
Agent that reads your codebase and generates comprehensive documentation including API docs, architecture guides, and setup instructions.
Ai Ethics Advisor Partner
All-in-one agent covering ethics, responsible, development, specialist. Includes structured workflows, validation checks, and reusable patterns for ai specialists.