@famgia/omnify-laravel 0.0.107 → 0.0.109
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/dist/{chunk-7YHLXBF5.js → chunk-GDFAEEEG.js} +35 -1
- package/dist/{chunk-7YHLXBF5.js.map → chunk-GDFAEEEG.js.map} +1 -1
- package/dist/index.cjs +34 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/plugin.cjs +27 -0
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.js +1 -1
- package/package.json +4 -4
- package/stubs/ai-guides/cursor/laravel-controller.mdc.stub +30 -0
- package/stubs/ai-guides/cursor/laravel.mdc.stub +15 -1
- package/stubs/ai-guides/cursor/omnify-migrations.mdc.stub +109 -0
- package/stubs/ai-guides/laravel/openapi.md.stub +85 -5
package/dist/plugin.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@famgia/omnify-laravel",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.109",
|
|
4
4
|
"description": "Laravel migration and TypeScript type generator for omnify-schema",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"README.md"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@famgia/omnify-types": "0.0.
|
|
29
|
-
"@famgia/omnify-core": "0.0.
|
|
30
|
-
"@famgia/omnify-atlas": "0.0.
|
|
28
|
+
"@famgia/omnify-types": "0.0.98",
|
|
29
|
+
"@famgia/omnify-core": "0.0.100",
|
|
30
|
+
"@famgia/omnify-atlas": "0.0.94"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
33
|
"build": "tsup",
|
|
@@ -6,6 +6,36 @@ alwaysApply: false
|
|
|
6
6
|
|
|
7
7
|
# Controller Rules
|
|
8
8
|
|
|
9
|
+
## ⚠️ CRITICAL: Check Route Prefix BEFORE Writing OpenAPI
|
|
10
|
+
|
|
11
|
+
**MUST check route file prefix first!** Don't assume - VERIFY.
|
|
12
|
+
|
|
13
|
+
### Before Writing OpenAPI Path:
|
|
14
|
+
|
|
15
|
+
1. **Check route file** → Which file has your route? (`api.php`, `web.php`, custom?)
|
|
16
|
+
2. **Check prefix** → Look in `RouteServiceProvider` or `bootstrap/app.php`
|
|
17
|
+
3. **Write path WITHOUT prefix** → OpenAPI path = Route definition path
|
|
18
|
+
|
|
19
|
+
```php
|
|
20
|
+
// Route trong api.php (prefix: /api)
|
|
21
|
+
Route::get('/users', [UserController::class, 'index']);
|
|
22
|
+
|
|
23
|
+
// ❌ SAI - Duplicate prefix → /api/api/users !!
|
|
24
|
+
#[OA\Get(path: '/api/users')]
|
|
25
|
+
|
|
26
|
+
// ✅ ĐÚNG - Path không có prefix
|
|
27
|
+
#[OA\Get(path: '/users')] // → /api/users
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
| Route File | Prefix | Route Definition | OpenAPI Path |
|
|
31
|
+
|------------|--------|------------------|--------------|
|
|
32
|
+
| `api.php` | `/api` | `/users` | `/users` |
|
|
33
|
+
| `web.php` | (none) | `/dashboard` | `/dashboard` |
|
|
34
|
+
|
|
35
|
+
**Full guide:** `.claude/guides/laravel/openapi.md`
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
9
39
|
## Golden Rule: Thin Controller
|
|
10
40
|
|
|
11
41
|
```php
|
|
@@ -7,7 +7,20 @@ alwaysApply: false
|
|
|
7
7
|
# Laravel Rules
|
|
8
8
|
|
|
9
9
|
> **Documentation:** `.claude/guides/laravel/`
|
|
10
|
-
> **Specific Rules:** See also `laravel-controller.mdc`, `laravel-resource.mdc`, `laravel-request.mdc`, `laravel-testing.mdc`
|
|
10
|
+
> **Specific Rules:** See also `laravel-controller.mdc`, `laravel-resource.mdc`, `laravel-request.mdc`, `laravel-testing.mdc`, `omnify-migrations.mdc`
|
|
11
|
+
|
|
12
|
+
## ⛔ CRITICAL: DO NOT EDIT
|
|
13
|
+
|
|
14
|
+
| Path | Reason |
|
|
15
|
+
|------|--------|
|
|
16
|
+
| `database/migrations/omnify/**` | Auto-generated by Omnify - will be overwritten! |
|
|
17
|
+
| `app/Models/OmnifyBase/**` | Auto-generated base models |
|
|
18
|
+
| `app/Http/Requests/OmnifyBase/**` | Auto-generated request bases |
|
|
19
|
+
| `app/Http/Resources/OmnifyBase/**` | Auto-generated resource bases |
|
|
20
|
+
|
|
21
|
+
**To modify schema:** Edit YAML in `schemas/` → run `npx omnify generate`
|
|
22
|
+
|
|
23
|
+
---
|
|
11
24
|
|
|
12
25
|
## Critical Rules
|
|
13
26
|
|
|
@@ -18,6 +31,7 @@ alwaysApply: false
|
|
|
18
31
|
5. **Dates** - Store UTC, return `->toISOString()`
|
|
19
32
|
6. **Testing** - Write 正常系 + 異常系 tests (see `laravel-testing.mdc`)
|
|
20
33
|
7. **Imports** - Always `use` and short class names, never FQCN inline
|
|
34
|
+
8. **OpenAPI Paths** - NO `/api` prefix! `api.php` already has it (see `laravel-controller.mdc`)
|
|
21
35
|
|
|
22
36
|
## File-Specific Rules
|
|
23
37
|
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "CRITICAL: Auto-generated Omnify migrations - DO NOT EDIT"
|
|
3
|
+
globs: ["{{LARAVEL_BASE}}/migrations/omnify/**"]
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ⛔ CRITICAL: DO NOT EDIT OMNIFY MIGRATIONS
|
|
8
|
+
|
|
9
|
+
## These files are AUTO-GENERATED
|
|
10
|
+
|
|
11
|
+
All files in `database/migrations/omnify/` are automatically generated by Omnify.
|
|
12
|
+
|
|
13
|
+
**ANY MANUAL CHANGES WILL BE OVERWRITTEN** when running `npx omnify generate`.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## ❌ ABSOLUTELY FORBIDDEN
|
|
18
|
+
|
|
19
|
+
```php
|
|
20
|
+
// NEVER modify files in database/migrations/omnify/
|
|
21
|
+
// Even "simple fixes" will be lost!
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
| Action | Result |
|
|
25
|
+
|--------|--------|
|
|
26
|
+
| Add column manually | ❌ Overwritten on next generate |
|
|
27
|
+
| Modify column type | ❌ Overwritten on next generate |
|
|
28
|
+
| Add index manually | ❌ Overwritten on next generate |
|
|
29
|
+
| Fix "typo" | ❌ Overwritten on next generate |
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## ✅ CORRECT APPROACH
|
|
34
|
+
|
|
35
|
+
### 1. Edit the YAML Schema
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
# schemas/auth/User.yaml
|
|
39
|
+
properties:
|
|
40
|
+
# Add or modify properties HERE
|
|
41
|
+
new_field:
|
|
42
|
+
type: String
|
|
43
|
+
length: 100
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. Regenerate Migrations
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx omnify generate
|
|
50
|
+
php artisan migrate
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Need Custom Migration?
|
|
56
|
+
|
|
57
|
+
For changes NOT supported by Omnify schemas:
|
|
58
|
+
|
|
59
|
+
1. Create migration **OUTSIDE** the `omnify/` folder:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
php artisan make:migration add_custom_field_to_users_table
|
|
63
|
+
# Creates: database/migrations/2026_01_12_000000_add_custom_field_to_users_table.php
|
|
64
|
+
# This is SAFE - Omnify won't touch it
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
2. Keep the omnify/ folder untouched
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Folder Structure
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
database/migrations/
|
|
75
|
+
├── omnify/ ← ⛔ AUTO-GENERATED - DO NOT EDIT
|
|
76
|
+
│ ├── 2026_01_01_000000_create_users_table.php
|
|
77
|
+
│ ├── 2026_01_01_000001_create_posts_table.php
|
|
78
|
+
│ └── ...
|
|
79
|
+
├── 2026_01_12_120000_add_custom_field.php ← ✅ Safe to edit
|
|
80
|
+
└── 2026_01_12_130000_custom_migration.php ← ✅ Safe to edit
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Quick Reference
|
|
86
|
+
|
|
87
|
+
| Want to... | Do this |
|
|
88
|
+
|------------|---------|
|
|
89
|
+
| Add column | Edit schema YAML → `npx omnify generate` |
|
|
90
|
+
| Modify column | Edit schema YAML → `npx omnify generate` |
|
|
91
|
+
| Add index | Edit schema YAML → `npx omnify generate` |
|
|
92
|
+
| Custom migration | `php artisan make:migration` (outside omnify/) |
|
|
93
|
+
| Fix generation bug | Report issue or edit Omnify plugin |
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## If You See This Warning
|
|
98
|
+
|
|
99
|
+
If a file has this header:
|
|
100
|
+
|
|
101
|
+
```php
|
|
102
|
+
/**
|
|
103
|
+
* DO NOT EDIT - This file is auto-generated by Omnify.
|
|
104
|
+
* Any changes will be overwritten on next generation.
|
|
105
|
+
* ...
|
|
106
|
+
*/
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**STOP!** Do not edit this file. Edit the schema YAML instead.
|
|
@@ -2,6 +2,86 @@
|
|
|
2
2
|
|
|
3
3
|
> **Related:** [README](./README.md) | [Controller Guide](./controller-guide.md) | [Checklist](./checklist.md)
|
|
4
4
|
|
|
5
|
+
## ⚠️ CRITICAL: Check Route Prefix BEFORE Writing OpenAPI Path
|
|
6
|
+
|
|
7
|
+
### Step 1: Check Which Route File the Controller Uses
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Find where your route is registered
|
|
11
|
+
grep -r "UserController" routes/
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Step 2: Check the Route Prefix in That File
|
|
15
|
+
|
|
16
|
+
```php
|
|
17
|
+
// bootstrap/app.php hoặc app/Providers/RouteServiceProvider.php
|
|
18
|
+
// Tìm xem route file có prefix gì
|
|
19
|
+
|
|
20
|
+
// Ví dụ Laravel 11+: bootstrap/app.php
|
|
21
|
+
->withRouting(
|
|
22
|
+
api: __DIR__.'/../routes/api.php', // ← /api prefix tự động!
|
|
23
|
+
web: __DIR__.'/../routes/web.php',
|
|
24
|
+
apiPrefix: 'api', // ← Đây là prefix!
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
// Ví dụ Laravel 10: app/Providers/RouteServiceProvider.php
|
|
28
|
+
Route::middleware('api')
|
|
29
|
+
->prefix('api') // ← Đây là prefix!
|
|
30
|
+
->group(base_path('routes/api.php'));
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Step 3: Write OpenAPI Path = Actual Route Path (KHÔNG có prefix)
|
|
34
|
+
|
|
35
|
+
| Route File | Route Definition | Prefix | OpenAPI Path | Final URL |
|
|
36
|
+
|------------|------------------|--------|--------------|-----------|
|
|
37
|
+
| `api.php` | `Route::get('/users', ...)` | `/api` | `path: '/users'` | `/api/users` |
|
|
38
|
+
| `api.php` | `Route::get('/users/{id}', ...)` | `/api` | `path: '/users/{id}'` | `/api/users/1` |
|
|
39
|
+
| `web.php` | `Route::get('/dashboard', ...)` | (none) | `path: '/dashboard'` | `/dashboard` |
|
|
40
|
+
| `admin.php` | `Route::get('/stats', ...)` | `/admin/api` | `path: '/stats'` | `/admin/api/stats` |
|
|
41
|
+
|
|
42
|
+
### ❌ CRITICAL BUG - Duplicate Prefix
|
|
43
|
+
|
|
44
|
+
```php
|
|
45
|
+
// Route trong api.php (đã có prefix /api)
|
|
46
|
+
Route::get('/users', [UserController::class, 'index']);
|
|
47
|
+
|
|
48
|
+
// ❌ SAI - Viết thêm /api vào path
|
|
49
|
+
#[OA\Get(path: '/api/users')] // → /api/api/users !!
|
|
50
|
+
|
|
51
|
+
// ✅ ĐÚNG - Chỉ viết path sau prefix
|
|
52
|
+
#[OA\Get(path: '/users')] // → /api/users ✓
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Quick Reference: Common Prefixes
|
|
56
|
+
|
|
57
|
+
| Route File | Default Prefix | OpenAPI Server URL |
|
|
58
|
+
|------------|----------------|-------------------|
|
|
59
|
+
| `api.php` | `/api` | `#[OA\Server(url: '/api')]` |
|
|
60
|
+
| `web.php` | (none) | `#[OA\Server(url: '/')]` |
|
|
61
|
+
| Custom | Check RouteServiceProvider | Match the prefix |
|
|
62
|
+
|
|
63
|
+
### Checklist Before Writing OpenAPI
|
|
64
|
+
|
|
65
|
+
- [ ] Check route file (`api.php` / `web.php` / custom)
|
|
66
|
+
- [ ] Check prefix in `RouteServiceProvider` or `bootstrap/app.php`
|
|
67
|
+
- [ ] OpenAPI path = Route path (WITHOUT prefix)
|
|
68
|
+
- [ ] `#[OA\Server(url: ...)]` matches the prefix
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## ⚠️ CRITICAL: L5-Swagger Configuration
|
|
73
|
+
|
|
74
|
+
**MUST set `use_absolute_path` to `false`** in `config/l5-swagger.php`:
|
|
75
|
+
|
|
76
|
+
```php
|
|
77
|
+
// config/l5-swagger.php
|
|
78
|
+
'use_absolute_path' => env('L5_SWAGGER_USE_ABSOLUTE_PATH', false),
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Without this, Swagger UI will fail to load the API documentation correctly.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
5
85
|
## Overview
|
|
6
86
|
|
|
7
87
|
This project uses [L5-Swagger](https://github.com/DarkaOnLine/L5-Swagger) with PHP 8 Attributes.
|
|
@@ -131,7 +211,7 @@ class Schemas
|
|
|
131
211
|
|
|
132
212
|
```php
|
|
133
213
|
#[OA\Get(
|
|
134
|
-
path: '/
|
|
214
|
+
path: '/users', // ⚠️ NO /api prefix! api.php already has it
|
|
135
215
|
summary: 'List users',
|
|
136
216
|
description: 'Paginated list with search and sorting',
|
|
137
217
|
tags: ['Users'],
|
|
@@ -153,7 +233,7 @@ public function index(Request $request): AnonymousResourceCollection
|
|
|
153
233
|
|
|
154
234
|
```php
|
|
155
235
|
#[OA\Post(
|
|
156
|
-
path: '/
|
|
236
|
+
path: '/users', // ⚠️ NO /api prefix!
|
|
157
237
|
summary: 'Create user',
|
|
158
238
|
description: 'Create a new user account',
|
|
159
239
|
tags: ['Users'],
|
|
@@ -181,7 +261,7 @@ public function store(UserStoreRequest $request): UserResource
|
|
|
181
261
|
|
|
182
262
|
```php
|
|
183
263
|
#[OA\Get(
|
|
184
|
-
path: '/
|
|
264
|
+
path: '/users/{id}', // ⚠️ NO /api prefix!
|
|
185
265
|
summary: 'Get user',
|
|
186
266
|
description: 'Get user by ID',
|
|
187
267
|
tags: ['Users'],
|
|
@@ -200,7 +280,7 @@ public function show(User $user): UserResource
|
|
|
200
280
|
|
|
201
281
|
```php
|
|
202
282
|
#[OA\Put(
|
|
203
|
-
path: '/
|
|
283
|
+
path: '/users/{id}', // ⚠️ NO /api prefix!
|
|
204
284
|
summary: 'Update user',
|
|
205
285
|
description: 'Update user (partial update supported)',
|
|
206
286
|
tags: ['Users'],
|
|
@@ -230,7 +310,7 @@ public function update(UserUpdateRequest $request, User $user): UserResource
|
|
|
230
310
|
|
|
231
311
|
```php
|
|
232
312
|
#[OA\Delete(
|
|
233
|
-
path: '/
|
|
313
|
+
path: '/users/{id}', // ⚠️ NO /api prefix!
|
|
234
314
|
summary: 'Delete user',
|
|
235
315
|
description: 'Permanently delete user',
|
|
236
316
|
tags: ['Users'],
|