.github_gpt/skills/laravel-conventions/SKILL.md
Modern Laravel 11+ / PHP 8.3+ coding standards reference. Use when writing or reviewing PHP/Laravel code to ensure convention compliance.
npx skillsauth add the-rabak/compound-engineering-plugin laravel-conventionsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Apply modern Laravel 11+ and PHP 8.3+ conventions when writing or reviewing Laravel code.
Controller -> FormRequest -> Action/Service -> Model
declare(strict_types=1); at the top of every PHP file.mixed unless absolutely necessary.failed() handling.declare(strict_types=1);
readonly class CreateUserData {
public function __construct(
public string $name,
public string $email,
public ?string $phone = null,
) {}
}
enum UserStatus: string {
case Active = 'active';
case Suspended = 'suspended';
case Pending = 'pending';
}
$users->map($this->transformUser(...));
Cache::put(key: $cacheKey, value: $data, ttl: 3600);
$label = match($status) {
UserStatus::Active => 'Active User',
UserStatus::Suspended => 'Account Suspended',
default => 'Unknown',
};
| Type | Convention | Example |
|------|------------|---------|
| Classes | PascalCase | UserService |
| Methods | camelCase | getUserById |
| Properties/Variables | camelCase | $userData |
| Constants | UPPER_SNAKE_CASE | MAX_RETRIES |
| Database tables | plural, snake_case | user_accounts |
| Database columns | snake_case | created_at |
| Routes | kebab-case | /user-profiles |
| Config keys | snake_case | cache.default_ttl |
| Enums | PascalCase | UserStatus::Active |
app/
|- Actions/
|- Console/Commands/
|- DTOs/
|- Enums/
|- Events/
|- Exceptions/
|- Http/
| |- Controllers/
| |- Middleware/
| |- Requests/
| `- Resources/
|- Jobs/
|- Listeners/
|- Mail/
|- Models/
| `- Concerns/
|- Notifications/
|- Observers/
|- Policies/
|- Providers/
|- Rules/
`- Services/
database/
|- factories/
|- migrations/
`- seeders/
routes/
|- api.php
|- web.php
`- console.php
tests/
|- Feature/
|- Unit/
`- Pest.php
protected $casts = [
'email_verified_at' => 'datetime',
'status' => UserStatus::class,
'settings' => 'array',
'is_admin' => 'boolean',
];
public function scopeActive(Builder $query): Builder
{
return $query->where('status', UserStatus::Active);
}
Model::preventLazyLoading(! app()->isProduction());
Model::shouldBeStrict(! app()->isProduction());
User::with(['posts', 'profile'])->get();
Migration naming:
YYYY_MM_DD_HHMMSS_description.php
Migration example:
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('title');
$table->string('slug')->unique();
$table->text('body');
$table->enum('status', ['draft', 'published', 'archived'])->default('draft');
$table->timestamp('published_at')->nullable();
$table->timestamps();
$table->softDeletes();
$table->index(['status', 'published_at']);
});
class UserResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'posts' => PostResource::collection($this->whenLoaded('posts')),
'created_at' => $this->created_at->toISOString(),
];
}
}
return UserResource::make($user);
return UserResource::collection($users);
class ProcessPayment implements ShouldQueue
{
use Queueable;
public int $tries = 3;
public int $backoff = 60;
public int $timeout = 120;
public function __construct(
private readonly Order $order,
) {}
public function handle(PaymentGateway $gateway): void
{
$gateway->charge($this->order);
}
public function failed(\Throwable $exception): void
{
// Notify team of failure
}
}
$request->validated().php artisan test
./vendor/bin/pest
./vendor/bin/pest tests/Feature/UserTest.php
./vendor/bin/pest --filter "creates a user"
php artisan test --parallel
./vendor/bin/pint
./vendor/bin/pint --test
./vendor/bin/phpstan analyse
tools
Package one plan execution packet into a compact ticket-local execution packet with parent refs, scope fences, feature-home ownership, and evidence commands. Use when converting plans into local tickets or when execution needs one ticket-sized context pack without the full plan.
tools
Package one plan execution packet into a compact ticket-local execution packet with parent refs, scope fences, feature-home ownership, and evidence commands. Use when converting plans into local tickets or when execution needs one ticket-sized context pack without the full plan.
testing
Run a deep adversarial review of plans and architecture before implementation. Use when validating strategy docs, contracts, roadmaps, and competitive positioning with scored findings and prioritized recommendations.
testing
Run a deep adversarial review of plans and architecture before implementation. Use when validating strategy docs, contracts, roadmaps, and competitive positioning with scored findings and prioritized recommendations.