From laravel-superpowers
Use in Laravel projects when completing a feature, reviewing code, or preparing for merge. Checks Laravel-specific concerns: N+1 queries, mass assignment protection, authorization coverage, validation completeness, security, performance. In Laravel codebases, invoke this alongside superpowers:requesting-code-review. Trigger on any 'review', 'check', 'PR', 'done with feature', 'ready to merge' in a Laravel project.
npx claudepluginhub altraweb/laravel-superpowers --plugin laravel-superpowersThis skill uses the workspace's default tool permissions.
Catch Laravel-specific issues before they reach production. Run this **after** the generic `superpowers:requesting-code-review` flow, or as a standalone review for Laravel-specific concerns.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
Catch Laravel-specific issues before they reach production. Run this after the generic superpowers:requesting-code-review flow, or as a standalone review for Laravel-specific concerns.
Work through each section. For every [ ] item, check the actual code — don't assume.
N+1 Queries
# Check for relationship access inside loops
grep -rn "foreach\|->each(" app/Http/ app/Services/ app/Actions/
# Then verify: is `with()` used before the loop?
hasMany/belongsToMany relationships loaded inside loops use eager loading (with())$collection->count() called on already-loaded collection (OK), not ->count() (fires query) — distinguish $user->posts->count() from $user->posts()->count()->exists() or ->doesntExist() used instead of counting for existence checksMass Assignment
$fillable defined (prefer) or $guarded = [] (intentional)$request->all() is NOT used for create()/fill() — use $request->validated() or $request->only([...])$fillableMigrations
constrained() and appropriate onDelete behaviorphp artisan migrate:fresh assumption in production migrationsQueries
Model::all() without pagination or explicit small-dataset justificationenv() is NOT called in application code — only config() (env() bypasses config cache)authorize() or uses a Policyauthorize() is called before querying the database (fail fast)guest middlewareauth middleware (not just relying on authorize() inside)# Check for missing authorization
grep -rn "public function " app/Http/Controllers/ | grep -v "__construct\|middleware"
# For each method, verify it calls $this->authorize() or has a policy
$request->validate() if reused)$request->input('field') without prior validation)'items.*.price' => 'required|numeric'$request->validated() used (not $request->all() or $request->input()) after validationDB::select("... WHERE id = '$id'") → use bindings{!! $var !!} (unescaped Blade) only used for explicitly trusted HTMLStorage::disk()config() not hardcoded@csrf or API routes use Sanctum/Passport->paginate(), ->simplePaginate(), ->cursorPaginate())cache()->remember(...))->toArray() for response shaping$tries, $backoff, and failed() method where appropriateHttp::get(...)) check ->failed() or ->throw()Exception or RuntimeException)Mail::fake() etc.)php artisan test --coverage # needs XDEBUG_MODE=coverage
php artisan pint (Laravel Pint) runs clean — no style violationshasMany → plural method name (posts()), belongsTo → singular (user())index, create, store, show, edit, update, destroymodule:action naming (orders:process-overdue)./vendor/bin/pint --test # check style without fixing
./vendor/bin/pint # fix style
After reviewing, report findings grouped by severity:
Blockers (must fix before merge):
Should fix (important but not blocking):
Nice to have (optional improvements):
Looks good (explicit sign-off areas):
php artisan test # run full test suite
./vendor/bin/pint --test # style check
php artisan route:list # verify routes
php artisan model:show Model # check schema/relationships
php artisan queue:failed # check for failed jobs