sonamu 0.10.7 → 0.10.9
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/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +5 -12
- package/dist/bin/cli.js +10 -253
- package/dist/database/base-model.d.ts +1 -0
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +14 -8
- package/dist/database/db.d.ts +2 -1
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +13 -3
- package/dist/database/puri-wrapper.d.ts.map +1 -1
- package/dist/database/puri-wrapper.js +4 -11
- package/dist/database/transaction-context.d.ts +8 -3
- package/dist/database/transaction-context.d.ts.map +1 -1
- package/dist/database/transaction-context.js +12 -7
- package/dist/migration/code-generation.js +2 -2
- package/dist/naite/naite-reporter.d.ts +8 -3
- package/dist/naite/naite-reporter.d.ts.map +1 -1
- package/dist/naite/naite-reporter.js +9 -4
- package/dist/ui-web/assets/{index-D0MHYbxl.js → index-CJf8uJYf.js} +47 -41
- package/dist/ui-web/assets/index-GMMIVGja.css +1 -0
- package/dist/ui-web/index.html +2 -2
- package/package.json +3 -3
- package/src/api/decorators.ts +11 -22
- package/src/bin/cli.ts +12 -375
- package/src/database/__tests__/transaction-scope.test.ts +227 -0
- package/src/database/base-model.ts +31 -6
- package/src/database/db.ts +17 -2
- package/src/database/puri-wrapper.ts +5 -22
- package/src/database/transaction-context.ts +14 -6
- package/src/migration/code-generation.ts +1 -1
- package/src/naite/naite-reporter.ts +8 -3
- package/dist/ui-web/assets/index-Dx_JX4aQ.css +0 -1
- package/src/skills/AGENTS.md +0 -108
- package/src/skills/sonamu/SKILL.md +0 -75
- package/src/skills/sonamu-ai-agents/SKILL.md +0 -205
- package/src/skills/sonamu-api/SKILL.md +0 -480
- package/src/skills/sonamu-auth/SKILL.md +0 -327
- package/src/skills/sonamu-auth/references/plugins.md +0 -310
- package/src/skills/sonamu-auth/references/user-id-migration-followups.md +0 -192
- package/src/skills/sonamu-auth/references/user-id-migration.md +0 -455
- package/src/skills/sonamu-config/SKILL.md +0 -203
- package/src/skills/sonamu-config/references/database.md +0 -452
- package/src/skills/sonamu-config/references/environments.md +0 -178
- package/src/skills/sonamu-config/references/server-options.md +0 -400
- package/src/skills/sonamu-entity/SKILL.md +0 -180
- package/src/skills/sonamu-entity/references/creation-workflow.md +0 -581
- package/src/skills/sonamu-entity/references/design-guides.md +0 -243
- package/src/skills/sonamu-entity/references/field-types.md +0 -170
- package/src/skills/sonamu-entity/references/relations-detail.md +0 -245
- package/src/skills/sonamu-entity/references/relations.md +0 -463
- package/src/skills/sonamu-entity/references/subset.md +0 -156
- package/src/skills/sonamu-fixture/SKILL.md +0 -180
- package/src/skills/sonamu-fixture/references/cli-usage.md +0 -439
- package/src/skills/sonamu-fixture/references/cone.md +0 -298
- package/src/skills/sonamu-frontend/SKILL.md +0 -142
- package/src/skills/sonamu-frontend/references/components.md +0 -323
- package/src/skills/sonamu-frontend/references/examples.md +0 -64
- package/src/skills/sonamu-frontend/references/hooks.md +0 -273
- package/src/skills/sonamu-frontend/references/runtime.md +0 -165
- package/src/skills/sonamu-frontend/references/scaffolding.md +0 -439
- package/src/skills/sonamu-i18n/SKILL.md +0 -287
- package/src/skills/sonamu-migration/SKILL.md +0 -316
- package/src/skills/sonamu-naite/SKILL.md +0 -266
- package/src/skills/sonamu-query/SKILL.md +0 -48
- package/src/skills/sonamu-query/references/model-patterns.md +0 -390
- package/src/skills/sonamu-query/references/model.md +0 -366
- package/src/skills/sonamu-query/references/puri.md +0 -413
- package/src/skills/sonamu-query/references/search.md +0 -238
- package/src/skills/sonamu-query/references/upsert.md +0 -324
- package/src/skills/sonamu-tasks/SKILL.md +0 -236
- package/src/skills/sonamu-testing/SKILL.md +0 -251
- package/src/skills/sonamu-testing/references/devrunner.md +0 -405
- package/src/skills/sonamu-testing/references/helpers.md +0 -185
- package/src/skills/sonamu-testing/references/patterns.md +0 -263
- package/src/skills/sonamu-testing/references/pitfalls.md +0 -588
- package/src/skills/sonamu-testing/references/quick-start.md +0 -285
- package/src/skills/sonamu-testing/references/type-safety.md +0 -172
- package/src/skills/sonamu-testing/references/writing-plan.md +0 -375
- package/src/skills/sonamu-vector/SKILL.md +0 -222
|
@@ -1,581 +0,0 @@
|
|
|
1
|
-
# Entity Creation Workflow
|
|
2
|
-
|
|
3
|
-
## Entity Creation Workflow
|
|
4
|
-
|
|
5
|
-
**Prerequisite: CRITICAL!**
|
|
6
|
-
|
|
7
|
-
**Always run `pnpm dev` in `/packages/api` before starting!**
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
cd packages/api
|
|
11
|
-
pnpm dev # keep this running during all work
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
> **Why**: In dev mode, the syncer detects changes to entity.json and auto-generates types.ts.
|
|
15
|
-
>
|
|
16
|
-
> Dev mode is required **for all entity creation**, not just auth entities.
|
|
17
|
-
|
|
18
|
-
### Step 1: Generate stub
|
|
19
|
-
|
|
20
|
-
**CRITICAL: EntityId must always start with an uppercase letter!**
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
pnpm sonamu stub entity {EntityId}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
**Correct examples:**
|
|
27
|
-
|
|
28
|
-
- `pnpm sonamu stub entity Course` (correct)
|
|
29
|
-
- `pnpm sonamu stub entity User` (correct)
|
|
30
|
-
- `pnpm sonamu stub entity ConsultationHistory` (correct)
|
|
31
|
-
|
|
32
|
-
**Incorrect examples:**
|
|
33
|
-
|
|
34
|
-
- `pnpm sonamu stub entity course` (wrong — starts with lowercase)
|
|
35
|
-
- `pnpm gen stub entity Course` (wrong — incorrect command)
|
|
36
|
-
|
|
37
|
-
Generated file: `api/src/application/{entity}/{entity}.entity.json`
|
|
38
|
-
|
|
39
|
-
### Step 2: Edit the stub file
|
|
40
|
-
|
|
41
|
-
Add props, relations, and subsets to the generated entity.json file.
|
|
42
|
-
|
|
43
|
-
### Step 3: Validate and generate required files
|
|
44
|
-
|
|
45
|
-
**CRITICAL: Always validate before running sync!**
|
|
46
|
-
|
|
47
|
-
**A. Validate entity.json** (see PHASE 1 below)
|
|
48
|
-
|
|
49
|
-
- [ ] Does every index have a `type` field?
|
|
50
|
-
- [ ] Does the subset use `relation.id` format instead of directly referencing FK columns?
|
|
51
|
-
- [ ] Is the Boolean `dbDefault` a string (`"true"` / `"false"`)?
|
|
52
|
-
- [ ] Does the OrderBy enum contain only `id-desc`?
|
|
53
|
-
- [ ] Is the Enum `dbDefault` using escaped double quotes? (e.g., `"\"pending\""`)
|
|
54
|
-
|
|
55
|
-
**B. model.ts (must be created manually)**
|
|
56
|
-
|
|
57
|
-
- Must be created manually
|
|
58
|
-
- Reference another entity's model.ts as a template
|
|
59
|
-
- Required methods: findById, findOne, findMany, save, del
|
|
60
|
-
- See PHASE 2 below for template
|
|
61
|
-
|
|
62
|
-
**C. types.ts (auto-generated — wait for it)**
|
|
63
|
-
|
|
64
|
-
- **If `pnpm dev` is running**, the syncer will auto-generate it within 2–3 seconds
|
|
65
|
-
- Check: `ls packages/api/src/application/{entity}/{entity}.types.ts`
|
|
66
|
-
- If not generated:
|
|
67
|
-
1. Verify `pnpm dev` is running
|
|
68
|
-
2. If still not generated, create manually (see PHASE 2 below for template)
|
|
69
|
-
|
|
70
|
-
**Done criteria:**
|
|
71
|
-
|
|
72
|
-
- [ ] entity.json validation passed
|
|
73
|
-
- [ ] model.ts exists
|
|
74
|
-
- [ ] types.ts exists (auto-generated or manually created)
|
|
75
|
-
|
|
76
|
-
### Step 4: Sync
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
pnpm sonamu sync
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
**Note:** Do not write entity JSON by hand. Always generate using the stub command, then edit.
|
|
83
|
-
|
|
84
|
-
### Step 5: Migration and Scaffolding
|
|
85
|
-
|
|
86
|
-
1. Generate and apply migration
|
|
87
|
-
2. Run scaffolding
|
|
88
|
-
3. Test the build
|
|
89
|
-
|
|
90
|
-
**Full workflow:** see the step-by-step checklist in PHASE 1–5 below
|
|
91
|
-
|
|
92
|
-
### Step 6: Handle nullable fields in types.ts (required)
|
|
93
|
-
|
|
94
|
-
**CRITICAL: Do this immediately after scaffolding, before writing tests!**
|
|
95
|
-
|
|
96
|
-
After scaffolding completes, nullable fields in the generated `*.types.ts` must be handled.
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
// Auto-generated types.ts
|
|
100
|
-
export const FAQSaveParams = FAQBaseSchema.partial({
|
|
101
|
-
id: true,
|
|
102
|
-
created_at: true,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// CORRECT: update immediately — add nullable fields
|
|
106
|
-
export const FAQSaveParams = FAQBaseSchema.partial({
|
|
107
|
-
id: true,
|
|
108
|
-
created_at: true,
|
|
109
|
-
category: true, // nullable added
|
|
110
|
-
order_num: true, // nullable added
|
|
111
|
-
}).extend({
|
|
112
|
-
category: z.string().nullish(),
|
|
113
|
-
order_num: z.number().nullish(),
|
|
114
|
-
updated_at: z.date().nullish(),
|
|
115
|
-
});
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
**Detailed guide:** see "Tasks to Do Immediately After Entity Creation" in `sonamu-testing`
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
## Overall Workflow
|
|
122
|
-
|
|
123
|
-
```
|
|
124
|
-
1. Generate stub
|
|
125
|
-
2. Write entity.json
|
|
126
|
-
3. Run automated validation (this checklist)
|
|
127
|
-
4. Create model.ts, types.ts
|
|
128
|
-
5. Run sync
|
|
129
|
-
6. Create migration
|
|
130
|
-
7. Apply migration
|
|
131
|
-
8. Run scaffolding
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
## PHASE 1: entity.json Validation (Before Sync)
|
|
135
|
-
|
|
136
|
-
Immediately after writing your entity.json file, validate the following **before running sync**.
|
|
137
|
-
|
|
138
|
-
### 1.1 Index Validation
|
|
139
|
-
|
|
140
|
-
**Does every index have a `type` field?**
|
|
141
|
-
|
|
142
|
-
```json
|
|
143
|
-
// DO NOT - Incorrect
|
|
144
|
-
"indexes": [
|
|
145
|
-
{ "name": "ix_user_email", "columns": [{ "name": "email" }] }
|
|
146
|
-
]
|
|
147
|
-
|
|
148
|
-
// DO - Correct
|
|
149
|
-
"indexes": [
|
|
150
|
-
{ "name": "ix_user_email", "type": "index", "columns": [{ "name": "email" }] }
|
|
151
|
-
]
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
**How to validate:**
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
# Find indexes without type in all entity.json files
|
|
158
|
-
grep -r '"indexes"' packages/api/src/application/*/\*.entity.json | \
|
|
159
|
-
xargs -I {} sh -c 'grep -L "\"type\":" {}'
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### 1.2 Subset Validation
|
|
163
|
-
|
|
164
|
-
**Are you avoiding direct foreign key references?**
|
|
165
|
-
|
|
166
|
-
```json
|
|
167
|
-
// DO NOT - Incorrect: direct foreign key reference
|
|
168
|
-
"subsets": {
|
|
169
|
-
"A": ["id", "user_id", "task_id"]
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// DO - Correct: reference through relation (Sonamu auto-optimizes when only .id is referenced)
|
|
173
|
-
"subsets": {
|
|
174
|
-
"A": ["id", "user.id", "task.id"]
|
|
175
|
-
}
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
**Rules:**
|
|
179
|
-
|
|
180
|
-
- `{relation_name}_id` → `{relation_name}.id`
|
|
181
|
-
- If a BelongsToOne relation exists, always use `relation.id` format
|
|
182
|
-
- Sonamu optimizes by reading the FK column directly and skipping JOINs when only `.id` is referenced
|
|
183
|
-
|
|
184
|
-
**How to validate:**
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
# Find subset fields ending in _id in entity.json
|
|
188
|
-
grep -A 20 '"subsets"' your-entity.entity.json | grep '_id"'
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
**Reference working code:**
|
|
192
|
-
|
|
193
|
-
- `sonamu/examples/miomock/api/src/application/project/project.entity.json`
|
|
194
|
-
- `sonamu/examples/miomock/api/src/application/employee/employee.entity.json`
|
|
195
|
-
|
|
196
|
-
### 1.3 Subset A Completeness Validation
|
|
197
|
-
|
|
198
|
-
**Does Subset A include all fields?**
|
|
199
|
-
|
|
200
|
-
```json
|
|
201
|
-
// DO - Correct: all props included
|
|
202
|
-
{
|
|
203
|
-
"props": [
|
|
204
|
-
{ "name": "id" },
|
|
205
|
-
{ "name": "created_at" },
|
|
206
|
-
{ "name": "title" },
|
|
207
|
-
{ "type": "relation", "name": "user" }
|
|
208
|
-
],
|
|
209
|
-
"subsets": {
|
|
210
|
-
"A": ["id", "created_at", "title", "user.id", "user.name"]
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
**Validation checklist:**
|
|
216
|
-
|
|
217
|
-
- [ ] All regular fields included
|
|
218
|
-
- [ ] All relations include at least `.id`
|
|
219
|
-
- [ ] Non-nullable relations also include required fields
|
|
220
|
-
|
|
221
|
-
### 1.4 Duplicate Column Validation
|
|
222
|
-
|
|
223
|
-
**Are BelongsToOne relations and their foreign keys not defined twice?**
|
|
224
|
-
|
|
225
|
-
```json
|
|
226
|
-
// DO NOT - Incorrect: duplicate definition
|
|
227
|
-
{
|
|
228
|
-
"props": [
|
|
229
|
-
{ "name": "user_id", "type": "integer" }, // should be removed
|
|
230
|
-
{
|
|
231
|
-
"type": "relation",
|
|
232
|
-
"name": "user",
|
|
233
|
-
"with": "User",
|
|
234
|
-
"relationType": "BelongsToOne"
|
|
235
|
-
}
|
|
236
|
-
]
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// DO - Correct: define relation only
|
|
240
|
-
{
|
|
241
|
-
"props": [
|
|
242
|
-
{
|
|
243
|
-
"type": "relation",
|
|
244
|
-
"name": "user",
|
|
245
|
-
"with": "User",
|
|
246
|
-
"relationType": "BelongsToOne"
|
|
247
|
-
}
|
|
248
|
-
]
|
|
249
|
-
}
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
**How to validate:**
|
|
253
|
-
|
|
254
|
-
```bash
|
|
255
|
-
# Check if a BelongsToOne relation also has an _id field
|
|
256
|
-
grep -A 5 '"relationType": "BelongsToOne"' your-entity.entity.json
|
|
257
|
-
grep '"name": ".*_id"' your-entity.entity.json
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### 1.5 Boolean dbDefault Validation
|
|
261
|
-
|
|
262
|
-
**Is the dbDefault for Boolean types the string "true"/"false"?**
|
|
263
|
-
|
|
264
|
-
```json
|
|
265
|
-
// DO NOT - Incorrect
|
|
266
|
-
{ "name": "is_active", "type": "boolean", "dbDefault": "1" }
|
|
267
|
-
{ "name": "is_deleted", "type": "boolean", "dbDefault": "0" }
|
|
268
|
-
|
|
269
|
-
// DO - Correct
|
|
270
|
-
{ "name": "is_active", "type": "boolean", "dbDefault": "true" }
|
|
271
|
-
{ "name": "is_deleted", "type": "boolean", "dbDefault": "false" }
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
### 1.6 OrderBy Enum Validation
|
|
275
|
-
|
|
276
|
-
**Does the OrderBy enum contain only `id-desc`?**
|
|
277
|
-
|
|
278
|
-
```json
|
|
279
|
-
// DO NOT - Incorrect: causes scaffolding errors!
|
|
280
|
-
"enums": {
|
|
281
|
-
"ProductOrderBy": {
|
|
282
|
-
"id-desc": "ID Latest",
|
|
283
|
-
"name-asc": "By Name",
|
|
284
|
-
"created_at-desc": "By Registration Date"
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// DO - Correct
|
|
289
|
-
"enums": {
|
|
290
|
-
"ProductOrderBy": { "id-desc": "ID Latest" }
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
**Reason:** The model code generated by scaffolding only handles `id-desc`.
|
|
295
|
-
|
|
296
|
-
### 1.7 Enum dbDefault Validation
|
|
297
|
-
|
|
298
|
-
**Is the dbDefault for Enum types wrapped in escaped double quotes?**
|
|
299
|
-
|
|
300
|
-
```json
|
|
301
|
-
// DO NOT - Incorrect
|
|
302
|
-
{ "name": "status", "type": "enum", "id": "Status", "dbDefault": "pending" }
|
|
303
|
-
{ "name": "status", "type": "enum", "id": "Status", "dbDefault": "'pending'" }
|
|
304
|
-
|
|
305
|
-
// DO - Correct
|
|
306
|
-
{ "name": "status", "type": "enum", "id": "Status", "dbDefault": "\"pending\"" }
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
## PHASE 2: Required File Generation Validation
|
|
310
|
-
|
|
311
|
-
### 2.1 model.ts File Creation
|
|
312
|
-
|
|
313
|
-
**Does the entity folder contain a `{entity}.model.ts` file?**
|
|
314
|
-
|
|
315
|
-
```bash
|
|
316
|
-
# Check
|
|
317
|
-
ls packages/api/src/application/your-entity/your-entity.model.ts
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
**If missing, manual creation is required** (refer to another entity's model.ts)
|
|
321
|
-
|
|
322
|
-
Required methods:
|
|
323
|
-
|
|
324
|
-
- `findById`
|
|
325
|
-
- `findOne`
|
|
326
|
-
- `findMany`
|
|
327
|
-
- `save`
|
|
328
|
-
- `del`
|
|
329
|
-
|
|
330
|
-
### 2.2 types.ts File Creation
|
|
331
|
-
|
|
332
|
-
**Does the entity folder contain a `{entity}.types.ts` file?**
|
|
333
|
-
|
|
334
|
-
```bash
|
|
335
|
-
# Check
|
|
336
|
-
ls packages/api/src/application/your-entity/your-entity.types.ts
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
**Required content:**
|
|
340
|
-
|
|
341
|
-
```typescript
|
|
342
|
-
import { z } from "zod";
|
|
343
|
-
import { YourEntityBaseListParams, YourEntityBaseSchema } from "../sonamu.generated";
|
|
344
|
-
|
|
345
|
-
export const YourEntityListParams = YourEntityBaseListParams;
|
|
346
|
-
export type YourEntityListParams = z.infer<typeof YourEntityListParams>;
|
|
347
|
-
|
|
348
|
-
// Basic pattern (no relations)
|
|
349
|
-
export const YourEntitySaveParams = YourEntityBaseSchema.partial({
|
|
350
|
-
id: true,
|
|
351
|
-
created_at: true,
|
|
352
|
-
});
|
|
353
|
-
export type YourEntitySaveParams = z.infer<typeof YourEntitySaveParams>;
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
**If a ManyToMany relation exists:**
|
|
357
|
-
|
|
358
|
-
```typescript
|
|
359
|
-
// ManyToMany relation: add {relation_name}_ids array
|
|
360
|
-
export const YourEntitySaveParams = YourEntityBaseSchema.partial({
|
|
361
|
-
id: true,
|
|
362
|
-
created_at: true,
|
|
363
|
-
}).extend({
|
|
364
|
-
relation_name_ids: z.array(z.number().int().positive()),
|
|
365
|
-
});
|
|
366
|
-
export type YourEntitySaveParams = z.infer<typeof YourEntitySaveParams>;
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
**Reference working code:**
|
|
370
|
-
|
|
371
|
-
- `sonamu/examples/miomock/api/src/application/project/project.types.ts` - ManyToMany example
|
|
372
|
-
- `sonamu/examples/miomock/api/src/application/employee/employee.types.ts` - basic pattern
|
|
373
|
-
|
|
374
|
-
## PHASE 3: Sync Execution and Validation
|
|
375
|
-
|
|
376
|
-
### 3.1 Run Sync
|
|
377
|
-
|
|
378
|
-
```bash
|
|
379
|
-
cd packages/api
|
|
380
|
-
pnpm sonamu sync
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
### 3.2 Sync Result Validation
|
|
384
|
-
|
|
385
|
-
**Are all 3 files registered in sonamu.lock?**
|
|
386
|
-
|
|
387
|
-
```bash
|
|
388
|
-
# Check
|
|
389
|
-
grep "your-entity" packages/api/sonamu.lock
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
**Expected result:**
|
|
393
|
-
|
|
394
|
-
```json
|
|
395
|
-
[
|
|
396
|
-
{
|
|
397
|
-
"path": "src/application/your-entity/your-entity.entity.json",
|
|
398
|
-
"checksum": "..."
|
|
399
|
-
},
|
|
400
|
-
{
|
|
401
|
-
"path": "src/application/your-entity/your-entity.model.ts",
|
|
402
|
-
"checksum": "..."
|
|
403
|
-
},
|
|
404
|
-
{
|
|
405
|
-
"path": "src/application/your-entity/your-entity.types.ts",
|
|
406
|
-
"checksum": "..."
|
|
407
|
-
}
|
|
408
|
-
]
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
### 3.3 Web Package Sync Validation
|
|
412
|
-
|
|
413
|
-
**Have the required files been generated in the web package?**
|
|
414
|
-
|
|
415
|
-
```bash
|
|
416
|
-
# Check service generation
|
|
417
|
-
grep "YourEntityService" packages/web/src/services/services.generated.ts
|
|
418
|
-
|
|
419
|
-
# Check component generation
|
|
420
|
-
ls packages/web/src/components/your-entity/
|
|
421
|
-
|
|
422
|
-
# Check route generation
|
|
423
|
-
ls packages/web/src/routes/admin/your-entities/
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
### 3.4 i18n Key Generation Validation
|
|
427
|
-
|
|
428
|
-
**Have labels been generated for foreign key fields?**
|
|
429
|
-
|
|
430
|
-
```bash
|
|
431
|
-
# Check
|
|
432
|
-
grep "entity.YourEntity" packages/web/src/i18n/sd.generated.ts
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
## PHASE 4: Migration Validation
|
|
436
|
-
|
|
437
|
-
### 4.1 Create Migration File
|
|
438
|
-
|
|
439
|
-
```bash
|
|
440
|
-
cd packages/api
|
|
441
|
-
pnpm sonamu migration:create
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
### 4.2 Migration File Validation
|
|
445
|
-
|
|
446
|
-
**Check the generated migration file:**
|
|
447
|
-
|
|
448
|
-
```bash
|
|
449
|
-
ls packages/api/src/migrations/*_create__your_entities.ts
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
**Validation checklist:**
|
|
453
|
-
|
|
454
|
-
- [ ] Is the table name correct? (plural, snake_case)
|
|
455
|
-
- [ ] Are all columns defined?
|
|
456
|
-
- [ ] Are foreign key constraints present?
|
|
457
|
-
- [ ] Are indexes created?
|
|
458
|
-
- [ ] Is the default for Boolean columns correct? (true/false)
|
|
459
|
-
|
|
460
|
-
### 4.3 Migration Dry-run
|
|
461
|
-
|
|
462
|
-
```bash
|
|
463
|
-
# Check SQL before applying migration
|
|
464
|
-
cd packages/api
|
|
465
|
-
pnpm sonamu migration:latest --dry-run
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
**Check for:**
|
|
469
|
-
|
|
470
|
-
- No SQL syntax errors
|
|
471
|
-
- No duplicate column definitions
|
|
472
|
-
- No Boolean default type errors
|
|
473
|
-
|
|
474
|
-
## PHASE 5: Scaffolding Validation
|
|
475
|
-
|
|
476
|
-
### 5.1 Pre-Scaffolding Check
|
|
477
|
-
|
|
478
|
-
**Have all previous steps been completed?**
|
|
479
|
-
|
|
480
|
-
- [ ] entity.json validation complete
|
|
481
|
-
- [ ] model.ts, types.ts created
|
|
482
|
-
- [ ] sync executed
|
|
483
|
-
- [ ] migration created and applied
|
|
484
|
-
|
|
485
|
-
### 5.2 Run Scaffolding
|
|
486
|
-
|
|
487
|
-
```bash
|
|
488
|
-
cd packages/api
|
|
489
|
-
pnpm sonamu scaffold your-entity
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
### 5.3 Build Validation
|
|
493
|
-
|
|
494
|
-
```bash
|
|
495
|
-
# API build
|
|
496
|
-
cd packages/api
|
|
497
|
-
pnpm build
|
|
498
|
-
|
|
499
|
-
# Web build
|
|
500
|
-
cd packages/web
|
|
501
|
-
pnpm build
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
**There must be no build errors!**
|
|
505
|
-
|
|
506
|
-
## Automated Validation Script (Optional)
|
|
507
|
-
|
|
508
|
-
Save the following script as `packages/api/scripts/validate-entity.sh`:
|
|
509
|
-
|
|
510
|
-
```bash
|
|
511
|
-
#!/bin/bash
|
|
512
|
-
|
|
513
|
-
ENTITY=$1
|
|
514
|
-
ENTITY_DIR="src/application/$ENTITY"
|
|
515
|
-
|
|
516
|
-
echo "[VALIDATION] Validating entity: $ENTITY"
|
|
517
|
-
|
|
518
|
-
# 1. Check files exist
|
|
519
|
-
echo "[CHECK] Checking required files..."
|
|
520
|
-
if [ ! -f "$ENTITY_DIR/$ENTITY.entity.json" ]; then
|
|
521
|
-
echo "[ERROR] Missing: $ENTITY.entity.json"
|
|
522
|
-
exit 1
|
|
523
|
-
fi
|
|
524
|
-
if [ ! -f "$ENTITY_DIR/$ENTITY.model.ts" ]; then
|
|
525
|
-
echo "[ERROR] Missing: $ENTITY.model.ts"
|
|
526
|
-
exit 1
|
|
527
|
-
fi
|
|
528
|
-
if [ ! -f "$ENTITY_DIR/$ENTITY.types.ts" ]; then
|
|
529
|
-
echo "[ERROR] Missing: $ENTITY.types.ts"
|
|
530
|
-
exit 1
|
|
531
|
-
fi
|
|
532
|
-
echo "[PASS] All required files exist"
|
|
533
|
-
|
|
534
|
-
# 2. Check indexes have type
|
|
535
|
-
echo "[CHECK] Checking index types..."
|
|
536
|
-
if grep -q '"indexes"' "$ENTITY_DIR/$ENTITY.entity.json"; then
|
|
537
|
-
if ! grep -A 10 '"indexes"' "$ENTITY_DIR/$ENTITY.entity.json" | grep -q '"type":'; then
|
|
538
|
-
echo "[ERROR] Some indexes are missing 'type' field"
|
|
539
|
-
exit 1
|
|
540
|
-
fi
|
|
541
|
-
fi
|
|
542
|
-
echo "[PASS] All indexes have type"
|
|
543
|
-
|
|
544
|
-
# 3. Check for _id in subsets
|
|
545
|
-
echo "[CHECK] Checking subset field expressions..."
|
|
546
|
-
if grep -A 20 '"subsets"' "$ENTITY_DIR/$ENTITY.entity.json" | grep -q '_id"'; then
|
|
547
|
-
echo "[WARNING] Found '_id' in subsets. Should use 'relation.id' instead"
|
|
548
|
-
fi
|
|
549
|
-
|
|
550
|
-
# 4. Check OrderBy enum
|
|
551
|
-
echo "[CHECK] Checking OrderBy enum..."
|
|
552
|
-
if grep -A 5 'OrderBy"' "$ENTITY_DIR/$ENTITY.entity.json" | grep -v 'id-desc' | grep -q ':'; then
|
|
553
|
-
echo "[WARNING] OrderBy has values other than 'id-desc'"
|
|
554
|
-
fi
|
|
555
|
-
|
|
556
|
-
echo "[COMPLETE] Entity validation complete!"
|
|
557
|
-
```
|
|
558
|
-
|
|
559
|
-
**Usage:**
|
|
560
|
-
|
|
561
|
-
```bash
|
|
562
|
-
chmod +x packages/api/scripts/validate-entity.sh
|
|
563
|
-
./packages/api/scripts/validate-entity.sh your-entity
|
|
564
|
-
```
|
|
565
|
-
|
|
566
|
-
## Checklist Summary
|
|
567
|
-
|
|
568
|
-
When creating an entity, **always** proceed in the following order:
|
|
569
|
-
|
|
570
|
-
1. STEP 1: `pnpm sonamu stub entity YourEntity`
|
|
571
|
-
2. STEP 2: Write `your-entity.entity.json`
|
|
572
|
-
3. STEP 3: **Validate using this checklist** (CRITICAL - must be performed)
|
|
573
|
-
4. STEP 4: Create `your-entity.model.ts`
|
|
574
|
-
5. STEP 5: Create `your-entity.types.ts`
|
|
575
|
-
6. STEP 6: `pnpm sonamu sync`
|
|
576
|
-
7. STEP 7: Validate sync results (sonamu.lock, web files)
|
|
577
|
-
8. STEP 8: `pnpm sonamu migration:create`
|
|
578
|
-
9. STEP 9: Validate migration file
|
|
579
|
-
10. STEP 10: `pnpm sonamu migration:latest` (apply)
|
|
580
|
-
11. STEP 11: `pnpm sonamu scaffold your-entity`
|
|
581
|
-
12. STEP 12: Build test
|