{"slug":"laravel-ops","title":"laravel-ops","summary":"Laravel framework patterns, Eloquent ORM, authentication, queues, and testing. Use for: laravel, eloquent, artisan, blade, php, sanctum, livewire, inertia, pest, phpunit, forge, vapor, queue, middleware, migration, factory, seeder.","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-09-30T19:36:47.717947Z","repo":{"url":"https://github.com/0xDarkMatter/claude-mods","stars":43,"forks":7,"license":"MIT","updatedAt":"2026-09-30T15:18:48Z"},"bodyHtml":"<hr>\n<h2>name: laravel-ops\ndescription: \"Laravel framework patterns, Eloquent ORM, authentication, queues, and testing. Use for: laravel, eloquent, artisan, blade, php, sanctum, livewire, inertia, pest, phpunit, forge, vapor, queue, middleware, migration, factory, seeder.\"\nwhen_to_use: \"Use when building Laravel 11+ apps — e.g. 'write an Eloquent query or migration', 'set up Sanctum auth', 'configure queues and jobs', 'test with Pest or PHPUnit'. Covers artisan, Blade, Livewire/Inertia, Forge/Vapor, factories, and seeders.\"\nlicense: MIT\nallowed-tools: \"Read Write Bash\"\nmetadata:\nauthor: claude-mods\nrelated-skills: sql-ops, postgres-ops, testing-ops, docker-ops</h2>\n<h1>Laravel Operations</h1>\n<blockquote>\n<p>Facts verified as of 2026-07.</p>\n</blockquote>\n<p>Authoritative reference for Laravel 11+ development: architecture decisions, Eloquent patterns, authentication strategies, queue configuration, and testing approaches.</p>\n<hr>\n<h2>Architecture Decision Tree</h2>\n<pre><code>What type of application?\n│\n├─ Full-stack web (HTML responses)\n│  ├─ Simple CRUD, small team → Monolith (Blade + Eloquent directly)\n│  │   └─ Use action classes for business logic over 20 lines\n│  ├─ Rich interactivity needed → Livewire (server-driven reactivity)\n│  │   └─ Add Alpine.js for client-side micro-interactions\n│  └─ SPA-like feel, React/Vue team → Inertia.js\n│      └─ Keep server-side routing, dump client-side routing overhead\n│\n├─ API backend (JSON responses)\n│  ├─ Single consumer (mobile/SPA) → API-only with Sanctum SPA auth\n│  ├─ Multiple consumers / public → RESTful API with token auth\n│  └─ Complex graph queries → Consider GraphQL (lighthouse-php/lighthouse)\n│\n├─ Large team / complex domain\n│  ├─ Domain-driven → Modular monolith (app/Modules/{Domain}/)\n│  │   ├─ Each module: Models, Actions, Events, Jobs, Http/\n│  │   └─ Shared: app/Shared/ for cross-cutting concerns\n│  └─ Independent deployability needed → Microservices\n│      └─ Use Laravel Octane for high-throughput services\n│\n└─ What business logic pattern?\n   ├─ Simple CRUD, &lt; 20 lines → Direct Eloquent in controller\n   ├─ Reusable operation (create order, send invoice) → Action class\n   │   └─ Single public handle() or execute() method\n   ├─ Complex queries, multiple data sources → Repository pattern\n   │   └─ Interface + Eloquent implementation (enables swapping)\n   └─ Cross-cutting operations (audit, caching) → Service class\n       └─ Inject via constructor, bind in ServiceProvider\n</code></pre>\n<h3>Action Class vs Repository vs Service</h3>\n<table>\n<thead>\n<tr>\n<th>Pattern</th>\n<th>Use When</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Action class</td>\n<td>Single, reusable business operation</td>\n<td><code>CreateOrderAction</code>, <code>SendInvoiceAction</code></td>\n</tr>\n<tr>\n<td>Repository</td>\n<td>Abstract data access, multiple sources</td>\n<td><code>OrderRepository</code> with <code>EloquentOrderRepository</code></td>\n</tr>\n<tr>\n<td>Service</td>\n<td>Orchestrate multiple actions/repos</td>\n<td><code>OrderService</code> combining payment + inventory</td>\n</tr>\n<tr>\n<td>Direct Eloquent</td>\n<td>Simple CRUD, &lt; 5 lines in controller</td>\n<td><code>User::create($data)</code></td>\n</tr>\n</tbody>\n</table>\n<hr>\n<h2>Eloquent Quick Reference</h2>\n<h3>Relationships</h3>\n<table>\n<thead>\n<tr>\n<th>Relationship</th>\n<th>Method</th>\n<th>Foreign Key Convention</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>hasOne</code></td>\n<td><code>return $this-&gt;hasOne(Profile::class)</code></td>\n<td><code>profiles.user_id</code></td>\n</tr>\n<tr>\n<td><code>hasMany</code></td>\n<td><code>return $this-&gt;hasMany(Post::class)</code></td>\n<td><code>posts.user_id</code></td>\n</tr>\n<tr>\n<td><code>belongsTo</code></td>\n<td><code>return $this-&gt;belongsTo(User::class)</code></td>\n<td><code>posts.user_id</code></td>\n</tr>\n<tr>\n<td><code>belongsToMany</code></td>\n<td><code>return $this-&gt;belongsToMany(Role::class)</code></td>\n<td><code>role_user</code> pivot</td>\n</tr>\n<tr>\n<td><code>hasManyThrough</code></td>\n<td><code>return $this-&gt;hasManyThrough(Post::class, User::class)</code></td>\n<td>Country → User → Post</td>\n</tr>\n<tr>\n<td><code>morphTo</code></td>\n<td><code>return $this-&gt;morphTo()</code></td>\n<td><code>{col}_type</code>, <code>{col}_id</code></td>\n</tr>\n<tr>\n<td><code>morphMany</code></td>\n<td><code>return $this-&gt;morphMany(Comment::class, 'commentable')</code></td>\n<td>Polymorphic</td>\n</tr>\n<tr>\n<td><code>morphToMany</code></td>\n<td><code>return $this-&gt;morphToMany(Tag::class, 'taggable')</code></td>\n<td>Polymorphic pivot</td>\n</tr>\n</tbody>\n</table>\n<h3>Eager Loading</h3>\n<pre><code>// Prevent N+1: always eager load in controllers\n$posts = Post::with(['author', 'comments.author', 'tags'])-&gt;paginate(15);\n\n// Conditional eager loading (load after retrieval)\n$user-&gt;load('posts.comments');\n$user-&gt;loadMissing('posts'); // only if not already loaded\n\n// Eager load counts (no SELECT *)\n$posts = Post::withCount('comments')-&gt;get();\n\n// Constrained eager loading\n$posts = Post::with(['comments' =&gt; fn($q) =&gt; $q-&gt;approved()-&gt;latest()])-&gt;get();\n</code></pre>\n<h3>Query Scopes</h3>\n<pre><code>// Local scope (reusable query constraint)\npublic function scopeActive(Builder $query): void\n{\n    $query-&gt;where('status', 'active');\n}\n\n// Usage: User::active()-&gt;get()\n\n// Dynamic scope\npublic function scopeOfType(Builder $query, string $type): void\n{\n    $query-&gt;where('type', $type);\n}\n// Usage: User::ofType('admin')-&gt;get()\n</code></pre>\n<h3>Mass Assignment</h3>\n<pre><code>// Fillable (allowlist - preferred)\nprotected $fillable = ['name', 'email', 'password'];\n\n// Guarded (denylist - use [] only if you trust all input)\nprotected $guarded = ['id', 'is_admin'];\n\n// Never set guarded = [] in production code\n</code></pre>\n<hr>\n<h2>Artisan Command Cheat Sheet</h2>\n<table>\n<thead>\n<tr>\n<th>Command</th>\n<th>Purpose</th>\n<th>Common Options</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>make:model Post -mfs</code></td>\n<td>Model + migration + factory + seeder</td>\n<td><code>-c</code> controller, <code>-r</code> resource</td>\n</tr>\n<tr>\n<td><code>make:controller PostController -r</code></td>\n<td>Resource controller (7 methods)</td>\n<td><code>--api</code> skips create/edit</td>\n</tr>\n<tr>\n<td><code>make:request StorePostRequest</code></td>\n<td>Form request for validation</td>\n<td></td>\n</tr>\n<tr>\n<td><code>make:job ProcessPayment</code></td>\n<td>Queueable job class</td>\n<td><code>--sync</code> for sync job</td>\n</tr>\n<tr>\n<td><code>make:event OrderPlaced</code></td>\n<td>Event class</td>\n<td></td>\n</tr>\n<tr>\n<td><code>make:listener SendOrderConfirmation -e OrderPlaced</code></td>\n<td>Listener for event</td>\n<td><code>--queued</code></td>\n</tr>\n<tr>\n<td><code>make:notification InvoicePaid</code></td>\n<td>Notification class</td>\n<td></td>\n</tr>\n<tr>\n<td><code>make:policy PostPolicy -m Post</code></td>\n<td>Policy with model</td>\n<td></td>\n</tr>\n<tr>\n<td><code>make:middleware EnsureUserIsAdmin</code></td>\n<td>HTTP middleware</td>\n<td></td>\n</tr>\n<tr>\n<td><code>make:command SendDailyReport</code></td>\n<td>Custom Artisan command</td>\n<td></td>\n</tr>\n<tr>\n<td><code>migrate</code></td>\n<td>Run pending migrations</td>\n<td><code>--step</code> for individual</td>\n</tr>\n<tr>\n<td><code>migrate:rollback</code></td>\n<td>Roll back last batch</td>\n<td><code>--step=5</code></td>\n</tr>\n<tr>\n<td><code>migrate:fresh --seed</code></td>\n<td>Drop all + re-migrate + seed</td>\n<td></td>\n</tr>\n<tr>\n<td><code>db:seed</code></td>\n<td>Run all seeders</td>\n<td><code>--class=UserSeeder</code></td>\n</tr>\n<tr>\n<td><code>tinker</code></td>\n<td>REPL with app context</td>\n<td></td>\n</tr>\n<tr>\n<td><code>route:list</code></td>\n<td>Show all routes</td>\n<td><code>--name=api</code> filter</td>\n</tr>\n<tr>\n<td><code>route:cache</code></td>\n<td>Cache routes for production</td>\n<td></td>\n</tr>\n<tr>\n<td><code>config:cache</code></td>\n<td>Cache config for production</td>\n<td></td>\n</tr>\n<tr>\n<td><code>view:cache</code></td>\n<td>Pre-compile Blade templates</td>\n<td></td>\n</tr>\n<tr>\n<td><code>optimize</code></td>\n<td>Run all cache commands</td>\n<td><code>optimize:clear</code> to reset</td>\n</tr>\n<tr>\n<td><code>queue:work</code></td>\n<td>Process queue jobs</td>\n<td><code>--queue=high,default</code></td>\n</tr>\n<tr>\n<td><code>queue:listen</code></td>\n<td>Work + auto-reload on code change</td>\n<td></td>\n</tr>\n<tr>\n<td><code>queue:failed</code></td>\n<td>List failed jobs</td>\n<td></td>\n</tr>\n<tr>\n<td><code>queue:retry all</code></td>\n<td>Retry all failed jobs</td>\n<td></td>\n</tr>\n<tr>\n<td><code>schedule:run</code></td>\n<td>Run due scheduled tasks</td>\n<td></td>\n</tr>\n<tr>\n<td><code>schedule:work</code></td>\n<td>Run scheduler every minute (dev)</td>\n<td></td>\n</tr>\n<tr>\n<td><code>key:generate</code></td>\n<td>Generate APP_KEY</td>\n<td></td>\n</tr>\n<tr>\n<td><code>test</code></td>\n<td>Run PHPUnit/Pest tests</td>\n<td><code>--filter=UserTest</code></td>\n</tr>\n<tr>\n<td><code>test --parallel</code></td>\n<td>Run tests in parallel</td>\n<td><code>--processes=4</code></td>\n</tr>\n<tr>\n<td><code>vendor:publish</code></td>\n<td>Publish package assets/config</td>\n<td><code>--tag=config</code></td>\n</tr>\n</tbody>\n</table>\n<hr>\n<h2>Authentication Decision Tree</h2>\n<pre><code>What do you need?\n│\n├─ SPA (Vue/React) + Laravel API backend\n│  └─ Sanctum SPA authentication\n│     ├─ Cookie-based (same domain or subdomain)\n│     ├─ Csrf-cookie endpoint: GET /sanctum/csrf-cookie\n│     └─ No tokens in localStorage (XSS safe)\n│\n├─ Mobile app or third-party API consumers\n│  └─ Sanctum API tokens (Bearer tokens)\n│     ├─ createToken($name, $abilities)\n│     ├─ Token abilities for fine-grained control\n│     └─ Token expiration with token:prune schedule\n│\n├─ Traditional web app (server-rendered)\n│  ├─ Just need auth pages quickly → Breeze\n│  │   ├─ Minimal, educational, Blade or Inertia stack\n│  │   └─ Install: composer require laravel/breeze --dev\n│  ├─ Need teams, 2FA, profile management → Jetstream\n│  │   ├─ Livewire or Inertia stack\n│  │   └─ Install: composer require laravel/jetstream\n│  └─ Need headless auth (API + custom UI) → Fortify\n│      ├─ Actions in app/Actions/Fortify/\n│      └─ Customize: CreateNewUser, UpdateUserPassword\n│\n└─ Custom / enterprise\n   ├─ LDAP/SAML → socialiteproviders/saml2\n   ├─ OAuth social login → laravel/socialite\n   └─ Custom guard → Implement Guard + UserProvider contracts\n</code></pre>\n<h3>Sanctum Quick Setup</h3>\n<pre><code>// config/sanctum.php - stateful domains for SPA\n'stateful' =&gt; explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost')),\n\n// API token creation\n$token = $user-&gt;createToken('mobile-app', ['orders:read', 'orders:write']);\nreturn ['token' =&gt; $token-&gt;plainTextToken];\n\n// Check token ability\nRoute::get('/orders', function (Request $request) {\n    $request-&gt;user()-&gt;tokenCan('orders:read'); // bool\n});\n\n// Protect routes\nRoute::middleware('auth:sanctum')-&gt;group(function () {\n    // authenticated routes\n});\n</code></pre>\n<hr>\n<h2>Queue Decision Tree</h2>\n<pre><code>Queue driver selection:\n│\n├─ Development / testing\n│  └─ sync driver (executes immediately, no worker needed)\n│     QUEUE_CONNECTION=sync\n│\n├─ Small app, no Redis available\n│  └─ database driver\n│     ├─ php artisan queue:table &amp;&amp; migrate\n│     ├─ Works fine for &lt; 100 jobs/min\n│     └─ QUEUE_CONNECTION=database\n│\n├─ Medium-high throughput, self-hosted\n│  └─ Redis driver (via predis or phpredis)\n│     ├─ QUEUE_CONNECTION=redis\n│     ├─ Laravel Horizon for monitoring\n│     └─ Supports priorities, pausing, metrics\n│\n└─ AWS infrastructure / massive scale\n   └─ SQS driver\n      ├─ QUEUE_CONNECTION=sqs\n      ├─ Managed, auto-scaling\n      └─ Use with Laravel Vapor for serverless\n</code></pre>\n<h3>Job Patterns</h3>\n<pre><code>// Basic job dispatch\nProcessPayment::dispatch($order);\nProcessPayment::dispatch($order)-&gt;onQueue('payments')-&gt;delay(now()-&gt;addMinutes(5));\n\n// Chaining (sequential)\nBus::chain([\n    new ProcessPayment($order),\n    new SendInvoice($order),\n    new UpdateInventory($order),\n])-&gt;dispatch();\n\n// Batching (parallel + callback)\n$batch = Bus::batch([\n    new ImportRow($row1),\n    new ImportRow($row2),\n    new ImportRow($row3),\n])-&gt;then(fn(Batch $batch) =&gt; ImportComplete::dispatch())\n  -&gt;catch(fn(Batch $batch, Throwable $e) =&gt; Log::error($e))\n  -&gt;dispatch();\n\n// Rate limiting (throttle to 5 per minute)\npublic function middleware(): array\n{\n    return [new RateLimited('payments')];\n}\n\n// Unique jobs (prevent duplicate processing)\nuse Illuminate\\Contracts\\Queue\\ShouldBeUnique;\n\nclass ProcessPayment implements ShouldQueue, ShouldBeUnique\n{\n    public string $uniqueId =&gt; $this-&gt;order-&gt;id;\n    public int $uniqueFor = 3600; // seconds\n}\n\n// Retry configuration\npublic int $tries = 3;\npublic int $backoff = 60; // seconds between retries\n\npublic function retryUntil(): DateTime\n{\n    return now()-&gt;addHours(24);\n}\n</code></pre>\n<h3>Task Scheduling</h3>\n<pre><code>// routes/console.php (Laravel 11+)\nSchedule::job(SendDailyReport::class)-&gt;dailyAt('08:00')-&gt;timezone('America/New_York');\nSchedule::command('backup:run')-&gt;daily()-&gt;runInBackground()-&gt;emailOutputOnFailure('ops@app.com');\nSchedule::call(fn() =&gt; Cache::flush())-&gt;weekly()-&gt;sundays()-&gt;at('00:00');\n\n// Prevent overlap (long-running tasks)\nSchedule::job(ProcessImport::class)-&gt;everyFiveMinutes()-&gt;withoutOverlapping();\n\n// Run on one server only (requires Redis/database cache driver)\nSchedule::job(SendNewsletters::class)-&gt;daily()-&gt;onOneServer();\n</code></pre>\n<hr>\n<h2>Testing Quick Reference</h2>\n<h3>Test Types</h3>\n<table>\n<thead>\n<tr>\n<th>Type</th>\n<th>Class extends</th>\n<th>Database</th>\n<th>Purpose</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Feature test</td>\n<td><code>Tests\\TestCase</code></td>\n<td>Yes (with trait)</td>\n<td>HTTP endpoints, full stack</td>\n</tr>\n<tr>\n<td>Unit test</td>\n<td><code>PHPUnit\\Framework\\TestCase</code></td>\n<td>No</td>\n<td>Pure logic, no app boot</td>\n</tr>\n<tr>\n<td>Browser test</td>\n<td><code>Laravel\\Dusk\\TestCase</code></td>\n<td>Yes</td>\n<td>Real browser via ChromeDriver</td>\n</tr>\n</tbody>\n</table>\n<h3>Database Traits</h3>\n<pre><code>use Illuminate\\Foundation\\Testing\\RefreshDatabase;   // migrate fresh each test (slower)\nuse Illuminate\\Foundation\\Testing\\DatabaseTransactions; // rollback each test (faster)\n</code></pre>\n<h3>Pest Syntax (preferred in Laravel 11+)</h3>\n<pre><code>describe('User authentication', function () {\n    beforeEach(function () {\n        $this-&gt;user = User::factory()-&gt;create();\n    });\n\n    it('allows login with valid credentials', function () {\n        $response = $this-&gt;post('/login', [\n            'email' =&gt; $this-&gt;user-&gt;email,\n            'password' =&gt; 'password',\n        ]);\n\n        $response-&gt;assertRedirect('/dashboard');\n        $this-&gt;assertAuthenticatedAs($this-&gt;user);\n    });\n\n    it('rejects invalid credentials')-&gt;todo();\n});\n</code></pre>\n<h3>Common Assertions</h3>\n<pre><code>// HTTP response\n$response-&gt;assertStatus(200);\n$response-&gt;assertOk();             // 200\n$response-&gt;assertCreated();        // 201\n$response-&gt;assertNoContent();      // 204\n$response-&gt;assertUnauthorized();   // 401\n$response-&gt;assertForbidden();      // 403\n$response-&gt;assertNotFound();       // 404\n$response-&gt;assertRedirect('/home');\n\n// JSON responses\n$response-&gt;assertJson(['status' =&gt; 'ok']);\n$response-&gt;assertJsonPath('data.email', 'user@example.com');\n$response-&gt;assertJsonCount(3, 'data');\n$response-&gt;assertJsonStructure(['data' =&gt; ['id', 'name', 'email']]);\n$response-&gt;assertJsonMissing(['password']);\n\n// Database\n$this-&gt;assertDatabaseHas('users', ['email' =&gt; 'user@example.com']);\n$this-&gt;assertDatabaseMissing('users', ['email' =&gt; 'deleted@example.com']);\n$this-&gt;assertDatabaseCount('posts', 5);\n$this-&gt;assertSoftDeleted('posts', ['id' =&gt; $post-&gt;id]);\n</code></pre>\n<hr>\n<h2>Common Gotchas</h2>\n<table>\n<thead>\n<tr>\n<th>Gotcha</th>\n<th>Why</th>\n<th>Fix</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>N+1 queries on relationships</td>\n<td>Eloquent lazy-loads by default</td>\n<td>Use <code>with()</code> eager loading; enable <code>Model::preventLazyLoading()</code> in AppServiceProvider during development</td>\n</tr>\n<tr>\n<td>Mass assignment vulnerability</td>\n<td><code>$fillable = []</code> accepts all</td>\n<td>Always define <code>$fillable</code>; never use <code>$guarded = []</code> in production</td>\n</tr>\n<tr>\n<td><code>created_at</code> not updating on <code>update()</code></td>\n<td>Only <code>updated_at</code> auto-sets</td>\n<td>Use <code>$model-&gt;touch()</code> or <code>timestamps = true</code> (default)</td>\n</tr>\n<tr>\n<td>Queue job fails on model serialization</td>\n<td>Model state may change between dispatch and processing</td>\n<td>Use <code>SerializesModels</code> trait; re-fetch from DB in <code>handle()</code> if needed</td>\n</tr>\n<tr>\n<td>Timezone mismatch in scheduled tasks</td>\n<td>Server tz != app tz</td>\n<td>Set <code>APP_TIMEZONE</code> in <code>.env</code>; use <code>-&gt;timezone()</code> on schedule entries</td>\n</tr>\n<tr>\n<td>Middleware order matters</td>\n<td>Auth middleware must run before policies</td>\n<td>Global → route group → route. Auth before throttle check or vice versa changes 401 vs 429</td>\n</tr>\n<tr>\n<td>Route model binding skips soft-deleted records</td>\n<td><code>RouteServiceProvider</code> ignores <code>trashed()</code></td>\n<td>Extend binding: <code>Route::bind('post', fn($id) =&gt; Post::withTrashed()-&gt;findOrFail($id))</code></td>\n</tr>\n<tr>\n<td>Service container binding not auto-resolved</td>\n<td>Interface not bound to implementation</td>\n<td>Register in <code>AppServiceProvider::register()</code>: <code>$this-&gt;app-&gt;bind(Interface::class, Implementation::class)</code></td>\n</tr>\n<tr>\n<td>Migration foreign key order</td>\n<td>Must create referenced table first</td>\n<td>Run <code>migrate:fresh</code> to verify; use <code>Schema::disableForeignKeyConstraints()</code> in tests</td>\n</tr>\n<tr>\n<td>CSRF protection blocks API routes</td>\n<td><code>VerifyCsrfToken</code> runs on all web routes</td>\n<td>Register API routes in <code>routes/api.php</code> (uses <code>api</code> middleware group without CSRF)</td>\n</tr>\n<tr>\n<td><code>env()</code> returns null after caching</td>\n<td><code>config:cache</code> bakes env values</td>\n<td>Always access env via <code>config()</code> helper in app code; only use <code>env()</code> in <code>config/</code> files</td>\n</tr>\n<tr>\n<td>Blade <code>@stack</code> renders in wrong order</td>\n<td><code>@push</code> must appear after <code>@stack</code> in execution</td>\n<td>Use <code>@prepend</code> for scripts that must appear first</td>\n</tr>\n<tr>\n<td>Event listener not firing</td>\n<td>Listener not registered or discovered</td>\n<td>Check <code>EventServiceProvider::$listen</code>; or enable <code>Event::discover()</code> in Laravel 11</td>\n</tr>\n</tbody>\n</table>\n<hr>\n<h2>Reference Files</h2>\n<table>\n<thead>\n<tr>\n<th>File</th>\n<th>Contents</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>references/eloquent-queries.md</code></td>\n<td>Deep-dive: relationships, query builder, scopes, accessors, mutators, events, soft deletes, pagination, performance, collections, factories</td>\n</tr>\n<tr>\n<td><code>references/architecture.md</code></td>\n<td>Service container, providers, facades, middleware, events, notifications, jobs, scheduling, Blade components, Livewire, Inertia</td>\n</tr>\n<tr>\n<td><code>references/testing-auth.md</code></td>\n<td>PHPUnit/Pest setup, HTTP tests, database testing, fakes, Sanctum, Fortify, policies, form requests, Dusk</td>\n</tr>\n</tbody>\n</table>\n<hr>\n<h2>See Also</h2>\n<ul>\n<li><code>sql-ops</code> - Query optimization, indexing strategy, raw SQL patterns</li>\n<li><code>postgres-ops</code> - PostgreSQL-specific features, JSON columns, full-text search</li>\n<li><code>testing-ops</code> - General testing philosophy, TDD, CI integration</li>\n<li><code>docker-ops</code> - Containerizing Laravel apps, Docker Compose, production setup</li>\n</ul>\n<h3>Key External Resources</h3>\n<ul>\n<li><a href=\"https://laravel.com/docs/11.x\">Laravel 11 Documentation</a></li>\n<li><a href=\"https://pestphp.com/\">Pest PHP</a></li>\n<li><a href=\"https://laravel.com/docs/11.x/horizon\">Laravel Horizon</a> - Queue monitoring</li>\n<li><a href=\"https://laravel.com/docs/11.x/telescope\">Laravel Telescope</a> - Local debugging and request/query monitoring</li>\n<li><a href=\"https://laravel.com/docs/11.x/octane\">Laravel Octane</a> - High-performance serving</li>\n<li><a href=\"https://forge.laravel.com/\">Laravel Forge</a> - Server management</li>\n<li><a href=\"https://vapor.laravel.com/\">Laravel Vapor</a> - Serverless deployment</li>\n</ul>\n","files":[{"path":"assets/.gitkeep","sizeBytes":0,"isText":false},{"path":"references/architecture.md","sizeBytes":24782,"isText":true},{"path":"references/eloquent-queries.md","sizeBytes":21248,"isText":true},{"path":"references/testing-auth.md","sizeBytes":27753,"isText":true},{"path":"scripts/.gitkeep","sizeBytes":0,"isText":false},{"path":"SKILL.md","sizeBytes":16960,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"notes-only","suspicious":0,"notes":2,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-09-30T19:37:58.789829Z","sha256":"8005A7842D8F8C9CE4B8CB14175F26DCB4A27DB8566C35E3ACE1F4A3BB1849EC","sizeBytes":31221},"review":null,"source":{"repositoryUrl":"https://github.com/0xDarkMatter/claude-mods","path":"skills/laravel-ops","license":"MIT","commit":"3dfaf0ba5753026a99ee13f9d9ed56b9793bb6e8","subtreeSha":"427C04A322B132102D4BA704330BF82A009C9881E03F6BFCFDA26247A902E1D9","lastSyncedAt":"2026-09-30T19:37:28.226022Z"},"reviewedAt":"2026-09-30T19:39:57.773352Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/0xDarkMatter/claude-mods/tree/main/skills/laravel-ops"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install 0xdarkmatter-claude-mods@llmmart"},{"target":"git","command":"git clone https://github.com/0xDarkMatter/claude-mods.git"}]}