@dedesfr/prompter 0.8.23 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/README.md +105 -77
- package/dist/cli/index.js +25 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/init.d.ts +1 -7
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +60 -299
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts +4 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +56 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +4 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +14 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +31 -41
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/whoami.d.ts +4 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +42 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/core/auth-store.d.ts +10 -0
- package/dist/core/auth-store.d.ts.map +1 -0
- package/dist/core/auth-store.js +39 -0
- package/dist/core/auth-store.js.map +1 -0
- package/dist/core/configurators/slash/antigravity.d.ts +2 -5
- package/dist/core/configurators/slash/antigravity.d.ts.map +1 -1
- package/dist/core/configurators/slash/antigravity.js +2 -57
- package/dist/core/configurators/slash/antigravity.js.map +1 -1
- package/dist/core/configurators/slash/base.d.ts +6 -18
- package/dist/core/configurators/slash/base.d.ts.map +1 -1
- package/dist/core/configurators/slash/base.js +8 -77
- package/dist/core/configurators/slash/base.js.map +1 -1
- package/dist/core/configurators/slash/claude.d.ts +2 -5
- package/dist/core/configurators/slash/claude.d.ts.map +1 -1
- package/dist/core/configurators/slash/claude.js +2 -57
- package/dist/core/configurators/slash/claude.js.map +1 -1
- package/dist/core/configurators/slash/codex.d.ts +2 -5
- package/dist/core/configurators/slash/codex.d.ts.map +1 -1
- package/dist/core/configurators/slash/codex.js +2 -57
- package/dist/core/configurators/slash/codex.js.map +1 -1
- package/dist/core/configurators/slash/droid.d.ts +2 -5
- package/dist/core/configurators/slash/droid.d.ts.map +1 -1
- package/dist/core/configurators/slash/droid.js +2 -32
- package/dist/core/configurators/slash/droid.js.map +1 -1
- package/dist/core/configurators/slash/forge.d.ts +2 -5
- package/dist/core/configurators/slash/forge.d.ts.map +1 -1
- package/dist/core/configurators/slash/forge.js +2 -32
- package/dist/core/configurators/slash/forge.js.map +1 -1
- package/dist/core/configurators/slash/github-copilot.d.ts +2 -7
- package/dist/core/configurators/slash/github-copilot.d.ts.map +1 -1
- package/dist/core/configurators/slash/github-copilot.js +2 -96
- package/dist/core/configurators/slash/github-copilot.js.map +1 -1
- package/dist/core/configurators/slash/index.d.ts +1 -1
- package/dist/core/configurators/slash/index.d.ts.map +1 -1
- package/dist/core/configurators/slash/index.js +1 -1
- package/dist/core/configurators/slash/index.js.map +1 -1
- package/dist/core/configurators/slash/kilocode.d.ts +2 -5
- package/dist/core/configurators/slash/kilocode.d.ts.map +1 -1
- package/dist/core/configurators/slash/kilocode.js +2 -57
- package/dist/core/configurators/slash/kilocode.js.map +1 -1
- package/dist/core/configurators/slash/opencode.d.ts +2 -5
- package/dist/core/configurators/slash/opencode.d.ts.map +1 -1
- package/dist/core/configurators/slash/opencode.js +2 -57
- package/dist/core/configurators/slash/opencode.js.map +1 -1
- package/dist/core/configurators/slash/registry.d.ts +4 -4
- package/dist/core/configurators/slash/registry.d.ts.map +1 -1
- package/dist/core/configurators/slash/registry.js.map +1 -1
- package/dist/core/registry.d.ts +18 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +94 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/templates/index.d.ts +0 -1
- package/dist/core/templates/index.d.ts.map +1 -1
- package/dist/core/templates/index.js +0 -1
- package/dist/core/templates/index.js.map +1 -1
- package/package.json +7 -1
- package/AGENTS.md +0 -123
- package/CLAUDE.md +0 -17
- package/build.js +0 -20
- package/convex-setup.md +0 -403
- package/dist/core/templates/slash-command-templates.d.ts +0 -7
- package/dist/core/templates/slash-command-templates.d.ts.map +0 -1
- package/dist/core/templates/slash-command-templates.js +0 -1041
- package/dist/core/templates/slash-command-templates.js.map +0 -1
- package/prompt/ai-humanizer.md +0 -45
- package/prompt/api-contract-generator.md +0 -234
- package/prompt/apply.md +0 -17
- package/prompt/archive.md +0 -21
- package/prompt/design-system.md +0 -210
- package/prompt/document-explainer.md +0 -149
- package/prompt/epic-generator.md +0 -198
- package/prompt/epic-single.md +0 -47
- package/prompt/erd-generator.md +0 -130
- package/prompt/fsd-generator.md +0 -157
- package/prompt/prd-agent-generator.md +0 -147
- package/prompt/prd-generator.md +0 -195
- package/prompt/product-brief.md +0 -289
- package/prompt/proposal.md +0 -22
- package/prompt/qa-test-scenario.md +0 -133
- package/prompt/skill-creator.md +0 -350
- package/prompt/story-generator.md +0 -278
- package/prompt/story-single.md +0 -70
- package/prompt/tdd-generator.md +0 -294
- package/prompt/tdd-lite-generator.md +0 -224
- package/prompt/wireframe-generator.md +0 -219
- package/skills/ai-context-generator/SKILL.md +0 -54
- package/skills/ai-context-generator/references/AGENTS.template.md +0 -83
- package/skills/ai-context-generator/references/CLAUDE.template.md +0 -39
- package/skills/ai-context-generator/references/behavioral-guidelines.md +0 -71
- package/skills/ai-context-generator/references/discovery-checklist.md +0 -40
- package/skills/ai-context-generator/references/examples/AGENTS.good.md +0 -103
- package/skills/ai-context-generator/references/extraction-checklist.md +0 -23
- package/skills/ai-context-generator/references/overlays/laravel.md +0 -44
- package/skills/cerebro/SKILL.md +0 -187
- package/skills/cerebro/references/agents.md +0 -213
- package/skills/code-review/SKILL.md +0 -373
- package/skills/code-review/assets/report-template-agent.md +0 -212
- package/skills/code-review/assets/report-template-compact.md +0 -81
- package/skills/code-review/assets/report-template-full.md +0 -264
- package/skills/code-review/assets/report-template-human.md +0 -168
- package/skills/code-review/references/universal-patterns.md +0 -495
- package/skills/design-md/README.md +0 -34
- package/skills/design-md/SKILL.md +0 -172
- package/skills/design-md/examples/DESIGN.md +0 -154
- package/skills/design-system-generator/SKILL.md +0 -324
- package/skills/design-system-generator/assets/design-system-template.md +0 -348
- package/skills/design-system-generator/references/extraction-patterns.md +0 -321
- package/skills/doc-builder/SKILL.md +0 -115
- package/skills/doc-builder/references/ui-patterns.md +0 -394
- package/skills/document-translator/SKILL.md +0 -58
- package/skills/enhance-prompt/README.md +0 -34
- package/skills/enhance-prompt/SKILL.md +0 -204
- package/skills/enhance-prompt/references/KEYWORDS.md +0 -114
- package/skills/feature-planner/SKILL.md +0 -305
- package/skills/feature-planner/assets/implementation-plan-template.md +0 -85
- package/skills/frontend-design/LICENSE.txt +0 -177
- package/skills/frontend-design/SKILL.md +0 -42
- package/skills/gamma-builder/SKILL.md +0 -134
- package/skills/laravel-code-review/SKILL.md +0 -383
- package/skills/laravel-code-review/assets/report-template-agent.md +0 -195
- package/skills/laravel-code-review/assets/report-template-compact.md +0 -79
- package/skills/laravel-code-review/assets/report-template-full.md +0 -253
- package/skills/laravel-code-review/assets/report-template-human.md +0 -159
- package/skills/laravel-code-review/references/laravel-patterns.md +0 -571
- package/skills/laravel-code-review/references/php84-features.md +0 -442
- package/skills/mcp-builder/LICENSE.txt +0 -202
- package/skills/mcp-builder/SKILL.md +0 -236
- package/skills/mcp-builder/reference/evaluation.md +0 -602
- package/skills/mcp-builder/reference/mcp_best_practices.md +0 -249
- package/skills/mcp-builder/reference/node_mcp_server.md +0 -970
- package/skills/mcp-builder/reference/python_mcp_server.md +0 -719
- package/skills/mcp-builder/scripts/connections.py +0 -151
- package/skills/mcp-builder/scripts/evaluation.py +0 -373
- package/skills/mcp-builder/scripts/example_evaluation.xml +0 -22
- package/skills/mcp-builder/scripts/requirements.txt +0 -2
- package/skills/meeting-notes/SKILL.md +0 -159
- package/skills/meeting-notes/evals/evals.json +0 -23
- package/skills/project-orchestrator/SKILL.md +0 -487
- package/skills/project-orchestrator/assets/caddy-vps-setup.md +0 -180
- package/skills/project-orchestrator/assets/plan-summary-template.md +0 -159
- package/skills/prompter-specs/SKILL.md +0 -115
- package/skills/prompter-workflow/SKILL.md +0 -166
- package/skills/prompter-workflow/evals/evals.json +0 -89
- package/skills/sph-generator/SKILL.md +0 -488
- package/skills/ui-ux-pro/SKILL.md +0 -199
- package/skills/ui-ux-pro/assets/design-spec-template.md +0 -173
- package/skills/ui-ux-pro/references/component-patterns.md +0 -255
- package/skills/ui-ux-pro/references/design-principles.md +0 -167
- package/src/cli/index.ts +0 -223
- package/src/commands/archive.ts +0 -302
- package/src/commands/change.ts +0 -292
- package/src/commands/config.ts +0 -233
- package/src/commands/guide.ts +0 -50
- package/src/commands/init.ts +0 -899
- package/src/commands/list.ts +0 -194
- package/src/commands/show.ts +0 -138
- package/src/commands/spec.ts +0 -251
- package/src/commands/update.ts +0 -156
- package/src/commands/upgrade.ts +0 -30
- package/src/commands/validate.ts +0 -326
- package/src/core/artifact-graph/graph.ts +0 -167
- package/src/core/artifact-graph/index.ts +0 -44
- package/src/core/artifact-graph/instruction-loader.ts +0 -302
- package/src/core/artifact-graph/resolver.ts +0 -226
- package/src/core/artifact-graph/schema.ts +0 -124
- package/src/core/artifact-graph/state.ts +0 -64
- package/src/core/artifact-graph/types.ts +0 -65
- package/src/core/completions/command-registry.ts +0 -382
- package/src/core/completions/completion-provider.ts +0 -128
- package/src/core/completions/generators/bash-generator.ts +0 -191
- package/src/core/completions/generators/fish-generator.ts +0 -188
- package/src/core/completions/generators/powershell-generator.ts +0 -223
- package/src/core/completions/generators/zsh-generator.ts +0 -281
- package/src/core/completions/templates/bash-templates.ts +0 -24
- package/src/core/completions/templates/fish-templates.ts +0 -40
- package/src/core/completions/templates/powershell-templates.ts +0 -25
- package/src/core/completions/templates/zsh-templates.ts +0 -36
- package/src/core/completions/types.ts +0 -90
- package/src/core/config-schema.ts +0 -230
- package/src/core/config.ts +0 -181
- package/src/core/configurators/slash/antigravity.ts +0 -70
- package/src/core/configurators/slash/base.ts +0 -203
- package/src/core/configurators/slash/claude.ts +0 -70
- package/src/core/configurators/slash/codex.ts +0 -70
- package/src/core/configurators/slash/droid.ts +0 -44
- package/src/core/configurators/slash/forge.ts +0 -44
- package/src/core/configurators/slash/github-copilot.ts +0 -114
- package/src/core/configurators/slash/index.ts +0 -10
- package/src/core/configurators/slash/kilocode.ts +0 -70
- package/src/core/configurators/slash/opencode.ts +0 -70
- package/src/core/configurators/slash/registry.ts +0 -51
- package/src/core/converters/json-converter.ts +0 -62
- package/src/core/global-config.ts +0 -136
- package/src/core/parsers/change-parser.ts +0 -234
- package/src/core/parsers/markdown-parser.ts +0 -237
- package/src/core/parsers/requirement-blocks.ts +0 -234
- package/src/core/prompt-templates.ts +0 -3504
- package/src/core/schemas/base.schema.ts +0 -20
- package/src/core/schemas/change.schema.ts +0 -42
- package/src/core/schemas/index.ts +0 -20
- package/src/core/schemas/spec.schema.ts +0 -17
- package/src/core/skill-discovery.ts +0 -68
- package/src/core/specs-apply.ts +0 -483
- package/src/core/styles/palette.ts +0 -8
- package/src/core/templates/agents-template.ts +0 -459
- package/src/core/templates/claude-template.ts +0 -2
- package/src/core/templates/index.ts +0 -4
- package/src/core/templates/project-template.ts +0 -32
- package/src/core/templates/slash-command-templates.ts +0 -1068
- package/src/core/validation/constants.ts +0 -48
- package/src/core/validation/types.ts +0 -19
- package/src/core/validation/validator.ts +0 -449
- package/src/core/view.ts +0 -219
- package/src/index.ts +0 -1
- package/src/utils/change-metadata.ts +0 -171
- package/src/utils/change-utils.ts +0 -131
- package/src/utils/file-system.ts +0 -252
- package/src/utils/index.ts +0 -12
- package/src/utils/interactive.ts +0 -29
- package/src/utils/item-discovery.ts +0 -66
- package/src/utils/match.ts +0 -26
- package/src/utils/shell-detection.ts +0 -62
- package/src/utils/task-progress.ts +0 -43
- package/tsconfig.json +0 -28
|
@@ -1,571 +0,0 @@
|
|
|
1
|
-
# Laravel 12 Issue Detection Patterns
|
|
2
|
-
|
|
3
|
-
Comprehensive reference for Laravel 12 + PHP 8.4 code issues.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Security Issues
|
|
8
|
-
|
|
9
|
-
### Mass Assignment Vulnerability
|
|
10
|
-
|
|
11
|
-
```php
|
|
12
|
-
// ❌ Bad: No $fillable defined
|
|
13
|
-
class User extends Model
|
|
14
|
-
{
|
|
15
|
-
// Missing $fillable or $guarded
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// ❌ Bad: Using $guarded = []
|
|
19
|
-
class User extends Model
|
|
20
|
-
{
|
|
21
|
-
protected $guarded = []; // Everything is fillable!
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// ✅ Good: Explicit $fillable
|
|
25
|
-
class User extends Model
|
|
26
|
-
{
|
|
27
|
-
protected $fillable = ['name', 'email'];
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### SQL Injection
|
|
32
|
-
|
|
33
|
-
```php
|
|
34
|
-
// ❌ Bad: Raw query with concatenation
|
|
35
|
-
DB::select("SELECT * FROM users WHERE id = " . $id);
|
|
36
|
-
|
|
37
|
-
// ❌ Bad: whereRaw without binding
|
|
38
|
-
User::whereRaw("email = '$email'")->get();
|
|
39
|
-
|
|
40
|
-
// ✅ Good: Parameter binding
|
|
41
|
-
DB::select("SELECT * FROM users WHERE id = ?", [$id]);
|
|
42
|
-
User::whereRaw("email = ?", [$email])->get();
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### Missing Authorization
|
|
46
|
-
|
|
47
|
-
```php
|
|
48
|
-
// ❌ Bad: No authorization check
|
|
49
|
-
public function update(Request $request, Post $post)
|
|
50
|
-
{
|
|
51
|
-
$post->update($request->all());
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// ✅ Good: Policy check
|
|
55
|
-
public function update(Request $request, Post $post)
|
|
56
|
-
{
|
|
57
|
-
$this->authorize('update', $post);
|
|
58
|
-
$post->update($request->validated());
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### XSS in Blade
|
|
63
|
-
|
|
64
|
-
```php
|
|
65
|
-
// ❌ Bad: Unescaped user input
|
|
66
|
-
{!! $user->bio !!}
|
|
67
|
-
{!! request('name') !!}
|
|
68
|
-
|
|
69
|
-
// ✅ Good: Escaped output
|
|
70
|
-
{{ $user->bio }}
|
|
71
|
-
{{ request('name') }}
|
|
72
|
-
|
|
73
|
-
// ✅ Good: If HTML needed, sanitize first
|
|
74
|
-
{!! clean($user->bio) !!}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Missing CSRF
|
|
78
|
-
|
|
79
|
-
```php
|
|
80
|
-
// ❌ Bad: Form without CSRF
|
|
81
|
-
<form method="POST" action="/users">
|
|
82
|
-
<input type="text" name="name">
|
|
83
|
-
</form>
|
|
84
|
-
|
|
85
|
-
// ✅ Good: Include CSRF token
|
|
86
|
-
<form method="POST" action="/users">
|
|
87
|
-
@csrf
|
|
88
|
-
<input type="text" name="name">
|
|
89
|
-
</form>
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## N+1 Query Problems
|
|
95
|
-
|
|
96
|
-
### Basic N+1
|
|
97
|
-
|
|
98
|
-
```php
|
|
99
|
-
// ❌ Bad: N+1 query
|
|
100
|
-
$posts = Post::all();
|
|
101
|
-
foreach ($posts as $post) {
|
|
102
|
-
echo $post->author->name; // Query per iteration!
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// ✅ Good: Eager loading
|
|
106
|
-
$posts = Post::with('author')->get();
|
|
107
|
-
foreach ($posts as $post) {
|
|
108
|
-
echo $post->author->name;
|
|
109
|
-
}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### Nested Relationships
|
|
113
|
-
|
|
114
|
-
```php
|
|
115
|
-
// ❌ Bad: Missing nested eager load
|
|
116
|
-
$posts = Post::with('author')->get();
|
|
117
|
-
foreach ($posts as $post) {
|
|
118
|
-
echo $post->author->profile->avatar; // N+1 on profile!
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// ✅ Good: Nested eager loading
|
|
122
|
-
$posts = Post::with('author.profile')->get();
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Conditional Eager Loading
|
|
126
|
-
|
|
127
|
-
```php
|
|
128
|
-
// ❌ Bad: Loading unnecessary data
|
|
129
|
-
$posts = Post::with('comments')->get();
|
|
130
|
-
|
|
131
|
-
// ✅ Good: Constrained eager loading
|
|
132
|
-
$posts = Post::with(['comments' => function ($query) {
|
|
133
|
-
$query->where('approved', true)->limit(5);
|
|
134
|
-
}])->get();
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Lazy Eager Loading
|
|
138
|
-
|
|
139
|
-
```php
|
|
140
|
-
// ❌ Bad: N+1 after initial query
|
|
141
|
-
$posts = Post::all();
|
|
142
|
-
// Later in code...
|
|
143
|
-
foreach ($posts as $post) {
|
|
144
|
-
echo $post->tags->count();
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// ✅ Good: Load when needed
|
|
148
|
-
$posts = Post::all();
|
|
149
|
-
$posts->load('tags');
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
## Controller Issues
|
|
155
|
-
|
|
156
|
-
### Fat Controller
|
|
157
|
-
|
|
158
|
-
```php
|
|
159
|
-
// ❌ Bad: Too much logic in controller
|
|
160
|
-
public function store(Request $request)
|
|
161
|
-
{
|
|
162
|
-
$validated = $request->validate([...]);
|
|
163
|
-
|
|
164
|
-
$user = User::create($validated);
|
|
165
|
-
$user->assignRole('customer');
|
|
166
|
-
|
|
167
|
-
Mail::to($user)->send(new WelcomeEmail($user));
|
|
168
|
-
|
|
169
|
-
event(new UserRegistered($user));
|
|
170
|
-
|
|
171
|
-
$token = $user->createToken('api')->plainTextToken;
|
|
172
|
-
|
|
173
|
-
return response()->json([...]);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// ✅ Good: Delegate to service
|
|
177
|
-
public function store(StoreUserRequest $request, UserService $service)
|
|
178
|
-
{
|
|
179
|
-
$user = $service->register($request->validated());
|
|
180
|
-
|
|
181
|
-
return new UserResource($user);
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### Missing Form Request
|
|
186
|
-
|
|
187
|
-
```php
|
|
188
|
-
// ❌ Bad: Inline validation
|
|
189
|
-
public function store(Request $request)
|
|
190
|
-
{
|
|
191
|
-
$validated = $request->validate([
|
|
192
|
-
'name' => 'required|string|max:255',
|
|
193
|
-
'email' => 'required|email|unique:users',
|
|
194
|
-
]);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// ✅ Good: Form Request class
|
|
198
|
-
public function store(StoreUserRequest $request)
|
|
199
|
-
{
|
|
200
|
-
$validated = $request->validated();
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### Direct $request->all()
|
|
205
|
-
|
|
206
|
-
```php
|
|
207
|
-
// ❌ Bad: Using all() without validation
|
|
208
|
-
User::create($request->all());
|
|
209
|
-
|
|
210
|
-
// ❌ Bad: Using only() without validation
|
|
211
|
-
User::create($request->only(['name', 'email']));
|
|
212
|
-
|
|
213
|
-
// ✅ Good: Use validated data
|
|
214
|
-
User::create($request->validated());
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
## Eloquent Anti-patterns
|
|
220
|
-
|
|
221
|
-
### Inefficient Queries
|
|
222
|
-
|
|
223
|
-
```php
|
|
224
|
-
// ❌ Bad: Get then count
|
|
225
|
-
$count = User::get()->count();
|
|
226
|
-
|
|
227
|
-
// ✅ Good: Direct count
|
|
228
|
-
$count = User::count();
|
|
229
|
-
|
|
230
|
-
// ❌ Bad: Get then pluck
|
|
231
|
-
$emails = User::get()->pluck('email');
|
|
232
|
-
|
|
233
|
-
// ✅ Good: Direct pluck
|
|
234
|
-
$emails = User::pluck('email');
|
|
235
|
-
|
|
236
|
-
// ❌ Bad: Get then first
|
|
237
|
-
$user = User::where('email', $email)->get()->first();
|
|
238
|
-
|
|
239
|
-
// ✅ Good: Direct first
|
|
240
|
-
$user = User::where('email', $email)->first();
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
### Missing Select
|
|
244
|
-
|
|
245
|
-
```php
|
|
246
|
-
// ❌ Bad: Selecting all columns
|
|
247
|
-
$userNames = User::all()->pluck('name');
|
|
248
|
-
|
|
249
|
-
// ✅ Good: Select only needed columns
|
|
250
|
-
$userNames = User::select('name')->pluck('name');
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### Large Dataset Handling
|
|
254
|
-
|
|
255
|
-
```php
|
|
256
|
-
// ❌ Bad: Loading all records
|
|
257
|
-
$users = User::all();
|
|
258
|
-
foreach ($users as $user) {
|
|
259
|
-
$user->update(['processed' => true]);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// ✅ Good: Chunking
|
|
263
|
-
User::chunk(100, function ($users) {
|
|
264
|
-
foreach ($users as $user) {
|
|
265
|
-
$user->update(['processed' => true]);
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
// ✅ Better: Lazy collection
|
|
270
|
-
User::lazy()->each(function ($user) {
|
|
271
|
-
$user->update(['processed' => true]);
|
|
272
|
-
});
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### Missing Indexes
|
|
276
|
-
|
|
277
|
-
```php
|
|
278
|
-
// ❌ Bad: Querying unindexed column
|
|
279
|
-
User::where('status', 'active')->get();
|
|
280
|
-
|
|
281
|
-
// Migration should have:
|
|
282
|
-
$table->string('status')->index();
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
---
|
|
286
|
-
|
|
287
|
-
## PHP 8.4 Issues
|
|
288
|
-
|
|
289
|
-
### Missing Constructor Property Promotion
|
|
290
|
-
|
|
291
|
-
```php
|
|
292
|
-
// ❌ Bad: Old-style properties
|
|
293
|
-
class UserService
|
|
294
|
-
{
|
|
295
|
-
private UserRepository $repository;
|
|
296
|
-
private CacheService $cache;
|
|
297
|
-
|
|
298
|
-
public function __construct(
|
|
299
|
-
UserRepository $repository,
|
|
300
|
-
CacheService $cache
|
|
301
|
-
) {
|
|
302
|
-
$this->repository = $repository;
|
|
303
|
-
$this->cache = $cache;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// ✅ Good: PHP 8+ property promotion
|
|
308
|
-
class UserService
|
|
309
|
-
{
|
|
310
|
-
public function __construct(
|
|
311
|
-
private readonly UserRepository $repository,
|
|
312
|
-
private readonly CacheService $cache,
|
|
313
|
-
) {}
|
|
314
|
-
}
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
### Missing Readonly Properties
|
|
318
|
-
|
|
319
|
-
```php
|
|
320
|
-
// ❌ Bad: Mutable when shouldn't be
|
|
321
|
-
class UserDTO
|
|
322
|
-
{
|
|
323
|
-
public function __construct(
|
|
324
|
-
public string $name,
|
|
325
|
-
public string $email,
|
|
326
|
-
) {}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// ✅ Good: Readonly for immutable data
|
|
330
|
-
class UserDTO
|
|
331
|
-
{
|
|
332
|
-
public function __construct(
|
|
333
|
-
public readonly string $name,
|
|
334
|
-
public readonly string $email,
|
|
335
|
-
) {}
|
|
336
|
-
}
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
### Not Using Match Expression
|
|
340
|
-
|
|
341
|
-
```php
|
|
342
|
-
// ❌ Bad: Switch statement
|
|
343
|
-
switch ($status) {
|
|
344
|
-
case 'pending':
|
|
345
|
-
return 'yellow';
|
|
346
|
-
case 'approved':
|
|
347
|
-
return 'green';
|
|
348
|
-
case 'rejected':
|
|
349
|
-
return 'red';
|
|
350
|
-
default:
|
|
351
|
-
return 'gray';
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// ✅ Good: Match expression
|
|
355
|
-
return match($status) {
|
|
356
|
-
'pending' => 'yellow',
|
|
357
|
-
'approved' => 'green',
|
|
358
|
-
'rejected' => 'red',
|
|
359
|
-
default => 'gray',
|
|
360
|
-
};
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
### Missing Named Arguments
|
|
364
|
-
|
|
365
|
-
```php
|
|
366
|
-
// ❌ Bad: Positional args unclear
|
|
367
|
-
$user = new User('John', 'john@example.com', true, false, null);
|
|
368
|
-
|
|
369
|
-
// ✅ Good: Named arguments for clarity
|
|
370
|
-
$user = new User(
|
|
371
|
-
name: 'John',
|
|
372
|
-
email: 'john@example.com',
|
|
373
|
-
isAdmin: true,
|
|
374
|
-
isVerified: false,
|
|
375
|
-
avatarUrl: null,
|
|
376
|
-
);
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
### Missing #[Override] Attribute
|
|
380
|
-
|
|
381
|
-
```php
|
|
382
|
-
// ❌ Bad: No override indication
|
|
383
|
-
class CustomException extends Exception
|
|
384
|
-
{
|
|
385
|
-
public function getMessage(): string
|
|
386
|
-
{
|
|
387
|
-
return 'Custom: ' . parent::getMessage();
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// ✅ Good: PHP 8.3+ Override attribute
|
|
392
|
-
class CustomException extends Exception
|
|
393
|
-
{
|
|
394
|
-
#[\Override]
|
|
395
|
-
public function getMessage(): string
|
|
396
|
-
{
|
|
397
|
-
return 'Custom: ' . parent::getMessage();
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
### Implicit Nullable (Deprecated)
|
|
403
|
-
|
|
404
|
-
```php
|
|
405
|
-
// ❌ Bad: Implicit nullable (deprecated in 8.4)
|
|
406
|
-
function process(string $value = null) {}
|
|
407
|
-
|
|
408
|
-
// ✅ Good: Explicit nullable
|
|
409
|
-
function process(?string $value = null) {}
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
---
|
|
413
|
-
|
|
414
|
-
## Laravel 12 Specific
|
|
415
|
-
|
|
416
|
-
### Missing Enums for Constants
|
|
417
|
-
|
|
418
|
-
```php
|
|
419
|
-
// ❌ Bad: String constants
|
|
420
|
-
class Order
|
|
421
|
-
{
|
|
422
|
-
const STATUS_PENDING = 'pending';
|
|
423
|
-
const STATUS_COMPLETED = 'completed';
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
// ✅ Good: Backed Enum
|
|
427
|
-
enum OrderStatus: string
|
|
428
|
-
{
|
|
429
|
-
case Pending = 'pending';
|
|
430
|
-
case Completed = 'completed';
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
// Usage in Model
|
|
434
|
-
protected $casts = [
|
|
435
|
-
'status' => OrderStatus::class,
|
|
436
|
-
];
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
### Missing API Resource
|
|
440
|
-
|
|
441
|
-
```php
|
|
442
|
-
// ❌ Bad: Direct model/array return
|
|
443
|
-
public function show(User $user)
|
|
444
|
-
{
|
|
445
|
-
return response()->json($user);
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
// ✅ Good: API Resource
|
|
449
|
-
public function show(User $user)
|
|
450
|
-
{
|
|
451
|
-
return new UserResource($user);
|
|
452
|
-
}
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
### Invokable Controllers
|
|
456
|
-
|
|
457
|
-
```php
|
|
458
|
-
// ❌ Bad: Single method controller
|
|
459
|
-
class ShowDashboardController extends Controller
|
|
460
|
-
{
|
|
461
|
-
public function index()
|
|
462
|
-
{
|
|
463
|
-
return view('dashboard');
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// ✅ Good: Invokable controller
|
|
468
|
-
class ShowDashboardController extends Controller
|
|
469
|
-
{
|
|
470
|
-
public function __invoke()
|
|
471
|
-
{
|
|
472
|
-
return view('dashboard');
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// Route
|
|
477
|
-
Route::get('/dashboard', ShowDashboardController::class);
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
### Missing Return Types
|
|
481
|
-
|
|
482
|
-
```php
|
|
483
|
-
// ❌ Bad: No return type
|
|
484
|
-
public function getUsers()
|
|
485
|
-
{
|
|
486
|
-
return User::all();
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
// ✅ Good: Explicit return type
|
|
490
|
-
public function getUsers(): Collection
|
|
491
|
-
{
|
|
492
|
-
return User::all();
|
|
493
|
-
}
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
---
|
|
497
|
-
|
|
498
|
-
## Blade Template Issues
|
|
499
|
-
|
|
500
|
-
### Inefficient Loops
|
|
501
|
-
|
|
502
|
-
```php
|
|
503
|
-
// ❌ Bad: Query in loop
|
|
504
|
-
@foreach(Category::all() as $category)
|
|
505
|
-
{{ $category->name }}
|
|
506
|
-
@endforeach
|
|
507
|
-
|
|
508
|
-
// ✅ Good: Pass from controller
|
|
509
|
-
// Controller: return view('page', ['categories' => Category::all()]);
|
|
510
|
-
@foreach($categories as $category)
|
|
511
|
-
{{ $category->name }}
|
|
512
|
-
@endforeach
|
|
513
|
-
```
|
|
514
|
-
|
|
515
|
-
### Missing @once Directive
|
|
516
|
-
|
|
517
|
-
```php
|
|
518
|
-
// ❌ Bad: Repeated scripts in loop
|
|
519
|
-
@foreach($items as $item)
|
|
520
|
-
<script src="/js/item-handler.js"></script>
|
|
521
|
-
@endforeach
|
|
522
|
-
|
|
523
|
-
// ✅ Good: Include once
|
|
524
|
-
@foreach($items as $item)
|
|
525
|
-
@once
|
|
526
|
-
<script src="/js/item-handler.js"></script>
|
|
527
|
-
@endonce
|
|
528
|
-
@endforeach
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
---
|
|
532
|
-
|
|
533
|
-
## Migration Issues
|
|
534
|
-
|
|
535
|
-
### Missing Indexes
|
|
536
|
-
|
|
537
|
-
```php
|
|
538
|
-
// ❌ Bad: Foreign key without index
|
|
539
|
-
$table->foreignId('user_id');
|
|
540
|
-
|
|
541
|
-
// ✅ Good: Constrained adds index
|
|
542
|
-
$table->foreignId('user_id')->constrained();
|
|
543
|
-
|
|
544
|
-
// ❌ Bad: Frequently queried column
|
|
545
|
-
$table->string('status');
|
|
546
|
-
|
|
547
|
-
// ✅ Good: Add index
|
|
548
|
-
$table->string('status')->index();
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
### Missing Soft Deletes Index
|
|
552
|
-
|
|
553
|
-
```php
|
|
554
|
-
// ❌ Bad: Soft deletes without index
|
|
555
|
-
$table->softDeletes();
|
|
556
|
-
|
|
557
|
-
// ✅ Good: Index for deleted_at
|
|
558
|
-
$table->softDeletes();
|
|
559
|
-
$table->index('deleted_at');
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
---
|
|
563
|
-
|
|
564
|
-
## Severity Classification
|
|
565
|
-
|
|
566
|
-
| Severity | Emoji | Laravel-Specific Criteria |
|
|
567
|
-
| ------------ | ----- | ------------------------------------------------------------- |
|
|
568
|
-
| Critical | 🔴 | Security vulnerabilities, mass assignment, SQL injection, XSS |
|
|
569
|
-
| Warning | 🟠 | N+1 queries, missing validation, fat controllers |
|
|
570
|
-
| Optimization | 🟡 | Missing eager loading, inefficient queries, no caching |
|
|
571
|
-
| Quality | 🔵 | PHP 8.4 features, Laravel conventions, return types |
|