sonamu 0.7.53 → 0.8.0

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 (271) hide show
  1. package/dist/api/config.d.ts +9 -1
  2. package/dist/api/config.d.ts.map +1 -1
  3. package/dist/api/config.js +1 -1
  4. package/dist/api/sonamu.d.ts +21 -1
  5. package/dist/api/sonamu.d.ts.map +1 -1
  6. package/dist/api/sonamu.js +159 -65
  7. package/dist/auth/plugins/entity-definitions/anonymous.d.ts +10 -0
  8. package/dist/auth/plugins/entity-definitions/anonymous.d.ts.map +1 -0
  9. package/dist/auth/plugins/entity-definitions/anonymous.js +23 -0
  10. package/dist/auth/plugins/entity-definitions/api-key.d.ts +9 -0
  11. package/dist/auth/plugins/entity-definitions/api-key.d.ts.map +1 -0
  12. package/dist/auth/plugins/entity-definitions/api-key.js +199 -0
  13. package/dist/auth/plugins/entity-definitions/index.d.ts +6 -0
  14. package/dist/auth/plugins/entity-definitions/index.d.ts.map +1 -1
  15. package/dist/auth/plugins/entity-definitions/index.js +20 -2
  16. package/dist/auth/plugins/entity-definitions/jwt.d.ts +9 -0
  17. package/dist/auth/plugins/entity-definitions/jwt.d.ts.map +1 -0
  18. package/dist/auth/plugins/entity-definitions/jwt.js +67 -0
  19. package/dist/auth/plugins/entity-definitions/organization.d.ts +9 -0
  20. package/dist/auth/plugins/entity-definitions/organization.d.ts.map +1 -0
  21. package/dist/auth/plugins/entity-definitions/organization.js +424 -0
  22. package/dist/auth/plugins/entity-definitions/passkey.d.ts +10 -0
  23. package/dist/auth/plugins/entity-definitions/passkey.d.ts.map +1 -0
  24. package/dist/auth/plugins/entity-definitions/passkey.js +129 -0
  25. package/dist/auth/plugins/entity-definitions/sso.d.ts +10 -0
  26. package/dist/auth/plugins/entity-definitions/sso.d.ts.map +1 -0
  27. package/dist/auth/plugins/entity-definitions/sso.js +110 -0
  28. package/dist/auth/plugins/entity-definitions/types.d.ts +1 -1
  29. package/dist/auth/plugins/entity-definitions/types.d.ts.map +1 -1
  30. package/dist/auth/plugins/entity-definitions/types.js +1 -1
  31. package/dist/auth/plugins/wrappers/admin.d.ts.map +1 -1
  32. package/dist/auth/plugins/wrappers/admin.js +2 -4
  33. package/dist/auth/plugins/wrappers/anonymous.d.ts +18 -0
  34. package/dist/auth/plugins/wrappers/anonymous.d.ts.map +1 -0
  35. package/dist/auth/plugins/wrappers/anonymous.js +26 -0
  36. package/dist/auth/plugins/wrappers/api-key.d.ts +18 -0
  37. package/dist/auth/plugins/wrappers/api-key.d.ts.map +1 -0
  38. package/dist/auth/plugins/wrappers/api-key.js +38 -0
  39. package/dist/auth/plugins/wrappers/index.d.ts +6 -0
  40. package/dist/auth/plugins/wrappers/index.d.ts.map +1 -1
  41. package/dist/auth/plugins/wrappers/index.js +7 -1
  42. package/dist/auth/plugins/wrappers/jwt.d.ts +18 -0
  43. package/dist/auth/plugins/wrappers/jwt.d.ts.map +1 -0
  44. package/dist/auth/plugins/wrappers/jwt.js +30 -0
  45. package/dist/auth/plugins/wrappers/organization.d.ts +18 -0
  46. package/dist/auth/plugins/wrappers/organization.d.ts.map +1 -0
  47. package/dist/auth/plugins/wrappers/organization.js +67 -0
  48. package/dist/auth/plugins/wrappers/passkey.d.ts +18 -0
  49. package/dist/auth/plugins/wrappers/passkey.d.ts.map +1 -0
  50. package/dist/auth/plugins/wrappers/passkey.js +32 -0
  51. package/dist/auth/plugins/wrappers/phone-number.d.ts.map +1 -1
  52. package/dist/auth/plugins/wrappers/phone-number.js +2 -4
  53. package/dist/auth/plugins/wrappers/sso.d.ts +853 -0
  54. package/dist/auth/plugins/wrappers/sso.d.ts.map +1 -0
  55. package/dist/auth/plugins/wrappers/sso.js +36 -0
  56. package/dist/auth/plugins/wrappers/two-factor.d.ts.map +1 -1
  57. package/dist/auth/plugins/wrappers/two-factor.js +2 -4
  58. package/dist/auth/plugins/wrappers/username.d.ts.map +1 -1
  59. package/dist/auth/plugins/wrappers/username.js +2 -4
  60. package/dist/bin/build-config.d.ts +2 -2
  61. package/dist/bin/build-config.js +6 -7
  62. package/dist/bin/cli.js +417 -32
  63. package/dist/bin/fixture.d.ts +27 -0
  64. package/dist/bin/fixture.d.ts.map +1 -0
  65. package/dist/bin/fixture.js +245 -0
  66. package/dist/cache/decorator.d.ts +4 -3
  67. package/dist/cache/decorator.d.ts.map +1 -1
  68. package/dist/cache/decorator.js +5 -4
  69. package/dist/cone/cone-generator.d.ts +33 -0
  70. package/dist/cone/cone-generator.d.ts.map +1 -0
  71. package/dist/cone/cone-generator.js +286 -0
  72. package/dist/database/_batch_update.d.ts.map +1 -1
  73. package/dist/database/_batch_update.js +16 -2
  74. package/dist/database/puri-subset.test-d.js +1 -1
  75. package/dist/database/puri-subset.types.d.ts +1 -1
  76. package/dist/database/puri-subset.types.d.ts.map +1 -1
  77. package/dist/database/puri-subset.types.js +1 -1
  78. package/dist/database/puri.d.ts +4 -0
  79. package/dist/database/puri.d.ts.map +1 -1
  80. package/dist/database/puri.js +20 -2
  81. package/dist/database/upsert-builder.d.ts.map +1 -1
  82. package/dist/database/upsert-builder.js +19 -3
  83. package/dist/dict/en.d.ts +15 -0
  84. package/dist/dict/en.d.ts.map +1 -1
  85. package/dist/dict/en.js +2 -1
  86. package/dist/dict/ko.d.ts +15 -0
  87. package/dist/dict/ko.d.ts.map +1 -1
  88. package/dist/dict/ko.js +2 -1
  89. package/dist/dict/rc-keys.d.ts +28 -0
  90. package/dist/dict/rc-keys.d.ts.map +1 -1
  91. package/dist/dict/rc-keys.js +31 -1
  92. package/dist/dict/sd.d.ts.map +1 -1
  93. package/dist/dict/sd.js +20 -4
  94. package/dist/entity/entity-manager.d.ts +298 -2
  95. package/dist/entity/entity-manager.d.ts.map +1 -1
  96. package/dist/entity/entity-manager.js +4 -1
  97. package/dist/entity/entity-template-cone.d.ts +14 -0
  98. package/dist/entity/entity-template-cone.d.ts.map +1 -0
  99. package/dist/entity/entity-template-cone.js +222 -0
  100. package/dist/entity/entity.d.ts +47 -2
  101. package/dist/entity/entity.d.ts.map +1 -1
  102. package/dist/entity/entity.js +161 -14
  103. package/dist/ssr/renderer.js +3 -3
  104. package/dist/syncer/api-parser.js +12 -1
  105. package/dist/syncer/checksum.d.ts +0 -14
  106. package/dist/syncer/checksum.d.ts.map +1 -1
  107. package/dist/syncer/checksum.js +1 -23
  108. package/dist/syncer/syncer-actions.d.ts.map +1 -1
  109. package/dist/syncer/syncer-actions.js +8 -2
  110. package/dist/syncer/syncer.d.ts +1 -1
  111. package/dist/syncer/syncer.d.ts.map +1 -1
  112. package/dist/syncer/syncer.js +17 -10
  113. package/dist/tasks/workflow-manager.d.ts +13 -1
  114. package/dist/tasks/workflow-manager.d.ts.map +1 -1
  115. package/dist/tasks/workflow-manager.js +18 -1
  116. package/dist/template/entity-converter.js +4 -4
  117. package/dist/template/helpers.d.ts +10 -0
  118. package/dist/template/helpers.d.ts.map +1 -1
  119. package/dist/template/helpers.js +48 -1
  120. package/dist/template/implementations/entry-server.template.d.ts +1 -1
  121. package/dist/template/implementations/entry-server.template.js +7 -2
  122. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  123. package/dist/template/implementations/generated.template.js +5 -1
  124. package/dist/template/implementations/generated_http.template.d.ts +1 -0
  125. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  126. package/dist/template/implementations/generated_http.template.js +6 -2
  127. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  128. package/dist/template/implementations/generated_sso.template.js +29 -8
  129. package/dist/template/implementations/queries.template.d.ts.map +1 -1
  130. package/dist/template/implementations/queries.template.js +9 -1
  131. package/dist/template/implementations/sd.template.d.ts +1 -1
  132. package/dist/template/implementations/sd.template.d.ts.map +1 -1
  133. package/dist/template/implementations/sd.template.js +28 -4
  134. package/dist/template/implementations/services.template.d.ts.map +1 -1
  135. package/dist/template/implementations/services.template.js +12 -12
  136. package/dist/template/implementations/view_form.template.d.ts +11 -7
  137. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  138. package/dist/template/implementations/view_form.template.js +97 -87
  139. package/dist/template/implementations/view_list.template.d.ts +3 -3
  140. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  141. package/dist/template/implementations/view_list.template.js +115 -109
  142. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
  143. package/dist/template/implementations/view_search_input.template.js +18 -14
  144. package/dist/template/zod-converter.d.ts.map +1 -1
  145. package/dist/template/zod-converter.js +95 -7
  146. package/dist/testing/_relation-graph.js +1 -1
  147. package/dist/testing/data-explorer.d.ts +61 -0
  148. package/dist/testing/data-explorer.d.ts.map +1 -0
  149. package/dist/testing/data-explorer.js +274 -0
  150. package/dist/testing/faker-mappings.d.ts +20 -0
  151. package/dist/testing/faker-mappings.d.ts.map +1 -0
  152. package/dist/testing/faker-mappings.js +421 -0
  153. package/dist/testing/fixture-generator.d.ts +161 -0
  154. package/dist/testing/fixture-generator.d.ts.map +1 -0
  155. package/dist/testing/fixture-generator.js +954 -0
  156. package/dist/testing/fixture-manager.d.ts +6 -1
  157. package/dist/testing/fixture-manager.d.ts.map +1 -1
  158. package/dist/testing/fixture-manager.js +72 -4
  159. package/dist/testing/index.d.ts +3 -0
  160. package/dist/testing/index.d.ts.map +1 -1
  161. package/dist/testing/index.js +4 -1
  162. package/dist/types/types.d.ts +1520 -26
  163. package/dist/types/types.d.ts.map +1 -1
  164. package/dist/types/types.js +136 -22
  165. package/dist/ui/ai-client.d.ts.map +1 -1
  166. package/dist/ui/ai-client.js +9 -4
  167. package/dist/ui/api.d.ts.map +1 -1
  168. package/dist/ui/api.js +303 -24
  169. package/dist/ui-web/assets/index-CsUr-_pV.js +254 -0
  170. package/dist/ui-web/assets/index-T42zzs1K.css +1 -0
  171. package/dist/ui-web/index.html +2 -2
  172. package/dist/utils/fs-utils.d.ts +2 -1
  173. package/dist/utils/fs-utils.d.ts.map +1 -1
  174. package/dist/utils/fs-utils.js +14 -3
  175. package/package.json +19 -11
  176. package/src/api/config.ts +12 -1
  177. package/src/api/sonamu.ts +179 -65
  178. package/src/auth/plugins/entity-definitions/anonymous.ts +17 -0
  179. package/src/auth/plugins/entity-definitions/api-key.ts +93 -0
  180. package/src/auth/plugins/entity-definitions/index.ts +18 -0
  181. package/src/auth/plugins/entity-definitions/jwt.ts +35 -0
  182. package/src/auth/plugins/entity-definitions/organization.ts +215 -0
  183. package/src/auth/plugins/entity-definitions/passkey.ts +64 -0
  184. package/src/auth/plugins/entity-definitions/sso.ts +62 -0
  185. package/src/auth/plugins/entity-definitions/types.ts +11 -1
  186. package/src/auth/plugins/wrappers/admin.ts +1 -3
  187. package/src/auth/plugins/wrappers/anonymous.ts +30 -0
  188. package/src/auth/plugins/wrappers/api-key.ts +42 -0
  189. package/src/auth/plugins/wrappers/index.ts +6 -0
  190. package/src/auth/plugins/wrappers/jwt.ts +34 -0
  191. package/src/auth/plugins/wrappers/organization.ts +73 -0
  192. package/src/auth/plugins/wrappers/passkey.ts +36 -0
  193. package/src/auth/plugins/wrappers/phone-number.ts +1 -3
  194. package/src/auth/plugins/wrappers/sso.ts +40 -0
  195. package/src/auth/plugins/wrappers/two-factor.ts +1 -3
  196. package/src/auth/plugins/wrappers/username.ts +1 -3
  197. package/src/bin/build-config.ts +6 -6
  198. package/src/bin/cli.ts +452 -31
  199. package/src/bin/fixture.ts +302 -0
  200. package/src/cache/decorator.ts +4 -3
  201. package/src/cone/cone-generator.ts +363 -0
  202. package/src/database/_batch_update.ts +11 -0
  203. package/src/database/puri-subset.test-d.ts +13 -13
  204. package/src/database/puri-subset.types.ts +1 -1
  205. package/src/database/puri.ts +43 -1
  206. package/src/database/upsert-builder.ts +16 -2
  207. package/src/dict/en.ts +1 -0
  208. package/src/dict/ko.ts +1 -0
  209. package/src/dict/rc-keys.ts +32 -0
  210. package/src/dict/sd.ts +23 -3
  211. package/src/entity/entity-manager.ts +4 -0
  212. package/src/entity/entity-template-cone.ts +298 -0
  213. package/src/entity/entity.ts +189 -13
  214. package/src/shared/app.shared.ts.txt +5 -0
  215. package/src/shared/web.shared.ts.txt +9 -5
  216. package/src/skills/project/README.md +21 -0
  217. package/src/skills/project/architecture.md +373 -0
  218. package/src/skills/project/business-logic.md +270 -0
  219. package/src/skills/project/requirements.md +160 -0
  220. package/src/skills/sonamu/SKILL.md +168 -3
  221. package/src/skills/sonamu/api.md +102 -0
  222. package/src/skills/sonamu/database.md +220 -1
  223. package/src/skills/sonamu/entity-relations.md +89 -1
  224. package/src/skills/sonamu/fixture-cli.md +501 -0
  225. package/src/skills/sonamu/frontend.md +214 -0
  226. package/src/skills/sonamu/i18n.md +95 -0
  227. package/src/skills/sonamu/model.md +153 -0
  228. package/src/skills/sonamu/project-init.md +178 -8
  229. package/src/skills/sonamu/scaffolding.md +112 -0
  230. package/src/skills/sonamu/subset.md +9 -3
  231. package/src/skills/sonamu/testing.md +287 -2
  232. package/src/skills/sonamu/workflow.md +70 -5
  233. package/src/ssr/renderer.ts +2 -2
  234. package/src/syncer/api-parser.ts +12 -0
  235. package/src/syncer/checksum.ts +0 -38
  236. package/src/syncer/syncer-actions.ts +7 -1
  237. package/src/syncer/syncer.ts +16 -5
  238. package/src/tasks/workflow-manager.ts +29 -8
  239. package/src/template/entity-converter.ts +3 -3
  240. package/src/template/helpers.ts +49 -0
  241. package/src/template/implementations/entry-server.template.ts +1 -1
  242. package/src/template/implementations/generated.template.ts +4 -0
  243. package/src/template/implementations/generated_http.template.ts +1 -0
  244. package/src/template/implementations/generated_sso.template.ts +40 -11
  245. package/src/template/implementations/queries.template.ts +8 -0
  246. package/src/template/implementations/sd.template.ts +22 -3
  247. package/src/template/implementations/services.template.ts +11 -10
  248. package/src/template/implementations/view_form.template.ts +111 -101
  249. package/src/template/implementations/view_list.template.ts +120 -119
  250. package/src/template/implementations/view_search_input.template.ts +17 -13
  251. package/src/template/zod-converter.ts +103 -6
  252. package/src/testing/_relation-graph.ts +1 -1
  253. package/src/testing/data-explorer.ts +427 -0
  254. package/src/testing/faker-mappings.ts +434 -0
  255. package/src/testing/fixture-generator.ts +1166 -0
  256. package/src/testing/fixture-manager.ts +91 -6
  257. package/src/testing/index.ts +3 -0
  258. package/src/types/types.ts +222 -26
  259. package/src/ui/ai-client.ts +9 -1
  260. package/src/ui/api.ts +429 -23
  261. package/src/utils/fs-utils.ts +14 -1
  262. package/dist/template/implementations/view_enums_select.template.d.ts +0 -17
  263. package/dist/template/implementations/view_enums_select.template.d.ts.map +0 -1
  264. package/dist/template/implementations/view_enums_select.template.js +0 -62
  265. package/dist/template/implementations/view_id_async_select.template.d.ts +0 -17
  266. package/dist/template/implementations/view_id_async_select.template.d.ts.map +0 -1
  267. package/dist/template/implementations/view_id_async_select.template.js +0 -125
  268. package/dist/ui-web/assets/index-Bd_2AkLb.css +0 -1
  269. package/dist/ui-web/assets/index-BpSbhQWo.js +0 -225
  270. package/src/template/implementations/view_enums_select.template.ts +0 -65
  271. package/src/template/implementations/view_id_async_select.template.ts +0 -139
@@ -0,0 +1,160 @@
1
+ # 프로젝트 요구사항 명세
2
+
3
+ > 이 문서는 프로젝트 생성 시 AI에게 제공한 요구사항을 기록합니다.
4
+ > AI는 개발 과정 내내 이 문서를 참고하여 일관된 구현을 유지합니다.
5
+
6
+ ## 프로젝트 개요
7
+
8
+ <!-- 프로젝트명, 목적, 주요 기능 개요 -->
9
+
10
+ ## 핵심 기능
11
+
12
+ <!--
13
+ 예시 (게시판):
14
+ - 사용자 인증 및 권한 관리
15
+ - 게시판 CRUD
16
+ - 파일 업로드/다운로드
17
+ - 통계 대시보드
18
+
19
+ 예시 (의료 실험자료 분석):
20
+ - 피험자 정보 관리
21
+ - 실험 데이터 수집 및 검증
22
+ - 통계 분석 및 차트 생성
23
+ - 프로토콜 버전 관리
24
+ - IRB 승인 문서 관리
25
+
26
+ 예시 (커머스):
27
+ - 상품 카탈로그 관리
28
+ - 장바구니 및 주문 처리
29
+ - 결제 연동 (PG사)
30
+ - 재고 관리
31
+ - 배송 추적
32
+
33
+ 예시 (AI Agent):
34
+ - 대화 세션 관리
35
+ - 프롬프트 템플릿 관리
36
+ - 모델 선택 및 파라미터 설정
37
+ - 대화 히스토리 저장
38
+ - 사용량 추적 및 과금
39
+
40
+ 예시 (의사 소통 도구):
41
+ - 다양한 메시지 타입 (텍스트, 이미지, 파일, 음성)
42
+ - 채널/그룹 관리
43
+ - 실시간 알림
44
+ - 읽음 상태 관리
45
+ - 검색 및 아카이브
46
+ -->
47
+
48
+ ## 사용자 역할
49
+
50
+ <!--
51
+ 예시 (게시판):
52
+ - **관리자**: 전체 시스템 관리, 사용자 관리
53
+ - **일반 사용자**: 게시글 작성, 댓글 작성
54
+ - **게스트**: 조회만 가능
55
+
56
+ 예시 (의료 실험자료):
57
+ - **연구책임자**: 프로토콜 승인, 전체 데이터 접근
58
+ - **연구원**: 데이터 입력, 분석
59
+ - **모니터**: 데이터 검증, 감사
60
+
61
+ 예시 (커머스):
62
+ - **고객**: 상품 구매, 주문 조회
63
+ - **판매자**: 상품 등록, 주문 관리
64
+ - **관리자**: 전체 시스템 관리
65
+
66
+ 예시 (AI Agent):
67
+ - **개발자**: 프롬프트 템플릿 관리
68
+ - **사용자**: 대화 세션 생성 및 사용
69
+ - **관리자**: 사용량 모니터링, 과금 관리
70
+
71
+ 예시 (의사 소통 도구):
72
+ - **의사**: 환자 케이스 공유, 자문 요청
73
+ - **전문의**: 자문 응답, 의견 제공
74
+ - **관리자**: 채널 관리, 권한 설정
75
+ -->
76
+
77
+ ## 주요 엔티티
78
+
79
+ <!--
80
+ 예시 (게시판):
81
+ - User: 사용자 정보
82
+ - Post: 게시글
83
+ - Comment: 댓글
84
+ - File: 첨부파일
85
+
86
+ 예시 (의료 실험자료):
87
+ - Subject: 피험자 정보
88
+ - Protocol: 실험 프로토콜
89
+ - DataPoint: 실험 데이터 포인트
90
+ - Analysis: 분석 결과
91
+ - Consent: 동의서
92
+
93
+ 예시 (커머스):
94
+ - Product: 상품
95
+ - Order: 주문
96
+ - OrderItem: 주문 항목
97
+ - Payment: 결제
98
+ - Inventory: 재고
99
+
100
+ 예시 (AI Agent):
101
+ - Session: 대화 세션
102
+ - Message: 메시지
103
+ - PromptTemplate: 프롬프트 템플릿
104
+ - Model: AI 모델 설정
105
+ - Usage: 사용량 기록
106
+
107
+ 예시 (의사 소통 도구):
108
+ - Channel: 채널
109
+ - Message: 메시지 (다형성: TextMessage, ImageMessage, FileMessage)
110
+ - Member: 멤버
111
+ - ReadStatus: 읽음 상태
112
+ - Notification: 알림
113
+ -->
114
+
115
+ ## 비즈니스 규칙
116
+
117
+ <!--
118
+ 예시 (게시판):
119
+ - 게시글은 작성자만 수정/삭제 가능
120
+ - 관리자는 모든 게시글 수정/삭제 가능
121
+ - 댓글은 24시간 이내에만 수정 가능
122
+ - 첨부파일은 최대 10MB까지
123
+
124
+ 예시 (의료 실험자료):
125
+ - 피험자 동의 없이는 데이터 수집 불가
126
+ - 프로토콜 변경시 IRB 재승인 필요
127
+ - 데이터 입력 후 24시간 내 검증 필수
128
+ - 개인식별정보는 암호화 저장
129
+
130
+ 예시 (커머스):
131
+ - 재고 부족시 주문 불가
132
+ - 결제 완료 전 재고 예약 (10분)
133
+ - 주문 취소는 배송 전까지만 가능
134
+ - 환불은 구매일로부터 7일 이내
135
+
136
+ 예시 (AI Agent):
137
+ - 무료 플랜: 일일 100회 제한
138
+ - 프롬프트 최대 길이: 4000 토큰
139
+ - 세션 타임아웃: 30분
140
+ - 대화 히스토리: 최근 10회까지 컨텍스트 포함
141
+
142
+ 예시 (의사 소통 도구):
143
+ - 메시지 수정은 10분 이내만 가능
144
+ - 파일 첨부 최대 50MB
145
+ - 채널 멤버만 메시지 조회 가능
146
+ - 의료 정보 포함 메시지는 자동 암호화
147
+ -->
148
+
149
+ ## 기술 스택
150
+
151
+ <!--
152
+ 예시:
153
+ - Backend: Sonamu + PostgreSQL
154
+ - Frontend: React + TanStack Router
155
+ - Auth: better-auth
156
+ -->
157
+
158
+ ## 추가 요구사항
159
+
160
+ <!-- 기타 특별한 요구사항이나 제약사항 -->
@@ -85,6 +85,166 @@ pnpm test:watch
85
85
 
86
86
  ---
87
87
 
88
+ ## 프로젝트 문서 체계
89
+
90
+ ### CRITICAL: 작업 시작 전 필수 확인
91
+
92
+ **프로젝트 작업을 시작하기 전에 반드시 `skills/project/` 하위의 모든 문서를 읽으세요.**
93
+
94
+ ```
95
+ skills/project/
96
+ ├── requirements.md # 요구사항 정의
97
+ ├── architecture.md # 엔티티 설계 + 시스템 아키텍처
98
+ └── business-logic.md # 사용자 권한별 비즈니스 로직
99
+ ```
100
+
101
+ ### 문서 작성 시점
102
+
103
+ #### 1. requirements.md
104
+ **언제:** 사용자로부터 요구사항을 받았을 때
105
+ **내용:**
106
+ - 프로젝트 목표 및 배경
107
+ - 기능 요구사항 (FR)
108
+ - 비기능 요구사항 (NFR)
109
+ - 제약사항 및 전제조건
110
+
111
+ **예시:**
112
+ ```markdown
113
+ # 요구사항 정의
114
+
115
+ ## 프로젝트 목표
116
+ 온라인 병원 예약 시스템
117
+
118
+ ## 기능 요구사항
119
+ 1. 환자가 의사를 검색하고 예약할 수 있어야 함
120
+ 2. 의사가 진료 일정을 관리할 수 있어야 함
121
+ ...
122
+
123
+ ## 사용자 유형
124
+ - 관리자: 시스템 전체 관리
125
+ - 의사: 진료 일정, 환자 기록 관리
126
+ - 환자: 예약, 진료 내역 조회
127
+ - 병원: 의사 관리, 통계 확인
128
+ ```
129
+
130
+ #### 2. architecture.md
131
+ **언제:** 엔티티를 설계하거나 시스템 아키텍처를 논의할 때
132
+ **내용:**
133
+ - Entity 구조 및 관계 설계
134
+ - 데이터베이스 스키마
135
+ - API 엔드포인트 설계
136
+ - 시스템 컴포넌트 구조
137
+
138
+ **예시:**
139
+ ```markdown
140
+ # 시스템 아키텍처
141
+
142
+ ## 엔티티 설계
143
+
144
+ ### User (사용자)
145
+ - id: number (PK)
146
+ - username: string
147
+ - email: string
148
+ - role: enum (admin, doctor, patient, hospital)
149
+
150
+ ### Doctor (의사)
151
+ - id: number (PK)
152
+ - user_id: number (FK → User)
153
+ - specialty: string
154
+ - hospital_id: number (FK → Hospital)
155
+
156
+ ### Appointment (예약)
157
+ - id: number (PK)
158
+ - patient_id: number (FK → User)
159
+ - doctor_id: number (FK → Doctor)
160
+ - appointment_date: datetime
161
+ - status: enum (pending, confirmed, cancelled)
162
+
163
+ ## 관계
164
+ - User ← Doctor (BelongsToOne)
165
+ - User ← Appointment.patient (BelongsToOne)
166
+ - Doctor ← Appointment.doctor (BelongsToOne)
167
+ ```
168
+
169
+ #### 3. business-logic.md
170
+ **언제:** 사용자 권한별 비즈니스 로직을 정의할 때
171
+ **내용:**
172
+ - 각 사용자 유형(role)별 권한
173
+ - 비즈니스 규칙 및 제약사항
174
+ - 상태 전이 규칙
175
+ - 검증 로직
176
+
177
+ **예시:**
178
+ ```markdown
179
+ # 비즈니스 로직
180
+
181
+ ## 사용자 권한
182
+
183
+ ### 관리자 (admin)
184
+ - 모든 데이터 CRUD 가능
185
+ - 사용자 role 변경 가능
186
+ - 시스템 설정 관리
187
+
188
+ ### 의사 (doctor)
189
+ - 자신의 일정 관리 (CRUD)
190
+ - 예약 확인/취소
191
+ - 환자 진료 기록 조회/작성
192
+ - 다른 의사 데이터 조회 불가
193
+
194
+ ### 환자 (patient)
195
+ - 의사 검색 및 조회
196
+ - 예약 생성/조회/취소 (자신의 예약만)
197
+ - 자신의 진료 기록 조회
198
+ - 다른 환자 데이터 접근 불가
199
+
200
+ ### 병원 (hospital)
201
+ - 소속 의사 관리
202
+ - 병원 통계 조회
203
+ - 소속 의사의 예약 현황 조회
204
+
205
+ ## 예약 상태 전이
206
+ pending → confirmed (의사 확인)
207
+ pending → cancelled (환자/의사 취소)
208
+ confirmed → cancelled (환자/의사 취소, 24시간 전까지만)
209
+
210
+ ## 비즈니스 규칙
211
+ 1. 예약은 진료 24시간 전까지만 취소 가능
212
+ 2. 의사는 동시에 2개 이상 예약 불가
213
+ 3. 환자는 같은 의사에게 1주일에 1번만 예약 가능
214
+ ```
215
+
216
+ ### 문서 업데이트 규칙
217
+
218
+ **CRITICAL: 설계 변경 시 즉시 문서 업데이트**
219
+
220
+ 1. **대화 중 설계가 변경되면:**
221
+ - 해당 문서를 즉시 업데이트
222
+ - 변경 이유와 컨텍스트를 기록
223
+
224
+ 2. **변경 기록 형식:**
225
+ ```markdown
226
+ ## 변경 이력
227
+
228
+ ### 2026-02-10: Appointment 상태 필드 추가
229
+ **변경 내용:** status 필드 추가 (pending, confirmed, cancelled)
230
+ **이유:** 예약 취소 기능 추가 요청
231
+ **영향:** Appointment 엔티티, API 응답 구조 변경
232
+ ```
233
+
234
+ 3. **문서 일관성 유지:**
235
+ - Entity 변경 → architecture.md 업데이트
236
+ - 권한 규칙 변경 → business-logic.md 업데이트
237
+ - 요구사항 추가/변경 → requirements.md 업데이트
238
+
239
+ ### Compacting 후에도 안전
240
+
241
+ **문서가 파일로 영속화되어 있어서:**
242
+ - 대화가 압축(compacting)되어도 프로젝트 맥락 유지
243
+ - 언제든 문서를 다시 읽어 일관성 있게 작업 가능
244
+ - 설계 결정의 히스토리 추적 가능
245
+
246
+ ---
247
+
88
248
  ## Skills 목록
89
249
 
90
250
  | Skill | 파일 | 용도 |
@@ -93,17 +253,18 @@ pnpm test:watch
93
253
  | 프로젝트 생성 | `create-sonamu.md` | create-sonamu CLI 옵션 |
94
254
  | 프로젝트 초기화 | `project-init.md` | 프로젝트 생성 여부 확인, 대화 흐름 |
95
255
  | 프로젝트 설정 | `config.md` | .env, sonamu.config.ts 설정 |
96
- | 데이터베이스 | `database.md` | DB 설정, 포트 충돌 해결 |
256
+ | 데이터베이스 | `database.md` | DB 설정, 포트 충돌 해결, 3-Tier 구조 |
97
257
  | Entity 검증 | `entity-validation-checklist.md` | Entity 생성 단계별 체크리스트 |
98
258
  | Entity 기본 | `entity-basic.md` | Entity JSON 구조, 필드 타입 |
99
- | Entity 관계 | `entity-relations.md` | BelongsToOne, HasMany, ManyToMany |
259
+ | Entity 관계 | `entity-relations.md` | BelongsToOne, HasMany, ManyToMany, FK 코드 패턴 |
100
260
  | Subset | `subset.md` | 조회 필드 범위 정의 |
101
261
  | Model | `model.md` | BaseModelClass, CRUD 패턴 |
102
262
  | API | `api.md` | @api 데코레이터 |
103
263
  | Puri | `puri.md` | SQL 쿼리 빌더 |
104
264
  | i18n | `i18n.md` | 다국어 지원, SD 함수 |
105
265
  | Upsert | `upsert.md` | 관계 데이터 저장 |
106
- | Testing | `testing.md` | Vitest 테스트 (test/testAs) |
266
+ | Testing | `testing.md` | Vitest 테스트 (test/testAs), Fixture 생성 팁 |
267
+ | **Fixture CLI** | `fixture-cli.md` | **fixture gen/fetch/explore 명령어, 3-Tier DB 활용** |
107
268
  | Migration | `migration.md` | DB 스키마 마이그레이션, PK 타입 변경 |
108
269
  | Auth Migration | `auth-migration.md` | better-auth 등 외부 인증 통합 시 User.id 타입 변경 |
109
270
  | Frontend | `frontend.md` | Service, TanStack Query |
@@ -120,13 +281,17 @@ pnpm test:watch
120
281
  | 프로젝트 설정 | config |
121
282
  | Sonamu 로컬 개발 설정 | config |
122
283
  | DB 설정/포트 충돌 | database, config |
284
+ | **3-Tier DB 구조 이해** | **database, fixture-cli** |
123
285
  | Entity/속성 정의 | entity-basic |
124
286
  | 관계 설정 | entity-relations |
287
+ | **BelongsToOne FK 코드 사용** | **entity-relations** |
125
288
  | API 응답 필드 구성 | subset |
126
289
  | 데이터 조회/저장 로직 | model, puri |
127
290
  | API 엔드포인트 | api |
128
291
  | 관계 데이터 배치 저장 | upsert |
129
292
  | 테스트 작성 | testing |
293
+ | **Fixture 데이터 생성/관리** | **fixture-cli** |
294
+ | **테스트 데이터 생성 팁** | **testing (Fixture 데이터 생성 팁), fixture-cli (실전 팁)** |
130
295
  | DB 스키마 변경 | migration |
131
296
  | PK 타입 변경 (better-auth 등) | auth-migration |
132
297
  | 프론트엔드 개발 | frontend |
@@ -262,3 +262,105 @@ describe("E. Business Logic", () => {
262
262
  });
263
263
  });
264
264
  ```
265
+
266
+ ---
267
+
268
+ ## 컨벤션과 베스트 프랙티스
269
+
270
+ ### 에러 메시지 패턴
271
+
272
+ 일관된 에러 메시지를 위해 `this.modelName`과 `SD()` 함수를 사용합니다.
273
+
274
+ **BAD: 하드코딩된 모델명**
275
+ ```typescript
276
+ // findById
277
+ if (!rows[0]) {
278
+ throw new NotFoundException(SD("error.entityNotFound")("Department", id));
279
+ }
280
+
281
+ // findMany
282
+ throw new BadRequestException(SD("error.unknownSearchField")(params.search));
283
+ ```
284
+
285
+ **GOOD: this.modelName 사용**
286
+ ```typescript
287
+ // findById - 모델명 자동 인식
288
+ if (!rows[0]) {
289
+ throw new NotFoundException(SD("notFound")(this.modelName, id));
290
+ }
291
+
292
+ // findMany - 짧고 명확한 키
293
+ throw new BadRequestException(SD("search.invalidField")(params.search));
294
+ ```
295
+
296
+ **장점:**
297
+ - DRY 원칙 준수: 모델명 한 곳에서 관리
298
+ - 리팩토링 안전: 모델명 변경 시 에러 메시지 자동 반영
299
+ - 짧은 i18n 키: `notFound`, `search.invalidField`가 더 간결
300
+
301
+ ### satisfies 키워드
302
+
303
+ TypeScript의 satisfies 키워드로 타입 추론을 유지하면서 타입 체크합니다.
304
+
305
+ **BAD: 타입 추론 상실**
306
+ ```typescript
307
+ const params: RoleListParams = {
308
+ num: 24,
309
+ page: 1,
310
+ search: "id" as const,
311
+ orderBy: "id-desc" as const,
312
+ ...rawParams,
313
+ };
314
+ ```
315
+
316
+ **GOOD: satisfies로 타입 체크 + 추론 유지**
317
+ ```typescript
318
+ const params = {
319
+ num: 24,
320
+ page: 1,
321
+ search: "id" as const,
322
+ orderBy: "id-desc" as const,
323
+ ...rawParams,
324
+ } satisfies RoleListParams;
325
+ ```
326
+
327
+ **장점:**
328
+ - 컴파일 타임 검증: params가 RoleListParams 타입을 만족하는지 확인
329
+ - 타입 추론 유지: params의 실제 타입이 좁혀진 상태로 유지됨
330
+ - IDE 지원 향상: 자동완성과 타입 체크가 더 정확
331
+
332
+ ### debug 옵션
333
+
334
+ executeSubsetQuery의 debug 옵션은 기본값이 false이므로 명시할 필요 없습니다.
335
+
336
+ **BAD: 불필요한 debug: false**
337
+ ```typescript
338
+ return this.executeSubsetQuery({
339
+ subset,
340
+ qb,
341
+ params,
342
+ enhancers,
343
+ debug: false, // 기본값이므로 불필요
344
+ });
345
+ ```
346
+
347
+ **GOOD: 기본값 활용**
348
+ ```typescript
349
+ return this.executeSubsetQuery({
350
+ subset,
351
+ qb,
352
+ params,
353
+ enhancers,
354
+ });
355
+ ```
356
+
357
+ **debug: true를 사용하는 경우:**
358
+ ```typescript
359
+ // 디버깅 시에만 명시
360
+ return this.executeSubsetQuery({
361
+ subset,
362
+ qb,
363
+ params,
364
+ debug: true, // SQL 쿼리 로그 출력
365
+ });
366
+ ```
@@ -12,11 +12,230 @@ cd packages/api
12
12
  pnpm docker:up
13
13
  ```
14
14
 
15
+ ## 3-Tier DB 구조
16
+
17
+ Sonamu는 3단계 데이터베이스 구조를 사용합니다. 각 DB의 역할과 데이터 흐름을 이해하는 것이 중요합니다.
18
+
19
+ ```
20
+ production/development master (실제 DB)
21
+ ↓ (fixture fetch)
22
+ project_fixture (fixture DB)
23
+ ↓ (fixture sync)
24
+ project_test (test DB)
25
+ ```
26
+
27
+ ### DB별 역할
28
+
29
+ | DB | 용도 | 데이터 출처 | 명령어 |
30
+ |----|------|-----------|--------|
31
+ | `project` | 운영/개발 실제 DB | 실제 사용자 데이터 | 직접 생성 |
32
+ | `project_fixture` | 테스트용 참조 데이터 저장소 | production에서 fetch 또는 gen으로 생성 | `pnpm sonamu fixture gen/fetch` |
33
+ | `project_test` | 테스트 실행 환경 | fixture에서 sync | `pnpm sonamu fixture sync` |
34
+
35
+ ### 데이터 흐름
36
+
37
+ **1. fixture fetch (실제 데이터 가져오기)**
38
+ ```bash
39
+ pnpm sonamu fixture fetch --include User --limit 10
40
+ ```
41
+ - production/development master → fixture DB
42
+ - 실제 운영 데이터를 테스트용으로 복사
43
+ - 관련 데이터(FK)도 함께 가져옴
44
+
45
+ **2. fixture gen (더미 데이터 생성)**
46
+ ```bash
47
+ pnpm sonamu fixture gen --include Department --count 5
48
+ ```
49
+ - fixture DB 내부에서 faker 기반 생성
50
+ - 참조 관계(FK) 자동 해결
51
+ - 한국어 데이터 생성 지원
52
+
53
+ **3. fixture sync (테스트 DB 동기화)**
54
+ ```bash
55
+ pnpm sonamu fixture sync
56
+ ```
57
+ - fixture DB → test DB
58
+ - 테스트 실행 전 최신 상태로 동기화
59
+ - 각 테스트는 트랜잭션으로 격리되어 자동 롤백
60
+
61
+ ### 주의사항
62
+
63
+ **CRITICAL: sourceDb vs targetDb 혼동 방지**
64
+
65
+ - `fixture gen`: sourceDb=fixture, targetDb=fixture (fixture 내부에서 생성)
66
+ - `fixture fetch`: sourceDb=production, targetDb=fixture (production → fixture)
67
+ - 잘못 설정하면 FK 참조 오류 발생
68
+
69
+ **예시 (올바른 설정)**:
70
+ ```typescript
71
+ // fixture gen: fixture DB 내에서 참조 및 저장
72
+ const fixtureDb = createKnexInstance(Sonamu.dbConfig.fixture);
73
+ const generator = new FixtureGenerator(fixtureDb, fixtureDb, "fixture", EntityManager);
74
+
75
+ // fixture fetch: production → fixture DB
76
+ const sourceDb = DB.getDB("r"); // production_master
77
+ const fixtureDb = createKnexInstance(Sonamu.dbConfig.fixture);
78
+ const generator = new FixtureGenerator(sourceDb, fixtureDb, "fixture", EntityManager);
79
+ ```
80
+
81
+ **참고**: Fixture CLI 명령어 상세 사용법은 `fixture-cli.md` 참조
82
+
83
+ ---
84
+
15
85
  ## Seed Data 관리
16
86
 
17
87
  테스트를 위한 기본 데이터(seed data)는 dump 파일에 추가하여 관리한다.
18
88
 
19
- ### 워크플로우
89
+ ### 전체 워크플로우 개요
90
+
91
+ Seed data 관리는 2단계로 진행된다:
92
+
93
+ | 단계 | 목적 | 대상 DB |
94
+ |------|------|---------|
95
+ | **Phase 1** | 개발/테스트용 seed 준비 | `project_test`, `project_fixture` |
96
+ | **Phase 2** | 실제 DB에 seed 적용 | `project` (실제 DB) |
97
+
98
+ ---
99
+
100
+ ### Phase 1: 개발/테스트용 Seed 준비
101
+
102
+ 개발 중 테스트를 위한 더미 데이터를 준비하는 단계.
103
+
104
+ #### 1-1. 초기 dump 생성 (테이블 구조만)
105
+
106
+ ```bash
107
+ pnpm dump
108
+ ```
109
+
110
+ 이 시점에서 생성된 `database/scripts/dump.sql`은:
111
+ - CREATE TABLE 구문
112
+ - CREATE SEQUENCE 구문
113
+ - ALTER TABLE ... PRIMARY KEY
114
+ - ALTER TABLE ... FOREIGN KEY
115
+ - **INSERT문은 없음** (아직 데이터가 없으므로)
116
+
117
+ #### 1-2. dump 파일에 INSERT문 추가
118
+
119
+ `database/scripts/dump.sql` 파일을 열고, **FK CONSTRAINT 전**에 INSERT문을 추가한다.
120
+
121
+ **중요: FK 의존성 순서를 고려하여 작성**
122
+ ```sql
123
+ -- 독립 테이블부터
124
+ INSERT INTO public.institutions (id, created_at, name, code) VALUES
125
+ (1, '2024-01-01 00:00:00+09', '본원', 'HQ');
126
+
127
+ -- 참조 테이블 (institutions를 참조)
128
+ INSERT INTO public.departments (id, created_at, name, code, institution_id) VALUES
129
+ (1, '2024-01-01 00:00:00+09', '연구부', 'RND', 1);
130
+
131
+ -- 시퀀스 값 설정 (INSERT 후)
132
+ SELECT pg_catalog.setval('public.institutions_id_seq', 1, true);
133
+ SELECT pg_catalog.setval('public.departments_id_seq', 1, true);
134
+ ```
135
+
136
+ #### 1-3. test DB에 적용
137
+
138
+ ```bash
139
+ pnpm seed
140
+ ```
141
+
142
+ `database/scripts/seed.sh`가 실행되며:
143
+ - `SOURCE_DB="${DATABASE_NAME}_test"` → dump.sql을 test DB에 적용
144
+
145
+ #### 1-4. fixture DB에 동기화
146
+
147
+ ```bash
148
+ pnpm sonamu fixture sync
149
+ ```
150
+
151
+ test DB의 데이터를 fixture DB로 복사.
152
+
153
+ ---
154
+
155
+ ### Phase 2: 실제 DB에 Seed 적용
156
+
157
+ **⚠️ CRITICAL WARNING:**
158
+ - 이 단계는 실제 DB(`project`)에 데이터를 넣는다
159
+ - 기존 데이터가 있다면 덮어쓰여질 수 있다
160
+ - **반드시 사용자에게 확인 후 진행해야 한다**
161
+
162
+ **Claude Code 규칙:**
163
+ ```
164
+ 실제 DB에 seed를 적용하기 전에:
165
+ 1. 사용자에게 "실제 데이터베이스(project)에 seed 데이터를 적용하시겠습니까?" 질문
166
+ 2. 사용자가 명시적으로 승인할 때만 진행
167
+ 3. 승인 없이 절대 실행하지 말것
168
+ ```
169
+
170
+ #### 2-1. 현재 상태 확인
171
+
172
+ ```bash
173
+ # test/fixture DB에 데이터가 들어가 있어야 함
174
+ PGPASSWORD=1234 psql -h 0.0.0.0 -U postgres -d project_test -c "SELECT COUNT(*) FROM users;"
175
+ ```
176
+
177
+ #### 2-2. 최종 dump 생성
178
+
179
+ ```bash
180
+ # test/fixture의 데이터가 포함된 dump 생성
181
+ pnpm dump
182
+ ```
183
+
184
+ 이번 dump에는 **INSERT문이 포함**되어 있다 (1-2에서 추가한 데이터).
185
+
186
+ #### 2-3. seed.sh 파일 수정
187
+
188
+ `database/scripts/seed.sh`를 열고 FIXTURE_DB 변경:
189
+
190
+ ```bash
191
+ # 변경 전 (개발/테스트 단계)
192
+ FIXTURE_DB="${DATABASE_NAME}_fixture"
193
+
194
+ # 변경 후 (실제 DB에 seed)
195
+ FIXTURE_DB="${DATABASE_NAME}"
196
+ ```
197
+
198
+ #### 2-4. 실제 DB에 seed 실행
199
+
200
+ **⚠️ 사용자 승인 후에만 실행:**
201
+
202
+ ```bash
203
+ pnpm seed
204
+ ```
205
+
206
+ 이제 실제 DB(`project`)에 seed 데이터가 적용된다.
207
+
208
+ #### 2-5. 확인
209
+
210
+ ```bash
211
+ # 실제 DB에서 데이터 확인
212
+ PGPASSWORD=1234 psql -h 0.0.0.0 -U postgres -d project -c "SELECT * FROM departments LIMIT 5;"
213
+ ```
214
+
215
+ #### 2-6. seed.sh 원복 (중요!)
216
+
217
+ 실제 DB seed 완료 후, seed.sh를 원래대로 되돌려야 다음 개발 시 test DB를 사용한다:
218
+
219
+ ```bash
220
+ # database/scripts/seed.sh
221
+ FIXTURE_DB="${DATABASE_NAME}_fixture" # 원복
222
+ ```
223
+
224
+ ---
225
+
226
+ ### 요약: Phase 1 vs Phase 2
227
+
228
+ | 항목 | Phase 1 (개발/테스트) | Phase 2 (실제 DB) |
229
+ |------|---------------------|------------------|
230
+ | **시점** | 개발 중 테스트 데이터 준비 | 개발 완료 후 실제 데이터 준비 |
231
+ | **dump 횟수** | 1회 (테이블 구조) | 2회 (데이터 포함) |
232
+ | **대상 DB** | `project_test` → `project_fixture` | `project` |
233
+ | **seed.sh** | `FIXTURE_DB="${DATABASE_NAME}_fixture"` | `FIXTURE_DB="${DATABASE_NAME}"` |
234
+ | **사용자 승인** | 불필요 | **반드시 필요** |
235
+
236
+ ---
237
+
238
+ ### 구 워크플로우 (Phase 1 간단 버전)
20
239
 
21
240
  ```bash
22
241
  # 1. test DB에 기본 데이터 직접 추가 (psql 또는 Sonamu UI 사용)