@famgia/omnify-laravel 0.0.87 → 0.0.89

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.
Files changed (46) hide show
  1. package/dist/{chunk-YVVAJA3T.js → chunk-V7LWJ6OM.js} +178 -12
  2. package/dist/chunk-V7LWJ6OM.js.map +1 -0
  3. package/dist/index.cjs +180 -11
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.cts +48 -1
  6. package/dist/index.d.ts +48 -1
  7. package/dist/index.js +5 -1
  8. package/dist/plugin.cjs +176 -11
  9. package/dist/plugin.cjs.map +1 -1
  10. package/dist/plugin.js +1 -1
  11. package/package.json +5 -5
  12. package/scripts/postinstall.js +29 -36
  13. package/stubs/ai-guides/claude-agents/architect.md.stub +150 -0
  14. package/stubs/ai-guides/claude-agents/developer.md.stub +190 -0
  15. package/stubs/ai-guides/claude-agents/reviewer.md.stub +134 -0
  16. package/stubs/ai-guides/claude-agents/tester.md.stub +196 -0
  17. package/stubs/ai-guides/claude-checklists/backend.md.stub +112 -0
  18. package/stubs/ai-guides/claude-omnify/antdesign-guide.md.stub +401 -0
  19. package/stubs/ai-guides/claude-omnify/config-guide.md.stub +253 -0
  20. package/stubs/ai-guides/claude-omnify/japan-guide.md.stub +186 -0
  21. package/stubs/ai-guides/claude-omnify/laravel-guide.md.stub +61 -0
  22. package/stubs/ai-guides/claude-omnify/schema-guide.md.stub +115 -0
  23. package/stubs/ai-guides/claude-omnify/typescript-guide.md.stub +310 -0
  24. package/stubs/ai-guides/claude-rules/naming.md.stub +364 -0
  25. package/stubs/ai-guides/claude-rules/performance.md.stub +251 -0
  26. package/stubs/ai-guides/claude-rules/security.md.stub +159 -0
  27. package/stubs/ai-guides/claude-workflows/bug-fix.md.stub +201 -0
  28. package/stubs/ai-guides/claude-workflows/code-review.md.stub +164 -0
  29. package/stubs/ai-guides/claude-workflows/new-feature.md.stub +327 -0
  30. package/stubs/ai-guides/cursor/laravel-controller.mdc.stub +391 -0
  31. package/stubs/ai-guides/cursor/laravel-request.mdc.stub +112 -0
  32. package/stubs/ai-guides/cursor/laravel-resource.mdc.stub +73 -0
  33. package/stubs/ai-guides/cursor/laravel-review.mdc.stub +69 -0
  34. package/stubs/ai-guides/cursor/laravel-testing.mdc.stub +138 -0
  35. package/stubs/ai-guides/cursor/laravel.mdc.stub +82 -0
  36. package/stubs/ai-guides/laravel/README.md.stub +59 -0
  37. package/stubs/ai-guides/laravel/architecture.md.stub +424 -0
  38. package/stubs/ai-guides/laravel/controller.md.stub +484 -0
  39. package/stubs/ai-guides/laravel/datetime.md.stub +334 -0
  40. package/stubs/ai-guides/laravel/openapi.md.stub +369 -0
  41. package/stubs/ai-guides/laravel/request.md.stub +450 -0
  42. package/stubs/ai-guides/laravel/resource.md.stub +516 -0
  43. package/stubs/ai-guides/laravel/service.md.stub +503 -0
  44. package/stubs/ai-guides/laravel/testing.md.stub +1504 -0
  45. package/ai-guides/laravel-guide.md +0 -461
  46. package/dist/chunk-YVVAJA3T.js.map +0 -1
@@ -0,0 +1,251 @@
1
+ # Performance & Quality Rules
2
+
3
+ > **Non-negotiable rules** for Laravel performance and code quality.
4
+
5
+ ## 🟠 N+1 Query Problem
6
+
7
+ **Always eager load relationships.**
8
+
9
+ ```php
10
+ // ❌ N+1 PROBLEM: 1 + N queries (N = number of posts)
11
+ $posts = Post::all();
12
+ foreach ($posts as $post) {
13
+ echo $post->author->name; // Query for each post!
14
+ }
15
+
16
+ // ✅ CORRECT: Eager loading with with()
17
+ $posts = Post::with('author')->get();
18
+ foreach ($posts as $post) {
19
+ echo $post->author->name; // No extra queries
20
+ }
21
+
22
+ // ✅ CORRECT: Multiple relationships
23
+ $posts = Post::with(['author', 'comments', 'tags'])->get();
24
+
25
+ // ✅ CORRECT: Nested eager loading
26
+ $posts = Post::with('comments.author')->get();
27
+ ```
28
+
29
+ **Enable N+1 detection in development:**
30
+
31
+ ```php
32
+ // In AppServiceProvider boot()
33
+ use Illuminate\Database\Eloquent\Model;
34
+
35
+ public function boot(): void
36
+ {
37
+ // Throw exception on lazy loading (dev only)
38
+ Model::preventLazyLoading(!app()->isProduction());
39
+ }
40
+ ```
41
+
42
+ ---
43
+
44
+ ## 🟠 Use `whenLoaded()` in Resources
45
+
46
+ **Prevent queries in Resources.**
47
+
48
+ ```php
49
+ // ❌ ERROR: Triggers query if not eager loaded
50
+ class PostResource extends JsonResource
51
+ {
52
+ public function toArray($request): array
53
+ {
54
+ return [
55
+ 'author' => new UserResource($this->author), // N+1!
56
+ ];
57
+ }
58
+ }
59
+
60
+ // ✅ CORRECT: Only include if already loaded
61
+ class PostResource extends JsonResource
62
+ {
63
+ public function toArray($request): array
64
+ {
65
+ return [
66
+ 'author' => new UserResource($this->whenLoaded('author')),
67
+ ];
68
+ }
69
+ }
70
+ ```
71
+
72
+ ---
73
+
74
+ ## 🟠 Pagination for List Endpoints
75
+
76
+ **Never return all records.**
77
+
78
+ ```php
79
+ // ❌ ERROR: Returns all records (memory + performance)
80
+ public function index()
81
+ {
82
+ return UserResource::collection(User::all()); // 1M users = crash
83
+ }
84
+
85
+ // ✅ CORRECT: Always paginate
86
+ public function index(Request $request)
87
+ {
88
+ $perPage = min($request->input('per_page', 15), 100); // Max 100
89
+ return UserResource::collection(User::paginate($perPage));
90
+ }
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 🟠 Select Only Needed Columns
96
+
97
+ **Don't SELECT * when you need few fields.**
98
+
99
+ ```php
100
+ // ❌ INEFFICIENT: Fetches all columns
101
+ $users = User::all();
102
+ $names = $users->pluck('name');
103
+
104
+ // ✅ EFFICIENT: Select only needed columns
105
+ $names = User::pluck('name');
106
+
107
+ // ✅ EFFICIENT: For multiple columns
108
+ $users = User::select(['id', 'name', 'email'])->get();
109
+ ```
110
+
111
+ ---
112
+
113
+ ## 🟡 Code Quality Rules
114
+
115
+ ### Never Validate in Controller
116
+
117
+ ```php
118
+ // ❌ BAD: Validation in controller
119
+ public function store(Request $request)
120
+ {
121
+ $validated = $request->validate([...]);
122
+ }
123
+
124
+ // ✅ CORRECT: Use FormRequest
125
+ public function store(UserStoreRequest $request)
126
+ {
127
+ $user = User::create($request->validated());
128
+ return new UserResource($user);
129
+ }
130
+ ```
131
+
132
+ ### Always Use Resource for Responses
133
+
134
+ ```php
135
+ // ❌ BAD: Exposes all fields, inconsistent format
136
+ return $user;
137
+ return response()->json($user);
138
+
139
+ // ✅ CORRECT: Use Resource
140
+ return new UserResource($user);
141
+ return UserResource::collection($users);
142
+ ```
143
+
144
+ ### Use Route Model Binding
145
+
146
+ ```php
147
+ // ❌ BAD: Manual find
148
+ public function show(int $id)
149
+ {
150
+ $user = User::findOrFail($id);
151
+ return new UserResource($user);
152
+ }
153
+
154
+ // ✅ CORRECT: Route model binding
155
+ public function show(User $user)
156
+ {
157
+ return new UserResource($user);
158
+ }
159
+ ```
160
+
161
+ ### Use Transactions for Multiple Operations
162
+
163
+ ```php
164
+ // ❌ BAD: Partial failure possible
165
+ $order = Order::create([...]);
166
+ $order->items()->createMany([...]);
167
+
168
+ // ✅ CORRECT: Transaction ensures atomicity
169
+ DB::transaction(function () use ($data) {
170
+ $order = Order::create([...]);
171
+ $order->items()->createMany([...]);
172
+ return $order;
173
+ });
174
+ ```
175
+
176
+ ### Never Use env() Outside Config
177
+
178
+ ```php
179
+ // ❌ BAD: env() won't work with config:cache
180
+ $apiKey = env('API_KEY');
181
+
182
+ // ✅ CORRECT: Use config()
183
+ $apiKey = config('services.api_key');
184
+ ```
185
+
186
+ ---
187
+
188
+ ## 🔵 Date/Time Rules
189
+
190
+ ### Always Store UTC
191
+
192
+ ```php
193
+ // config/app.php
194
+ 'timezone' => 'UTC', // NEVER change this
195
+
196
+ // ❌ BAD: Store local time
197
+ $event->scheduled_at = Carbon::now('Asia/Tokyo');
198
+
199
+ // ✅ CORRECT: Store UTC
200
+ $event->scheduled_at = Carbon::now(); // UTC
201
+ ```
202
+
203
+ ### Always Return ISO 8601 in API
204
+
205
+ ```php
206
+ // ❌ BAD: Local format
207
+ 'created_at' => $this->created_at->format('Y-m-d H:i:s'),
208
+
209
+ // ✅ CORRECT: ISO 8601 UTC
210
+ 'created_at' => $this->created_at?->toISOString(),
211
+ // Output: "2024-01-15T10:30:00.000000Z"
212
+ ```
213
+
214
+ ---
215
+
216
+ ## Quick Reference
217
+
218
+ | Category | ❌ Never Do | ✅ Always Do |
219
+ | --------------- | ----------------------------------- | ------------------------ |
220
+ | **Performance** | `Model::all()` without limit | `Model::paginate()` |
221
+ | | Access relation without `with()` | Eager load with `with()` |
222
+ | | `$this->relation` in Resource | `$this->whenLoaded()` |
223
+ | **Quality** | Validate in Controller | Use FormRequest |
224
+ | | Return Model directly | Return Resource |
225
+ | | `findOrFail($id)` | Route model binding |
226
+ | | Multiple DB ops without transaction | `DB::transaction()` |
227
+ | **Config** | `env()` in code | `config()` |
228
+ | **Dates** | Local timezone | UTC everywhere |
229
+ | | `format('Y-m-d')` | `->toISOString()` |
230
+
231
+ ---
232
+
233
+ ## Development Safeguards
234
+
235
+ Add to `AppServiceProvider::boot()`:
236
+
237
+ ```php
238
+ public function boot(): void
239
+ {
240
+ // Prevent N+1 queries (throws exception on lazy load)
241
+ Model::preventLazyLoading(!app()->isProduction());
242
+
243
+ // Prevent accessing missing attributes
244
+ Model::preventAccessingMissingAttributes(!app()->isProduction());
245
+
246
+ // Prevent silently discarding attributes
247
+ Model::preventSilentlyDiscardingAttributes(!app()->isProduction());
248
+ }
249
+ ```
250
+
251
+ These will throw exceptions during development, helping you catch issues early.
@@ -0,0 +1,159 @@
1
+ # Security Rules
2
+
3
+ > **Non-negotiable rules** for Laravel security. Violations = vulnerabilities.
4
+
5
+ ## 🔴 Mass Assignment Vulnerability
6
+
7
+ **ALWAYS define `$fillable` in Models.**
8
+
9
+ ```php
10
+ // ❌ CRITICAL ERROR: No $fillable = mass assignment vulnerability
11
+ class User extends Model
12
+ {
13
+ // Missing $fillable!
14
+ }
15
+
16
+ // ❌ DANGEROUS: Using $request->all()
17
+ User::create($request->all()); // Attacker can set is_admin=true
18
+
19
+ // ✅ CORRECT: Define $fillable explicitly
20
+ class User extends Model
21
+ {
22
+ protected $fillable = [
23
+ 'name_lastname',
24
+ 'name_firstname',
25
+ 'email',
26
+ 'password',
27
+ ];
28
+
29
+ // $guarded is alternative but $fillable is preferred (explicit)
30
+ }
31
+
32
+ // ✅ CORRECT: Use validated data only
33
+ User::create($request->validated());
34
+ ```
35
+
36
+ | Rule | Description |
37
+ | --------------------------------------------- | ------------------------------------------------------ |
38
+ | **Always define `$fillable`** | Explicitly list assignable fields |
39
+ | **Never use `$request->all()`** | Use `$request->validated()` or `$request->only([...])` |
40
+ | **Prefer `$fillable` over `$guarded`** | Whitelist is safer than blacklist |
41
+ | **Never put sensitive fields in `$fillable`** | `is_admin`, `role`, `balance` must NOT be fillable |
42
+
43
+ ---
44
+
45
+ ## 🔴 SQL Injection Prevention
46
+
47
+ **NEVER use raw user input in queries.**
48
+
49
+ ```php
50
+ // ❌ CRITICAL ERROR: SQL Injection vulnerability
51
+ $email = $request->input('email');
52
+ DB::select("SELECT * FROM users WHERE email = '$email'"); // DANGEROUS!
53
+
54
+ // ❌ DANGEROUS: String interpolation in whereRaw
55
+ User::whereRaw("email = '$email'")->get(); // DANGEROUS!
56
+
57
+ // ✅ CORRECT: Use parameter binding
58
+ DB::select("SELECT * FROM users WHERE email = ?", [$email]);
59
+
60
+ // ✅ CORRECT: Use Query Builder (auto-escapes)
61
+ User::where('email', $email)->get();
62
+
63
+ // ✅ CORRECT: Parameter binding in whereRaw
64
+ User::whereRaw('email = ?', [$email])->get();
65
+ ```
66
+
67
+ | Rule | Description |
68
+ | -------------------------------- | ---------------------------------- |
69
+ | **Use Query Builder** | Eloquent auto-escapes values |
70
+ | **Use parameter binding** | `?` placeholders with array values |
71
+ | **Never concatenate user input** | No string interpolation in SQL |
72
+ | **Validate sort fields** | Whitelist allowed sort columns |
73
+
74
+ ```php
75
+ // ✅ CORRECT: Whitelist sort fields to prevent SQL injection
76
+ $allowedSorts = ['id', 'name', 'email', 'created_at'];
77
+ $sortBy = in_array($request->sort_by, $allowedSorts)
78
+ ? $request->sort_by
79
+ : 'id';
80
+ ```
81
+
82
+ ---
83
+
84
+ ## 🔴 XSS Prevention
85
+
86
+ **Always escape output in Blade templates.**
87
+
88
+ ```php
89
+ // ❌ DANGEROUS: Raw HTML output
90
+ {!! $user->bio !!} // XSS if bio contains <script>
91
+
92
+ // ✅ CORRECT: Escaped output (default)
93
+ {{ $user->bio }} // Auto-escapes HTML entities
94
+
95
+ // ✅ CORRECT: Only use {!! !!} for trusted HTML
96
+ {!! $trustedHtml !!} // Only for admin-generated content
97
+ ```
98
+
99
+ ---
100
+
101
+ ## 🔴 CSRF Protection
102
+
103
+ **Never disable CSRF for web routes.**
104
+
105
+ ```php
106
+ // ❌ DANGEROUS: Disabling CSRF
107
+ // In VerifyCsrfToken middleware
108
+ protected $except = ['*']; // NEVER do this!
109
+
110
+ // ✅ CORRECT: CSRF is enabled by default for web routes
111
+ // API routes use Sanctum tokens instead
112
+ ```
113
+
114
+ ---
115
+
116
+ ## 🔴 Sensitive Data Exposure
117
+
118
+ **Hide sensitive fields from JSON responses.**
119
+
120
+ ```php
121
+ // ❌ ERROR: Password exposed in API response
122
+ return response()->json($user); // Includes password!
123
+
124
+ // ✅ CORRECT: Use $hidden in Model
125
+ class User extends Model
126
+ {
127
+ protected $hidden = [
128
+ 'password',
129
+ 'remember_token',
130
+ 'two_factor_secret',
131
+ ];
132
+ }
133
+
134
+ // ✅ CORRECT: Use Resource to control output
135
+ class UserResource extends JsonResource
136
+ {
137
+ public function toArray($request): array
138
+ {
139
+ return [
140
+ 'id' => $this->id,
141
+ 'name' => $this->name,
142
+ // password NOT included
143
+ ];
144
+ }
145
+ }
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Quick Reference
151
+
152
+ | ❌ Never Do | ✅ Always Do |
153
+ | ----------------------- | --------------------------------- |
154
+ | `$request->all()` | `$request->validated()` |
155
+ | Raw SQL with user input | Query Builder / parameter binding |
156
+ | Missing `$fillable` | Define `$fillable` explicitly |
157
+ | Missing `$hidden` | Hide sensitive fields |
158
+ | Disable CSRF | Keep CSRF enabled |
159
+ | `{!! $userInput !!}` | `{{ $userInput }}` |
@@ -0,0 +1,201 @@
1
+ # Bug Fix Workflow
2
+
3
+ > Step-by-step guide for fixing bugs.
4
+
5
+ ## Overview
6
+
7
+ ```mermaid
8
+ flowchart LR
9
+ Reproduce --> Locate --> Fix --> Test --> PR
10
+ ```
11
+
12
+ | Step | Action | Output |
13
+ | ---- | --------------------- | ------------------------------ |
14
+ | 1 | Reproduce the bug | Clear reproduction steps |
15
+ | 2 | Locate the cause | File(s) and line(s) identified |
16
+ | 3 | Write failing test | Test that reproduces bug |
17
+ | 4 | Fix the bug | Code changes |
18
+ | 5 | Verify test passes | `./artisan test` |
19
+ | 6 | Check for regressions | All tests pass |
20
+ | 7 | Create PR | Pull request |
21
+
22
+ ---
23
+
24
+ ## Step 1: Reproduce
25
+
26
+ Before fixing, confirm you can reproduce:
27
+
28
+ ```bash
29
+ # Check logs
30
+ tail -f backend/storage/logs/laravel.log
31
+
32
+ # Test the endpoint
33
+ curl -X GET https://api.boilerplate.app/api/users
34
+ ```
35
+
36
+ **Document:**
37
+ - Steps to reproduce
38
+ - Expected behavior
39
+ - Actual behavior
40
+ - Error message/stack trace
41
+
42
+ ---
43
+
44
+ ## Step 2: Locate the Cause
45
+
46
+ ### Common Locations
47
+
48
+ | Symptom | Check |
49
+ | ------------------- | -------------------------------- |
50
+ | 500 error | `storage/logs/laravel.log` |
51
+ | 422 validation | `*Request.php` rules |
52
+ | Wrong data returned | `*Resource.php` |
53
+ | 404 not found | `routes/api.php` + model binding |
54
+ | N+1 queries | Missing `with()` in controller |
55
+ | Date format wrong | Missing `->toISOString()` |
56
+
57
+ ### Debug Commands
58
+
59
+ ```bash
60
+ # Check route exists
61
+ ./artisan route:list | grep users
62
+
63
+ # Check model
64
+ ./artisan tinker
65
+ >>> User::find(1)
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Step 3: Write Failing Test
71
+
72
+ **ALWAYS write a test that reproduces the bug first.**
73
+
74
+ ```php
75
+ // tests/Feature/Api/UserControllerTest.php
76
+
77
+ it('異常: bug #123 - returns 500 when name is null', function () {
78
+ // This should NOT happen but currently does
79
+ $response = $this->postJson('/api/users', [
80
+ 'email' => 'test@example.com',
81
+ 'password' => 'password123',
82
+ // name is missing - should return 422, not 500
83
+ ]);
84
+
85
+ $response->assertUnprocessable(); // Currently fails with 500
86
+ });
87
+ ```
88
+
89
+ Run test to confirm it fails:
90
+
91
+ ```bash
92
+ ./artisan test --filter="bug #123"
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Step 4: Fix the Bug
98
+
99
+ Make the minimal change to fix the issue.
100
+
101
+ **Don't:**
102
+ - Refactor unrelated code
103
+ - Add features
104
+ - Change coding style
105
+
106
+ **Do:**
107
+ - Fix only the bug
108
+ - Keep changes focused
109
+ - Follow existing patterns
110
+
111
+ ---
112
+
113
+ ## Step 5: Verify Fix
114
+
115
+ ```bash
116
+ # Run the specific test
117
+ ./artisan test --filter="bug #123"
118
+
119
+ # Run all tests for the affected controller
120
+ ./artisan test --filter=UserControllerTest
121
+
122
+ # Run all tests
123
+ ./artisan test
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Step 6: Check for Regressions
129
+
130
+ ```bash
131
+ # All backend tests
132
+ ./artisan test
133
+
134
+ # Specific test file
135
+ ./artisan test tests/Feature/Api/UserControllerTest.php
136
+ ```
137
+
138
+ ---
139
+
140
+ ## Step 7: Create PR
141
+
142
+ ### PR Title Format
143
+
144
+ ```
145
+ fix: [#issue] brief description
146
+ ```
147
+
148
+ Example: `fix: [#123] return 422 instead of 500 when name is missing`
149
+
150
+ ### PR Description
151
+
152
+ ```markdown
153
+ ## Bug
154
+
155
+ [Link to issue or description]
156
+
157
+ ## Root Cause
158
+
159
+ [Explanation of what caused the bug]
160
+
161
+ ## Fix
162
+
163
+ [Description of the fix]
164
+
165
+ ## Test
166
+
167
+ - [ ] Added test that reproduces bug
168
+ - [ ] Test passes after fix
169
+ - [ ] All existing tests pass
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Debugging Tips
175
+
176
+ ### Laravel Logs
177
+
178
+ ```php
179
+ // Add temporary logging
180
+ Log::info('Debug', ['user' => $user, 'request' => $request->all()]);
181
+ ```
182
+
183
+ ### Database Queries
184
+
185
+ ```php
186
+ // Enable query log
187
+ DB::enableQueryLog();
188
+
189
+ // ... your code ...
190
+
191
+ // Dump queries
192
+ dd(DB::getQueryLog());
193
+ ```
194
+
195
+ ### Tinker
196
+
197
+ ```bash
198
+ ./artisan tinker
199
+ >>> User::where('email', 'test@example.com')->first()
200
+ >>> app(UserService::class)->someMethod()
201
+ ```