From asyrafhussin-agent-skills-1
Guides Laravel 13 development with 31 rules across architecture, Eloquent, controllers, validation, security, performance, and API design. Activates on tasks involving controllers, models, migrations, services, or database queries.
How this skill is triggered — by the user, by Claude, or both
Slash command
/asyrafhussin-agent-skills-1:laravel-best-practicesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Comprehensive best practices guide for Laravel 13 applications. Contains 31 rules across 7 categories for building scalable, maintainable Laravel applications.
AGENTS.mdREADME.mdmetadata.jsonrules/_sections.mdrules/_template.mdrules/arch-action-classes.mdrules/arch-dto-pattern.mdrules/arch-event-driven.mdrules/arch-feature-folders.mdrules/arch-queue-routing.mdrules/arch-repository-pattern.mdrules/arch-service-classes.mdrules/arch-value-objects.mdrules/controller-api-resources.mdrules/controller-dependency-injection.mdrules/controller-form-requests.mdrules/controller-middleware.mdrules/controller-resource-controllers.mdrules/controller-resource-methods.mdrules/controller-single-action.mdComprehensive best practices guide for Laravel 13 applications. Contains 31 rules across 7 categories for building scalable, maintainable Laravel applications.
Reference these guidelines when:
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Architecture & Structure | CRITICAL | arch- |
| 2 | Eloquent & Database | CRITICAL | eloquent- |
| 3 | Controllers & Routing | HIGH | controller-, ctrl- |
| 4 | Validation & Requests | HIGH | validation-, valid- |
| 5 | Security | HIGH | sec- |
| 6 | Performance | MEDIUM | perf- |
| 7 | API Design | MEDIUM | api- |
arch-service-classes - Extract business logic to servicesarch-action-classes - Single-purpose action classesarch-repository-pattern - When to use repositoriesarch-dto-pattern - Data transfer objectsarch-value-objects - Encapsulate domain conceptsarch-event-driven - Decouple with events and listenersarch-feature-folders - Organize by domain/featurearch-queue-routing - Centralized job queue routing (Laravel 13+)eloquent-eager-loading - Prevent N+1 querieseloquent-chunking - Process large datasetseloquent-query-scopes - Reusable query logiceloquent-model-events - Use observers for side effectseloquent-relationships - Define relationships properlyeloquent-casts - Automatic attribute castingeloquent-accessors-mutators - Transform attributeseloquent-soft-deletes - Safe deletion with recoveryeloquent-pruning - Automatic cleanup of old recordseloquent-vector-search - Semantic search with pgvector (Laravel 13+)controller-resource-controllers - Use resource controllerscontroller-single-action - Single action invokable controllerscontroller-resource-methods - RESTful resource methodscontroller-form-requests - Use form requestscontroller-api-resources - Transform API responsescontroller-middleware - Apply middleware properlycontroller-dependency-injection - Inject dependenciesvalidation-form-requests - Use form request classesvalidation-custom-rules - Create custom rulesvalidation-conditional-rules - Conditional validationvalidation-array-validation - Validate nested arraysvalidation-after-hooks - Complex validation logicsec-mass-assignment - Protect against mass assignmentNo rule files exist yet for this category.
No rule files exist yet for this category.
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StorePostRequest;
use App\Http\Requests\UpdatePostRequest;
use App\Models\Post;
use Illuminate\Http\RedirectResponse;
class PostController extends Controller
{
public function store(StorePostRequest $request): RedirectResponse
{
// Validation happens automatically
$validated = $request->validated();
$post = Post::create($validated);
return redirect()
->route('posts.show', $post)
->with('success', 'Post created successfully.');
}
public function update(UpdatePostRequest $request, Post $post): RedirectResponse
{
$post->update($request->validated());
return redirect()
->route('posts.show', $post)
->with('success', 'Post updated successfully.');
}
}
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StorePostRequest extends FormRequest
{
public function authorize(): bool
{
return $this->user()->can('create', Post::class);
}
public function rules(): array
{
return [
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string', 'min:100'],
'category_id' => ['required', 'exists:categories,id'],
'tags' => ['nullable', 'array'],
'tags.*' => ['exists:tags,id'],
'published_at' => ['nullable', 'date', 'after:now'],
];
}
public function messages(): array
{
return [
'body.min' => 'The post body must be at least 100 characters.',
];
}
}
<?php
namespace App\Services;
use App\Models\User;
use App\Models\Post;
use App\Events\PostPublished;
use Illuminate\Support\Facades\DB;
class PostService
{
public function __construct(
private readonly NotificationService $notifications,
) {}
public function publish(Post $post): Post
{
return DB::transaction(function () use ($post) {
$post->update([
'published_at' => now(),
'status' => 'published',
]);
event(new PostPublished($post));
$this->notifications->notifyFollowers($post->author, $post);
return $post->fresh();
});
}
}
<?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\BelongsToMany;
use Illuminate\Database\Eloquent\Builder;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title',
'slug',
'body',
'category_id',
'published_at',
];
protected $casts = [
'published_at' => 'datetime',
];
// Relationships
public function author(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class)->withTimestamps();
}
// Scopes
public function scopePublished(Builder $query): Builder
{
return $query->whereNotNull('published_at')
->where('published_at', '<=', now());
}
public function scopeByCategory(Builder $query, int $categoryId): Builder
{
return $query->where('category_id', $categoryId);
}
// Accessors & Mutators
protected function title(): Attribute
{
return Attribute::make(
set: fn (string $value) => ucfirst($value),
);
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->foreignId('category_id')->constrained()->cascadeOnDelete();
$table->string('title');
$table->string('slug')->unique();
$table->text('body');
$table->timestamp('published_at')->nullable();
$table->timestamps();
// Indexes for common queries
$table->index(['user_id', 'published_at']);
$table->index('category_id');
});
}
public function down(): void
{
Schema::dropIfExists('posts');
}
};
// N+1 Problem
$posts = Post::all();
foreach ($posts as $post) {
echo $post->author->name; // Query per post
}
// Eager loading — only 3 queries total
$posts = Post::with(['author', 'category', 'tags'])->get();
foreach ($posts as $post) {
echo $post->author->name; // No additional queries
}
// Nested eager loading
$posts = Post::with([
'author.profile',
'comments.user',
'tags',
])->get();
// Constrained eager loading
$posts = Post::with([
'comments' => fn ($query) => $query->latest()->limit(5),
])->get();
Read individual rule files for detailed explanations and code examples:
rules/arch-service-classes.md
rules/eloquent-eager-loading.md
rules/validation-form-requests.md
rules/_sections.md
Each rule file contains:
For the complete guide with all rules expanded: AGENTS.md
npx claudepluginhub joshuarweaver/cascade-code-languages-misc-1 --plugin asyrafhussin-agent-skills-1Senior Laravel Engineer role for production-grade, maintainable, and idiomatic Laravel solutions. Focuses on clean architecture, security, performance, and modern standards (Laravel 10/11+).
Designs Laravel app architecture with services, repositories, actions, and clean code patterns. Use when structuring projects, implementing DI, or organizing code layers.
Guides developers to use Laravel-specific vocabulary for Eloquent queries, Form Requests, API resources, jobs/queues, and validation to produce idiomatic framework code.