composer lock fix
linter / quality (pull_request) Failing after 1m7s
tests / ci (8.4) (pull_request) Successful in 1m27s

This commit is contained in:
2026-04-13 19:14:35 +02:00
parent b63906caf9
commit 5ecdc02a4c
16 changed files with 273 additions and 302 deletions
@@ -94,7 +94,7 @@ Check sibling files, related controllers, models, or tests for established patte
### 9. Queue & Job Patterns → `rules/queue-jobs.md`
- `retry_after` must exceed job `timeout`; use exponential backoff `[1, 5, 10]`
- `ShouldBeUnique` to prevent duplicates; `WithoutOverlapping::untilProcessing()` for concurrency
- `ShouldBeUnique` to prevent duplicates; `ShouldBeUniqueUntilProcessing` for early lock release
- Always implement `failed()`; with `retryUntil()`, set `$tries = 0`
- `RateLimited` middleware for external API calls; `Bus::batch()` for related jobs
- Horizon for complex multi-queue scenarios
@@ -82,7 +82,7 @@ $this->app->bind(PaymentGateway::class, StripeGateway::class);
## Default Sort by Descending
When no explicit order is specified, sort by `id` or `created_at` descending. Explicit ordering prevents cross-database inconsistencies between MySQL and Postgres.
When no explicit order is specified, sort by `id` or `created_at` descending. Without an explicit `ORDER BY`, row order is undefined.
Incorrect:
```php
@@ -2,7 +2,7 @@
## Use `Cache::remember()` Instead of Manual Get/Put
Atomic pattern prevents race conditions and removes boilerplate.
Cleaner cache-aside pattern that removes boilerplate. use `Cache::lock()` for race conditions.
Incorrect:
```php
@@ -2,7 +2,7 @@
## `env()` Only in Config Files
Direct `env()` calls return `null` when config is cached.
Direct `env()` calls may return `null` when config is cached.
Incorrect:
```php
@@ -29,7 +29,11 @@ class InvoicePaid extends Notification implements ShouldQueue
## Use `afterCommit()` on Notifications in Transactions
Same race condition as events — the queued notification job may run before the transaction commits.
Same race condition as events — call `afterCommit()` to delay dispatch until the transaction commits.
```php
$user->notify((new InvoicePaid($invoice))->afterCommit());
```
## Route Notification Channels to Dedicated Queues
@@ -52,7 +52,7 @@ $response = Http::retry([100, 500, 1000])
Only retry on specific errors:
```php
$response = Http::retry(3, 100, function (Exception $exception, PendingRequest $request) {
$response = Http::retry(3, 100, function (Throwable $exception, PendingRequest $request) {
return $exception instanceof ConnectionException
|| ($exception instanceof RequestException && $exception->response->serverError());
})->post('https://api.example.com/data');
@@ -10,7 +10,7 @@ A queued mailable dispatched inside a transaction may process before the commit.
## Use `assertQueued()` Not `assertSent()` for Queued Mailables
`Mail::assertSent()` only catches synchronous mail. Queued mailables silently pass `assertSent`, giving false confidence.
`Mail::assertSent()` only catches synchronous mail. Queued mailables fail `assertSent` with a "Did you mean to use assertQueued()?" hint.
Incorrect: `Mail::assertSent(OrderShipped::class);` when mailable implements `ShouldQueue`.
@@ -106,25 +106,23 @@ When using time-based retry limits, set `$tries = 0` to avoid premature failure.
```php
public $tries = 0;
public function retryUntil(): DateTime
public function retryUntil(): \DateTimeInterface
{
return now()->addHours(4);
}
```
## Use `WithoutOverlapping::untilProcessing()`
## Use `ShouldBeUniqueUntilProcessing` for Early Lock Release
Prevents concurrent execution while allowing new instances to queue.
`ShouldBeUnique` holds the lock until the job completes. `ShouldBeUniqueUntilProcessing` releases it when processing starts, allowing new instances to queue.
```php
public function middleware(): array
class UpdateSearchIndex implements ShouldQueue, ShouldBeUniqueUntilProcessing
{
return [new WithoutOverlapping($this->product->id)->untilProcessing()];
// Lock releases when processing begins, not when it finishes
}
```
Without `untilProcessing()`, the lock extends through queue wait time. With it, the lock releases when processing starts.
## Use Horizon for Complex Queue Scenarios
Use Laravel Horizon when you need monitoring, auto-scaling, failure tracking, or multiple queues with different priorities.
@@ -36,7 +36,8 @@ Use `Route::resource()` or `apiResource()` for RESTful endpoints.
```php
Route::resource('posts', PostController::class);
Route::apiResource('api/posts', Api\PostController::class);
// In routes/api.php — the /api prefix is applied automatically
Route::apiResource('posts', Api\PostController::class);
```
## Keep Controllers Thin
@@ -32,7 +32,7 @@ Use policies or gates in controllers. Never skip authorization.
Incorrect:
```php
public function update(Request $request, Post $post)
public function update(UpdatePostRequest $request, Post $post)
{
$post->update($request->validated());
}
@@ -90,7 +90,7 @@ Correct:
## CSRF Protection
Include `@csrf` in all POST/PUT/DELETE Blade forms. Not needed in Inertia.
Include `@csrf` in all POST/PUT/DELETE Blade forms. In Inertia apps, the `@csrf` directive is automatically applied.
Incorrect:
```blade
@@ -121,7 +121,7 @@ Route::post('/login', LoginController::class)->middleware('throttle:login');
## Validate File Uploads
Validate MIME type, extension, and size. Never trust client-provided filenames.
Validate extension, MIME type, and size. The `mimes` rule checks extensions; use `mimetypes` for actual MIME type validation. Never trust client-provided filenames.
```php
public function rules(): array
Binary file not shown.
@@ -2,7 +2,7 @@
## Use `LazilyRefreshDatabase` Over `RefreshDatabase`
`RefreshDatabase` runs all migrations every test run even when the schema hasn't changed. `LazilyRefreshDatabase` only migrates when needed, significantly speeding up large suites.
`RefreshDatabase` migrates once per process and wraps each test in a rolled-back transaction. `LazilyRefreshDatabase` skips even that first migration if the schema is already up to date.
## Use Model Assertions Over Raw Database Assertions
@@ -1,6 +1,6 @@
---
name: wayfinder-development
description: "Activates whenever referencing backend routes in frontend components. Use when importing from @/actions or @/routes, calling Laravel routes from TypeScript, or working with Wayfinder route functions."
description: "Use this skill for Laravel Wayfinder which auto-generates typed functions for Laravel controllers and routes. ALWAYS use this skill when frontend code needs to call backend routes or controller actions. Trigger when: connecting any React/Vue/Svelte/Inertia frontend to Laravel controllers, routes, building end-to-end features with both frontend and backend, wiring up forms or links to backend endpoints, fixing route-related TypeScript errors, importing from @/actions or @/routes, or running wayfinder:generate. Use Wayfinder route functions instead of hardcoded URLs. Covers: wayfinder() vite plugin, .url()/.get()/.post()/.form(), query params, route model binding, tree-shaking. Do not use for backend-only task"
license: MIT
metadata:
author: laravel