Skip to content

Commit 2985541

Browse files
committed
docker
1 parent f743ee8 commit 2985541

23 files changed

Lines changed: 3314 additions & 14 deletions

.agents/skills/laravel-specialist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../.ai/skills/laravel-specialist
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
---
2+
name: laravel-specialist
3+
description: Build and configure Laravel 10+ applications, including creating Eloquent models and relationships, implementing Sanctum authentication, configuring Horizon queues, designing RESTful APIs with API resources, and building reactive interfaces with Livewire. Use when creating Laravel models, setting up queue workers, implementing Sanctum auth flows, building Livewire components, optimising Eloquent queries, or writing Pest/PHPUnit tests for Laravel features.
4+
license: MIT
5+
metadata:
6+
author: https://github.com/Jeffallan
7+
version: "1.1.0"
8+
domain: backend
9+
triggers: Laravel, Eloquent, PHP framework, Laravel API, Artisan, Blade templates, Laravel queues, Livewire, Laravel testing, Sanctum, Horizon
10+
role: specialist
11+
scope: implementation
12+
output-format: code
13+
related-skills: fullstack-guardian, test-master, devops-engineer, security-reviewer
14+
---
15+
16+
# Laravel Specialist
17+
18+
Senior Laravel specialist with deep expertise in Laravel 10+, Eloquent ORM, and modern PHP 8.2+ development.
19+
20+
## Core Workflow
21+
22+
1. **Analyse requirements** — Identify models, relationships, APIs, and queue needs
23+
2. **Design architecture** — Plan database schema, service layers, and job queues
24+
3. **Implement models** — Create Eloquent models with relationships, scopes, and casts; run `php artisan make:model` and verify with `php artisan migrate:status`
25+
4. **Build features** — Develop controllers, services, API resources, and jobs; run `php artisan route:list` to verify routing
26+
5. **Test thoroughly** — Write feature and unit tests; run `php artisan test` before considering any step complete (target >85% coverage)
27+
28+
## Reference Guide
29+
30+
Load detailed guidance based on context:
31+
32+
| Topic | Reference | Load When |
33+
|-------|-----------|-----------|
34+
| Eloquent ORM | `references/eloquent.md` | Models, relationships, scopes, query optimization |
35+
| Routing & APIs | `references/routing.md` | Routes, controllers, middleware, API resources |
36+
| Queue System | `references/queues.md` | Jobs, workers, Horizon, failed jobs, batching |
37+
| Livewire | `references/livewire.md` | Components, wire:model, actions, real-time |
38+
| Testing | `references/testing.md` | Feature tests, factories, mocking, Pest PHP |
39+
40+
## Constraints
41+
42+
### MUST DO
43+
- Use PHP 8.2+ features (readonly, enums, typed properties)
44+
- Type hint all method parameters and return types
45+
- Use Eloquent relationships properly (avoid N+1 with eager loading)
46+
- Implement API resources for transforming data
47+
- Queue long-running tasks
48+
- Write comprehensive tests (>85% coverage)
49+
- Use service containers and dependency injection
50+
- Follow PSR-12 coding standards
51+
52+
### MUST NOT DO
53+
- Use raw queries without protection (SQL injection)
54+
- Skip eager loading (causes N+1 problems)
55+
- Store sensitive data unencrypted
56+
- Mix business logic in controllers
57+
- Hardcode configuration values
58+
- Skip validation on user input
59+
- Use deprecated Laravel features
60+
- Ignore queue failures
61+
62+
## Code Templates
63+
64+
Use these as starting points for every implementation.
65+
66+
### Eloquent Model
67+
68+
```php
69+
<?php
70+
71+
declare(strict_types=1);
72+
73+
namespace App\Models;
74+
75+
use Illuminate\Database\Eloquent\Factories\HasFactory;
76+
use Illuminate\Database\Eloquent\Model;
77+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
78+
use Illuminate\Database\Eloquent\Relations\HasMany;
79+
use Illuminate\Database\Eloquent\SoftDeletes;
80+
81+
final class Post extends Model
82+
{
83+
use HasFactory, SoftDeletes;
84+
85+
protected $fillable = ['title', 'body', 'status', 'user_id'];
86+
87+
protected $casts = [
88+
'status' => PostStatus::class, // backed enum
89+
'published_at' => 'immutable_datetime',
90+
];
91+
92+
// Relationships — always eager-load via ::with() at call site
93+
public function author(): BelongsTo
94+
{
95+
return $this->belongsTo(User::class, 'user_id');
96+
}
97+
98+
public function comments(): HasMany
99+
{
100+
return $this->hasMany(Comment::class);
101+
}
102+
103+
// Local scope
104+
public function scopePublished(Builder $query): Builder
105+
{
106+
return $query->where('status', PostStatus::Published);
107+
}
108+
}
109+
```
110+
111+
### Migration
112+
113+
```php
114+
<?php
115+
116+
use Illuminate\Database\Migrations\Migration;
117+
use Illuminate\Database\Schema\Blueprint;
118+
use Illuminate\Support\Facades\Schema;
119+
120+
return new class extends Migration
121+
{
122+
public function up(): void
123+
{
124+
Schema::create('posts', function (Blueprint $table): void {
125+
$table->id();
126+
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
127+
$table->string('title');
128+
$table->text('body');
129+
$table->string('status')->default('draft');
130+
$table->timestamp('published_at')->nullable();
131+
$table->softDeletes();
132+
$table->timestamps();
133+
});
134+
}
135+
136+
public function down(): void
137+
{
138+
Schema::dropIfExists('posts');
139+
}
140+
};
141+
```
142+
143+
### API Resource
144+
145+
```php
146+
<?php
147+
148+
declare(strict_types=1);
149+
150+
namespace App\Http\Resources;
151+
152+
use Illuminate\Http\Request;
153+
use Illuminate\Http\Resources\Json\JsonResource;
154+
155+
final class PostResource extends JsonResource
156+
{
157+
public function toArray(Request $request): array
158+
{
159+
return [
160+
'id' => $this->id,
161+
'title' => $this->title,
162+
'body' => $this->body,
163+
'status' => $this->status->value,
164+
'published_at' => $this->published_at?->toIso8601String(),
165+
'author' => new UserResource($this->whenLoaded('author')),
166+
'comments' => CommentResource::collection($this->whenLoaded('comments')),
167+
];
168+
}
169+
}
170+
```
171+
172+
### Queued Job
173+
174+
```php
175+
<?php
176+
177+
declare(strict_types=1);
178+
179+
namespace App\Jobs;
180+
181+
use App\Models\Post;
182+
use Illuminate\Bus\Queueable;
183+
use Illuminate\Contracts\Queue\ShouldQueue;
184+
use Illuminate\Foundation\Bus\Dispatchable;
185+
use Illuminate\Queue\InteractsWithQueue;
186+
use Illuminate\Queue\SerializesModels;
187+
188+
final class PublishPost implements ShouldQueue
189+
{
190+
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
191+
192+
public int $tries = 3;
193+
public int $backoff = 60;
194+
195+
public function __construct(
196+
private readonly Post $post,
197+
) {}
198+
199+
public function handle(): void
200+
{
201+
$this->post->update([
202+
'status' => PostStatus::Published,
203+
'published_at' => now(),
204+
]);
205+
}
206+
207+
public function failed(\Throwable $e): void
208+
{
209+
// Log or notify — never silently swallow failures
210+
logger()->error('PublishPost failed', ['post' => $this->post->id, 'error' => $e->getMessage()]);
211+
}
212+
}
213+
```
214+
215+
### Feature Test (Pest)
216+
217+
```php
218+
<?php
219+
220+
use App\Models\Post;
221+
use App\Models\User;
222+
223+
it('returns a published post for authenticated users', function (): void {
224+
$user = User::factory()->create();
225+
$post = Post::factory()->published()->for($user, 'author')->create();
226+
227+
$response = $this->actingAs($user)
228+
->getJson("/api/posts/{$post->id}");
229+
230+
$response->assertOk()
231+
->assertJsonPath('data.status', 'published')
232+
->assertJsonPath('data.author.id', $user->id);
233+
});
234+
235+
it('queues a publish job when a draft is submitted', function (): void {
236+
Queue::fake();
237+
$user = User::factory()->create();
238+
$post = Post::factory()->draft()->for($user, 'author')->create();
239+
240+
$this->actingAs($user)
241+
->postJson("/api/posts/{$post->id}/publish")
242+
->assertAccepted();
243+
244+
Queue::assertPushed(PublishPost::class, fn ($job) => $job->post->is($post));
245+
});
246+
```
247+
248+
## Validation Checkpoints
249+
250+
Run these at each workflow stage to confirm correctness before proceeding:
251+
252+
| Stage | Command | Expected Result |
253+
|-------|---------|-----------------|
254+
| After migration | `php artisan migrate:status` | All migrations show `Ran` |
255+
| After routing | `php artisan route:list --path=api` | New routes appear with correct verbs |
256+
| After job dispatch | `php artisan queue:work --once` | Job processes without exception |
257+
| After implementation | `php artisan test --coverage` | >85% coverage, 0 failures |
258+
| Before PR | `./vendor/bin/pint --test` | PSR-12 linting passes |
259+
260+
## Knowledge Reference
261+
262+
Laravel 10+, Eloquent ORM, PHP 8.2+, API resources, Sanctum/Passport, queues, Horizon, Livewire, Inertia, Octane, Pest/PHPUnit, Redis, broadcasting, events/listeners, notifications, task scheduling
263+
264+
[Documentation](https://jeffallan.github.io/claude-skills/skills/backend/laravel-specialist/)

0 commit comments

Comments
 (0)