@famgia/omnify-ai-guides 2.0.15

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 (91) hide show
  1. package/README.md +105 -0
  2. package/dist/chunk-RCTEXK7C.js +549 -0
  3. package/dist/chunk-RCTEXK7C.js.map +1 -0
  4. package/dist/config/rules.yaml +524 -0
  5. package/dist/index.cjs +587 -0
  6. package/dist/index.cjs.map +1 -0
  7. package/dist/index.d.cts +55 -0
  8. package/dist/index.d.ts +55 -0
  9. package/dist/index.js +26 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/knowledge/agents/architect.md.stub +150 -0
  12. package/dist/knowledge/agents/developer.md.stub +190 -0
  13. package/dist/knowledge/agents/reviewer.md.stub +134 -0
  14. package/dist/knowledge/agents/tester.md.stub +196 -0
  15. package/dist/knowledge/checklists/backend.md.stub +112 -0
  16. package/dist/knowledge/checklists/react.md.stub +108 -0
  17. package/dist/knowledge/claude-rules/laravel-controllers.md.stub +57 -0
  18. package/dist/knowledge/claude-rules/laravel-migrations.md.stub +47 -0
  19. package/dist/knowledge/claude-rules/laravel-tests.md.stub +52 -0
  20. package/dist/knowledge/claude-rules/naming.md.stub +369 -0
  21. package/dist/knowledge/claude-rules/performance.md.stub +256 -0
  22. package/dist/knowledge/claude-rules/php-standards.md.stub +305 -0
  23. package/dist/knowledge/claude-rules/react-components.md.stub +67 -0
  24. package/dist/knowledge/claude-rules/schema-yaml.md.stub +83 -0
  25. package/dist/knowledge/claude-rules/security.md.stub +164 -0
  26. package/dist/knowledge/cursor-rules/antd-deprecations.mdc.stub +62 -0
  27. package/dist/knowledge/cursor-rules/basemodel-readonly.mdc.stub +66 -0
  28. package/dist/knowledge/cursor-rules/baserequest-readonly.mdc.stub +74 -0
  29. package/dist/knowledge/cursor-rules/baseresource-readonly.mdc.stub +78 -0
  30. package/dist/knowledge/cursor-rules/laravel-controller.mdc.stub +421 -0
  31. package/dist/knowledge/cursor-rules/laravel-request.mdc.stub +112 -0
  32. package/dist/knowledge/cursor-rules/laravel-resource.mdc.stub +73 -0
  33. package/dist/knowledge/cursor-rules/laravel-review.mdc.stub +69 -0
  34. package/dist/knowledge/cursor-rules/laravel-testing.mdc.stub +138 -0
  35. package/dist/knowledge/cursor-rules/laravel.mdc.stub +138 -0
  36. package/dist/knowledge/cursor-rules/migrations-workflow.mdc.stub +224 -0
  37. package/dist/knowledge/cursor-rules/model-editable.mdc.stub +120 -0
  38. package/dist/knowledge/cursor-rules/omnify-migrations.mdc.stub +109 -0
  39. package/dist/knowledge/cursor-rules/omnify-schema.mdc.stub +358 -0
  40. package/dist/knowledge/cursor-rules/omnify.mdc.stub +58 -0
  41. package/dist/knowledge/cursor-rules/react-design.mdc.stub +693 -0
  42. package/dist/knowledge/cursor-rules/react-form.mdc.stub +292 -0
  43. package/dist/knowledge/cursor-rules/react-services.mdc.stub +304 -0
  44. package/dist/knowledge/cursor-rules/react.mdc.stub +336 -0
  45. package/dist/knowledge/cursor-rules/request-editable.mdc.stub +111 -0
  46. package/dist/knowledge/cursor-rules/resource-editable.mdc.stub +125 -0
  47. package/dist/knowledge/cursor-rules/schema-create.mdc.stub +440 -0
  48. package/dist/knowledge/cursor-rules/validation-rules.mdc.stub +181 -0
  49. package/dist/knowledge/laravel/README.md.stub +59 -0
  50. package/dist/knowledge/laravel/architecture.md.stub +424 -0
  51. package/dist/knowledge/laravel/authentication.md.stub +588 -0
  52. package/dist/knowledge/laravel/controller.md.stub +484 -0
  53. package/dist/knowledge/laravel/datetime.md.stub +334 -0
  54. package/dist/knowledge/laravel/migrations-team.md.stub +376 -0
  55. package/dist/knowledge/laravel/openapi.md.stub +449 -0
  56. package/dist/knowledge/laravel/request.md.stub +450 -0
  57. package/dist/knowledge/laravel/resource.md.stub +516 -0
  58. package/dist/knowledge/laravel/service.md.stub +503 -0
  59. package/dist/knowledge/laravel/testing.md.stub +1504 -0
  60. package/dist/knowledge/omnify/antdesign-guide.md.stub +401 -0
  61. package/dist/knowledge/omnify/config-guide.md.stub +405 -0
  62. package/dist/knowledge/omnify/japan-guide.md.stub +186 -0
  63. package/dist/knowledge/omnify/laravel-guide.md.stub +61 -0
  64. package/dist/knowledge/omnify/partial-schema-guide.md.stub +353 -0
  65. package/dist/knowledge/omnify/react-form-guide.md.stub +225 -0
  66. package/dist/knowledge/omnify/schema-guide.md.stub +144 -0
  67. package/dist/knowledge/omnify/typescript-guide.md.stub +337 -0
  68. package/dist/knowledge/react/README.md.stub +221 -0
  69. package/dist/knowledge/react/antd-guide.md +528 -0
  70. package/dist/knowledge/react/antd-guide.md.stub +528 -0
  71. package/dist/knowledge/react/checklist.md.stub +108 -0
  72. package/dist/knowledge/react/datetime-guide.md.stub +137 -0
  73. package/dist/knowledge/react/design-philosophy.md.stub +363 -0
  74. package/dist/knowledge/react/i18n-guide.md.stub +211 -0
  75. package/dist/knowledge/react/laravel-integration.md.stub +181 -0
  76. package/dist/knowledge/react/service-pattern.md.stub +180 -0
  77. package/dist/knowledge/react/tanstack-query.md.stub +339 -0
  78. package/dist/knowledge/react/types-guide.md +669 -0
  79. package/dist/knowledge/react/types-guide.md.stub +669 -0
  80. package/dist/knowledge/workflows/bug-fix.md.stub +201 -0
  81. package/dist/knowledge/workflows/code-review.md.stub +164 -0
  82. package/dist/knowledge/workflows/new-feature.md.stub +327 -0
  83. package/dist/plugin-M95GyBll.d.cts +191 -0
  84. package/dist/plugin-M95GyBll.d.ts +191 -0
  85. package/dist/plugin.cjs +573 -0
  86. package/dist/plugin.cjs.map +1 -0
  87. package/dist/plugin.d.cts +2 -0
  88. package/dist/plugin.d.ts +2 -0
  89. package/dist/plugin.js +15 -0
  90. package/dist/plugin.js.map +1 -0
  91. package/package.json +53 -0
@@ -0,0 +1,369 @@
1
+ ---
2
+ paths:
3
+ - "{{LARAVEL_ROOT}}app/**/*.php"
4
+ ---
5
+
6
+ # Naming Conventions Guide
7
+
8
+ > **Related:** [README](./README.md) | [Testing Guide](./testing-guide.md)
9
+
10
+ ## Overview
11
+
12
+ Consistent naming is critical for maintainability. This guide defines naming patterns for all backend code.
13
+
14
+ ---
15
+
16
+ ## PHP Imports
17
+
18
+ **Always use `use` statements. Never use FQCN (Fully Qualified Class Name) inline.**
19
+
20
+ ```php
21
+ // ❌ WRONG: Inline FQCN
22
+ public function store(): \Illuminate\Http\JsonResponse
23
+ {
24
+ return new \App\Http\Resources\UserResource($user);
25
+ }
26
+
27
+ // ✅ CORRECT: Import at top, use short names
28
+ use Illuminate\Http\JsonResponse;
29
+ use App\Http\Resources\UserResource;
30
+
31
+ public function store(): JsonResponse
32
+ {
33
+ return new UserResource($user);
34
+ }
35
+ ```
36
+
37
+ | Rule | Description |
38
+ | ------------------ | -------------------------------- |
39
+ | Import all classes | Use `use` at top of file |
40
+ | Short class names | Never `\Full\Path\Class` inline |
41
+ | Group imports | Framework, then App, then Others |
42
+ | No unused imports | Remove unused `use` statements |
43
+
44
+ ---
45
+
46
+ ## File & Class Naming
47
+
48
+ ### Pattern: `{Model}{Type}.php`
49
+
50
+ | Type | Pattern | Example |
51
+ | ---------- | ------------------------ | ------------------------- |
52
+ | Controller | `{Model}Controller` | `UserController.php` |
53
+ | Request | `{Model}{Action}Request` | `UserStoreRequest.php` |
54
+ | Resource | `{Model}Resource` | `UserResource.php` |
55
+ | Model | `{Model}` (singular) | `User.php` |
56
+ | Service | `{Model}Service` | `OrderService.php` |
57
+ | Action | `{Verb}{Noun}Action` | `CreateInvoiceAction.php` |
58
+ | Job | `{Verb}{Noun}Job` | `SendWelcomeEmailJob.php` |
59
+ | Event | `{Model}{PastTense}` | `UserRegistered.php` |
60
+ | Observer | `{Model}Observer` | `UserObserver.php` |
61
+ | Policy | `{Model}Policy` | `UserPolicy.php` |
62
+ | Test | `{Model}ControllerTest` | `UserControllerTest.php` |
63
+
64
+ ### Request Naming
65
+
66
+ | Action | Pattern | Example |
67
+ | ------ | ---------------------- | ----------------------- |
68
+ | Create | `{Model}StoreRequest` | `UserStoreRequest.php` |
69
+ | Update | `{Model}UpdateRequest` | `UserUpdateRequest.php` |
70
+
71
+ > **Note:** Use `Store` (not `Create`) and `Update` (not `Edit`) to match Laravel CRUD conventions.
72
+
73
+ ---
74
+
75
+ ## Method Naming
76
+
77
+ ### Controller Methods (RESTful)
78
+
79
+ | HTTP Method | Controller Method | Route | Description |
80
+ | ----------- | ----------------- | ----------------- | --------------- |
81
+ | GET | `index()` | `/api/users` | List all |
82
+ | POST | `store()` | `/api/users` | Create new |
83
+ | GET | `show()` | `/api/users/{id}` | Get single |
84
+ | PUT/PATCH | `update()` | `/api/users/{id}` | Update existing |
85
+ | DELETE | `destroy()` | `/api/users/{id}` | Delete |
86
+
87
+ ### Service Methods
88
+
89
+ | Pattern | Example |
90
+ | --------------------- | ------------------------- |
91
+ | `{verb}{Noun}` | `processPayment()` |
92
+ | `{verb}{Noun}{State}` | `calculateTotalWithTax()` |
93
+
94
+ ```php
95
+ // ✅ Good
96
+ public function processPayment(Order $order): Payment
97
+ public function calculateDiscount(Cart $cart): float
98
+ public function sendNotification(User $user): void
99
+
100
+ // ❌ Bad
101
+ public function payment(Order $order) // Missing verb
102
+ public function doStuff() // Too vague
103
+ ```
104
+
105
+ ### Model Methods
106
+
107
+ | Type | Pattern | Example |
108
+ | -------- | --------------------- | ----------------------- |
109
+ | Scope | `scope{Name}` | `scopeActive($query)` |
110
+ | Accessor | `{attribute}` (PHP 8) | `fullName(): Attribute` |
111
+ | Mutator | `{attribute}` (PHP 8) | `password(): Attribute` |
112
+ | Relation | `{relation}` (noun) | `posts()`, `author()` |
113
+
114
+ ```php
115
+ // Scope - filter queries
116
+ public function scopeActive(Builder $query): Builder
117
+ {
118
+ return $query->where('status', 'active');
119
+ }
120
+
121
+ // Accessor (PHP 8+)
122
+ protected function fullName(): Attribute
123
+ {
124
+ return Attribute::get(fn () => "{$this->first_name} {$this->last_name}");
125
+ }
126
+
127
+ // Relationship
128
+ public function posts(): HasMany
129
+ {
130
+ return $this->hasMany(Post::class);
131
+ }
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Test Naming (PEST)
137
+
138
+ Use `describe()` to group tests by endpoint, `it()` for individual test cases.
139
+
140
+ ### Naming Rules
141
+
142
+ | Category | Prefix | Pattern | Example |
143
+ | --------------------- | ------- | ---------------------------------------- | ----------------------------------------------------- |
144
+ | **正常系 (Normal)** | `正常:` | `it('正常: {verb} {what}')` | `it('正常: creates user with valid data')` |
145
+ | **異常系 (Abnormal)** | `異常:` | `it('異常: fails to {action} {reason}')` | `it('異常: fails to create user with invalid email')` |
146
+ | **異常系 (404/401)** | `異常:` | `it('異常: returns {status} {reason}')` | `it('異常: returns 404 when user not found')` |
147
+
148
+ ### 正常系 (Normal Cases) - Success Behavior
149
+
150
+ **Pattern:** `it('正常: {verb} {what}')`
151
+
152
+ **Common verbs:** `returns`, `creates`, `updates`, `deletes`, `filters`, `sorts`, `paginates`
153
+
154
+ ```php
155
+ // GET (index)
156
+ it('正常: returns paginated users')
157
+ it('正常: returns users filtered by search')
158
+ it('正常: returns users sorted by created_at')
159
+
160
+ // POST (store)
161
+ it('正常: creates user with valid data')
162
+
163
+ // GET (show)
164
+ it('正常: returns user by id')
165
+
166
+ // PUT (update)
167
+ it('正常: updates user with valid data')
168
+ it('正常: updates user with partial data')
169
+
170
+ // DELETE (destroy)
171
+ it('正常: deletes user')
172
+ ```
173
+
174
+ ### 異常系 (Abnormal Cases) - Failure Behavior
175
+
176
+ **Pattern:** `it('異常: fails to {action} {reason}')` or `it('異常: returns {status} {reason}')`
177
+
178
+ ```php
179
+ // Validation errors (422) - use "fails to"
180
+ it('異常: fails to create user with missing email')
181
+ it('異常: fails to create user with invalid email format')
182
+ it('異常: fails to create user with duplicate email')
183
+ it('異常: fails to create user with short password')
184
+ it('異常: fails to create user with invalid kana format') // Japanese
185
+ it('異常: fails to update user with invalid data')
186
+
187
+ // Not found (404) - use "returns 404"
188
+ it('異常: returns 404 when user not found')
189
+ it('異常: returns 404 when updating nonexistent user')
190
+ it('異常: returns 404 when deleting nonexistent user')
191
+
192
+ // Authentication (401) - use "returns 401"
193
+ it('異常: returns 401 when not authenticated')
194
+
195
+ // Authorization (403) - use "returns 403"
196
+ it('異常: returns 403 when user cannot access resource')
197
+ it('異常: returns 403 when deleting without admin role')
198
+ ```
199
+
200
+ ### Complete Example
201
+
202
+ ```php
203
+ describe('POST /api/users', function () {
204
+ // ================================================================
205
+ // 正常系 (Normal Cases)
206
+ // ================================================================
207
+ it('正常: creates user with valid data', function () { ... });
208
+
209
+ // ================================================================
210
+ // 異常系 (Abnormal Cases)
211
+ // ================================================================
212
+
213
+ // Required fields
214
+ it('異常: fails to create user with missing email', function () { ... });
215
+ it('異常: fails to create user with missing password', function () { ... });
216
+
217
+ // Format validation
218
+ it('異常: fails to create user with invalid email format', function () { ... });
219
+ it('異常: fails to create user with short password', function () { ... });
220
+
221
+ // Unique constraint
222
+ it('異常: fails to create user with duplicate email', function () { ... });
223
+
224
+ // Japanese field validation
225
+ it('異常: fails to create user with invalid kana format', function () { ... });
226
+ });
227
+
228
+ describe('GET /api/users/{id}', function () {
229
+ // 正常系
230
+ it('正常: returns user by id', function () { ... });
231
+
232
+ // 異常系
233
+ it('異常: returns 404 when user not found', function () { ... });
234
+ });
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Database Naming
240
+
241
+ ### Tables
242
+
243
+ | Pattern | Example |
244
+ | ------------------------ | ----------- |
245
+ | Plural, snake_case | `users` |
246
+ | Pivot: singular_singular | `post_tag` |
247
+ | (alphabetical order) | `role_user` |
248
+
249
+ ### Columns
250
+
251
+ | Type | Pattern | Example |
252
+ | ------------- | ------------------ | -------------------- |
253
+ | Primary key | `id` | `id` |
254
+ | Foreign key | `{table}_id` | `user_id` |
255
+ | Boolean | `is_{state}` | `is_active` |
256
+ | Timestamp | `{action}_at` | `verified_at` |
257
+ | Japanese name | `name_{part}` | `name_lastname` |
258
+ | Japanese kana | `name_kana_{part}` | `name_kana_lastname` |
259
+
260
+ ### Japanese Name Fields (JapaneseName type)
261
+
262
+ | Field | Description | Max Length |
263
+ | --------------------- | ---------------- | ---------- |
264
+ | `name_lastname` | Family name (姓) | 50 |
265
+ | `name_firstname` | Given name (名) | 50 |
266
+ | `name_kana_lastname` | Family name kana | 100 |
267
+ | `name_kana_firstname` | Given name kana | 100 |
268
+
269
+ ---
270
+
271
+ ## Route Naming
272
+
273
+ ### API Routes
274
+
275
+ | Pattern | Example |
276
+ | ------------------ | -------------------------- |
277
+ | Plural resource | `/api/users` |
278
+ | Nested resource | `/api/users/{user}/posts` |
279
+ | Action on resource | `/api/orders/{order}/ship` |
280
+
281
+ ```php
282
+ // routes/api.php
283
+ Route::apiResource('users', UserController::class);
284
+ Route::apiResource('posts', PostController::class);
285
+
286
+ // Nested
287
+ Route::apiResource('users.posts', UserPostController::class);
288
+
289
+ // Custom actions
290
+ Route::post('/orders/{order}/ship', [OrderController::class, 'ship']);
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Variable Naming
296
+
297
+ ### PHP Variables
298
+
299
+ | Type | Pattern | Example |
300
+ | -------------- | ------------ | ------------------ |
301
+ | Model instance | `$camelCase` | `$user`, `$post` |
302
+ | Collection | `$plural` | `$users`, `$posts` |
303
+ | Boolean | `$is{State}` | `$isActive` |
304
+ | Query builder | `$query` | `$query` |
305
+
306
+ ```php
307
+ // ✅ Good
308
+ $user = User::find($id);
309
+ $users = User::all();
310
+ $isActive = $user->status === 'active';
311
+
312
+ // ❌ Bad
313
+ $u = User::find($id); // Too short
314
+ $userData = User::find($id); // Redundant "Data"
315
+ $active = true; // Missing "is" prefix for boolean
316
+ ```
317
+
318
+ ---
319
+
320
+ ## OpenAPI/Swagger Naming
321
+
322
+ ### Tag Names
323
+
324
+ | Pattern | Example |
325
+ | ------------------ | ------- |
326
+ | Plural, PascalCase | `Users` |
327
+
328
+ ### Parameter Names
329
+
330
+ | Type | Pattern | Example |
331
+ | ----- | ------------- | ------------- |
332
+ | Query | `Query{Name}` | `QuerySearch` |
333
+ | Path | `Path{Name}` | `PathId` |
334
+
335
+ ### Response Names
336
+
337
+ | Pattern | Example |
338
+ | --------------- | ----------------- |
339
+ | `{Description}` | `Success` |
340
+ | `{HttpStatus}` | `NotFound` |
341
+ | `{Error}Error` | `ValidationError` |
342
+
343
+ ---
344
+
345
+ ## Summary Table
346
+
347
+ | Type | Convention | Example |
348
+ | -------------------- | ---------------------------------------- | ----------------------------------------------------- |
349
+ | **Imports** | | |
350
+ | PHP imports | `use` at top, short name inline | `use JsonResponse;` → `: JsonResponse` |
351
+ | **Files** | | |
352
+ | Controller | `{Model}Controller` | `UserController.php` |
353
+ | Request | `{Model}{Action}Request` | `UserStoreRequest.php` |
354
+ | Resource | `{Model}Resource` | `UserResource.php` |
355
+ | Test | `{Model}ControllerTest` | `UserControllerTest.php` |
356
+ | **Methods** | | |
357
+ | Controller | RESTful verbs | `index`, `store`, `show` |
358
+ | Service | `{verb}{Noun}` | `processPayment()` |
359
+ | Scope | `scope{Name}` | `scopeActive()` |
360
+ | **Test Naming** | | |
361
+ | 正常系 (Normal) | `it('正常: {verb} {what}')` | `it('正常: creates user with valid data')` |
362
+ | 異常系 (Abnormal) | `it('異常: fails to {action} {reason}')` | `it('異常: fails to create user with invalid email')` |
363
+ | 異常系 (404/401/403) | `it('異常: returns {status} {reason}')` | `it('異常: returns 404 when user not found')` |
364
+ | **Database** | | |
365
+ | Table | plural, snake_case | `users`, `order_items` |
366
+ | Column | snake_case | `user_id`, `created_at` |
367
+ | Boolean column | `is_{state}` | `is_verified` |
368
+ | **Routes** | | |
369
+ | API | plural, kebab-case | `/api/users`, `/api/order-items` |
@@ -0,0 +1,256 @@
1
+ ---
2
+ paths:
3
+ - "{{LARAVEL_ROOT}}app/**/*.php"
4
+ ---
5
+
6
+ # Performance & Quality Rules
7
+
8
+ > **Non-negotiable rules** for Laravel performance and code quality.
9
+
10
+ ## 🟠 N+1 Query Problem
11
+
12
+ **Always eager load relationships.**
13
+
14
+ ```php
15
+ // ❌ N+1 PROBLEM: 1 + N queries (N = number of posts)
16
+ $posts = Post::all();
17
+ foreach ($posts as $post) {
18
+ echo $post->author->name; // Query for each post!
19
+ }
20
+
21
+ // ✅ CORRECT: Eager loading with with()
22
+ $posts = Post::with('author')->get();
23
+ foreach ($posts as $post) {
24
+ echo $post->author->name; // No extra queries
25
+ }
26
+
27
+ // ✅ CORRECT: Multiple relationships
28
+ $posts = Post::with(['author', 'comments', 'tags'])->get();
29
+
30
+ // ✅ CORRECT: Nested eager loading
31
+ $posts = Post::with('comments.author')->get();
32
+ ```
33
+
34
+ **Enable N+1 detection in development:**
35
+
36
+ ```php
37
+ // In AppServiceProvider boot()
38
+ use Illuminate\Database\Eloquent\Model;
39
+
40
+ public function boot(): void
41
+ {
42
+ // Throw exception on lazy loading (dev only)
43
+ Model::preventLazyLoading(!app()->isProduction());
44
+ }
45
+ ```
46
+
47
+ ---
48
+
49
+ ## 🟠 Use `whenLoaded()` in Resources
50
+
51
+ **Prevent queries in Resources.**
52
+
53
+ ```php
54
+ // ❌ ERROR: Triggers query if not eager loaded
55
+ class PostResource extends JsonResource
56
+ {
57
+ public function toArray($request): array
58
+ {
59
+ return [
60
+ 'author' => new UserResource($this->author), // N+1!
61
+ ];
62
+ }
63
+ }
64
+
65
+ // ✅ CORRECT: Only include if already loaded
66
+ class PostResource extends JsonResource
67
+ {
68
+ public function toArray($request): array
69
+ {
70
+ return [
71
+ 'author' => new UserResource($this->whenLoaded('author')),
72
+ ];
73
+ }
74
+ }
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 🟠 Pagination for List Endpoints
80
+
81
+ **Never return all records.**
82
+
83
+ ```php
84
+ // ❌ ERROR: Returns all records (memory + performance)
85
+ public function index()
86
+ {
87
+ return UserResource::collection(User::all()); // 1M users = crash
88
+ }
89
+
90
+ // ✅ CORRECT: Always paginate
91
+ public function index(Request $request)
92
+ {
93
+ $perPage = min($request->input('per_page', 15), 100); // Max 100
94
+ return UserResource::collection(User::paginate($perPage));
95
+ }
96
+ ```
97
+
98
+ ---
99
+
100
+ ## 🟠 Select Only Needed Columns
101
+
102
+ **Don't SELECT * when you need few fields.**
103
+
104
+ ```php
105
+ // ❌ INEFFICIENT: Fetches all columns
106
+ $users = User::all();
107
+ $names = $users->pluck('name');
108
+
109
+ // ✅ EFFICIENT: Select only needed columns
110
+ $names = User::pluck('name');
111
+
112
+ // ✅ EFFICIENT: For multiple columns
113
+ $users = User::select(['id', 'name', 'email'])->get();
114
+ ```
115
+
116
+ ---
117
+
118
+ ## 🟡 Code Quality Rules
119
+
120
+ ### Never Validate in Controller
121
+
122
+ ```php
123
+ // ❌ BAD: Validation in controller
124
+ public function store(Request $request)
125
+ {
126
+ $validated = $request->validate([...]);
127
+ }
128
+
129
+ // ✅ CORRECT: Use FormRequest
130
+ public function store(UserStoreRequest $request)
131
+ {
132
+ $user = User::create($request->validated());
133
+ return new UserResource($user);
134
+ }
135
+ ```
136
+
137
+ ### Always Use Resource for Responses
138
+
139
+ ```php
140
+ // ❌ BAD: Exposes all fields, inconsistent format
141
+ return $user;
142
+ return response()->json($user);
143
+
144
+ // ✅ CORRECT: Use Resource
145
+ return new UserResource($user);
146
+ return UserResource::collection($users);
147
+ ```
148
+
149
+ ### Use Route Model Binding
150
+
151
+ ```php
152
+ // ❌ BAD: Manual find
153
+ public function show(int $id)
154
+ {
155
+ $user = User::findOrFail($id);
156
+ return new UserResource($user);
157
+ }
158
+
159
+ // ✅ CORRECT: Route model binding
160
+ public function show(User $user)
161
+ {
162
+ return new UserResource($user);
163
+ }
164
+ ```
165
+
166
+ ### Use Transactions for Multiple Operations
167
+
168
+ ```php
169
+ // ❌ BAD: Partial failure possible
170
+ $order = Order::create([...]);
171
+ $order->items()->createMany([...]);
172
+
173
+ // ✅ CORRECT: Transaction ensures atomicity
174
+ DB::transaction(function () use ($data) {
175
+ $order = Order::create([...]);
176
+ $order->items()->createMany([...]);
177
+ return $order;
178
+ });
179
+ ```
180
+
181
+ ### Never Use env() Outside Config
182
+
183
+ ```php
184
+ // ❌ BAD: env() won't work with config:cache
185
+ $apiKey = env('API_KEY');
186
+
187
+ // ✅ CORRECT: Use config()
188
+ $apiKey = config('services.api_key');
189
+ ```
190
+
191
+ ---
192
+
193
+ ## 🔵 Date/Time Rules
194
+
195
+ ### Always Store UTC
196
+
197
+ ```php
198
+ // config/app.php
199
+ 'timezone' => 'UTC', // NEVER change this
200
+
201
+ // ❌ BAD: Store local time
202
+ $event->scheduled_at = Carbon::now('Asia/Tokyo');
203
+
204
+ // ✅ CORRECT: Store UTC
205
+ $event->scheduled_at = Carbon::now(); // UTC
206
+ ```
207
+
208
+ ### Always Return ISO 8601 in API
209
+
210
+ ```php
211
+ // ❌ BAD: Local format
212
+ 'created_at' => $this->created_at->format('Y-m-d H:i:s'),
213
+
214
+ // ✅ CORRECT: ISO 8601 UTC
215
+ 'created_at' => $this->created_at?->toISOString(),
216
+ // Output: "2024-01-15T10:30:00.000000Z"
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Quick Reference
222
+
223
+ | Category | ❌ Never Do | ✅ Always Do |
224
+ | --------------- | ----------------------------------- | ------------------------ |
225
+ | **Performance** | `Model::all()` without limit | `Model::paginate()` |
226
+ | | Access relation without `with()` | Eager load with `with()` |
227
+ | | `$this->relation` in Resource | `$this->whenLoaded()` |
228
+ | **Quality** | Validate in Controller | Use FormRequest |
229
+ | | Return Model directly | Return Resource |
230
+ | | `findOrFail($id)` | Route model binding |
231
+ | | Multiple DB ops without transaction | `DB::transaction()` |
232
+ | **Config** | `env()` in code | `config()` |
233
+ | **Dates** | Local timezone | UTC everywhere |
234
+ | | `format('Y-m-d')` | `->toISOString()` |
235
+
236
+ ---
237
+
238
+ ## Development Safeguards
239
+
240
+ Add to `AppServiceProvider::boot()`:
241
+
242
+ ```php
243
+ public function boot(): void
244
+ {
245
+ // Prevent N+1 queries (throws exception on lazy load)
246
+ Model::preventLazyLoading(!app()->isProduction());
247
+
248
+ // Prevent accessing missing attributes
249
+ Model::preventAccessingMissingAttributes(!app()->isProduction());
250
+
251
+ // Prevent silently discarding attributes
252
+ Model::preventSilentlyDiscardingAttributes(!app()->isProduction());
253
+ }
254
+ ```
255
+
256
+ These will throw exceptions during development, helping you catch issues early.