sonamu 0.8.24 → 0.8.26
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/__tests__/config.test.js +189 -0
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +7 -2
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +14 -10
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +2 -1
- package/dist/auth/knex-adapter.d.ts +23 -0
- package/dist/auth/knex-adapter.d.ts.map +1 -0
- package/dist/auth/knex-adapter.js +163 -0
- package/dist/auth/plugins/wrappers/admin.d.ts +2 -2
- package/dist/bin/__tests__/ts-loader-register.test.js +45 -0
- package/dist/bin/cli.js +47 -9
- package/dist/bin/ts-loader-register.js +3 -29
- package/dist/bin/ts-loader-registration.d.ts +2 -0
- package/dist/bin/ts-loader-registration.d.ts.map +1 -0
- package/dist/bin/ts-loader-registration.js +42 -0
- package/dist/cone/cone-generator.js +3 -3
- package/dist/database/puri-subset.test-d.js +9 -1
- package/dist/database/puri-subset.types.d.ts +1 -1
- package/dist/database/puri-subset.types.d.ts.map +1 -1
- package/dist/database/puri-subset.types.js +1 -1
- package/dist/testing/fixture-generator.js +5 -5
- package/dist/ui/ai-client.js +2 -2
- package/dist/ui/api.d.ts.map +1 -1
- package/dist/ui/api.js +14 -14
- package/dist/ui/cdd-service.d.ts +15 -18
- package/dist/ui/cdd-service.d.ts.map +1 -1
- package/dist/ui/cdd-service.js +246 -222
- package/dist/ui/cdd-types.d.ts +41 -68
- package/dist/ui/cdd-types.d.ts.map +1 -1
- package/dist/ui/cdd-types.js +2 -2
- package/dist/ui-web/assets/index-CKo0Z2Iu.css +1 -0
- package/dist/ui-web/assets/{index-CxiydzeC.js → index-DK-2aacv.js} +83 -83
- package/dist/ui-web/index.html +2 -2
- package/package.json +6 -2
- package/src/api/__tests__/config.test.ts +225 -0
- package/src/api/config.ts +10 -4
- package/src/api/sonamu.ts +16 -13
- package/src/auth/index.ts +1 -0
- package/src/auth/knex-adapter.ts +208 -0
- package/src/bin/__tests__/ts-loader-register.test.ts +62 -0
- package/src/bin/cli.ts +52 -9
- package/src/bin/ts-loader-register.ts +2 -32
- package/src/bin/ts-loader-registration.ts +55 -0
- package/src/cone/cone-generator.ts +2 -2
- package/src/database/puri-subset.test-d.ts +102 -0
- package/src/database/puri-subset.types.ts +1 -1
- package/src/skills/commands/sonamu-skills.md +20 -0
- package/src/skills/sonamu/SKILL.md +179 -137
- package/src/skills/sonamu/ai-agents.md +69 -69
- package/src/skills/sonamu/api.md +147 -147
- package/src/skills/sonamu/auth-migration.md +220 -220
- package/src/skills/sonamu/auth-plugins.md +83 -83
- package/src/skills/sonamu/auth.md +106 -106
- package/src/skills/sonamu/cdd.md +65 -200
- package/src/skills/sonamu/cone.md +138 -138
- package/src/skills/sonamu/config.md +191 -191
- package/src/skills/sonamu/create-sonamu.md +66 -66
- package/src/skills/sonamu/database.md +158 -158
- package/src/skills/sonamu/entity-basic.md +292 -293
- package/src/skills/sonamu/entity-relations.md +246 -246
- package/src/skills/sonamu/entity-validation-checklist.md +124 -124
- package/src/skills/sonamu/fixture-cli.md +231 -231
- package/src/skills/sonamu/framework-change.md +37 -37
- package/src/skills/sonamu/frontend.md +223 -223
- package/src/skills/sonamu/i18n.md +82 -82
- package/src/skills/sonamu/migration.md +77 -77
- package/src/skills/sonamu/model.md +222 -222
- package/src/skills/sonamu/naite.md +86 -86
- package/src/skills/sonamu/project-init.md +228 -228
- package/src/skills/sonamu/puri.md +122 -122
- package/src/skills/sonamu/scaffolding.md +154 -154
- package/src/skills/sonamu/skill-contribution.md +124 -124
- package/src/skills/sonamu/subset.md +46 -46
- package/src/skills/sonamu/tasks.md +82 -82
- package/src/skills/sonamu/testing-devrunner.md +147 -147
- package/src/skills/sonamu/testing.md +673 -673
- package/src/skills/sonamu/upsert.md +79 -79
- package/src/skills/sonamu/vector.md +67 -67
- package/src/testing/fixture-generator.ts +4 -4
- package/src/ui/ai-client.ts +1 -1
- package/src/ui/api.ts +18 -17
- package/src/ui/cdd-service.ts +264 -254
- package/src/ui/cdd-types.ts +40 -75
- package/dist/ui-web/assets/index-BrQKU3j9.css +0 -1
- package/src/skills/sonamu/workflow.md +0 -317
|
@@ -1,220 +1,220 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sonamu-fixture-cli
|
|
3
|
-
description: Sonamu Fixture CLI
|
|
3
|
+
description: Sonamu Fixture CLI usage guide. Create and manage test data with the fixture gen/fetch/explore commands. Use when creating or managing fixture data.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Fixture CLI
|
|
6
|
+
# Fixture CLI Usage Guide
|
|
7
7
|
|
|
8
|
-
Sonamu
|
|
8
|
+
Sonamu provides CLI commands for generating and managing fixture data for testing.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
**Note**: See the "Practical Tips" section below for fixture generation tips.
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
## 3-Tier DB
|
|
14
|
+
## Understanding the 3-Tier DB Structure (Required)
|
|
15
15
|
|
|
16
|
-
Sonamu
|
|
16
|
+
Sonamu uses a three-tier database structure. **Without understanding this structure, using fixture commands will be confusing.**
|
|
17
17
|
|
|
18
18
|
```
|
|
19
|
-
production/development master (
|
|
19
|
+
production/development master (live DB)
|
|
20
20
|
↓ (fixture fetch)
|
|
21
21
|
project_fixture (fixture DB)
|
|
22
22
|
↓ (fixture sync)
|
|
23
23
|
project_test (test DB)
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
### DB
|
|
26
|
+
### Role of Each DB
|
|
27
27
|
|
|
28
|
-
| DB |
|
|
29
|
-
|
|
30
|
-
| `project` |
|
|
31
|
-
| `project_fixture` |
|
|
32
|
-
| `project_test` |
|
|
28
|
+
| DB | Purpose | Data origin |
|
|
29
|
+
|----|---------|-------------|
|
|
30
|
+
| `project` | Production/development live DB | Real user data |
|
|
31
|
+
| `project_fixture` | Reference data store for testing | Imported via fetch or generated via gen |
|
|
32
|
+
| `project_test` | Test execution environment | Synced from fixture |
|
|
33
33
|
|
|
34
|
-
###
|
|
34
|
+
### Which DB Each Command Uses
|
|
35
35
|
|
|
36
|
-
|
|
|
37
|
-
|
|
38
|
-
| `fixture gen` | fixture DB | fixture DB |
|
|
39
|
-
| `fixture fetch` | production master | fixture DB |
|
|
40
|
-
| `fixture sync` | fixture DB | test DB | fixture DB → test DB
|
|
36
|
+
| Command | sourceDb | targetDb | Description |
|
|
37
|
+
|---------|----------|----------|-------------|
|
|
38
|
+
| `fixture gen` | fixture DB | fixture DB | Resolves and generates relations within the fixture DB |
|
|
39
|
+
| `fixture fetch` | production master | fixture DB | Imports from live DB → fixture DB |
|
|
40
|
+
| `fixture sync` | fixture DB | test DB | Synchronizes fixture DB → test DB (existing behavior) |
|
|
41
41
|
|
|
42
|
-
**CRITICAL**: sourceDb
|
|
42
|
+
**CRITICAL**: Incorrect sourceDb or targetDb settings will cause FK reference errors.
|
|
43
43
|
|
|
44
44
|
---
|
|
45
45
|
|
|
46
|
-
## CLI
|
|
46
|
+
## CLI Commands
|
|
47
47
|
|
|
48
|
-
### 1. fixture gen -
|
|
48
|
+
### 1. fixture gen - Generate new fixtures
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
Generates new test data based on faker.
|
|
51
51
|
|
|
52
|
-
**CRITICAL: `--use-llm`
|
|
52
|
+
**CRITICAL: The `--use-llm` option must always be used in real projects.** Without `--use-llm`, domain context from cone.note is not applied and only faker defaults are used, potentially producing meaningless data. This option is required for the LLM to reference `contract/**/*.contract.md` and generate contextually appropriate data.
|
|
53
53
|
|
|
54
|
-
**CRITICAL: fixture gen
|
|
54
|
+
**CRITICAL: Before running fixture gen, verify that `cone.note` exists for key props.** Without cone.note, the LLM cannot understand context and cannot generate meaningful data. If cone.note is insufficient, regenerate it with `pnpm sonamu cone generate --use-llm`.
|
|
55
55
|
|
|
56
|
-
####
|
|
56
|
+
#### Basic Usage
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
|
-
#
|
|
59
|
+
# Interactive mode (recommended)
|
|
60
60
|
pnpm sonamu fixture gen
|
|
61
61
|
|
|
62
|
-
# Entity
|
|
62
|
+
# Specify Entity
|
|
63
63
|
pnpm sonamu fixture gen --include User --count 10
|
|
64
64
|
|
|
65
|
-
#
|
|
65
|
+
# Multiple Entities
|
|
66
66
|
pnpm sonamu fixture gen --include User,Post,Comment --count 5
|
|
67
67
|
|
|
68
|
-
#
|
|
68
|
+
# All Entities
|
|
69
69
|
pnpm sonamu fixture gen --all --count 3
|
|
70
70
|
|
|
71
|
-
#
|
|
71
|
+
# All minus exclusions
|
|
72
72
|
pnpm sonamu fixture gen --all --exclude Admin,Log --count 3
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
####
|
|
75
|
+
#### Save Options
|
|
76
76
|
|
|
77
77
|
```bash
|
|
78
|
-
# DB
|
|
78
|
+
# Save to DB (default)
|
|
79
79
|
pnpm sonamu fixture gen --include User --count 10 --save-to db
|
|
80
80
|
|
|
81
|
-
#
|
|
81
|
+
# Save to file (tablename.json)
|
|
82
82
|
pnpm sonamu fixture gen --include User --count 10 --save-to file
|
|
83
83
|
# → test/fixtures/users.json
|
|
84
84
|
|
|
85
|
-
#
|
|
85
|
+
# Specify filename
|
|
86
86
|
pnpm sonamu fixture gen --include User --count 10 --save-to file:my-users.json
|
|
87
87
|
# → test/fixtures/my-users.json
|
|
88
88
|
|
|
89
|
-
#
|
|
89
|
+
# Output only (do not save)
|
|
90
90
|
pnpm sonamu fixture gen --include User --count 10 --save-to none
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
####
|
|
93
|
+
#### Options
|
|
94
94
|
|
|
95
|
-
- `--include <entities>`:
|
|
96
|
-
- `--all`:
|
|
97
|
-
- `--exclude <entities>`: --all
|
|
98
|
-
- `--count <number>`:
|
|
99
|
-
- `--save-to <target>`:
|
|
100
|
-
- `--use-llm`:
|
|
101
|
-
- `--no-cache`: LLM
|
|
102
|
-
- `--llm-model <model>`: LLM
|
|
95
|
+
- `--include <entities>`: List of Entities to generate (comma-separated)
|
|
96
|
+
- `--all`: All Entities
|
|
97
|
+
- `--exclude <entities>`: Used with --all; Entities to exclude
|
|
98
|
+
- `--count <number>`: Number to generate per Entity (default: 5)
|
|
99
|
+
- `--save-to <target>`: Save mode - `db` | `file` | `file:name.json` | `none`
|
|
100
|
+
- `--use-llm`: Enable LLM-based generation from cone.note (requires ANTHROPIC_API_KEY)
|
|
101
|
+
- `--no-cache`: Disable LLM cache (default: cache ON)
|
|
102
|
+
- `--llm-model <model>`: Specify LLM model (default: `claude-sonnet-4-5`)
|
|
103
103
|
|
|
104
104
|
---
|
|
105
105
|
|
|
106
|
-
### 2. fixture fetch -
|
|
106
|
+
### 2. fixture fetch - Import from live DB
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
Fetches data from the production/development DB and saves it to the fixture DB.
|
|
109
109
|
|
|
110
|
-
####
|
|
110
|
+
#### Basic Usage
|
|
111
111
|
|
|
112
112
|
```bash
|
|
113
|
-
#
|
|
113
|
+
# Interactive mode
|
|
114
114
|
pnpm sonamu fixture fetch
|
|
115
115
|
|
|
116
|
-
#
|
|
116
|
+
# Fetch recent data
|
|
117
117
|
pnpm sonamu fixture fetch --include User --strategy recent --limit 10
|
|
118
118
|
|
|
119
|
-
#
|
|
119
|
+
# Multiple Entities
|
|
120
120
|
pnpm sonamu fixture fetch --include User,Post --strategy sample --limit 5
|
|
121
121
|
|
|
122
|
-
#
|
|
122
|
+
# All Entities
|
|
123
123
|
pnpm sonamu fixture fetch --all --strategy recent --limit 3
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
####
|
|
126
|
+
#### Strategies
|
|
127
127
|
|
|
128
|
-
|
|
|
129
|
-
|
|
130
|
-
| `recent` |
|
|
131
|
-
| `sample` |
|
|
132
|
-
| `random` |
|
|
128
|
+
| Strategy | Description | Example |
|
|
129
|
+
|----------|-------------|---------|
|
|
130
|
+
| `recent` | Most recent data (by created_at) | `--strategy recent --limit 10` |
|
|
131
|
+
| `sample` | Uniform sampling | `--strategy sample --limit 10` |
|
|
132
|
+
| `random` | Random sampling | `--strategy random --limit 10` |
|
|
133
133
|
|
|
134
|
-
**CRITICAL**: fetch
|
|
135
|
-
- User
|
|
136
|
-
- Post
|
|
134
|
+
**CRITICAL**: fetch retrieves related data **recursively** (maxDepth: 2)
|
|
135
|
+
- Fetching User → also imports User's department and institution
|
|
136
|
+
- Fetching Post → also imports Post's author (User)
|
|
137
137
|
|
|
138
|
-
####
|
|
138
|
+
#### Options
|
|
139
139
|
|
|
140
|
-
- `--include <entities>`:
|
|
141
|
-
- `--all`:
|
|
142
|
-
- `--exclude <entities>`: --all
|
|
143
|
-
- `--strategy <strategy>`:
|
|
144
|
-
- `--limit <number>`:
|
|
140
|
+
- `--include <entities>`: List of Entities to import
|
|
141
|
+
- `--all`: All Entities
|
|
142
|
+
- `--exclude <entities>`: Used with --all; Entities to exclude
|
|
143
|
+
- `--strategy <strategy>`: Fetch strategy - `recent` | `sample` | `random` (default: recent)
|
|
144
|
+
- `--limit <number>`: Number of records per Entity (default: 10)
|
|
145
145
|
|
|
146
146
|
---
|
|
147
147
|
|
|
148
|
-
### 3. fixture explore -
|
|
148
|
+
### 3. fixture explore - Query data (without saving)
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
Queries data from the live DB and prints it to the console. **Query only — nothing is saved.**
|
|
151
151
|
|
|
152
|
-
####
|
|
152
|
+
#### Basic Usage
|
|
153
153
|
|
|
154
154
|
```bash
|
|
155
|
-
#
|
|
155
|
+
# Interactive mode
|
|
156
156
|
pnpm sonamu fixture explore
|
|
157
157
|
|
|
158
|
-
#
|
|
158
|
+
# Query recent Users
|
|
159
159
|
pnpm sonamu fixture explore --include User --strategy recent --limit 10
|
|
160
160
|
|
|
161
|
-
#
|
|
161
|
+
# Sampling
|
|
162
162
|
pnpm sonamu fixture explore --include Department --strategy sample --limit 5
|
|
163
163
|
```
|
|
164
164
|
|
|
165
|
-
####
|
|
165
|
+
#### When to use
|
|
166
166
|
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
167
|
+
- Quickly check what data exists in the live DB
|
|
168
|
+
- Preview before running fixture fetch
|
|
169
|
+
- Understand data distribution
|
|
170
170
|
|
|
171
171
|
---
|
|
172
172
|
|
|
173
|
-
##
|
|
173
|
+
## Practical Scenarios
|
|
174
174
|
|
|
175
|
-
###
|
|
175
|
+
### Scenario 1: Starting from an empty DB
|
|
176
176
|
|
|
177
177
|
```bash
|
|
178
|
-
# 1.
|
|
178
|
+
# 1. Generate base fixtures
|
|
179
179
|
pnpm sonamu fixture gen --all --exclude Admin,Log --count 5
|
|
180
180
|
|
|
181
|
-
# 2. fixture → test DB
|
|
181
|
+
# 2. Sync fixture → test DB
|
|
182
182
|
pnpm sonamu fixture sync
|
|
183
183
|
|
|
184
|
-
# 3.
|
|
184
|
+
# 3. Run tests
|
|
185
185
|
pnpm test
|
|
186
186
|
```
|
|
187
187
|
|
|
188
|
-
###
|
|
188
|
+
### Scenario 2: Testing with real data
|
|
189
189
|
|
|
190
190
|
```bash
|
|
191
|
-
# 1.
|
|
191
|
+
# 1. Fetch recent data from live DB
|
|
192
192
|
pnpm sonamu fixture fetch --include User,Department --strategy recent --limit 20
|
|
193
193
|
|
|
194
|
-
# 2.
|
|
194
|
+
# 2. Generate additional data
|
|
195
195
|
pnpm sonamu fixture gen --include Post,Comment --count 50
|
|
196
196
|
|
|
197
|
-
# 3. fixture → test DB
|
|
197
|
+
# 3. Sync fixture → test DB
|
|
198
198
|
pnpm sonamu fixture sync
|
|
199
199
|
|
|
200
|
-
# 4.
|
|
200
|
+
# 4. Run tests
|
|
201
201
|
pnpm test
|
|
202
202
|
```
|
|
203
203
|
|
|
204
|
-
###
|
|
204
|
+
### Scenario 3: Preparing for a specific scenario test
|
|
205
205
|
|
|
206
206
|
```bash
|
|
207
|
-
# 1.
|
|
207
|
+
# 1. Generate specific Entities only
|
|
208
208
|
pnpm sonamu fixture gen --include User --count 3
|
|
209
209
|
|
|
210
|
-
# 2.
|
|
210
|
+
# 2. Generate additional interactively
|
|
211
211
|
pnpm sonamu fixture gen
|
|
212
|
-
# ?
|
|
213
|
-
# ?
|
|
212
|
+
# ? Select entities to generate fixtures for: choose Post, Comment
|
|
213
|
+
# ? Count per entity: 10
|
|
214
214
|
|
|
215
|
-
# 3.
|
|
215
|
+
# 3. Save to file (for version control)
|
|
216
216
|
pnpm sonamu fixture gen --include User --count 10 --save-to file
|
|
217
|
-
# → test/fixtures/users.json
|
|
217
|
+
# → creates test/fixtures/users.json
|
|
218
218
|
|
|
219
219
|
# 4. fixture sync
|
|
220
220
|
pnpm sonamu fixture sync
|
|
@@ -222,17 +222,17 @@ pnpm sonamu fixture sync
|
|
|
222
222
|
|
|
223
223
|
---
|
|
224
224
|
|
|
225
|
-
##
|
|
225
|
+
## Practical Tips
|
|
226
226
|
|
|
227
|
-
### 1.
|
|
227
|
+
### 1. Automatic Korean data generation
|
|
228
228
|
|
|
229
|
-
FixtureGenerator
|
|
229
|
+
FixtureGenerator automatically generates Korean data for specific field names:
|
|
230
230
|
|
|
231
|
-
|
|
232
|
-
- `name`, `username`:
|
|
233
|
-
- Entity
|
|
231
|
+
**Fields with automatic Korean generation**:
|
|
232
|
+
- `name`, `username`: Korean full name (`fakerKO.person.fullName()`)
|
|
233
|
+
- Entity is `Department` and prop is `name`: Korean department name
|
|
234
234
|
|
|
235
|
-
|
|
235
|
+
**Example output**:
|
|
236
236
|
```typescript
|
|
237
237
|
// User
|
|
238
238
|
{ name: "김민준", username: "이서연" }
|
|
@@ -241,44 +241,44 @@ FixtureGenerator는 특정 필드명에 대해 한국어 데이터를 자동으
|
|
|
241
241
|
{ name: "개발팀 1팀", name: "글로벌 마케팅팀" }
|
|
242
242
|
```
|
|
243
243
|
|
|
244
|
-
|
|
244
|
+
**Customization**:
|
|
245
245
|
```typescript
|
|
246
|
-
// fixture-generator.ts
|
|
246
|
+
// Edit in fixture-generator.ts
|
|
247
247
|
if (entity?.id === "Department" && prop.name === "name") {
|
|
248
248
|
const departments = ["개발팀", "기획팀", "마케팅팀", "영업팀"];
|
|
249
249
|
// ...
|
|
250
250
|
}
|
|
251
251
|
```
|
|
252
252
|
|
|
253
|
-
### 2. Unique
|
|
253
|
+
### 2. Handling Unique Constraints
|
|
254
254
|
|
|
255
|
-
|
|
255
|
+
Fields with unique constraints require a deduplication strategy.
|
|
256
256
|
|
|
257
|
-
|
|
257
|
+
**Problem**:
|
|
258
258
|
```sql
|
|
259
|
-
-- departments
|
|
259
|
+
-- departments table
|
|
260
260
|
UNIQUE (company_id, name)
|
|
261
261
|
```
|
|
262
262
|
|
|
263
|
-
|
|
263
|
+
**Solution: Automatic variation**
|
|
264
264
|
```typescript
|
|
265
|
-
//
|
|
266
|
-
//
|
|
265
|
+
// Prevents "개발팀" from being generated multiple times under the same company_id
|
|
266
|
+
// Automatically adds prefix/suffix with 70% probability
|
|
267
267
|
|
|
268
|
-
//
|
|
268
|
+
// Result:
|
|
269
269
|
"개발팀" // 30%
|
|
270
270
|
"개발팀 1팀" // 20%
|
|
271
271
|
"개발팀 본부" // 20%
|
|
272
272
|
"글로벌 개발팀" // 30%
|
|
273
273
|
```
|
|
274
274
|
|
|
275
|
-
|
|
275
|
+
**Implementation location**: `generateDefaultValue()` in `fixture-generator.ts`
|
|
276
276
|
|
|
277
|
-
### 3. BelongsToOne FK
|
|
277
|
+
### 3. BelongsToOne FK Setup
|
|
278
278
|
|
|
279
|
-
BelongsToOne
|
|
279
|
+
BelongsToOne relations auto-generate a `{name}_id` column, so code must use the `_id` suffix.
|
|
280
280
|
|
|
281
|
-
**Entity
|
|
281
|
+
**Entity definition**:
|
|
282
282
|
```json
|
|
283
283
|
{
|
|
284
284
|
"type": "relation",
|
|
@@ -288,45 +288,45 @@ BelongsToOne 관계는 `{name}_id` 컬럼을 자동 생성하므로, 코드에
|
|
|
288
288
|
}
|
|
289
289
|
```
|
|
290
290
|
|
|
291
|
-
**FixtureGenerator
|
|
291
|
+
**Inside FixtureGenerator**:
|
|
292
292
|
```typescript
|
|
293
293
|
// ✓ CORRECT
|
|
294
294
|
fixture[`${prop.name}_id`] = relationValue; // company_id
|
|
295
295
|
|
|
296
296
|
// ✗ WRONG
|
|
297
|
-
fixture[prop.name] = relationValue; // company (FK
|
|
297
|
+
fixture[prop.name] = relationValue; // company (FK saved as NULL!)
|
|
298
298
|
```
|
|
299
299
|
|
|
300
|
-
|
|
301
|
-
- Entity JSON
|
|
302
|
-
- DB
|
|
303
|
-
-
|
|
300
|
+
**Easy to get wrong because**:
|
|
301
|
+
- Entity JSON defines `name: "company"`
|
|
302
|
+
- DB column is auto-created as `company_id`
|
|
303
|
+
- Code must use `company_id`
|
|
304
304
|
|
|
305
|
-
### 4.
|
|
305
|
+
### 4. Resolving Ordering Issues
|
|
306
306
|
|
|
307
|
-
fixture gen
|
|
307
|
+
fixture gen **automatically sorts by dependency order** (uses FixtureManager's RelationGraph).
|
|
308
308
|
|
|
309
|
-
|
|
309
|
+
**Example**:
|
|
310
310
|
```bash
|
|
311
|
-
# Department
|
|
311
|
+
# Department references Company, but no need to worry about order
|
|
312
312
|
pnpm sonamu fixture gen --include Department,Company --count 5
|
|
313
313
|
|
|
314
|
-
#
|
|
315
|
-
# 1. Company
|
|
316
|
-
# 2. Department
|
|
314
|
+
# Internally:
|
|
315
|
+
# 1. Company generated first (no FK)
|
|
316
|
+
# 2. Department generated next (references company_id)
|
|
317
317
|
```
|
|
318
318
|
|
|
319
|
-
|
|
319
|
+
**Note**: Circular references will produce a warning.
|
|
320
320
|
|
|
321
|
-
|
|
321
|
+
**Internal implementation (RelationGraph):**
|
|
322
322
|
|
|
323
|
-
`FixtureManager
|
|
323
|
+
`FixtureManager` uses the `RelationGraph` class (`_relation-graph.ts`) to build a dependency graph and topologically sort it to determine insertion order. It analyzes BelongsToOne and OneToOne (hasJoinColumn) relations to guarantee that parent entities are always inserted before children.
|
|
324
324
|
|
|
325
|
-
### 5. DB
|
|
325
|
+
### 5. DB Sequence Reset
|
|
326
326
|
|
|
327
|
-
|
|
327
|
+
After generating fixtures, ID sequences may be out of sync.
|
|
328
328
|
|
|
329
|
-
|
|
329
|
+
**Check**:
|
|
330
330
|
```bash
|
|
331
331
|
PGPASSWORD=1234 psql -h 0.0.0.0 -U postgres -d project_fixture -c "
|
|
332
332
|
SELECT sequencename, last_value
|
|
@@ -336,16 +336,16 @@ ORDER BY sequencename;
|
|
|
336
336
|
"
|
|
337
337
|
```
|
|
338
338
|
|
|
339
|
-
|
|
339
|
+
**Reset**:
|
|
340
340
|
```sql
|
|
341
|
-
--
|
|
341
|
+
-- Per table
|
|
342
342
|
SELECT setval('departments_id_seq', (SELECT MAX(id) FROM departments), true);
|
|
343
343
|
SELECT setval('companies_id_seq', (SELECT MAX(id) FROM companies), true);
|
|
344
344
|
```
|
|
345
345
|
|
|
346
|
-
|
|
346
|
+
**Automated**:
|
|
347
347
|
```bash
|
|
348
|
-
#
|
|
348
|
+
# Reset all sequences script
|
|
349
349
|
PGPASSWORD=1234 psql -h 0.0.0.0 -U postgres -d project_fixture -c "
|
|
350
350
|
SELECT 'SELECT setval(''' || sequencename || ''', (SELECT COALESCE(MAX(id), 1) FROM ' ||
|
|
351
351
|
replace(sequencename, '_id_seq', '') || '), true);'
|
|
@@ -354,34 +354,34 @@ WHERE schemaname = 'public' AND sequencename LIKE '%_id_seq';
|
|
|
354
354
|
" | grep SELECT | PGPASSWORD=1234 psql -h 0.0.0.0 -U postgres -d project_fixture
|
|
355
355
|
```
|
|
356
356
|
|
|
357
|
-
### 6.
|
|
357
|
+
### 6. Using File Storage
|
|
358
358
|
|
|
359
|
-
|
|
359
|
+
Saving to file enables **version control**.
|
|
360
360
|
|
|
361
361
|
```bash
|
|
362
|
-
# 1.
|
|
362
|
+
# 1. Save to file
|
|
363
363
|
pnpm sonamu fixture gen --include User --count 10 --save-to file
|
|
364
364
|
# → test/fixtures/users.json
|
|
365
365
|
|
|
366
|
-
# 2. git
|
|
366
|
+
# 2. Commit to git
|
|
367
367
|
git add test/fixtures/users.json
|
|
368
368
|
git commit -m "Add user fixtures for testing"
|
|
369
369
|
|
|
370
|
-
# 3.
|
|
370
|
+
# 3. Other developers can test with the same data
|
|
371
371
|
```
|
|
372
372
|
|
|
373
|
-
|
|
374
|
-
-
|
|
375
|
-
-
|
|
376
|
-
-
|
|
373
|
+
**When to use**:
|
|
374
|
+
- Consistent test data needed in CI/CD environments
|
|
375
|
+
- Reproducing specific scenarios
|
|
376
|
+
- Sharing test data across team members
|
|
377
377
|
|
|
378
378
|
---
|
|
379
379
|
|
|
380
|
-
##
|
|
380
|
+
## Advanced: cone Metadata (Optional)
|
|
381
381
|
|
|
382
|
-
|
|
382
|
+
Adding `cone` metadata to Entity JSON gives you finer control over fixture generation.
|
|
383
383
|
|
|
384
|
-
### dataSource -
|
|
384
|
+
### dataSource - Specify a reference strategy
|
|
385
385
|
|
|
386
386
|
```json
|
|
387
387
|
{
|
|
@@ -403,15 +403,15 @@ Entity JSON에 `cone` 메타데이터를 추가하면 fixture 생성을 더욱
|
|
|
403
403
|
}
|
|
404
404
|
```
|
|
405
405
|
|
|
406
|
-
|
|
407
|
-
- `sample`:
|
|
408
|
-
- `recent`:
|
|
409
|
-
- `random`:
|
|
410
|
-
- `ids`:
|
|
411
|
-
- `query`:
|
|
412
|
-
- `file`:
|
|
406
|
+
**Supported strategies**:
|
|
407
|
+
- `sample`: Uniform sampling
|
|
408
|
+
- `recent`: Most recent data (by created_at)
|
|
409
|
+
- `random`: Random sampling
|
|
410
|
+
- `ids`: Specific IDs
|
|
411
|
+
- `query`: Custom query
|
|
412
|
+
- `file`: Load from file
|
|
413
413
|
|
|
414
|
-
### fixtureGenerator -
|
|
414
|
+
### fixtureGenerator - Custom generation logic
|
|
415
415
|
|
|
416
416
|
```json
|
|
417
417
|
{
|
|
@@ -423,9 +423,9 @@ Entity JSON에 `cone` 메타데이터를 추가하면 fixture 생성을 더욱
|
|
|
423
423
|
}
|
|
424
424
|
```
|
|
425
425
|
|
|
426
|
-
|
|
426
|
+
**Security note**: Security risk due to eval usage (only use trusted expressions)
|
|
427
427
|
|
|
428
|
-
### fixtureDefault -
|
|
428
|
+
### fixtureDefault - Specify a default value
|
|
429
429
|
|
|
430
430
|
```json
|
|
431
431
|
{
|
|
@@ -437,152 +437,152 @@ Entity JSON에 `cone` 메타데이터를 추가하면 fixture 생성을 더욱
|
|
|
437
437
|
}
|
|
438
438
|
```
|
|
439
439
|
|
|
440
|
-
### note -
|
|
440
|
+
### note - Description and LLM trigger
|
|
441
441
|
|
|
442
442
|
```json
|
|
443
443
|
{
|
|
444
444
|
"name": "phone",
|
|
445
445
|
"type": "string",
|
|
446
446
|
"cone": {
|
|
447
|
-
"note": "010-XXXX-XXXX
|
|
447
|
+
"note": "Korean phone number in 010-XXXX-XXXX format"
|
|
448
448
|
}
|
|
449
449
|
}
|
|
450
450
|
```
|
|
451
451
|
|
|
452
|
-
|
|
453
|
-
- `--use-llm
|
|
454
|
-
- `--use-llm
|
|
452
|
+
**How it works**:
|
|
453
|
+
- Without `--use-llm`: serves only as a reference description for developers/LLMs (used by cone-generator when generating metadata)
|
|
454
|
+
- With `--use-llm`: fixture gen calls the Claude API and generates actual values based on the note content
|
|
455
455
|
|
|
456
|
-
|
|
457
|
-
-
|
|
458
|
-
-
|
|
459
|
-
-
|
|
456
|
+
**Use cases**:
|
|
457
|
+
- Contextual text that is hard to express with simple faker.js (self-introductions, descriptions, etc.)
|
|
458
|
+
- Explaining the field's meaning and generation pattern to developers
|
|
459
|
+
- No length limit (short patterns or long descriptions are both fine)
|
|
460
460
|
|
|
461
461
|
---
|
|
462
462
|
|
|
463
|
-
### LLM
|
|
463
|
+
### LLM-based Data Generation
|
|
464
464
|
|
|
465
|
-
`--use-llm`
|
|
465
|
+
When the `--use-llm` flag is used, `cone.note` acts as the trigger for Claude API calls.
|
|
466
466
|
|
|
467
|
-
####
|
|
467
|
+
#### Priority chain
|
|
468
468
|
|
|
469
469
|
```
|
|
470
|
-
1. override
|
|
471
|
-
2. cone.note + LLM ← --use-llm
|
|
472
|
-
3. fixtureGenerator (faker.js
|
|
473
|
-
4. fixtureDefault (
|
|
474
|
-
5.
|
|
470
|
+
1. override value (passed at generate() call time)
|
|
471
|
+
2. cone.note + LLM ← activated with --use-llm flag (highest priority when API key is present)
|
|
472
|
+
3. fixtureGenerator (faker.js expression) ← fallback when LLM fails
|
|
473
|
+
4. fixtureDefault (fixed default value)
|
|
474
|
+
5. type-based default (auto-generated)
|
|
475
475
|
```
|
|
476
476
|
|
|
477
|
-
#### CLI
|
|
477
|
+
#### CLI usage
|
|
478
478
|
|
|
479
479
|
```bash
|
|
480
|
-
# LLM
|
|
480
|
+
# Enable LLM
|
|
481
481
|
pnpm sonamu fixture gen --include User --count 10 --use-llm
|
|
482
482
|
|
|
483
|
-
#
|
|
483
|
+
# Disable cache
|
|
484
484
|
pnpm sonamu fixture gen --include User --count 10 --use-llm --no-cache
|
|
485
485
|
```
|
|
486
486
|
|
|
487
|
-
#### API
|
|
487
|
+
#### API Key Setup
|
|
488
488
|
|
|
489
489
|
```bash
|
|
490
|
-
#
|
|
490
|
+
# Option 1: environment variable
|
|
491
491
|
export ANTHROPIC_API_KEY=sk-ant-...
|
|
492
492
|
|
|
493
|
-
#
|
|
493
|
+
# Option 2: sonamu.config.ts
|
|
494
494
|
export default defineConfig({
|
|
495
495
|
secret: { anthropic_api_key: "sk-ant-..." }
|
|
496
496
|
});
|
|
497
497
|
```
|
|
498
498
|
|
|
499
|
-
####
|
|
499
|
+
#### Caching behavior
|
|
500
500
|
|
|
501
|
-
- `useLLM=true
|
|
502
|
-
-
|
|
503
|
-
-
|
|
504
|
-
-
|
|
505
|
-
- `--no-cache
|
|
501
|
+
- When `useLLM=true`, all LLM-targeted fields in a single row are generated in **a single LLM call** (not per-field individual calls)
|
|
502
|
+
- This single call guarantees automatic consistency across correlated fields such as `name`, `name_en`, `name_cn`, `email`
|
|
503
|
+
- Generated results are stored in an in-memory cache keyed by `rowKey:fieldName`, and returned immediately for subsequent fields in the same row
|
|
504
|
+
- Cache is valid only within the same FixtureGenerator instance
|
|
505
|
+
- Cache can be disabled with `--no-cache` (the row-level generation approach itself is preserved)
|
|
506
506
|
|
|
507
|
-
#### Fallback
|
|
507
|
+
#### Fallback behavior
|
|
508
508
|
|
|
509
|
-
- API
|
|
510
|
-
- LLM
|
|
509
|
+
- No API key → falls back to fixtureDefault or type default (no error)
|
|
510
|
+
- LLM call fails → same fallback (console warning only)
|
|
511
511
|
|
|
512
|
-
#### note vs fixtureGenerator
|
|
512
|
+
#### When to choose note vs fixtureGenerator
|
|
513
513
|
|
|
514
|
-
|
|
|
515
|
-
|
|
516
|
-
|
|
|
517
|
-
|
|
|
518
|
-
|
|
|
514
|
+
| Situation | Recommended |
|
|
515
|
+
|-----------|-------------|
|
|
516
|
+
| Simple values such as email, name, number | `fixtureGenerator` (faker.js) |
|
|
517
|
+
| Contextual text such as self-introductions or descriptions | `cone.note` + `--use-llm` (LLM) |
|
|
518
|
+
| Selecting from a specific list of values | `fixtureGenerator` (arrayElement) |
|
|
519
519
|
|
|
520
520
|
---
|
|
521
521
|
|
|
522
|
-
## FixtureGenerator
|
|
522
|
+
## FixtureGenerator Options (FixtureGeneratorOptions)
|
|
523
523
|
|
|
524
|
-
|
|
524
|
+
**Source:** `modules/sonamu/src/testing/fixture-generator.ts`
|
|
525
525
|
|
|
526
|
-
|
|
|
527
|
-
|
|
528
|
-
| `locale` | `"ko"` \| `"en"` \| `"ja"` | `"ko"` |
|
|
529
|
-
| `useLLM` | boolean | `false` | LLM
|
|
530
|
-
| `enableLLMCache` | boolean | `true` | LLM
|
|
531
|
-
| `llmModel` | string | `"claude-sonnet-4-5"` |
|
|
526
|
+
| Option | Type | Default | Description |
|
|
527
|
+
|--------|------|---------|-------------|
|
|
528
|
+
| `locale` | `"ko"` \| `"en"` \| `"ja"` | `"ko"` | Locale for generated data |
|
|
529
|
+
| `useLLM` | boolean | `false` | LLM-based data generation (`--use-llm`) |
|
|
530
|
+
| `enableLLMCache` | boolean | `true` | Cache LLM results (disable with `--no-cache`) |
|
|
531
|
+
| `llmModel` | string | `"claude-sonnet-4-5"` | LLM model to use |
|
|
532
532
|
|
|
533
533
|
---
|
|
534
534
|
|
|
535
|
-
##
|
|
535
|
+
## Troubleshooting
|
|
536
536
|
|
|
537
|
-
###
|
|
537
|
+
### Problem 1: "Cannot generate non-nullable relation without dataSource"
|
|
538
538
|
|
|
539
|
-
|
|
539
|
+
**Cause**: BelongsToOne relation is non-nullable but there is no data to reference
|
|
540
540
|
|
|
541
|
-
|
|
541
|
+
**Solution**:
|
|
542
542
|
```bash
|
|
543
|
-
#
|
|
543
|
+
# Generate the referenced Entity first
|
|
544
544
|
pnpm sonamu fixture gen --include Company --count 5
|
|
545
545
|
|
|
546
|
-
#
|
|
546
|
+
# Then generate Department
|
|
547
547
|
pnpm sonamu fixture gen --include Department --count 10
|
|
548
548
|
```
|
|
549
549
|
|
|
550
|
-
|
|
550
|
+
Or:
|
|
551
551
|
```bash
|
|
552
|
-
#
|
|
552
|
+
# Generate together (auto-sorted by dependency order)
|
|
553
553
|
pnpm sonamu fixture gen --include Company,Department --count 5
|
|
554
554
|
```
|
|
555
555
|
|
|
556
|
-
###
|
|
556
|
+
### Problem 2: "duplicate key value violates unique constraint"
|
|
557
557
|
|
|
558
|
-
|
|
558
|
+
**Cause**: Duplicate values generated for a field with a unique constraint
|
|
559
559
|
|
|
560
|
-
|
|
561
|
-
1.
|
|
562
|
-
2. prefix/suffix
|
|
563
|
-
3. count
|
|
560
|
+
**Solution**:
|
|
561
|
+
1. Modify the per-field generation logic for that Entity in `fixture-generator.ts`
|
|
562
|
+
2. Add prefix/suffix or use UUID
|
|
563
|
+
3. Reduce count
|
|
564
564
|
|
|
565
|
-
###
|
|
565
|
+
### Problem 3: FK reference error "violates foreign key constraint"
|
|
566
566
|
|
|
567
|
-
|
|
567
|
+
**Cause**: Incorrect sourceDb/targetDb configuration
|
|
568
568
|
|
|
569
|
-
|
|
569
|
+
**Check**:
|
|
570
570
|
```typescript
|
|
571
|
-
// fixture.ts
|
|
571
|
+
// Verify in fixture.ts
|
|
572
572
|
const fixtureDb = createKnexInstance(Sonamu.dbConfig.fixture);
|
|
573
573
|
const generator = new FixtureGenerator(fixtureDb, fixtureDb, "fixture", EntityManager);
|
|
574
574
|
```
|
|
575
575
|
|
|
576
|
-
|
|
576
|
+
**Correct configuration**:
|
|
577
577
|
- `fixture gen`: sourceDb = fixtureDb, targetDb = fixtureDb
|
|
578
578
|
- `fixture fetch`: sourceDb = production, targetDb = fixtureDb
|
|
579
579
|
|
|
580
580
|
---
|
|
581
581
|
|
|
582
|
-
##
|
|
582
|
+
## References
|
|
583
583
|
|
|
584
|
-
- **3-Tier DB
|
|
585
|
-
- **Fixture
|
|
586
|
-
- **BelongsToOne FK**: `entity-relations.md`
|
|
587
|
-
-
|
|
588
|
-
-
|
|
584
|
+
- **3-Tier DB Structure**: "3-Tier DB Structure" section in `database.md`
|
|
585
|
+
- **Fixture generation tips**: "Fixture Data Generation Tips" section in `testing.md`
|
|
586
|
+
- **BelongsToOne FK**: "Using FK in Code" section in `entity-relations.md`
|
|
587
|
+
- **Implementation**: `modules/sonamu/src/bin/fixture.ts`
|
|
588
|
+
- **Generation logic**: `modules/sonamu/src/testing/fixture-generator.ts`
|