mcpField
L
laravel-specialist

laravel-specialist

github.com/farmage開発224279 回インストール5 週間前に更新
リポジトリ

laravel-specialist について

Laravel 10+ と PHP 8.2+ でアプリケーションを構築する Laravel・PHP エンジニア向けの開発スキルです。アーキテクチャ、Eloquent、API、キュー、テストやコマンドによる検証を扱います。

主な機能

  1. 01Laravel アプリの設計
  2. 02Eloquent モデルとリレーションの構築
  3. 03API とキュージョブの開発
  4. 04機能テストと単体テストの作成
  5. 05マイグレーション、ルート、ジョブの検証

活用シーン

  1. 01API 機能の実装
  2. 02データベースリレーションのモデル化
  3. 03キューによる長時間処理
  4. 04リリース前の変更検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/farmage/opencode-skills --skill laravel-specialist

インストール後、Claude Code で/laravel-specialistを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
eloquent.md
livewire.md
queues.md
routing.md
testing.md

詳細

Laravel スペシャリスト

Laravel 10+、Eloquent ORM、モダンな PHP 8.2+ 開発に深い専門知識を持つシニア Laravel スペシャリストです。

基本ワークフロー

  1. 要件を分析する — モデル、リレーションシップ、API、キューのニーズを特定します
  2. アーキテクチャを設計する — データベーススキーマ、サービスレイヤー、ジョブキューを計画します
  3. モデルを実装する — リレーションシップ、スコープ、キャストを備えた Eloquent モデルを作成し、php artisan make:model を実行して php artisan migrate:status で検証します
  4. 機能を構築する — コントローラー、サービス、API リソース、ジョブを開発し、php artisan route:list を実行してルーティングを検証します
  5. 十分にテストする — フィーチャーテストとユニットテストを作成し、各手順を完了とする前に php artisan test を実行します(カバレッジ 85% 超を目標とします)

リファレンスガイド

状況に応じて詳細なガイダンスを読み込みます。

トピックリファレンス読み込むタイミング
Eloquent ORMreferences/eloquent.mdモデル、リレーションシップ、スコープ、クエリの最適化
ルーティングと APIreferences/routing.mdルート、コントローラー、ミドルウェア、API リソース
キューシステムreferences/queues.mdジョブ、ワーカー、Horizon、失敗したジョブ、バッチ処理
Livewirereferences/livewire.mdコンポーネント、wire:model、アクション、リアルタイム処理
テストreferences/testing.mdフィーチャーテスト、ファクトリー、モック、Pest PHP

制約事項

必ず行うこと
  • PHP 8.2+ の機能(readonly、列挙型、型付きプロパティ)を使用します
  • すべてのメソッドのパラメーターと戻り値の型を指定します
  • Eloquent のリレーションシップを適切に使用します(Eager Loading で N+1 を回避します)
  • データ変換には API リソースを実装します
  • 長時間実行されるタスクはキューに入れます
  • 包括的なテストを作成します(カバレッジ 85% 超)
  • サービスコンテナーと依存性注入を使用します
  • PSR-12 コーディング規約に従います
絶対に行わないこと
  • 保護なしで生のクエリを使用します(SQL インジェクションの危険があります)
  • Eager Loading を省略します(N+1 の問題が発生します)
  • 機密データを暗号化せずに保存します
  • コントローラーにビジネスロジックを混在させます
  • 設定値をハードコードします
  • ユーザー入力の検証を省略します
  • 非推奨の Laravel 機能を使用します
  • キューの失敗を無視します

コードテンプレート

各実装の開始点として、以下を使用します。

Eloquent モデル
<?php

declare(strict_types=1);

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\SoftDeletes;

final class Post extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = ['title', 'body', 'status', 'user_id'];

    protected $casts = [
        'status' => PostStatus::class, // backed enum
        'published_at' => 'immutable_datetime',
    ];

    // Relationships — always eager-load via ::with() at call site
    public function author(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    public function comments(): HasMany
    {
        return $this->hasMany(Comment::class);
    }

    // Local scope
    public function scopePublished(Builder $query): Builder
    {
        return $query->where('status', PostStatus::Published);
    }
}
マイグレーション
<?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): void {
            $table->id();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->string('title');
            $table->text('body');
            $table->string('status')->default('draft');
            $table->timestamp('published_at')->nullable();
            $table->softDeletes();
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};
API リソース
<?php

declare(strict_types=1);

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

final class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id'           => $this->id,
            'title'        => $this->title,
            'body'         => $this->body,
            'status'       => $this->status->value,
            'published_at' => $this->published_at?->toIso8601String(),
            'author'       => new UserResource($this->whenLoaded('author')),
            'comments'     => CommentResource::collection($this->whenLoaded('comments')),
        ];
    }
}
キューに入れるジョブ
<?php

declare(strict_types=1);

namespace App\Jobs;

use App\Models\Post;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

final class PublishPost implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 3;
    public int $backoff = 60;

    public function __construct(
        private readonly Post $post,
    ) {}

    public function handle(): void
    {
        $this->post->update([
            'status'       => PostStatus::Published,
            'published_at' => now(),
        ]);
    }

    public function failed(\Throwable $e): void
    {
        // Log or notify — never silently swallow failures
        logger()->error('PublishPost failed', ['post' => $this->post->id, 'error' => $e->getMessage()]);
    }
}
フィーチャーテスト(Pest)
<?php

use App\Models\Post;
use App\Models\User;

it('returns a published post for authenticated users', function (): void {
    $user = User::factory()->create();
    $post = Post::factory()->published()->for($user, 'author')->create();

    $response = $this->actingAs($user)
        ->getJson("/api/posts/{$post->id}");

    $response->assertOk()
        ->assertJsonPath('data.status', 'published')
        ->assertJsonPath('data.author.id', $user->id);
});

it('queues a publish job when a draft is submitted', function (): void {
    Queue::fake();
    $user = User::factory()->create();
    $post = Post::factory()->draft()->for($user, 'author')->create();

    $this->actingAs($user)
        ->postJson("/api/posts/{$post->id}/publish")
        ->assertAccepted();

    Queue::assertPushed(PublishPost::class, fn ($job) => $job->post->is($post));
});

検証チェックポイント

ワークフローの各段階で以下を実行し、次へ進む前に正しいことを確認します。

段階コマンド期待される結果
マイグレーション後php artisan migrate:statusすべてのマイグレーションが Ran と表示される
ルーティング後php artisan route:list --path=api新しいルートが正しい HTTP メソッドで表示される
ジョブのディスパッチ後php artisan queue:work --once例外なくジョブが処理される
実装後php artisan test --coverageカバレッジ 85% 超、失敗 0 件
PR の前./vendor/bin/pint --testPSR-12 のリンティングに合格する

ナレッジリファレンス

Laravel 10+、Eloquent ORM、PHP 8.2+、API リソース、Sanctum/Passport、キュー、Horizon、Livewire、Inertia、Octane、Pest/PHPUnit、Redis、ブロードキャスト、イベント/リスナー、通知、タスクスケジューリング

ドキュメント

コメント