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.
Files changed (88) hide show
  1. package/dist/api/__tests__/config.test.js +189 -0
  2. package/dist/api/config.d.ts.map +1 -1
  3. package/dist/api/config.js +7 -2
  4. package/dist/api/sonamu.d.ts.map +1 -1
  5. package/dist/api/sonamu.js +14 -10
  6. package/dist/auth/index.d.ts +1 -0
  7. package/dist/auth/index.d.ts.map +1 -1
  8. package/dist/auth/index.js +2 -1
  9. package/dist/auth/knex-adapter.d.ts +23 -0
  10. package/dist/auth/knex-adapter.d.ts.map +1 -0
  11. package/dist/auth/knex-adapter.js +163 -0
  12. package/dist/auth/plugins/wrappers/admin.d.ts +2 -2
  13. package/dist/bin/__tests__/ts-loader-register.test.js +45 -0
  14. package/dist/bin/cli.js +47 -9
  15. package/dist/bin/ts-loader-register.js +3 -29
  16. package/dist/bin/ts-loader-registration.d.ts +2 -0
  17. package/dist/bin/ts-loader-registration.d.ts.map +1 -0
  18. package/dist/bin/ts-loader-registration.js +42 -0
  19. package/dist/cone/cone-generator.js +3 -3
  20. package/dist/database/puri-subset.test-d.js +9 -1
  21. package/dist/database/puri-subset.types.d.ts +1 -1
  22. package/dist/database/puri-subset.types.d.ts.map +1 -1
  23. package/dist/database/puri-subset.types.js +1 -1
  24. package/dist/testing/fixture-generator.js +5 -5
  25. package/dist/ui/ai-client.js +2 -2
  26. package/dist/ui/api.d.ts.map +1 -1
  27. package/dist/ui/api.js +14 -14
  28. package/dist/ui/cdd-service.d.ts +15 -18
  29. package/dist/ui/cdd-service.d.ts.map +1 -1
  30. package/dist/ui/cdd-service.js +246 -222
  31. package/dist/ui/cdd-types.d.ts +41 -68
  32. package/dist/ui/cdd-types.d.ts.map +1 -1
  33. package/dist/ui/cdd-types.js +2 -2
  34. package/dist/ui-web/assets/index-CKo0Z2Iu.css +1 -0
  35. package/dist/ui-web/assets/{index-CxiydzeC.js → index-DK-2aacv.js} +83 -83
  36. package/dist/ui-web/index.html +2 -2
  37. package/package.json +6 -2
  38. package/src/api/__tests__/config.test.ts +225 -0
  39. package/src/api/config.ts +10 -4
  40. package/src/api/sonamu.ts +16 -13
  41. package/src/auth/index.ts +1 -0
  42. package/src/auth/knex-adapter.ts +208 -0
  43. package/src/bin/__tests__/ts-loader-register.test.ts +62 -0
  44. package/src/bin/cli.ts +52 -9
  45. package/src/bin/ts-loader-register.ts +2 -32
  46. package/src/bin/ts-loader-registration.ts +55 -0
  47. package/src/cone/cone-generator.ts +2 -2
  48. package/src/database/puri-subset.test-d.ts +102 -0
  49. package/src/database/puri-subset.types.ts +1 -1
  50. package/src/skills/commands/sonamu-skills.md +20 -0
  51. package/src/skills/sonamu/SKILL.md +179 -137
  52. package/src/skills/sonamu/ai-agents.md +69 -69
  53. package/src/skills/sonamu/api.md +147 -147
  54. package/src/skills/sonamu/auth-migration.md +220 -220
  55. package/src/skills/sonamu/auth-plugins.md +83 -83
  56. package/src/skills/sonamu/auth.md +106 -106
  57. package/src/skills/sonamu/cdd.md +65 -200
  58. package/src/skills/sonamu/cone.md +138 -138
  59. package/src/skills/sonamu/config.md +191 -191
  60. package/src/skills/sonamu/create-sonamu.md +66 -66
  61. package/src/skills/sonamu/database.md +158 -158
  62. package/src/skills/sonamu/entity-basic.md +292 -293
  63. package/src/skills/sonamu/entity-relations.md +246 -246
  64. package/src/skills/sonamu/entity-validation-checklist.md +124 -124
  65. package/src/skills/sonamu/fixture-cli.md +231 -231
  66. package/src/skills/sonamu/framework-change.md +37 -37
  67. package/src/skills/sonamu/frontend.md +223 -223
  68. package/src/skills/sonamu/i18n.md +82 -82
  69. package/src/skills/sonamu/migration.md +77 -77
  70. package/src/skills/sonamu/model.md +222 -222
  71. package/src/skills/sonamu/naite.md +86 -86
  72. package/src/skills/sonamu/project-init.md +228 -228
  73. package/src/skills/sonamu/puri.md +122 -122
  74. package/src/skills/sonamu/scaffolding.md +154 -154
  75. package/src/skills/sonamu/skill-contribution.md +124 -124
  76. package/src/skills/sonamu/subset.md +46 -46
  77. package/src/skills/sonamu/tasks.md +82 -82
  78. package/src/skills/sonamu/testing-devrunner.md +147 -147
  79. package/src/skills/sonamu/testing.md +673 -673
  80. package/src/skills/sonamu/upsert.md +79 -79
  81. package/src/skills/sonamu/vector.md +67 -67
  82. package/src/testing/fixture-generator.ts +4 -4
  83. package/src/ui/ai-client.ts +1 -1
  84. package/src/ui/api.ts +18 -17
  85. package/src/ui/cdd-service.ts +264 -254
  86. package/src/ui/cdd-types.ts +40 -75
  87. package/dist/ui-web/assets/index-BrQKU3j9.css +0 -1
  88. package/src/skills/sonamu/workflow.md +0 -317
@@ -1,17 +1,17 @@
1
1
  ---
2
2
  name: sonamu-config
3
- description: Sonamu 프로젝트 설정. .env 환경변수, sonamu.config.ts 설정. Use when configuring a new Sonamu project.
3
+ description: Sonamu project configuration. .env environment variables, sonamu.config.ts settings. Use when configuring a new Sonamu project.
4
4
  ---
5
5
 
6
- # Sonamu 프로젝트 설정
6
+ # Sonamu Project Configuration
7
7
 
8
- 프로젝트 생성 `.env`와 `sonamu.config.ts` 설정 가이드.
8
+ A guide for setting up `.env` and `sonamu.config.ts` after project creation.
9
9
 
10
- ## .env 파일
10
+ ## .env File
11
11
 
12
- 위치: `packages/api/.env`
12
+ Location: `packages/api/.env`
13
13
 
14
- ### 기본 환경변수 (create-sonamu 생성)
14
+ ### Default Environment Variables (generated by create-sonamu)
15
15
 
16
16
  ```env
17
17
  # Database Configuration
@@ -24,49 +24,49 @@ DATABASE_NAME=myproject
24
24
  PROJECT_NAME=myproject
25
25
  ```
26
26
 
27
- ### 추가 환경변수 (필요시)
27
+ ### Additional Environment Variables (as needed)
28
28
 
29
29
  ```env
30
- # Session (프로덕션에서 반드시 변경)
30
+ # Session (must be changed in production)
31
31
  SESSION_SECRET=your-secret-key-change-in-production
32
32
  SESSION_SALT=random-16-char-salt
33
33
 
34
- # AWS S3 (파일 업로드용)
34
+ # AWS S3 (for file uploads)
35
35
  AWS_ACCESS_KEY_ID=your-access-key
36
36
  AWS_SECRET_ACCESS_KEY=your-secret-key
37
37
  S3_REGION=ap-northeast-2
38
38
  S3_BUCKET=your-bucket-name
39
39
 
40
- # Slack 알림 (마이그레이션 확인용)
40
+ # Slack notifications (for migration confirmation)
41
41
  SLACK_BOT_TOKEN=xoxb-your-token
42
42
  SLACK_CHANNEL_ID=C0123456789
43
43
  ```
44
44
 
45
- ### 환경변수 설명
45
+ ### Environment Variable Reference
46
46
 
47
- | 변수 | 필수 | 설명 |
47
+ | Variable | Required | Description |
48
48
  |-----|-----|------|
49
- | `DB_HOST` | ✓ | DB 호스트 (Docker: `0.0.0.0`, 외부 DB: 해당 IP) |
50
- | `DB_PORT` | ✓ | DB 포트 (기본값: `5432`) |
51
- | `DB_USER` | ✓ | DB 사용자명 (기본값: `postgres`) |
52
- | `DB_PASSWORD` | ✓ | DB 비밀번호 |
53
- | `DATABASE_NAME` | ✓ | 데이터베이스명 |
54
- | `PROJECT_NAME` | ✓ | 프로젝트명 (Docker, config에서 사용) |
55
- | `CONTAINER_NAME` | | Docker 컨테이너명 |
56
- | `SESSION_SECRET` | | 세션 암호화 (프로덕션 필수) |
57
- | `SESSION_SALT` | | 세션 salt (16) |
58
- | `AWS_ACCESS_KEY_ID` | | S3 사용 필수 |
59
- | `AWS_SECRET_ACCESS_KEY` | | S3 사용 필수 |
60
- | `S3_REGION` | | S3 리전 (기본값: `ap-northeast-2`) |
61
- | `S3_BUCKET` | | S3 버킷명 |
49
+ | `DB_HOST` | ✓ | DB host (Docker: `0.0.0.0`, external DB: the relevant IP) |
50
+ | `DB_PORT` | ✓ | DB port (default: `5432`) |
51
+ | `DB_USER` | ✓ | DB username (default: `postgres`) |
52
+ | `DB_PASSWORD` | ✓ | DB password |
53
+ | `DATABASE_NAME` | ✓ | Database name |
54
+ | `PROJECT_NAME` | ✓ | Project name (used in Docker, config) |
55
+ | `CONTAINER_NAME` | | Docker container name |
56
+ | `SESSION_SECRET` | | Session encryption key (required in production) |
57
+ | `SESSION_SALT` | | Session salt (16 characters) |
58
+ | `AWS_ACCESS_KEY_ID` | | Required when using S3 |
59
+ | `AWS_SECRET_ACCESS_KEY` | | Required when using S3 |
60
+ | `S3_REGION` | | S3 region (default: `ap-northeast-2`) |
61
+ | `S3_BUCKET` | | S3 bucket name |
62
62
 
63
63
  ---
64
64
 
65
65
  ## sonamu.config.ts
66
66
 
67
- 위치: `packages/api/src/sonamu.config.ts`
67
+ Location: `packages/api/src/sonamu.config.ts`
68
68
 
69
- ### 전체 구조
69
+ ### Full Structure
70
70
 
71
71
  ```typescript
72
72
  import path from "node:path";
@@ -79,18 +79,18 @@ const port = 34900;
79
79
 
80
80
  export default defineConfig({
81
81
  projectName: process.env.PROJECT_NAME ?? "MyProject",
82
- api: { /* API 설정 */ },
83
- i18n: { /* 다국어 설정 */ },
84
- sync: { /* 동기화 설정 */ },
85
- database: { /* DB 설정 */ },
86
- logging: { /* 로깅 설정 (false로 비활성화 가능) */ },
87
- test: { /* 테스트 설정 */ },
88
- server: { /* 서버 설정 */ },
89
- slackConfirm: { /* Production 마이그레이션 Slack 승인 */ },
82
+ api: { /* API settings */ },
83
+ i18n: { /* i18n settings */ },
84
+ sync: { /* sync settings */ },
85
+ database: { /* DB settings */ },
86
+ logging: { /* logging settings (disable with false) */ },
87
+ test: { /* test settings */ },
88
+ server: { /* server settings */ },
89
+ slackConfirm: { /* Production migration Slack approval */ },
90
90
  });
91
91
  ```
92
92
 
93
- ### 주요 섹션별 설정
93
+ ### Key Section Settings
94
94
 
95
95
  #### projectName
96
96
 
@@ -102,10 +102,10 @@ projectName: process.env.PROJECT_NAME ?? "MyProject",
102
102
 
103
103
  ```typescript
104
104
  api: {
105
- dir: "api", // API 디렉토리명
106
- timezone: "Asia/Seoul", // 타임존
105
+ dir: "api", // API directory name
106
+ timezone: "Asia/Seoul", // timezone
107
107
  route: {
108
- prefix: "/api", // API 라우트 prefix
108
+ prefix: "/api", // API route prefix
109
109
  },
110
110
  },
111
111
  ```
@@ -119,13 +119,13 @@ i18n: {
119
119
  },
120
120
  ```
121
121
 
122
- 자세한 내용은 `i18n.md` 참조.
122
+ See `i18n.md` for details.
123
123
 
124
124
  #### sync
125
125
 
126
126
  ```typescript
127
127
  sync: {
128
- targets: ["web"], // 타입 동기화 대상 패키지
128
+ targets: ["web"], // target packages for type sync
129
129
  },
130
130
  ```
131
131
 
@@ -146,65 +146,65 @@ database: {
146
146
  },
147
147
  ```
148
148
 
149
- 자세한 내용은 `database.md` 참조.
149
+ See `database.md` for details.
150
150
 
151
151
  #### test
152
152
 
153
153
  ```typescript
154
154
  test: {
155
- parallel: true, // 병렬 테스트 활성화
156
- maxWorkers: 4, // Worker
157
- devRunner: { // Dev 서버 Vitest 상주 인스턴스
155
+ parallel: true, // enable parallel testing
156
+ maxWorkers: 4, // number of workers
157
+ devRunner: { // Vitest resident instance inside Dev server
158
158
  enabled: true,
159
159
  watch: true,
160
160
  },
161
161
  },
162
162
  ```
163
163
 
164
- 자세한 내용은 `testing.md`, `testing-devrunner.md` 참조.
164
+ See `testing.md`, `testing-devrunner.md` for details.
165
165
 
166
166
  #### server
167
167
 
168
168
  ```typescript
169
169
  server: {
170
170
  listen: { port: 34900, host: "localhost" },
171
- plugins: { /* 플러그인 설정 */ },
171
+ plugins: { /* plugin settings */ },
172
172
  auth: true,
173
- apiConfig: { /* API 설정 */ },
174
- storage: { /* 스토리지 설정 */ },
175
- cache: { /* 캐시 설정 */ },
176
- lifecycle: { /* 라이프사이클 */ },
173
+ apiConfig: { /* API settings */ },
174
+ storage: { /* storage settings */ },
175
+ cache: { /* cache settings */ },
176
+ lifecycle: { /* lifecycle hooks */ },
177
177
  },
178
178
  ```
179
179
 
180
180
  ---
181
181
 
182
- ## server.auth 상세 (better-auth 인증)
182
+ ## server.auth Details (better-auth Authentication)
183
183
 
184
- Sonamu **better-auth**를 사용한 인증 시스템을 제공한다.
184
+ Sonamu provides an authentication system using **better-auth**.
185
185
 
186
- ### 1. 엔티티 자동 생성
186
+ ### 1. Auto-generate Entities
187
187
 
188
188
  ```bash
189
189
  pnpm sonamu auth generate
190
190
  ```
191
191
 
192
- 생성되는 엔티티:
193
- - **User** - 사용자 (id, name, email, email_verified, image)
194
- - **Session** - 세션 (token, expires_at, user_id)
195
- - **Account** - 계정 (provider_id, access_token )
196
- - **Verification** - 이메일 인증
192
+ Generated entities:
193
+ - **User** - user (id, name, email, email_verified, image)
194
+ - **Session** - session (token, expires_at, user_id)
195
+ - **Account** - account (provider_id, access_token, etc.)
196
+ - **Verification** - email verification
197
197
 
198
- ### 2. server.auth 설정
198
+ ### 2. server.auth Configuration
199
199
 
200
200
  ```typescript
201
201
  server: {
202
- // 기본 설정 (emailAndPassword 활성화)
202
+ // Basic configuration (emailAndPassword enabled)
203
203
  auth: {
204
204
  emailAndPassword: { enabled: true },
205
205
  },
206
206
 
207
- // 소셜 로그인 추가
207
+ // Add social login
208
208
  // auth: {
209
209
  // emailAndPassword: { enabled: true },
210
210
  // socialProviders: {
@@ -217,18 +217,18 @@ server: {
217
217
  }
218
218
  ```
219
219
 
220
- ### 3. 인증 API 엔드포인트
220
+ ### 3. Authentication API Endpoints
221
221
 
222
- `/api/auth/*` 경로로 자동 등록:
222
+ Automatically registered under the `/api/auth/*` path:
223
223
 
224
- | 엔드포인트 | 메서드 | 설명 |
224
+ | Endpoint | Method | Description |
225
225
  |------------|--------|------|
226
- | `/api/auth/sign-up/email` | POST | 회원가입 |
227
- | `/api/auth/sign-in/email` | POST | 로그인 |
228
- | `/api/auth/sign-out` | POST | 로그아웃 |
229
- | `/api/auth/get-session` | GET | 세션 조회 |
226
+ | `/api/auth/sign-up/email` | POST | Sign up |
227
+ | `/api/auth/sign-in/email` | POST | Sign in |
228
+ | `/api/auth/sign-out` | POST | Sign out |
229
+ | `/api/auth/get-session` | GET | Get session |
230
230
 
231
- ### 4. Context에서 user/session 접근
231
+ ### 4. Accessing user/session from Context
232
232
 
233
233
  ```typescript
234
234
  @api({ httpMethod: "GET", guards: ["user"] })
@@ -239,9 +239,9 @@ async me(): Promise<UserSubsetA | null> {
239
239
  }
240
240
  ```
241
241
 
242
- ### 5. 필드 매핑 (camelCase → snake_case)
242
+ ### 5. Field Mapping (camelCase → snake_case)
243
243
 
244
- better-auth camelCase, Sonamu snake_case 사용. 자동 매핑 적용:
244
+ better-auth uses camelCase, Sonamu uses snake_case. Automatic mapping is applied:
245
245
 
246
246
  | better-auth | Sonamu |
247
247
  |-------------|--------|
@@ -252,22 +252,22 @@ better-auth는 camelCase, Sonamu는 snake_case 사용. 자동 매핑 적용:
252
252
 
253
253
  ---
254
254
 
255
- ## Guards 시스템 (권한 제어)
255
+ ## Guards System (Access Control)
256
256
 
257
- Sonamu 권한 시스템은 2가지 요소로 구성:
257
+ The Sonamu permission system consists of 2 components:
258
258
 
259
- 1. **GuardKeys** - 권한 정의
260
- 2. **guardHandler** - 권한 검사 로직
259
+ 1. **GuardKeys** - permission key definitions
260
+ 2. **guardHandler** - permission check logic
261
261
 
262
- ### 1. GuardKeys 확장 (커스텀 권한)
262
+ ### 1. Extending GuardKeys (Custom Permissions)
263
263
 
264
- **소스코드:** `modules/sonamu/src/api/decorators.ts` (GuardKeys 인터페이스)
264
+ **Source code:** `modules/sonamu/src/api/decorators.ts` (GuardKeys interface)
265
265
 
266
- 기본 제공: `query`, `admin`, `user`
266
+ Provided by default: `query`, `admin`, `user`
267
267
 
268
- 커스텀 권한 추가 `src/typings/sonamu.d.ts`에서 확장:
268
+ To add custom permissions, extend in `src/typings/sonamu.d.ts`:
269
269
 
270
- **파일 위치:** `src/typings/sonamu.d.ts`
270
+ **File location:** `src/typings/sonamu.d.ts`
271
271
 
272
272
  ```typescript
273
273
  import {} from "sonamu";
@@ -277,13 +277,13 @@ declare module "sonamu" {
277
277
  query: true;
278
278
  admin: true;
279
279
  user: true;
280
- manager: true; // 추가
281
- superadmin: true; // 추가
280
+ manager: true; // added
281
+ superadmin: true; // added
282
282
  }
283
283
  }
284
284
  ```
285
285
 
286
- ### 2. @api 데코레이터에서 guards 사용
286
+ ### 2. Using guards in the @api Decorator
287
287
 
288
288
  ```typescript
289
289
  // user.model.ts
@@ -292,22 +292,22 @@ import { api } from "sonamu";
292
292
  class UserModelClass extends BaseModelClass {
293
293
  @api({ httpMethod: "GET", guards: ["user"] })
294
294
  async me(): Promise<UserSubsetA | null> {
295
- // 로그인한 사용자만 접근
295
+ // only logged-in users can access
296
296
  }
297
297
 
298
298
  @api({ httpMethod: "DELETE", guards: ["admin"] })
299
299
  async del(ids: number[]): Promise<number> {
300
- // 관리자만 접근
300
+ // only admins can access
301
301
  }
302
302
 
303
303
  @api({ httpMethod: "GET", guards: ["admin", "manager"] })
304
304
  async adminList(): Promise<UserSubsetA[]> {
305
- // admin 또는 manager 권한
305
+ // admin or manager permission
306
306
  }
307
307
  }
308
308
  ```
309
309
 
310
- ### 3. guardHandler 구현
310
+ ### 3. Implementing guardHandler
311
311
 
312
312
  ```typescript
313
313
  import { Sonamu } from "sonamu";
@@ -315,44 +315,44 @@ import { Sonamu } from "sonamu";
315
315
  // sonamu.config.ts
316
316
  apiConfig: {
317
317
  guardHandler: (guard, request, api) => {
318
- // better-auth Context에서 user 접근
318
+ // Access user from better-auth Context
319
319
  const { user } = Sonamu.getContext();
320
320
 
321
321
  switch (guard) {
322
322
  case "user":
323
- // 로그인 필수
323
+ // login required
324
324
  if (!user) {
325
- throw new Error("로그인이 필요합니다");
325
+ throw new Error("Login is required");
326
326
  }
327
327
  break;
328
328
 
329
329
  case "admin":
330
- // 관리자 권한 (User 엔티티에 role 필드 추가 필요)
330
+ // admin permission (requires adding role field to User entity)
331
331
  if (!user || (user as any).role !== "admin") {
332
- throw new Error("관리자만 접근 가능합니다");
332
+ throw new Error("Only admins can access");
333
333
  }
334
334
  break;
335
335
 
336
336
  case "manager":
337
- // 매니저 권한 (커스텀 Guard 예시)
338
- if (!user || ![admin”, manager].includes((user as any).role)) {
339
- throw new Error("매니저 권한이 필요합니다");
337
+ // manager permission (custom Guard example)
338
+ if (!user || !["admin", "manager"].includes((user as any).role)) {
339
+ throw new Error("Manager permission is required");
340
340
  }
341
341
  break;
342
342
 
343
343
  case "query":
344
- // 모든 사용자 허용 (비로그인 포함)
344
+ // allow all users (including unauthenticated)
345
345
  break;
346
346
  }
347
347
  },
348
348
  },
349
349
  ```
350
350
 
351
- **NOTE:** better-auth 기본 User 엔티티는 `role` 필드가 없다. 권한 기반 인증이 필요하면 User 엔티티에 `role` 필드를 추가하거나, 별도 Role 엔티티를 만들어야 한다.
351
+ **NOTE:** better-auth's default User entity does not have a `role` field. If role-based authentication is needed, add a `role` field to the User entity or create a separate Role entity.
352
352
 
353
- ### 권한별 메뉴/화면 접근 제어
353
+ ### Menu/Screen Access Control by Permission
354
354
 
355
- 권한별 UI 접근 제어는 **프론트엔드에서** 처리한다:
355
+ UI access control by permission is handled **on the frontend**:
356
356
 
357
357
  ```typescript
358
358
  // web/src/lib/auth.ts
@@ -371,34 +371,34 @@ export function canAccess(userRole: string, menu: keyof typeof menuPermissions)
371
371
  ```tsx
372
372
  // web/src/components/Sidebar.tsx
373
373
  {canAccess(user.role, "userManagement") && (
374
- <MenuItem href="/admin/users">사용자 관리</MenuItem>
374
+ <MenuItem href="/admin/users">User Management</MenuItem>
375
375
  )}
376
376
  ```
377
377
 
378
378
  ---
379
379
 
380
- ## server.plugins 상세
380
+ ## server.plugins Details
381
381
 
382
- ### session (세션 관리)
382
+ ### session (Session Management)
383
383
 
384
384
  ```typescript
385
385
  session: {
386
386
  secret: process.env.SESSION_SECRET || "change-this-in-production",
387
387
  salt: process.env.SESSION_SALT || "mq9hDxBCDbsQDR6N",
388
388
  cookie: {
389
- domain: "localhost", // 프로덕션에서 실제 도메인으로 변경
389
+ domain: "localhost", // change to actual domain in production
390
390
  path: "/",
391
- maxAge: 60 * 60 * 24 * 365 * 10, // 10
391
+ maxAge: 60 * 60 * 24 * 365 * 10, // 10 years
392
392
  },
393
393
  },
394
394
  ```
395
395
 
396
- **프로덕션 체크리스트:**
397
- - `SESSION_SECRET`: 반드시 강력한 무작위 문자열로 변경
398
- - `SESSION_SALT`: 16 무작위 문자열로 변경
399
- - `cookie.domain`: 실제 도메인으로 변경
396
+ **Production checklist:**
397
+ - `SESSION_SECRET`: must be changed to a strong random string
398
+ - `SESSION_SALT`: change to a 16-character random string
399
+ - `cookie.domain`: change to the actual domain
400
400
 
401
- ### static (정적 파일)
401
+ ### static (Static Files)
402
402
 
403
403
  ```typescript
404
404
  static: {
@@ -407,7 +407,7 @@ static: {
407
407
  },
408
408
  ```
409
409
 
410
- ### multipart (파일 업로드)
410
+ ### multipart (File Upload)
411
411
 
412
412
  ```typescript
413
413
  multipart: {
@@ -419,9 +419,9 @@ multipart: {
419
419
 
420
420
  ---
421
421
 
422
- ## server.storage 상세
422
+ ## server.storage Details
423
423
 
424
- ### 로컬 파일 시스템
424
+ ### Local File System
425
425
 
426
426
  ```typescript
427
427
  storage: {
@@ -462,9 +462,9 @@ storage: {
462
462
 
463
463
  ---
464
464
 
465
- ## server.cache 상세
465
+ ## server.cache Details
466
466
 
467
- Sonamu **BentoCache**를 사용한다.
467
+ Sonamu uses **BentoCache**.
468
468
 
469
469
  ```typescript
470
470
  import { drivers as cacheDrivers, store } from "sonamu/cache";
@@ -479,21 +479,21 @@ cache: {
479
479
  },
480
480
  ```
481
481
 
482
- **사용 가능한 드라이버:**
483
- - `memory` - 메모리 캐시 (기본)
484
- - `file` - 파일 기반 캐시
485
- - `redis` - Redis 캐시
486
- - `knex` - DB 기반 캐시
482
+ **Available drivers:**
483
+ - `memory` - in-memory cache (default)
484
+ - `file` - file-based cache
485
+ - `redis` - Redis cache
486
+ - `knex` - DB-based cache
487
487
 
488
- 다른 드라이버 사용 [BentoCache 문서](https://bentocache.dev/) 참조.
488
+ For other drivers, refer to the [BentoCache documentation](https://bentocache.dev/).
489
489
 
490
490
  ---
491
491
 
492
- ## server.apiConfig 상세
492
+ ## server.apiConfig Details
493
493
 
494
494
  ### contextProvider
495
495
 
496
- 요청마다 Context 추가 정보 주입:
496
+ Inject additional information into Context per request:
497
497
 
498
498
  ```typescript
499
499
  contextProvider: (defaultContext, request) => {
@@ -502,34 +502,34 @@ contextProvider: (defaultContext, request) => {
502
502
  ip: request.ip,
503
503
  session: request.session,
504
504
  body: request.body,
505
- // 커스텀 필드 추가 가능
505
+ // custom fields can be added
506
506
  };
507
507
  },
508
508
  ```
509
509
 
510
510
  ### guardHandler
511
511
 
512
- API 가드 처리:
512
+ Handle API guard processing:
513
513
 
514
514
  ```typescript
515
515
  guardHandler: (guard, request, api) => {
516
- // guard 값에 따라 접근 제어
516
+ // access control based on guard value
517
517
  if (guard === "admin" && request.user?.role !== "admin") {
518
- throw new Error("관리자만 접근 가능합니다");
518
+ throw new Error("Only admins can access");
519
519
  }
520
520
  },
521
521
  ```
522
522
 
523
523
  ### cacheControlHandler
524
524
 
525
- HTTP 캐시 헤더 설정:
525
+ Set HTTP cache headers:
526
526
 
527
527
  ```typescript
528
528
  cacheControlHandler: (req) => {
529
529
  switch (req.type) {
530
530
  case "assets":
531
531
  if (req.path.match(/-[a-f0-9]+\./)) {
532
- return CachePresets.immutable; // 해시 포함 파일
532
+ return CachePresets.immutable; // files with hash
533
533
  }
534
534
  return CachePresets.longLived;
535
535
 
@@ -550,7 +550,7 @@ cacheControlHandler: (req) => {
550
550
 
551
551
  ---
552
552
 
553
- ## server.lifecycle 상세
553
+ ## server.lifecycle Details
554
554
 
555
555
  ```typescript
556
556
  lifecycle: {
@@ -559,7 +559,7 @@ lifecycle: {
559
559
  },
560
560
  onShutdown: () => {
561
561
  console.log("graceful shutdown");
562
- // DB 연결 종료, 리소스 정리
562
+ // close DB connections, clean up resources, etc.
563
563
  },
564
564
  onError: (error, request, reply) => {
565
565
  console.error(error);
@@ -573,78 +573,78 @@ lifecycle: {
573
573
 
574
574
  ---
575
575
 
576
- ## Sonamu 로컬 개발 환경 설정
576
+ ## Sonamu Local Development Environment Setup
577
577
 
578
- **언제 필요한가:**
579
- - Sonamu 프레임워크 소스코드를 수정하며 개발하는 경우
580
- - 로컬의 Sonamu 저장소와 프로젝트를 연동하여 작업하는 경우
578
+ **When is this needed:**
579
+ - When modifying the Sonamu framework source code during development
580
+ - When linking a local Sonamu repository to a project for development
581
581
 
582
- **문제 상황:**
582
+ **Problem:**
583
583
 
584
- pnpm link Sonamu를 연결하면 빌드 타입 에러 발생:
584
+ When linking Sonamu with pnpm link, type errors occur at build time:
585
585
 
586
586
  ```
587
587
  error TS2345: Argument of type 'ZodNumber' is not assignable to parameter...
588
588
  Type '2' is not assignable to type '3'.
589
589
  ```
590
590
 
591
- **원인:**
591
+ **Cause:**
592
592
 
593
- - 링크된 Sonamu 프로젝트가 각자의 `node_modules`를 유지
594
- - 공통 의존성(zod 등)의 버전이 달라서 TypeScript 타입 불일치 발생
595
- - TypeScript 개의 다른 타입 정의를 동시에 참조하여 에러 발생
593
+ - The linked Sonamu and the project each maintain their own `node_modules`
594
+ - TypeScript type mismatches occur due to different versions of shared dependencies (e.g. zod)
595
+ - TypeScript simultaneously references two different type definitions, causing errors
596
596
 
597
- **해결 방법:**
597
+ **Solution:**
598
598
 
599
- ### 1. pnpm-workspace.yaml에 override 추가
599
+ ### 1. Add override to pnpm-workspace.yaml
600
600
 
601
- 프로젝트 루트의 `pnpm-workspace.yaml`:
601
+ In the project root's `pnpm-workspace.yaml`:
602
602
 
603
603
  ```yaml
604
604
  overrides:
605
605
  sonamu: link:../../sonamu/modules/sonamu
606
606
  ```
607
607
 
608
- ### 2. packages/api/package.json에 배포 버전 명시
608
+ ### 2. Specify published version in packages/api/package.json
609
609
 
610
610
  ```json
611
611
  {
612
612
  "dependencies": {
613
- "sonamu": "^0.7.45" // 최신 배포 버전으로 명시
613
+ "sonamu": "^0.7.45" // specify the latest published version
614
614
  }
615
615
  }
616
616
  ```
617
617
 
618
- ### 3. 설치 실행
618
+ ### 3. Run install
619
619
 
620
620
  ```bash
621
621
  pnpm install
622
622
  ```
623
623
 
624
- ### 4. 빌드 확인
624
+ ### 4. Verify build
625
625
 
626
626
  ```bash
627
627
  cd packages/api
628
628
  pnpm build
629
629
  ```
630
630
 
631
- **작동 원리:**
631
+ **How it works:**
632
632
 
633
- - **TypeScript 타입 체크**: `package.json`의 배포 버전을 보고 npm registry 타입 정의 참조
634
- - **실제 런타임**: `pnpm overrides`의 로컬 링크가 우선순위를 가져 로컬 소스코드 실행
635
- - 타입 체크와 런타임을 분리하여 버전 불일치 문제 해결
633
+ - **TypeScript type check**: references type definitions from the npm registry based on the published version in `package.json`
634
+ - **Actual runtime**: `pnpm overrides` local link takes priority and runs local source code
635
+ - Separates type checking and runtime to resolve version mismatch issues
636
636
 
637
- **주의사항:**
637
+ **Notes:**
638
638
 
639
- - Sonamu 소스코드를 수정한 프로젝트에서 즉시 반영됨
640
- - Sonamu 빌드 프로젝트 재시작 필요
641
- - 일반 프로젝트 개발 시에는 npm 버전 사용 권장
639
+ - Changes to Sonamu source code are immediately reflected in the project
640
+ - Restarting the project is required after building Sonamu
641
+ - For general project development, using the npm version is recommended
642
642
 
643
643
  ---
644
644
 
645
- ## 환경별 설정
645
+ ## Environment-Specific Configuration
646
646
 
647
- ### 개발 환경
647
+ ### Development Environment
648
648
 
649
649
  ```env
650
650
  # packages/api/.env
@@ -656,7 +656,7 @@ DATABASE_NAME=myproject
656
656
  PROJECT_NAME=myproject
657
657
  ```
658
658
 
659
- ### 프로덕션 환경
659
+ ### Production Environment
660
660
 
661
661
  ```env
662
662
  # packages/api/.env.production
@@ -678,54 +678,54 @@ S3_BUCKET=myproject-prod-bucket
678
678
 
679
679
  ---
680
680
 
681
- ## server 추가 옵션
681
+ ## server Additional Options
682
682
 
683
683
  ### baseUrl
684
684
 
685
685
  ```typescript
686
686
  server: {
687
- baseUrl: "https://api.example.com", // 외부 접근 URL (기본: host:port)
687
+ baseUrl: "https://api.example.com", // external access URL (default: host:port)
688
688
  }
689
689
  ```
690
690
 
691
691
  ### fastify
692
692
 
693
- Fastify 서버 옵션을 직접 전달합니다 (`logger` 제외).
693
+ Pass Fastify server options directly (excluding `logger`).
694
694
 
695
- ### plugins 전체 목록
695
+ ### Full Plugin List
696
696
 
697
- | 플러그인 | 타입 | 설명 |
697
+ | Plugin | Type | Description |
698
698
  |----------|------|------|
699
- | `compress` | `boolean \| FastifyCompressOptions` | 응답 압축 (@fastify/compress) |
700
- | `cors` | `boolean \| FastifyCorsOptions` | CORS 설정 |
701
- | `formbody` | `boolean \| FastifyFormbodyOptions` | x-www-form-urlencoded 파싱 |
702
- | `multipart` | `boolean \| FastifyMultipartOptions` | 파일 업로드 |
703
- | `qs` | `boolean \| QsPluginOptions` | 쿼리 스트링 파싱 |
704
- | `session` | 세션 설정 | 세션 관리 |
699
+ | `compress` | `boolean \| FastifyCompressOptions` | Response compression (@fastify/compress) |
700
+ | `cors` | `boolean \| FastifyCorsOptions` | CORS configuration |
701
+ | `formbody` | `boolean \| FastifyFormbodyOptions` | x-www-form-urlencoded parsing |
702
+ | `multipart` | `boolean \| FastifyMultipartOptions` | File upload |
703
+ | `qs` | `boolean \| QsPluginOptions` | Query string parsing |
704
+ | `session` | session config | Session management |
705
705
  | `sse` | `boolean \| SsePluginOptions` | Server-Sent Events |
706
- | `static` | `boolean \| FastifyStaticOptions` | 정적 파일 서빙 |
707
- | `custom` | `(server: FastifyInstance) => void` | 커스텀 플러그인 등록 함수 |
706
+ | `static` | `boolean \| FastifyStaticOptions` | Static file serving |
707
+ | `custom` | `(server: FastifyInstance) => void` | Custom plugin registration function |
708
708
 
709
709
  ## logging
710
710
 
711
- 로깅 설정을 정의합니다. `false`로 설정하면 로깅을 완전히 비활성화합니다.
711
+ Define logging configuration. Set to `false` to completely disable logging.
712
712
 
713
713
  ```typescript
714
- logging: false, // 로깅 비활성화
715
- // 또는
714
+ logging: false, // disable logging
715
+ // or
716
716
  logging: {
717
- sinks: { /* 로그 출력 대상 정의 */ },
718
- filters: { /* 필터 정의 */ },
717
+ sinks: { /* define log output targets */ },
718
+ filters: { /* define filters */ },
719
719
  },
720
720
  ```
721
721
 
722
722
  ## slackConfirm
723
723
 
724
- Production DB 마이그레이션 Slack을 통한 승인 프로세스를 활성화합니다.
724
+ Activates a Slack-based approval process for production DB migrations.
725
725
 
726
726
  ```typescript
727
727
  slackConfirm: {
728
- targets: ["production"], // 승인이 필요한 DB 목록
728
+ targets: ["production"], // list of DB keys requiring approval
729
729
  botToken: process.env.SLACK_BOT_TOKEN ?? "", // Slack Bot Token (xoxb-...)
730
730
  channelId: process.env.SLACK_CHANNEL_ID ?? "", // Slack Channel ID (C...)
731
731
  },
@@ -733,17 +733,17 @@ slackConfirm: {
733
733
 
734
734
  ---
735
735
 
736
- ## 설정 후 체크리스트
736
+ ## Post-Configuration Checklist
737
737
 
738
- 1. `.env` 파일 생성 확인
739
- 2. Docker 실행: `pnpm docker:up`
740
- 3. 빌드 확인: `pnpm build`
741
- 4. 서버 실행: `pnpm dev`
742
- 5. Sonamu UI 접속: http://localhost:34900/sonamu-ui
738
+ 1. Confirm `.env` file is created
739
+ 2. Start Docker: `pnpm docker:up`
740
+ 3. Verify build: `pnpm build`
741
+ 4. Start server: `pnpm dev`
742
+ 5. Access Sonamu UI: http://localhost:34900/sonamu-ui
743
743
 
744
- 프로덕션 배포 전:
745
- - [ ] `SESSION_SECRET` 변경
746
- - [ ] `SESSION_SALT` 변경
747
- - [ ] `cookie.domain` 실제 도메인으로 변경
748
- - [ ] S3 설정 (필요시)
749
- - [ ] 에러 핸들링 로직 추가
744
+ Before production deployment:
745
+ - [ ] Change `SESSION_SECRET`
746
+ - [ ] Change `SESSION_SALT`
747
+ - [ ] Change `cookie.domain` to the actual domain
748
+ - [ ] Configure S3 (if needed)
749
+ - [ ] Add error handling logic