@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,353 @@
1
+ # Partial Schema Guide
2
+
3
+ ## Overview
4
+
5
+ Partial schemas (`kind: partial`) allow packages to extend or provide default schemas without modifying main application files.
6
+
7
+ ```yaml
8
+ # packages/sso-client/schemas/User.yaml
9
+ kind: partial
10
+ priority: 10
11
+
12
+ properties:
13
+ sso_token:
14
+ type: String
15
+ nullable: true
16
+ ```
17
+
18
+ ## Key Concepts
19
+
20
+ ### Target is Inferred from Filename
21
+
22
+ **No `target` field needed.** The target schema is determined by the filename:
23
+
24
+ ```
25
+ User.yaml → targets User schema
26
+ Permission.yaml → targets Permission schema
27
+ Team.yaml → targets Team schema
28
+ ```
29
+
30
+ ### Merge Behavior
31
+
32
+ | Scenario | Result |
33
+ | --------------------------------------------------------------- | --------------------------- |
34
+ | Main app has `User.yaml` + Package has `User.yaml` (partial) | Merge into main User |
35
+ | Main app has NO `User.yaml` + Package has `User.yaml` (partial) | Partial becomes User schema |
36
+ | Multiple packages have `User.yaml` (partial) | Merge via priority |
37
+
38
+ ## Priority System
39
+
40
+ Lower number = Higher priority = Merged first = Wins conflicts
41
+
42
+ ```yaml
43
+ kind: partial
44
+ priority: 10 # High priority (1-49)
45
+ priority: 50 # Default priority
46
+ priority: 90 # Low priority (51-100)
47
+ ```
48
+
49
+ ### Priority Ranges
50
+
51
+ | Range | Use For |
52
+ | ------ | ------------------------- |
53
+ | 1-20 | Core system packages |
54
+ | 21-40 | Feature modules |
55
+ | 41-60 | Business logic extensions |
56
+ | 61-80 | Tenant customizations |
57
+ | 81-100 | Development/testing |
58
+
59
+ ## Use Cases
60
+
61
+ ### 1. Package Provides Default Schema
62
+
63
+ SSO package provides default User schema if main app has none:
64
+
65
+ ```yaml
66
+ # packages/sso-client/schemas/User.yaml
67
+ kind: partial
68
+ priority: 10
69
+
70
+ displayName:
71
+ ja: ユーザー
72
+ en: User
73
+
74
+ options:
75
+ timestamps: true
76
+ authenticatable: true
77
+
78
+ properties:
79
+ email:
80
+ type: Email
81
+ unique: true
82
+ name:
83
+ type: String
84
+ console_user_id:
85
+ type: BigInt
86
+ nullable: true
87
+ ```
88
+
89
+ **Result:**
90
+ - Apps WITH existing User.yaml → SSO fields merge into their User
91
+ - Apps WITHOUT User.yaml → Package's User becomes the User schema
92
+
93
+ ### 2. Package Extends Existing Schema
94
+
95
+ Add fields to main app's User:
96
+
97
+ ```yaml
98
+ # packages/billing/schemas/User.yaml
99
+ kind: partial
100
+ priority: 50
101
+
102
+ properties:
103
+ stripe_customer_id:
104
+ type: String
105
+ nullable: true
106
+ subscription_status:
107
+ type: String
108
+ nullable: true
109
+ ```
110
+
111
+ **Result:** User schema has all original properties + billing properties
112
+
113
+ ### 3. Multiple Packages Extend Same Schema
114
+
115
+ ```
116
+ Main App: schemas/auth/User.yaml (regular schema)
117
+ ├─ SSO Package: User.yaml (partial, priority: 10)
118
+ └─ Billing Package: User.yaml (partial, priority: 50)
119
+ ```
120
+
121
+ **Merge Order:**
122
+ 1. SSO Package (priority 10) merges first
123
+ 2. Billing Package (priority 50) merges second
124
+ 3. Main app properties always win over partials
125
+
126
+ ## Configuration
127
+
128
+ ### omnify.config.ts
129
+
130
+ ```typescript
131
+ const config: OmnifyConfig = {
132
+ schemasDir: './schemas',
133
+
134
+ additionalSchemaPaths: [
135
+ {
136
+ path: './packages/sso-client/database/schemas',
137
+ namespace: 'Sso',
138
+ // Optional: Package-specific output
139
+ output: {
140
+ laravel: {
141
+ base: './packages/sso-client',
142
+ modelsNamespace: 'Vendor\\SsoClient\\Models',
143
+ modelsPath: 'src/Models',
144
+ },
145
+ },
146
+ },
147
+ ],
148
+ };
149
+ ```
150
+
151
+ ## File Structure Examples
152
+
153
+ ### Package with Partial Schemas
154
+
155
+ ```
156
+ packages/sso-client/
157
+ ├── database/
158
+ │ └── schemas/
159
+ │ ├── User.yaml # kind: partial (extends/provides User)
160
+ │ ├── Permission.yaml # kind: partial (provides Permission)
161
+ │ ├── Role.yaml # regular schema (package-only)
162
+ │ └── RolePermission.yaml
163
+ ├── src/
164
+ │ └── Models/
165
+ └── composer.json
166
+ ```
167
+
168
+ ### Main App Schemas
169
+
170
+ ```
171
+ schemas/
172
+ ├── auth/
173
+ │ └── User.yaml # Main User schema (takes priority)
174
+ ├── blog/
175
+ │ ├── Post.yaml
176
+ │ └── Comment.yaml
177
+ └── shop/
178
+ └── Product.yaml
179
+ ```
180
+
181
+ ## Property Merge Rules
182
+
183
+ | Scenario | Result |
184
+ | ----------------------------- | ---------------------------- |
185
+ | Property only in main | Main property used |
186
+ | Property only in partial | Partial property added |
187
+ | Property in both | **Main wins** |
188
+ | Property in multiple partials | Higher priority partial wins |
189
+
190
+ ### Example: Property Conflict
191
+
192
+ ```yaml
193
+ # Main app User.yaml
194
+ properties:
195
+ name:
196
+ type: String
197
+ length: 100
198
+
199
+ # Package User.yaml (partial)
200
+ properties:
201
+ name: # Same property!
202
+ type: Text # Different type
203
+ nullable: true
204
+ ```
205
+
206
+ **Result:** `name` remains `String(100)` from main app
207
+
208
+ ## What Partials Can Define
209
+
210
+ | ✅ Allowed | ❌ Not Allowed |
211
+ | ----------- | ------------------ |
212
+ | properties | options.id |
213
+ | displayName | options.timestamps |
214
+ | priority | options.softDelete |
215
+ | - | options.tableName |
216
+
217
+ ## Best Practices
218
+
219
+ ### 1. Use Descriptive Filenames
220
+
221
+ ```
222
+ ✅ User.yaml # Clear: extends/provides User
223
+ ✅ Permission.yaml # Clear: extends/provides Permission
224
+ ❌ UserExtension.yaml # Confusing (targets UserExtension, not User)
225
+ ```
226
+
227
+ ### 2. Prefix Package-Specific Fields
228
+
229
+ ```yaml
230
+ # ✅ Good: Unique, prefixed names
231
+ sso_token:
232
+ billing_status:
233
+ console_user_id:
234
+
235
+ # ❌ Bad: Generic names that might conflict
236
+ token:
237
+ status:
238
+ user_id:
239
+ ```
240
+
241
+ ### 3. Document Dependencies
242
+
243
+ ```yaml
244
+ # User.yaml
245
+ # Package: @famgia/sso-client
246
+ # Requires: Role schema from same package
247
+ # Priority: 10 (core system)
248
+
249
+ kind: partial
250
+ priority: 10
251
+
252
+ properties:
253
+ role:
254
+ type: Association
255
+ relation: ManyToOne
256
+ target: Role
257
+ ```
258
+
259
+ ### 4. Keep Partials Focused
260
+
261
+ ```yaml
262
+ # ✅ Good: Single responsibility
263
+ # sso-client/User.yaml - Only SSO fields
264
+ kind: partial
265
+ properties:
266
+ sso_token:
267
+ type: String
268
+ console_user_id:
269
+ type: BigInt
270
+
271
+ # ❌ Bad: Mixed responsibilities
272
+ # Don't put billing + SSO + notifications in one partial
273
+ ```
274
+
275
+ ## Troubleshooting
276
+
277
+ ### Partial Not Merging
278
+
279
+ **Problem:** Package partial not appearing in generated model
280
+
281
+ **Check:**
282
+ 1. Package path in `additionalSchemaPaths`?
283
+ 2. Filename matches target? (User.yaml → User)
284
+ 3. `kind: partial` set correctly?
285
+
286
+ ```bash
287
+ # Verify schemas loaded
288
+ npx omnify generate --verbose
289
+ ```
290
+
291
+ ### Property Conflict
292
+
293
+ **Problem:** Partial property being ignored
294
+
295
+ **Reason:** Main app has same property (main always wins)
296
+
297
+ **Solution:**
298
+ - Use different property name in partial
299
+ - Or remove from main app if partial should own it
300
+
301
+ ### Priority Not Working
302
+
303
+ **Problem:** Wrong partial winning in conflict
304
+
305
+ **Check:**
306
+ ```yaml
307
+ # Lower number = higher priority
308
+ priority: 10 # Wins over
309
+ priority: 50 # This one
310
+ ```
311
+
312
+ ## Generate Output
313
+
314
+ ```bash
315
+ npx omnify generate
316
+ ```
317
+
318
+ **Console shows:**
319
+ ```
320
+ → Loading schemas from /app/schemas
321
+ → Loading schemas from 1 additional path(s)
322
+ • ./packages/sso-client/schemas [Sso]: 2 schema(s) + 2 partial(s)
323
+ → Validating schemas...
324
+ ✓ Generation complete!
325
+ ```
326
+
327
+ ## Quick Reference
328
+
329
+ ```yaml
330
+ # Minimal partial schema
331
+ kind: partial
332
+ properties:
333
+ new_field:
334
+ type: String
335
+
336
+ # Full partial schema
337
+ kind: partial
338
+ priority: 10
339
+
340
+ displayName:
341
+ ja: 拡張
342
+ en: Extension
343
+
344
+ properties:
345
+ field1:
346
+ type: String
347
+ displayName:
348
+ ja: フィールド1
349
+ en: Field 1
350
+ field2:
351
+ type: Int
352
+ nullable: true
353
+ ```
@@ -0,0 +1,225 @@
1
+ # Omnify React Form Guide
2
+
3
+ This guide explains how to build forms using Omnify generated schemas with **Ant Design** and **TanStack Query**.
4
+
5
+ ## Setup
6
+
7
+ Install the runtime package:
8
+
9
+ ```bash
10
+ npm install @famgia/omnify-react
11
+ ```
12
+
13
+ ```typescript
14
+ // omnify.config.ts
15
+ import typescriptPlugin from '@famgia/omnify-typescript/plugin';
16
+
17
+ export default defineConfig({
18
+ plugins: [
19
+ typescriptPlugin({
20
+ modelsPath: 'node_modules/.omnify/schemas',
21
+ }),
22
+ ],
23
+ });
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ```tsx
29
+ import { Form, Button } from 'antd';
30
+ import {
31
+ useFormMutation,
32
+ JapaneseNameField,
33
+ setZodLocale,
34
+ zodRule,
35
+ } from '@famgia/omnify-react';
36
+ import { customerSchemas, customerI18n, type CustomerCreate } from './.omnify/schemas';
37
+ import { api } from '@/lib/api';
38
+
39
+ function CreateCustomerPage() {
40
+ const [form] = Form.useForm<CustomerCreate>();
41
+ setZodLocale('ja');
42
+
43
+ const mutation = useFormMutation<CustomerCreate>({
44
+ form,
45
+ mutationFn: (data) => api.post('/customers', data),
46
+ invalidateKeys: [['customers']],
47
+ successMessage: 'Customer created successfully',
48
+ onSuccess: () => form.resetFields(),
49
+ });
50
+
51
+ return (
52
+ <Form form={form} onFinish={mutation.mutate}>
53
+ <JapaneseNameField
54
+ schemas={customerSchemas}
55
+ i18n={customerI18n}
56
+ prefix="name"
57
+ showKana
58
+ />
59
+ <Button loading={mutation.isPending}>Save</Button>
60
+ </Form>
61
+ );
62
+ }
63
+ ```
64
+
65
+ ## useFormMutation Hook
66
+
67
+ ```tsx
68
+ import { useFormMutation } from '@famgia/omnify-react';
69
+
70
+ const mutation = useFormMutation<CustomerCreate>({
71
+ form,
72
+ mutationFn: (data) => api.post('/customers', data),
73
+ invalidateKeys: [['customers']],
74
+ successMessage: 'Saved successfully',
75
+ onSuccess: () => form.resetFields(),
76
+ });
77
+ ```
78
+
79
+ ### Options
80
+
81
+ | Option | Type | Description |
82
+ | ---------------- | ---------------------- | ----------------------------------- |
83
+ | `form` | `FormInstance<T>` | Ant Design form instance (required) |
84
+ | `mutationFn` | `(data: T) => Promise` | API call function (required) |
85
+ | `invalidateKeys` | `string[][]` | Query keys to invalidate on success |
86
+ | `successMessage` | `string` | Toast message on success |
87
+ | `onSuccess` | `(data) => void` | Callback after success |
88
+ | `onError` | `(error) => void` | Callback after error |
89
+
90
+ ### Laravel Error Handling
91
+
92
+ The hook automatically handles Laravel validation errors (422):
93
+
94
+ ```json
95
+ {
96
+ "message": "The given data was invalid.",
97
+ "errors": {
98
+ "email": ["The email has already been taken."]
99
+ }
100
+ }
101
+ ```
102
+
103
+ ## Japanese Form Components
104
+
105
+ ### JapaneseNameField
106
+
107
+ ```tsx
108
+ import { JapaneseNameField } from '@famgia/omnify-react';
109
+
110
+ <JapaneseNameField
111
+ schemas={customerSchemas}
112
+ i18n={customerI18n}
113
+ prefix="name" // name_lastname, name_firstname, etc.
114
+ required // Show required asterisk
115
+ showKana={true} // Show kana fields (default)
116
+ />
117
+ ```
118
+
119
+ **Fields:** `{prefix}_lastname`, `{prefix}_firstname`, `{prefix}_kana_lastname`, `{prefix}_kana_firstname`
120
+
121
+ ### JapaneseAddressField
122
+
123
+ ```tsx
124
+ import { JapaneseAddressField } from '@famgia/omnify-react';
125
+
126
+ <JapaneseAddressField
127
+ form={form}
128
+ schemas={customerSchemas}
129
+ i18n={customerI18n}
130
+ prefix="address"
131
+ prefectureOptions={prefectureOptions} // Required for Select
132
+ enablePostalLookup={true} // Postal code → address lookup
133
+ />
134
+ ```
135
+
136
+ **Fields:** `{prefix}_postal_code`, `{prefix}_prefecture`, `{prefix}_address1`, `{prefix}_address2`, `{prefix}_address3`
137
+
138
+ **Options:**
139
+ - `prefectureOptions` - Select options for prefecture dropdown
140
+ - `enablePostalLookup` - Enable postal code search
141
+ - `autoSearch` - Auto-search when 7 digits entered
142
+ - `usePrefectureId` - Use numeric ID instead of string enum
143
+
144
+ ### JapaneseBankField
145
+
146
+ ```tsx
147
+ import { JapaneseBankField } from '@famgia/omnify-react';
148
+
149
+ <JapaneseBankField
150
+ schemas={customerSchemas}
151
+ i18n={customerI18n}
152
+ prefix="bank"
153
+ accountTypeOptions={accountTypeOptions} // Required for Select
154
+ />
155
+ ```
156
+
157
+ **Fields:** `{prefix}_bank_code`, `{prefix}_branch_code`, `{prefix}_account_type`, `{prefix}_account_number`, `{prefix}_account_holder`
158
+
159
+ ## Zod Validation with i18n
160
+
161
+ ```tsx
162
+ import { zodRule, setZodLocale } from '@famgia/omnify-react';
163
+
164
+ // Set locale once at component level
165
+ setZodLocale('ja');
166
+
167
+ // Use zodRule for field validation
168
+ <Form.Item
169
+ name="email"
170
+ label="メールアドレス"
171
+ rules={[zodRule(customerSchemas.email, 'メールアドレス')]}
172
+ >
173
+ <Input />
174
+ </Form.Item>
175
+ ```
176
+
177
+ ## Kana Validation Rules
178
+
179
+ ```tsx
180
+ import { kanaString, KATAKANA_PATTERN } from '@famgia/omnify-react';
181
+
182
+ // Full-width katakana (default)
183
+ const kanaSchema = kanaString();
184
+
185
+ // Custom options
186
+ const kanaSchema = kanaString({
187
+ fullWidthKatakana: true,
188
+ hiragana: true,
189
+ allowNumbers: true,
190
+ });
191
+ ```
192
+
193
+ ### Kana Presets
194
+
195
+ | Preset | Description |
196
+ | ----------------------- | ---------------------- |
197
+ | `KATAKANA_FULL_WIDTH` | 全角カタカナ (default) |
198
+ | `KATAKANA_HALF_WIDTH` | 半角カタカナ |
199
+ | `HIRAGANA` | ひらがな |
200
+ | `KANA_ANY` | All kana types |
201
+ | `KATAKANA_WITH_NUMBERS` | カタカナ + numbers |
202
+
203
+ ## File Structure
204
+
205
+ ```
206
+ node_modules/
207
+ ├── @famgia/omnify-react/ # Runtime package (npm)
208
+ │ ├── components/ # JapaneseNameField, etc.
209
+ │ ├── hooks/ # useFormMutation
210
+ │ └── lib/ # zodRule, kanaString, etc.
211
+ └── .omnify/ # Generated (regeneratable)
212
+ ├── schemas/
213
+ │ ├── Customer.ts
214
+ │ └── Post.ts
215
+ └── enum/
216
+ └── PostStatus.ts
217
+ ```
218
+
219
+ ## Tips
220
+
221
+ 1. **Use type generics** - `useFormMutation<CustomerCreate>` for type safety
222
+ 2. **Use `setZodLocale`** - Call once for localized validation messages
223
+ 3. **Use Japanese components** - Built-in i18n, validation, postal lookup
224
+ 4. **Set `invalidateKeys`** - Auto-refresh lists after mutations
225
+ 5. **Provide options for Select** - Components need `prefectureOptions` or `accountTypeOptions`
@@ -0,0 +1,144 @@
1
+ # Omnify Schema Guide
2
+
3
+ ## Schema File Format
4
+
5
+ Schemas are YAML files defining data models. Each file represents one entity.
6
+
7
+ ```yaml
8
+ name: User
9
+ displayName:
10
+ ja: ユーザー
11
+ en: User
12
+ kind: object
13
+
14
+ properties:
15
+ email:
16
+ type: Email
17
+ unique: true
18
+ name:
19
+ type: String
20
+ bio:
21
+ type: Text
22
+ nullable: true
23
+
24
+ options:
25
+ timestamps: true
26
+ softDelete: true
27
+ ```
28
+
29
+ ## Property Types
30
+
31
+ ### String Types
32
+ - `String` - VARCHAR(255)
33
+ - `Text` - TEXT
34
+ - `LongText` - LONGTEXT
35
+ - `Email` - VARCHAR(255) for email addresses
36
+ - `Password` - VARCHAR(255), hidden in serialization
37
+
38
+ ### Numeric Types
39
+ - `Int` - INTEGER
40
+ - `BigInt` - BIGINT
41
+ - `TinyInt` - TINYINT
42
+ - `Float` - DOUBLE
43
+ - `Decimal` - DECIMAL(precision, scale)
44
+
45
+ ### Date/Time Types
46
+ - `Date` - DATE
47
+ - `Time` - TIME
48
+ - `DateTime` - DATETIME
49
+ - `Timestamp` - TIMESTAMP
50
+
51
+ ### Other Types
52
+ - `Boolean` - BOOLEAN
53
+ - `Json` - JSON
54
+ - `Enum` - ENUM with values
55
+ - `EnumRef` - Reference to enum schema
56
+
57
+ ## Property Options
58
+
59
+ ```yaml
60
+ propertyName:
61
+ type: String
62
+ nullable: true # Can be NULL
63
+ unique: true # Unique constraint
64
+ default: "value" # Default value
65
+ length: 100 # VARCHAR length
66
+ hidden: true # Hide from JSON output
67
+ fillable: false # Exclude from mass assignment
68
+ ```
69
+
70
+ ## ⚠️ Default Value Rules
71
+
72
+ **DB functions NOT allowed in default:**
73
+
74
+ ```yaml
75
+ # ❌ WRONG
76
+ failed_at:
77
+ type: Timestamp
78
+ default: CURRENT_TIMESTAMP # ERROR!
79
+
80
+ # ✅ CORRECT
81
+ failed_at:
82
+ type: Timestamp
83
+ useCurrent: true # = CURRENT_TIMESTAMP
84
+
85
+ updated_at:
86
+ type: Timestamp
87
+ useCurrent: true
88
+ useCurrentOnUpdate: true # ON UPDATE CURRENT_TIMESTAMP
89
+ ```
90
+
91
+ | Type | Valid Default | Invalid |
92
+ |------|---------------|---------|
93
+ | Int | 0, 100, -1 | AUTO_INCREMENT, RAND() |
94
+ | Date | 2024-01-01 | CURRENT_DATE |
95
+ | Time | 14:30:00 | CURRENT_TIME |
96
+ | Timestamp | use `useCurrent` | CURRENT_TIMESTAMP |
97
+ | Uuid | static UUID | UUID() |
98
+
99
+ ## Associations
100
+
101
+ ```yaml
102
+ # Many-to-One (belongsTo)
103
+ author:
104
+ type: Association
105
+ relation: ManyToOne
106
+ target: User
107
+ onDelete: CASCADE
108
+
109
+ # One-to-Many (hasMany)
110
+ posts:
111
+ type: Association
112
+ relation: OneToMany
113
+ target: Post
114
+
115
+ # Many-to-Many (belongsToMany)
116
+ tags:
117
+ type: Association
118
+ relation: ManyToMany
119
+ target: Tag
120
+ joinTable: post_tags
121
+
122
+ # Polymorphic
123
+ commentable:
124
+ type: Association
125
+ relation: MorphTo
126
+ ```
127
+
128
+ ## Indexes
129
+
130
+ ```yaml
131
+ indexes:
132
+ - columns: [status, published_at]
133
+ - columns: [email]
134
+ unique: true
135
+ ```
136
+
137
+ ## Schema Options
138
+
139
+ ```yaml
140
+ options:
141
+ timestamps: true # Add created_at, updated_at
142
+ softDelete: true # Add deleted_at
143
+ idType: BigInt # Primary key type (Int, BigInt, Uuid)
144
+ ```