@kood/claude-code 0.6.6 → 0.7.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 (170) hide show
  1. package/dist/index.js +7 -1
  2. package/package.json +1 -1
  3. package/templates/.claude/agents/analyst.md +5 -0
  4. package/templates/.claude/agents/architect.md +5 -0
  5. package/templates/.claude/agents/build-fixer.md +1 -0
  6. package/templates/.claude/agents/code-reviewer.md +1 -0
  7. package/templates/.claude/agents/critic.md +4 -0
  8. package/templates/.claude/agents/deep-executor.md +1 -0
  9. package/templates/.claude/agents/dependency-manager.md +2 -0
  10. package/templates/.claude/agents/deployment-validator.md +2 -0
  11. package/templates/.claude/agents/designer.md +2 -0
  12. package/templates/.claude/agents/document-writer.md +3 -0
  13. package/templates/.claude/agents/explore.md +1 -0
  14. package/templates/.claude/agents/git-operator.md +2 -0
  15. package/templates/.claude/agents/implementation-executor.md +2 -0
  16. package/templates/.claude/agents/ko-to-en-translator.md +3 -0
  17. package/templates/.claude/agents/lint-fixer.md +2 -0
  18. package/templates/.claude/agents/planner.md +3 -0
  19. package/templates/.claude/agents/pm.md +349 -0
  20. package/templates/.claude/agents/qa-tester.md +1 -0
  21. package/templates/.claude/agents/refactor-advisor.md +4 -0
  22. package/templates/.claude/agents/researcher.md +9 -1
  23. package/templates/.claude/agents/scientist.md +1 -0
  24. package/templates/.claude/agents/security-reviewer.md +1 -0
  25. package/templates/.claude/agents/tdd-guide.md +1 -0
  26. package/templates/.claude/agents/vision.md +1 -0
  27. package/templates/.claude/instructions/agent-patterns/agent-teams-usage.md +376 -0
  28. package/templates/.claude/instructions/sourcing/reliable-search.md +49 -2
  29. package/templates/.claude/scripts/agent-teams/check-availability.sh +238 -0
  30. package/templates/.claude/scripts/agent-teams/setup-tmux.sh +125 -0
  31. package/templates/.claude/skills/agent-teams-setup/SKILL.md +460 -0
  32. package/templates/.claude/skills/brainstorm/SKILL.md +1 -0
  33. package/templates/.claude/skills/bug-fix/SKILL.md +1 -0
  34. package/templates/.claude/skills/crawler/SKILL.md +2 -0
  35. package/templates/.claude/skills/docs-creator/SKILL.md +1 -0
  36. package/templates/.claude/skills/docs-fetch/SKILL.md +6 -4
  37. package/templates/.claude/skills/docs-refactor/SKILL.md +1 -0
  38. package/templates/.claude/skills/elon-musk/SKILL.md +1 -0
  39. package/templates/.claude/skills/execute/SKILL.md +1 -0
  40. package/templates/.claude/skills/feedback/SKILL.md +1 -0
  41. package/templates/.claude/skills/figma-to-code/SKILL.md +1 -0
  42. package/templates/.claude/skills/genius-thinking/SKILL.md +1 -0
  43. package/templates/.claude/skills/global-uiux-design/SKILL.md +1 -0
  44. package/templates/.claude/skills/korea-uiux-design/SKILL.md +1 -0
  45. package/templates/.claude/skills/nextjs-react-best-practices/SKILL.md +1 -0
  46. package/templates/.claude/skills/plan/SKILL.md +1 -0
  47. package/templates/.claude/skills/prd/SKILL.md +1 -0
  48. package/templates/.claude/skills/project-optimizer/AGENTS.md +275 -0
  49. package/templates/.claude/skills/project-optimizer/SKILL.md +375 -0
  50. package/templates/.claude/skills/project-optimizer/rules/arch-config-centralize.md +66 -0
  51. package/templates/.claude/skills/project-optimizer/rules/arch-hot-path.md +35 -0
  52. package/templates/.claude/skills/project-optimizer/rules/arch-interface-segregation.md +51 -0
  53. package/templates/.claude/skills/project-optimizer/rules/arch-module-boundary.md +42 -0
  54. package/templates/.claude/skills/project-optimizer/rules/build-cache.md +57 -0
  55. package/templates/.claude/skills/project-optimizer/rules/build-code-split.md +56 -0
  56. package/templates/.claude/skills/project-optimizer/rules/build-incremental.md +65 -0
  57. package/templates/.claude/skills/project-optimizer/rules/build-minify.md +61 -0
  58. package/templates/.claude/skills/project-optimizer/rules/build-tree-shake.md +60 -0
  59. package/templates/.claude/skills/project-optimizer/rules/code-complexity.md +65 -0
  60. package/templates/.claude/skills/project-optimizer/rules/code-dead-elimination.md +32 -0
  61. package/templates/.claude/skills/project-optimizer/rules/code-duplication.md +54 -0
  62. package/templates/.claude/skills/project-optimizer/rules/code-error-handling.md +75 -0
  63. package/templates/.claude/skills/project-optimizer/rules/code-naming.md +52 -0
  64. package/templates/.claude/skills/project-optimizer/rules/concurrency-defer-await.md +54 -0
  65. package/templates/.claude/skills/project-optimizer/rules/concurrency-parallel.md +90 -0
  66. package/templates/.claude/skills/project-optimizer/rules/concurrency-pipeline.md +68 -0
  67. package/templates/.claude/skills/project-optimizer/rules/concurrency-pool.md +68 -0
  68. package/templates/.claude/skills/project-optimizer/rules/deps-lightweight-alt.md +37 -0
  69. package/templates/.claude/skills/project-optimizer/rules/deps-peer-align.md +44 -0
  70. package/templates/.claude/skills/project-optimizer/rules/deps-security-audit.md +45 -0
  71. package/templates/.claude/skills/project-optimizer/rules/deps-unused-removal.md +25 -0
  72. package/templates/.claude/skills/project-optimizer/rules/deps-version-pin.md +40 -0
  73. package/templates/.claude/skills/project-optimizer/rules/dx-ci-speed.md +47 -0
  74. package/templates/.claude/skills/project-optimizer/rules/dx-dev-server.md +35 -0
  75. package/templates/.claude/skills/project-optimizer/rules/dx-lint-config.md +36 -0
  76. package/templates/.claude/skills/project-optimizer/rules/dx-test-coverage.md +34 -0
  77. package/templates/.claude/skills/project-optimizer/rules/dx-type-safety.md +49 -0
  78. package/templates/.claude/skills/project-optimizer/rules/io-batch-queries.md +67 -0
  79. package/templates/.claude/skills/project-optimizer/rules/io-cache-layer.md +67 -0
  80. package/templates/.claude/skills/project-optimizer/rules/io-connection-reuse.md +67 -0
  81. package/templates/.claude/skills/project-optimizer/rules/io-serialize-minimal.md +61 -0
  82. package/templates/.claude/skills/project-optimizer/rules/io-stream.md +75 -0
  83. package/templates/.claude/skills/project-optimizer/rules/memory-bounded-cache.md +65 -0
  84. package/templates/.claude/skills/project-optimizer/rules/memory-large-data.md +64 -0
  85. package/templates/.claude/skills/project-optimizer/rules/memory-lazy-init.md +78 -0
  86. package/templates/.claude/skills/project-optimizer/rules/memory-leak-prevention.md +79 -0
  87. package/templates/.claude/skills/project-optimizer/rules/memory-pool-reuse.md +70 -0
  88. package/templates/.claude/skills/ralph/SKILL.md +1 -0
  89. package/templates/.claude/skills/refactor/SKILL.md +1 -0
  90. package/templates/.claude/skills/research/SKILL.md +1 -0
  91. package/templates/.claude/skills/sql-optimizer/SKILL.md +438 -0
  92. package/templates/.claude/skills/sql-optimizer/orm-patterns.md +218 -0
  93. package/templates/.claude/skills/startup-validator/SKILL.md +1 -0
  94. package/templates/.claude/skills/tanstack-start-react-best-practices/AGENTS.md +53 -14
  95. package/templates/.claude/skills/tanstack-start-react-best-practices/SKILL.md +94 -27
  96. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-defer-third-party.md +42 -19
  97. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-optimistic-updates.md +109 -0
  98. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-suspense-query.md +74 -0
  99. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-use-hook.md +81 -0
  100. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-react-compiler.md +81 -0
  101. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-beforeload-auth.md +121 -0
  102. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-file-conventions.md +104 -0
  103. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-link-navigation.md +119 -0
  104. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-nested-layouts.md +155 -0
  105. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-path-params.md +89 -0
  106. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-pending-component.md +110 -0
  107. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-preload-strategy.md +91 -0
  108. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-router-context.md +120 -0
  109. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-search-params.md +114 -0
  110. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-deferred-data.md +1 -1
  111. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-error-boundaries.md +79 -0
  112. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-middleware.md +85 -0
  113. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-serialization.md +56 -21
  114. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-streaming.md +84 -0
  115. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-validator.md +71 -0
  116. package/templates/.claude/skills/tauri-react-best-practices/AGENTS.md +527 -0
  117. package/templates/.claude/skills/tauri-react-best-practices/SKILL.md +571 -0
  118. package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-barrel-imports.md +140 -0
  119. package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-cargo-profile.md +96 -0
  120. package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-frontend-treeshake.md +242 -0
  121. package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-lazy-components.md +255 -0
  122. package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-remove-unused-commands.md +160 -0
  123. package/templates/.claude/skills/tauri-react-best-practices/rules/deploy-ci-pipeline.md +269 -0
  124. package/templates/.claude/skills/tauri-react-best-practices/rules/deploy-signing.md +207 -0
  125. package/templates/.claude/skills/tauri-react-best-practices/rules/deploy-updater.md +226 -0
  126. package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-async-commands.md +172 -0
  127. package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-batch-commands.md +133 -0
  128. package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-binary-response.md +198 -0
  129. package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-channel-streaming.md +186 -0
  130. package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-error-handling.md +250 -0
  131. package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-type-safe.md +227 -0
  132. package/templates/.claude/skills/tauri-react-best-practices/rules/perf-derived-state.md +231 -0
  133. package/templates/.claude/skills/tauri-react-best-practices/rules/perf-functional-setstate.md +191 -0
  134. package/templates/.claude/skills/tauri-react-best-practices/rules/perf-index-maps.md +276 -0
  135. package/templates/.claude/skills/tauri-react-best-practices/rules/perf-lazy-state-init.md +196 -0
  136. package/templates/.claude/skills/tauri-react-best-practices/rules/plugin-lifecycle.md +265 -0
  137. package/templates/.claude/skills/tauri-react-best-practices/rules/plugin-mobile-compat.md +199 -0
  138. package/templates/.claude/skills/tauri-react-best-practices/rules/plugin-permission-scope.md +193 -0
  139. package/templates/.claude/skills/tauri-react-best-practices/rules/react-error-boundary.md +239 -0
  140. package/templates/.claude/skills/tauri-react-best-practices/rules/react-event-listener.md +151 -0
  141. package/templates/.claude/skills/tauri-react-best-practices/rules/react-file-src.md +155 -0
  142. package/templates/.claude/skills/tauri-react-best-practices/rules/react-invoke-hook.md +139 -0
  143. package/templates/.claude/skills/tauri-react-best-practices/rules/react-optimistic-update.md +211 -0
  144. package/templates/.claude/skills/tauri-react-best-practices/rules/security-capability-split.md +205 -0
  145. package/templates/.claude/skills/tauri-react-best-practices/rules/security-csp.md +207 -0
  146. package/templates/.claude/skills/tauri-react-best-practices/rules/security-least-privilege.md +106 -0
  147. package/templates/.claude/skills/tauri-react-best-practices/rules/security-no-wildcard.md +253 -0
  148. package/templates/.claude/skills/tauri-react-best-practices/rules/security-scope-paths.md +160 -0
  149. package/templates/.claude/skills/tauri-react-best-practices/rules/state-async-mutex.md +270 -0
  150. package/templates/.claude/skills/tauri-react-best-practices/rules/state-mutex-pattern.md +265 -0
  151. package/templates/.claude/skills/tauri-react-best-practices/rules/state-react-sync.md +375 -0
  152. package/templates/.claude/skills/tauri-react-best-practices/rules/state-single-container.md +275 -0
  153. package/templates/tanstack-start/docs/architecture.md +238 -167
  154. package/templates/tanstack-start/docs/library/tanstack-router/error-handling.md +777 -38
  155. package/templates/tanstack-start/docs/library/tanstack-router/hooks.md +549 -37
  156. package/templates/tanstack-start/docs/library/tanstack-router/index.md +895 -111
  157. package/templates/tanstack-start/docs/library/tanstack-router/navigation.md +641 -43
  158. package/templates/tanstack-start/docs/library/tanstack-router/route-context.md +889 -38
  159. package/templates/tanstack-start/docs/library/tanstack-router/search-params.md +891 -29
  160. package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +972 -36
  161. package/templates/tanstack-start/docs/library/tanstack-start/index.md +1525 -881
  162. package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +1099 -20
  163. package/templates/tanstack-start/docs/library/tanstack-start/routing.md +796 -30
  164. package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +953 -35
  165. package/templates/tanstack-start/docs/library/tanstack-start/setup.md +371 -15
  166. package/templates/tauri/CLAUDE.md +189 -0
  167. package/templates/tauri/docs/guides/distribution.md +261 -0
  168. package/templates/tauri/docs/guides/getting-started.md +302 -0
  169. package/templates/tauri/docs/guides/mobile.md +288 -0
  170. package/templates/tauri/docs/library/tauri/index.md +510 -0
@@ -18,9 +18,10 @@
18
18
  | **라우트** | Flat 파일 라우트 (`routes/users.tsx`) |
19
19
  | **Route Export** | `export const IndexRoute`, `const Route` (export 안함) |
20
20
  | **API** | `/api` 라우터 생성 (Server Functions 사용) |
21
- | **레이어** | Service Layer 건너뛰기, Routes에서 직접 DB 접근 |
21
+ | **레이어** | Features 건너뛰기, Routes에서 직접 DB 접근 |
22
22
  | **검증** | Handler 내부 수동 검증, 인증 로직 분산 |
23
- | **Barrel Export** | `functions/index.ts` 생성 (Tree Shaking 실패, 서버 라이브러리 Client 오염) |
23
+ | **Barrel Export** | `functions/index.ts` 생성 (Tree Shaking 실패) |
24
+ | **폴더 구조** | `lib/db`, `lib/store` (→ `database/`, `stores/` 사용) |
24
25
 
25
26
  </forbidden>
26
27
 
@@ -32,9 +33,10 @@
32
33
  |------|------|
33
34
  | **라우트 구조** | 페이지마다 폴더 생성 (`routes/users/index.tsx`) |
34
35
  | **Route Export** | `export const Route = createFileRoute(...)` 필수 |
35
- | **계층 구조** | Routes → Server Functions → Services → Database |
36
+ | **계층 구조** | Routes → Server Functions → Features → Database |
36
37
  | **Route Group** | 목록 → `(main)/`, 생성/편집 → 외부 |
37
38
  | **페이지 분리** | 100줄+ → `-components`, 200줄+ → `-sections` |
39
+ | **컴포넌트 분리** | 로직 있는 컴포넌트 → `-components/-hooks/`로 훅 분리 |
38
40
  | **beforeLoad** | 인증 체크, Context 전달, 리다이렉트 |
39
41
  | **loader** | 데이터 로딩 (beforeLoad 완료 후 병렬 실행) |
40
42
  | **Server Fn** | `createServerFn` 기본 사용 |
@@ -58,17 +60,29 @@
58
60
  │ │ React Router │───▶│ TanStack Query │───▶│ React UI │ │
59
61
  │ │ (Navigation) │◀───│ (Caching) │◀───│ (Components) │ │
60
62
  │ └────────────────┘ └───────┬────────┘ └───────────────┘ │
63
+ │ ┌─────────────────────────────┴─────────────────────────────┐ │
64
+ │ │ State: TanStack Query + Zustand │ │
65
+ │ └───────────────────────────────────────────────────────────┘ │
61
66
  └────────────────────────────────┼─────────────────────────────────┘
62
67
 
63
68
  ┌─────────────────────────────────────────────────────────────────┐
64
69
  │ TanStack Start Server │
65
70
  │ ┌────────────────────────────────────────────────────────────┐ │
71
+ │ │ Security: CSP | Rate Limit | CORS │ │
72
+ │ └────────────────────────────┬───────────────────────────────┘ │
73
+ │ ┌────────────────────────────▼───────────────────────────────┐ │
66
74
  │ │ Server Functions │ │
67
- │ │ routes/-functions/ 페이지 전용 | functions/ 글로벌 │ │
75
+ │ │ routes/-functions/ (페이지) | functions/ (글로벌) │ │
76
+ │ └────────────────────────────┬───────────────────────────────┘ │
77
+ │ ┌────────────────────────────▼───────────────────────────────┐ │
78
+ │ │ Features (내부 도메인) | Services (외부 SDK) │ │
79
+ │ │ Prisma 쿼리, 스키마 | Stripe, S3, SendGrid │ │
80
+ │ └────────────────────────────┬───────────────────────────────┘ │
81
+ │ ┌────────────────────────────▼───────────────────────────────┐ │
82
+ │ │ Caching: Redis (분산) | Query (로컬) | CDN │ │
68
83
  │ └────────────────────────────┬───────────────────────────────┘ │
69
84
  │ ┌────────────────────────────▼───────────────────────────────┐ │
70
- │ │ Services Layer │ │
71
- │ │ Zod Validation | Business Logic | Data Transformation │ │
85
+ │ │ Monitoring: Sentry (에러) | OpenTelemetry │ │
72
86
  │ └────────────────────────────┬───────────────────────────────┘ │
73
87
  └───────────────────────────────┼──────────────────────────────────┘
74
88
 
@@ -84,6 +98,61 @@
84
98
 
85
99
  ---
86
100
 
101
+ <folder_structure>
102
+
103
+ ## Folder Structure
104
+
105
+ ```
106
+ src/
107
+ ├── routes/ # 라우팅 (파일 기반)
108
+ ├── components/ # UI 컴포넌트
109
+ │ ├── ui/ # shadcn/ui
110
+ │ ├── layout/ # Header, Sidebar, Footer
111
+ │ └── shared/ # 공용 컴포넌트
112
+ ├── features/ # 내부 도메인 (DB 레이어)
113
+ │ └── <domain>/
114
+ │ ├── schemas.ts
115
+ │ ├── queries.ts
116
+ │ └── mutations.ts
117
+ ├── services/ # 외부 SDK 연동
118
+ │ ├── stripe/
119
+ │ ├── sendgrid/
120
+ │ ├── s3/
121
+ │ └── openai/
122
+ ├── functions/ # 글로벌 Server Functions
123
+ │ └── middlewares/
124
+ ├── database/ # Prisma Client
125
+ ├── stores/ # Zustand 스토어
126
+ ├── hooks/ # 글로벌 훅
127
+ ├── types/ # 전역 타입
128
+ ├── env/ # 환경 변수 검증 (t3-env)
129
+ ├── styles/ # CSS
130
+ ├── config/ # 설정
131
+ │ ├── auth.ts
132
+ │ ├── query-client.ts
133
+ │ └── sentry.ts
134
+ └── lib/ # 유틸리티
135
+ ├── utils/
136
+ ├── constants/
137
+ └── validators/
138
+ ```
139
+
140
+ ### 폴더 역할
141
+
142
+ | 폴더 | 역할 | 예시 |
143
+ |------|------|------|
144
+ | **features/** | 내부 도메인, Prisma 쿼리 | users, projects, billing |
145
+ | **services/** | 외부 SDK 래퍼 | Stripe, SendGrid, S3, OpenAI |
146
+ | **functions/** | Server Functions | API 레이어 |
147
+ | **database/** | Prisma Client | 싱글톤 인스턴스 |
148
+ | **stores/** | Zustand 스토어 | 클라이언트 전역 상태 |
149
+ | **config/** | 설정 파일 | auth, query-client, sentry |
150
+ | **lib/** | 유틸리티 | utils, constants, validators |
151
+
152
+ </folder_structure>
153
+
154
+ ---
155
+
87
156
  <route_export_rule>
88
157
 
89
158
  ## Route Export 규칙
@@ -91,8 +160,6 @@
91
160
  > ⚠️ **`export const Route` 필수**
92
161
  >
93
162
  > TanStack Router는 모든 라우트 파일에서 **정확히 `Route`라는 이름**으로 내보내야 합니다.
94
- >
95
- > `tsr generate` 및 `tsr watch` 명령어가 자동으로 경로를 생성하고 업데이트합니다.
96
163
 
97
164
  | ❌ 금지 | ✅ 필수 |
98
165
  |--------|--------|
@@ -101,16 +168,6 @@
101
168
  | `export default createFileRoute(...)` | `export const Route = createFileRoute(...)` |
102
169
 
103
170
  ```typescript
104
- // ❌ 금지: export 없음
105
- const Route = createFileRoute('/users')({
106
- component: UsersPage,
107
- })
108
-
109
- // ❌ 금지: 다른 이름
110
- export const UsersRoute = createFileRoute('/users')({
111
- component: UsersPage,
112
- })
113
-
114
171
  // ✅ 필수: 정확히 'Route' 이름으로 export
115
172
  export const Route = createFileRoute('/users')({
116
173
  component: UsersPage,
@@ -129,10 +186,6 @@ export const Route = createFileRoute('/users')({
129
186
 
130
187
  > ⚠️ **페이지마다 폴더 생성 필수**
131
188
  >
132
- > 모든 페이지는 **반드시 폴더 구조**로 만들어야 합니다. Flat 파일 방식(`routes/users.tsx`)은 금지됩니다.
133
- >
134
- > **이유:** -components/, -functions/, -hooks/ 등 페이지 전용 리소스를 체계적으로 관리하기 위함입니다.
135
- >
136
189
  > | ❌ 금지 | ✅ 필수 |
137
190
  > |--------|--------|
138
191
  > | `routes/users.tsx` | `routes/users/index.tsx` |
@@ -143,117 +196,174 @@ routes/<route-name>/
143
196
  ├── (main)/ # route group (목록 페이지)
144
197
  │ ├── index.tsx # 페이지 컴포넌트
145
198
  │ ├── -components/ # 페이지 전용 컴포넌트
146
- │ ├── -sections/ # UI 섹션 분리 (200줄+ 페이지)
147
- │ ├── -tabs/ # 탭 콘텐츠 분리
199
+ │ ├── -sections/ # UI 섹션 분리 (200줄+)
148
200
  │ ├── -hooks/ # 페이지 전용 훅
149
201
  │ └── -utils/ # 상수, 헬퍼
150
- ├── new/ # 생성 페이지 (route group 외부)
202
+ ├── new/ # 생성 페이지
151
203
  │ └── index.tsx
152
- ├── route.tsx # route 설정 (loader, beforeLoad)
204
+ ├── route.tsx # 레이아웃 (loader, beforeLoad)
153
205
  └── -functions/ # 페이지 전용 서버 함수
154
206
  ```
155
207
 
156
- | 패턴 | 위치 | 용도 |
157
- |------|------|------|
158
- | **Route Group** | `(main)/` | 목록 페이지, URL에 미포함 |
159
- | **-components/** | 100-200줄 | 페이지 전용 컴포넌트 분리 |
160
- | **-sections/** | 200줄+ | 논리적 섹션 분리 |
161
- | **-tabs/** | UI | 콘텐츠 분리 |
162
- | **route.tsx** | 레이아웃 | 하위 경로 공통 레이아웃 |
208
+ | 패턴 | 용도 |
209
+ |------|------|
210
+ | **Route Group `()`** | URL 미포함, 레이아웃 공유 |
211
+ | **-components/** | 페이지 전용 컴포넌트 (100줄+) |
212
+ | **-sections/** | 논리적 섹션 분리 (200줄+) |
213
+ | **route.tsx** | 하위 경로 공통 레이아웃 |
163
214
 
164
- #### Layout Routes 패턴
215
+ #### Component + Hook 분리
165
216
 
166
- > ⚠️ **route.tsx로 레이아웃 구성**
167
- >
168
- > `route.tsx`는 하위 경로의 공통 레이아웃 역할을 합니다.
169
- > `index.tsx`는 Route Group `()`으로 묶어야 합니다.
170
- >
171
- > **필수:** `route.tsx`는 반드시 `component`를 export해야 합니다.
172
- >
173
- > | ❌ 금지 | ✅ 필수 |
174
- > |--------|--------|
175
- > | `export const Route = createFileRoute(...)({})` | `export const Route = createFileRoute(...)({ component: ... })` |
217
+ > 컴포넌트에 로직(서버 연동, 상태 관리)이 있으면 폴더로 묶고 훅 분리
176
218
 
177
219
  ```
178
- routes/
179
- ├── (auth)/
180
- │ ├── route.tsx # 레이아웃 (<Outlet />)
181
- ├── (main)/
182
- └── index.tsx # /auth (목록/메인)
183
- │ ├── login/
184
- │ │ └── index.tsx # /auth/login
185
- └── register/
186
- └── index.tsx # /auth/register
220
+ -components/
221
+ ├── user-card/
222
+ │ ├── index.tsx # UI만
223
+ └── -hooks/
224
+ └── use-user-card.ts # 서버 연동, 상태 로직
225
+ └── user-form/
226
+ ├── index.tsx # UI만
227
+ └── -hooks/
228
+ └── use-user-form.ts # 폼 로직, mutation
187
229
  ```
188
230
 
189
231
  ```typescript
190
- // ❌ 금지: component 없음
191
- export const Route = createFileRoute('/(auth)')({
192
- beforeLoad: async () => ({ user: await getUser() }),
193
- })
232
+ // -components/user-form/-hooks/use-user-form.ts
233
+ export function useUserForm(userId?: string) {
234
+ const queryClient = useQueryClient()
235
+
236
+ const { data: user } = useQuery({
237
+ queryKey: ['user', userId],
238
+ queryFn: () => getUser(userId!),
239
+ enabled: !!userId,
240
+ })
194
241
 
195
- // 필수: component 반드시 포함
196
- // routes/(auth)/route.tsx - 레이아웃
197
- export const Route = createFileRoute('/(auth)')({
198
- component: () => (
199
- <div className="auth-container">
200
- <Outlet />
201
- </div>
202
- ),
203
- })
242
+ const mutation = useMutation({
243
+ mutationFn: userId ? updateUser : createUser,
244
+ onSuccess: () => {
245
+ queryClient.invalidateQueries({ queryKey: ['users'] })
246
+ },
247
+ })
248
+
249
+ return { user, mutation, isLoading: mutation.isPending }
250
+ }
251
+
252
+ // -components/user-form/index.tsx
253
+ export function UserForm({ userId }: Props) {
254
+ const { user, mutation, isLoading } = useUserForm(userId)
255
+
256
+ return (
257
+ <form onSubmit={(e) => mutation.mutate(formData)}>
258
+ {/* UI만 */}
259
+ </form>
260
+ )
261
+ }
262
+ ```
263
+
264
+ | 분리 기준 | 컴포넌트 (`index.tsx`) | 훅 (`-hooks/`) |
265
+ |----------|----------------------|----------------|
266
+ | **역할** | UI 렌더링 | 로직 처리 |
267
+ | **내용** | JSX, 스타일 | useQuery, useMutation, 상태 |
204
268
 
205
- // routes/(auth)/(main)/index.tsx - 메인 페이지
206
- export const Route = createFileRoute('/(auth)/')({
207
- component: AuthMainPage,
269
+ ### 2. Features Layer
270
+
271
+ > 내부 도메인 로직, Prisma 쿼리
272
+
273
+ ```
274
+ features/<domain>/
275
+ ├── schemas.ts # Zod 스키마
276
+ ├── queries.ts # TanStack Query 옵션
277
+ └── mutations.ts # useMutation 옵션
278
+ ```
279
+
280
+ ```typescript
281
+ // features/users/schemas.ts
282
+ export const createUserSchema = z.object({
283
+ email: z.email(),
284
+ name: z.string().min(1),
208
285
  })
209
286
 
210
- // routes/(auth)/login/index.tsx
211
- export const Route = createFileRoute('/(auth)/login')({
212
- component: LoginPage,
287
+ // features/users/queries.ts
288
+ export const userQueryOptions = queryOptions({
289
+ queryKey: ['users'],
290
+ queryFn: getUsers,
291
+ staleTime: 5 * 60 * 1000,
213
292
  })
214
293
  ```
215
294
 
216
- ### 2. Services Layer
295
+ ### 3. Services Layer
296
+
297
+ > 외부 SDK 연동
217
298
 
218
299
  ```
219
- services/<domain>/
220
- ├── index.ts # 진입점 (re-export)
221
- ├── schemas.ts # Zod 스키마
222
- ├── queries.ts # GET 요청
223
- └── mutations.ts # POST/PUT/PATCH
300
+ services/<provider>/
301
+ ├── client.ts # SDK 클라이언트
302
+ ├── types.ts # 타입 정의
303
+ └── utils.ts # 헬퍼 함수
304
+ ```
305
+
306
+ ```typescript
307
+ // services/stripe/client.ts
308
+ import Stripe from 'stripe'
309
+
310
+ export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!)
311
+
312
+ // services/stripe/utils.ts
313
+ export async function createCheckoutSession(priceId: string) {
314
+ return stripe.checkout.sessions.create({
315
+ mode: 'subscription',
316
+ line_items: [{ price: priceId, quantity: 1 }],
317
+ })
318
+ }
224
319
  ```
225
320
 
226
- ### 3. Server Functions Layer
321
+ ### 4. Server Functions Layer
227
322
 
228
323
  ```
229
- functions/ # 글로벌 (재사용)
230
- ├── <function-name>.ts # 파일당 하나
324
+ functions/ # 글로벌
325
+ ├── <function-name>.ts
231
326
  └── middlewares/
232
- └── <middleware-name>.ts
327
+ ├── auth.ts
328
+ └── logging.ts
233
329
 
234
330
  routes/<route>/-functions/ # 페이지 전용
235
331
  └── <function-name>.ts
236
332
  ```
237
333
 
238
- > ⚠️ **`functions/index.ts` 생성 금지**
239
- >
240
- > `functions/` 폴더에 `index.ts` (barrel export) 파일을 만들지 마세요.
241
- >
242
- > **문제점:**
243
- > 1. **Tree Shaking 실패** - 번들러가 사용하지 않는 함수도 포함
244
- > 2. **Client 번들 오염** - `pg`, `prisma` 등 서버 전용 라이브러리가 클라이언트에 import되어 빌드 에러 발생
245
- >
246
- > ```typescript
247
- > // ❌ functions/index.ts 만들지 말 것
248
- > export * from './get-users'
249
- > export * from './create-post' // pg import → 클라이언트 빌드 실패
250
- >
251
- > // ✅ 개별 파일에서 직접 import
252
- > import { getUsers } from '@/functions/get-users'
253
- > import { createPost } from '@/functions/create-post'
254
- > ```
334
+ > ⚠️ **`functions/index.ts` 생성 금지** - Tree Shaking 실패, Client 번들 오염
335
+
336
+ ```typescript
337
+ // ✅ 개별 파일에서 직접 import
338
+ import { getUsers } from '@/functions/get-users'
339
+ import { createPost } from '@/functions/create-post'
340
+ ```
341
+
342
+ ### 5. State Management Layer
255
343
 
256
- ### 4. Database Layer
344
+ | 상태 유형 | 도구 | 사용 |
345
+ |----------|------|------|
346
+ | **서버 상태** | TanStack Query | API 데이터, 캐싱 (80%) |
347
+ | **클라이언트 상태** | Zustand | UI 상태, 설정 (20%) |
348
+
349
+ ```typescript
350
+ // stores/app.ts
351
+ import { create } from 'zustand'
352
+ import { persist } from 'zustand/middleware'
353
+
354
+ export const useAppStore = create(
355
+ persist(
356
+ (set) => ({
357
+ theme: 'dark' as 'light' | 'dark',
358
+ sidebarOpen: true,
359
+ setTheme: (theme) => set({ theme }),
360
+ }),
361
+ { name: 'app-store' }
362
+ )
363
+ )
364
+ ```
365
+
366
+ ### 6. Database Layer
257
367
 
258
368
  ```typescript
259
369
  // database/prisma.ts
@@ -282,16 +392,7 @@ if (process.env.NODE_ENV !== 'production') {
282
392
  |------|-----------|--------|
283
393
  | **실행 순서** | 순차 (outermost → innermost) | 병렬 (beforeLoad 완료 후) |
284
394
  | **용도** | 인증, Context 전달, 리다이렉트 | 데이터 로딩 |
285
- | **블로킹** | 모든 loader 차단 | 다른 loader와 병렬 |
286
- | **성능 영향** | ⚠️ 높음 | ✅ 낮음 |
287
-
288
- ```
289
- 1. Parent beforeLoad (순차) ──┐
290
- 2. Child beforeLoad (순차) ──┼→ 완료 후
291
- 3. All loaders (병렬) ────────┘
292
- ```
293
-
294
- ### 코드 패턴
395
+ | **성능 영향** | ⚠️ 높음 (블로킹) | 낮음 (병렬) |
295
396
 
296
397
  ```typescript
297
398
  // ✅ beforeLoad: 인증 & Context
@@ -311,11 +412,6 @@ loader: async () => {
311
412
  }
312
413
  ```
313
414
 
314
- | ❌ 금지 | ✅ 권장 |
315
- |--------|--------|
316
- | beforeLoad에서 데이터 로딩 | loader에서 데이터 로딩 |
317
- | loader 차단 | 병렬 실행 |
318
-
319
415
  </route_lifecycle>
320
416
 
321
417
  ---
@@ -340,22 +436,14 @@ export const Route = createRootRouteWithContext<RouterContext>()({
340
436
  beforeLoad: async () => ({ user: await getUser() }),
341
437
  })
342
438
 
343
- // 2. 확장: Context 확장
439
+ // 2. 확장
344
440
  beforeLoad: async ({ context }) => ({
345
441
  ...context,
346
442
  permissions: await getPermissions(context.user.id),
347
443
  })
348
444
 
349
- // 3. 사용: Component
445
+ // 3. 사용
350
446
  const { user, permissions } = useRouteContext({ from: '/dashboard' })
351
-
352
- // 4. 사용: Loader
353
- loader: async ({ context }) => {
354
- if (!context.permissions.includes('users:read')) {
355
- throw new Error('Unauthorized')
356
- }
357
- return { users: await getUsers() }
358
- }
359
447
  ```
360
448
 
361
449
  </context_management>
@@ -369,17 +457,14 @@ loader: async ({ context }) => {
369
457
  ### Query Flow (읽기)
370
458
 
371
459
  ```
372
- Page → useQuery → Server Function → Prisma → Database
460
+ Page → useQuery → Server Function → Features → Prisma → Database
373
461
 
374
462
  TanStack Query (Cache)
375
463
  ```
376
464
 
377
465
  ```typescript
378
466
  // Page
379
- const { data } = useQuery({
380
- queryKey: ['users'],
381
- queryFn: getUsers,
382
- })
467
+ const { data } = useQuery(userQueryOptions)
383
468
 
384
469
  // Server Function
385
470
  export const getUsers = createServerFn()
@@ -390,13 +475,9 @@ export const getUsers = createServerFn()
390
475
  ### Mutation Flow (쓰기)
391
476
 
392
477
  ```
393
- Form → useMutation → Server Function
394
-
395
- inputValidator
396
-
397
- Prisma → Database
398
-
399
- invalidateQueries
478
+ Form → useMutation → Server Function → inputValidator → Features → Database
479
+
480
+ invalidateQueries
400
481
  ```
401
482
 
402
483
  ```typescript
@@ -425,18 +506,16 @@ export const createUser = createServerFn({ method: 'POST' })
425
506
 
426
507
  ### Server Functions 타입
427
508
 
428
- | 타입 | 실행 위치 | 사용 시나리오 |
429
- |------|----------|-------------|
430
- | **createServerFn** | 서버 | DB 접근, 비밀키, 서버 로직 (기본) |
509
+ | 타입 | 실행 위치 | 사용 |
510
+ |------|----------|------|
511
+ | **createServerFn** | 서버 | DB 접근, 비밀키 (기본) |
431
512
  | createClientOnlyFn | 클라이언트 | localStorage, window |
432
513
  | createIsomorphicFn | 양쪽 | 환경별 구현 |
433
514
 
434
- **기본 규칙**: 별도 요청 없으면 `createServerFn` 사용
435
-
436
515
  ### Middleware 패턴
437
516
 
438
517
  ```typescript
439
- // 1. authMiddleware
518
+ // functions/middlewares/auth.ts
440
519
  export const authMiddleware = createMiddleware()
441
520
  .server(async ({ next, context }) => {
442
521
  const session = await getSession()
@@ -444,9 +523,19 @@ export const authMiddleware = createMiddleware()
444
523
  return next({ context: { ...context, user: session.user } })
445
524
  })
446
525
 
447
- // 2. 사용
526
+ // functions/middlewares/logging.ts
527
+ export const loggingMiddleware = createMiddleware()
528
+ .server(async ({ next }) => {
529
+ const start = Date.now()
530
+ const traceId = crypto.randomUUID()
531
+ const result = await next({ context: { traceId } })
532
+ console.log({ traceId, duration: Date.now() - start })
533
+ return result
534
+ })
535
+
536
+ // 사용
448
537
  export const createPost = createServerFn({ method: 'POST' })
449
- .middleware([authMiddleware])
538
+ .middleware([loggingMiddleware, authMiddleware])
450
539
  .inputValidator(createPostSchema)
451
540
  .handler(async ({ data, context }) => {
452
541
  return prisma.post.create({
@@ -482,27 +571,6 @@ export const Route = createRootRoute({
482
571
  export const Route = createFileRoute('/dashboard')({
483
572
  errorComponent: ({ error }) => <div>{error.message}</div>,
484
573
  })
485
-
486
- // Loader 에러
487
- loader: async () => {
488
- try {
489
- return { users: await getUsers() }
490
- } catch (error) {
491
- throw new Error('데이터 로딩 실패')
492
- }
493
- }
494
-
495
- // Server Function 에러
496
- .handler(async ({ data }) => {
497
- try {
498
- return await prisma.user.create({ data })
499
- } catch (error) {
500
- if (error.code === 'P2002') {
501
- throw new Error('이미 존재하는 이메일')
502
- }
503
- throw new Error('사용자 생성 실패')
504
- }
505
- })
506
574
  ```
507
575
 
508
576
  </error_handling>
@@ -518,9 +586,12 @@ loader: async () => {
518
586
  | Framework | TanStack Start | latest |
519
587
  | Router | TanStack Router | latest |
520
588
  | Data | TanStack Query | latest |
589
+ | State | Zustand | latest |
521
590
  | ORM | Prisma | 7.x |
522
591
  | Validation | Zod | 4.x |
523
592
  | Database | PostgreSQL | - |
524
- | UI | React 18+ | - |
593
+ | Cache | Redis | - |
594
+ | Monitoring | Sentry | latest |
595
+ | UI | React 19+ | - |
525
596
 
526
597
  </tech_stack>