@kood/claude-code 0.2.4 → 0.3.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 (130) hide show
  1. package/dist/index.js +13 -8
  2. package/package.json +1 -1
  3. package/templates/.claude/agents/code-reviewer.md +371 -19
  4. package/templates/.claude/agents/dependency-manager.md +197 -0
  5. package/templates/.claude/agents/deployment-validator.md +136 -0
  6. package/templates/.claude/agents/git-operator.md +147 -0
  7. package/templates/.claude/agents/implementation-executor.md +202 -0
  8. package/templates/.claude/agents/lint-fixer.md +155 -0
  9. package/templates/.claude/agents/refactor-advisor.md +339 -29
  10. package/templates/.claude/commands/agent-creator.md +355 -0
  11. package/templates/.claude/commands/docs-creator.md +404 -163
  12. package/templates/.claude/commands/docs-refactor.md +400 -113
  13. package/templates/.claude/commands/execute.md +357 -185
  14. package/templates/.claude/commands/git-all.md +16 -70
  15. package/templates/.claude/commands/git-session.md +36 -68
  16. package/templates/.claude/commands/git.md +20 -69
  17. package/templates/.claude/commands/lint-fix.md +164 -107
  18. package/templates/.claude/commands/lint-init.md +142 -168
  19. package/templates/.claude/commands/plan.md +300 -84
  20. package/templates/.claude/commands/prd.md +613 -0
  21. package/templates/.claude/commands/pre-deploy.md +242 -0
  22. package/templates/.claude/commands/subagent-creator.md +118 -0
  23. package/templates/.claude/commands/version-update.md +45 -57
  24. package/templates/hono/CLAUDE.md +99 -54
  25. package/templates/hono/docs/guides/conventions.md +352 -0
  26. package/templates/hono/docs/guides/env-setup.md +347 -0
  27. package/templates/hono/docs/guides/getting-started.md +239 -0
  28. package/templates/hono/docs/library/hono/error-handling.md +20 -29
  29. package/templates/hono/docs/library/hono/index.md +25 -52
  30. package/templates/hono/docs/library/hono/middleware.md +16 -75
  31. package/templates/hono/docs/library/hono/rpc.md +7 -35
  32. package/templates/hono/docs/library/hono/validation.md +25 -45
  33. package/templates/hono/docs/library/t3-env/index.md +374 -0
  34. package/templates/npx/CLAUDE.md +165 -65
  35. package/templates/npx/docs/library/commander/index.md +10 -73
  36. package/templates/npx/docs/library/fs-extra/index.md +21 -113
  37. package/templates/npx/docs/library/prompts/index.md +30 -176
  38. package/templates/npx/docs/references/patterns.md +75 -48
  39. package/templates/tanstack-start/CLAUDE.md +101 -77
  40. package/templates/tanstack-start/docs/architecture.md +427 -0
  41. package/templates/tanstack-start/docs/design.md +558 -0
  42. package/templates/tanstack-start/docs/guides/conventions.md +132 -32
  43. package/templates/tanstack-start/docs/guides/env-setup.md +127 -62
  44. package/templates/tanstack-start/docs/guides/getting-started.md +81 -20
  45. package/templates/tanstack-start/docs/guides/hooks.md +241 -36
  46. package/templates/tanstack-start/docs/guides/routes.md +213 -61
  47. package/templates/tanstack-start/docs/guides/services.md +260 -24
  48. package/templates/tanstack-start/docs/library/better-auth/index.md +469 -16
  49. package/templates/tanstack-start/docs/library/t3-env/index.md +307 -0
  50. package/templates/tanstack-start/docs/library/tanstack-query/index.md +12 -21
  51. package/templates/tanstack-start/docs/library/tanstack-query/invalidation.md +22 -35
  52. package/templates/tanstack-start/docs/library/tanstack-query/optimistic-updates.md +7 -24
  53. package/templates/tanstack-start/docs/library/tanstack-query/use-mutation.md +26 -39
  54. package/templates/tanstack-start/docs/library/tanstack-query/use-query.md +23 -26
  55. package/templates/tanstack-start/docs/library/tanstack-router/error-handling.md +32 -147
  56. package/templates/tanstack-start/docs/library/tanstack-router/hooks.md +25 -167
  57. package/templates/tanstack-start/docs/library/tanstack-router/index.md +39 -74
  58. package/templates/tanstack-start/docs/library/tanstack-router/navigation.md +46 -116
  59. package/templates/tanstack-start/docs/library/tanstack-router/route-context.md +35 -154
  60. package/templates/tanstack-start/docs/library/tanstack-router/search-params.md +32 -171
  61. package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +7 -15
  62. package/templates/tanstack-start/docs/library/tanstack-start/routing.md +16 -23
  63. package/templates/tanstack-start/docs/library/zod/complex-types.md +12 -31
  64. package/templates/tanstack-start/docs/library/zod/index.md +18 -35
  65. package/templates/tanstack-start/docs/library/zod/transforms.md +11 -25
  66. package/templates/tanstack-start/docs/library/zod/validation.md +12 -34
  67. package/templates/.claude/agents/debug-detective.md +0 -37
  68. package/templates/.claude/agents/test-writer.md +0 -41
  69. package/templates/.claude/commands/feedback.md +0 -199
  70. package/templates/.claude/commands/ts-fix.md +0 -176
  71. package/templates/.claude/skills/command-creator/LICENSE.txt +0 -202
  72. package/templates/.claude/skills/command-creator/SKILL.md +0 -245
  73. package/templates/.claude/skills/command-creator/scripts/init_command.py +0 -244
  74. package/templates/.claude/skills/command-creator/scripts/package_command.py +0 -125
  75. package/templates/.claude/skills/command-creator/scripts/quick_validate.py +0 -143
  76. package/templates/.claude/skills/frontend-design/SKILL.md +0 -310
  77. package/templates/.claude/skills/frontend-design/references/animation-patterns.md +0 -446
  78. package/templates/.claude/skills/frontend-design/references/colors-2026.md +0 -244
  79. package/templates/.claude/skills/frontend-design/references/typography-2026.md +0 -302
  80. package/templates/.claude/skills/gemini-review/SKILL.md +0 -118
  81. package/templates/.claude/skills/gemini-review/references/checklists.md +0 -129
  82. package/templates/.claude/skills/gemini-review/references/prompt-templates.md +0 -274
  83. package/templates/.claude/skills/skill-creator/LICENSE.txt +0 -202
  84. package/templates/.claude/skills/skill-creator/SKILL.md +0 -184
  85. package/templates/.claude/skills/skill-creator/scripts/init_skill.py +0 -303
  86. package/templates/.claude/skills/skill-creator/scripts/package_skill.py +0 -110
  87. package/templates/.claude/skills/skill-creator/scripts/quick_validate.py +0 -65
  88. package/templates/hono/docs/library/ai-sdk/index.md +0 -190
  89. package/templates/hono/docs/library/ai-sdk/openrouter.md +0 -111
  90. package/templates/hono/docs/library/ai-sdk/providers.md +0 -102
  91. package/templates/hono/docs/library/ai-sdk/streaming.md +0 -146
  92. package/templates/hono/docs/library/ai-sdk/structured-output.md +0 -161
  93. package/templates/hono/docs/library/ai-sdk/tools.md +0 -144
  94. package/templates/hono/docs/library/drizzle/cloudflare-d1.md +0 -247
  95. package/templates/hono/docs/library/drizzle/config.md +0 -167
  96. package/templates/hono/docs/library/drizzle/index.md +0 -259
  97. package/templates/hono/docs/library/hono/env-setup.md +0 -169
  98. package/templates/hono/docs/library/pino/index.md +0 -146
  99. package/templates/tanstack-start/docs/architecture/architecture.md +0 -243
  100. package/templates/tanstack-start/docs/deployment/cloudflare.md +0 -132
  101. package/templates/tanstack-start/docs/deployment/index.md +0 -163
  102. package/templates/tanstack-start/docs/deployment/nitro.md +0 -110
  103. package/templates/tanstack-start/docs/deployment/railway.md +0 -147
  104. package/templates/tanstack-start/docs/deployment/vercel.md +0 -135
  105. package/templates/tanstack-start/docs/design/components.md +0 -175
  106. package/templates/tanstack-start/docs/design/index.md +0 -151
  107. package/templates/tanstack-start/docs/design/safe-area.md +0 -118
  108. package/templates/tanstack-start/docs/design/tailwind-setup.md +0 -156
  109. package/templates/tanstack-start/docs/library/ai-sdk/hooks.md +0 -472
  110. package/templates/tanstack-start/docs/library/ai-sdk/index.md +0 -264
  111. package/templates/tanstack-start/docs/library/ai-sdk/openrouter.md +0 -371
  112. package/templates/tanstack-start/docs/library/ai-sdk/providers.md +0 -403
  113. package/templates/tanstack-start/docs/library/ai-sdk/streaming.md +0 -320
  114. package/templates/tanstack-start/docs/library/ai-sdk/structured-output.md +0 -454
  115. package/templates/tanstack-start/docs/library/ai-sdk/tools.md +0 -473
  116. package/templates/tanstack-start/docs/library/better-auth/2fa.md +0 -48
  117. package/templates/tanstack-start/docs/library/better-auth/advanced.md +0 -55
  118. package/templates/tanstack-start/docs/library/better-auth/plugins.md +0 -34
  119. package/templates/tanstack-start/docs/library/better-auth/session.md +0 -47
  120. package/templates/tanstack-start/docs/library/better-auth/setup.md +0 -41
  121. package/templates/tanstack-start/docs/library/drizzle/cloudflare-d1.md +0 -147
  122. package/templates/tanstack-start/docs/library/drizzle/config.md +0 -118
  123. package/templates/tanstack-start/docs/library/drizzle/crud.md +0 -205
  124. package/templates/tanstack-start/docs/library/drizzle/index.md +0 -79
  125. package/templates/tanstack-start/docs/library/drizzle/relations.md +0 -202
  126. package/templates/tanstack-start/docs/library/drizzle/schema.md +0 -154
  127. package/templates/tanstack-start/docs/library/drizzle/setup.md +0 -96
  128. package/templates/tanstack-start/docs/library/drizzle/transactions.md +0 -127
  129. package/templates/tanstack-start/docs/library/pino/index.md +0 -320
  130. /package/templates/hono/docs/{architecture/architecture.md → architecture.md} +0 -0
@@ -1,19 +1,35 @@
1
1
  # Custom Hook 패턴
2
2
 
3
- 페이지/섹션의 모든 로직, 상태, 라이프사이클을 중앙화.
3
+ > 페이지/섹션의 모든 로직, 상태, 라이프사이클 중앙화
4
4
 
5
- ## 필수: Hook 내부 순서
5
+ <instructions>
6
+ @../library/tanstack-router/hooks.md
7
+ @../library/tanstack-query/use-query.md
8
+ @../library/tanstack-query/use-mutation.md
9
+ </instructions>
6
10
 
7
- ```
8
- 1. State (useState, zustand store)
9
- 2. Global Hooks (useParams, useNavigate, useQueryClient)
10
- 3. React Query (useQuery → useMutation)
11
- 4. Event Handlers & Functions
12
- 5. useMemo
13
- 6. useEffect
14
- ```
11
+ ---
12
+
13
+ <hook_order>
14
+
15
+ ## Hook 내부 순서 (필수)
16
+
17
+ | 순서 | Hook 타입 | 예시 |
18
+ |------|-----------|------|
19
+ | 1 | State | `useState`, zustand store |
20
+ | 2 | Global Hooks | `useParams`, `useNavigate`, `useQueryClient` |
21
+ | 3 | React Query | `useQuery` → `useMutation` |
22
+ | 4 | Event Handlers | `handleCreate`, `handleDelete` |
23
+ | 5 | useMemo | 계산된 값 |
24
+ | 6 | useEffect | 부수 효과 |
15
25
 
16
- ## Page Hook 예시
26
+ </hook_order>
27
+
28
+ ---
29
+
30
+ <patterns>
31
+
32
+ ## Page Hook 패턴
17
33
 
18
34
  ```typescript
19
35
  // routes/users/-hooks/use-users.ts
@@ -28,13 +44,10 @@ interface UseUsersReturn {
28
44
  users: User[] | undefined
29
45
  filteredUsers: User[]
30
46
  isLoading: boolean
31
- error: Error | null
32
47
  search: string
33
48
  setSearch: (value: string) => void
34
49
  handleCreate: (data: { email: string; name: string }) => void
35
50
  handleDelete: (id: string) => void
36
- isCreating: boolean
37
- isDeleting: boolean
38
51
  }
39
52
 
40
53
  export const useUsers = (): UseUsersReturn => {
@@ -54,7 +67,7 @@ export const useUsers = (): UseUsersReturn => {
54
67
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
55
68
  // 3. React Query
56
69
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
57
- const { data: users, isLoading, error } = useQuery({
70
+ const { data: users, isLoading } = useQuery({
58
71
  queryKey: ['users'],
59
72
  queryFn: () => getUsers(),
60
73
  })
@@ -110,35 +123,15 @@ export const useUsers = (): UseUsersReturn => {
110
123
  users,
111
124
  filteredUsers,
112
125
  isLoading,
113
- error,
114
126
  search,
115
127
  setSearch,
116
128
  handleCreate,
117
129
  handleDelete,
118
- isCreating: createMutation.isPending,
119
- isDeleting: deleteMutation.isPending,
120
130
  }
121
131
  }
122
132
  ```
123
133
 
124
- ## 잘못된 순서 (금지)
125
-
126
- ```typescript
127
- // ❌ 순서가 뒤섞인 잘못된 예시
128
- export const useBadHook = () => {
129
- const queryClient = useQueryClient() // ❌ Global Hook이 먼저
130
-
131
- useEffect(() => { /* ... */ }, []) // ❌ useEffect가 중간에
132
-
133
- const [state, setState] = useState() // ❌ State가 나중에
134
-
135
- const { data } = useQuery({ /* ... */ }) // ❌ Query가 Effect 다음에
136
-
137
- const computed = useMemo(() => {}, []) // ❌ useMemo 위치 잘못됨
138
- }
139
- ```
140
-
141
- ## Filter Hook 예시
134
+ ## Filter Hook 패턴
142
135
 
143
136
  ```typescript
144
137
  // routes/users/-hooks/use-user-filter.ts
@@ -164,3 +157,215 @@ export const useUserFilter = (): UseUserFilterReturn => {
164
157
  return { search, setSearch, role, setRole, clearFilters }
165
158
  }
166
159
  ```
160
+
161
+ ## Form Hook 패턴
162
+
163
+ ```typescript
164
+ // routes/users/-hooks/use-user-form.ts
165
+ import { useState } from 'react'
166
+ import { useMutation, useQueryClient } from '@tanstack/react-query'
167
+ import { createUser } from '@/services/user'
168
+ import type { CreateUserInput } from '@/services/user'
169
+
170
+ interface UseUserFormReturn {
171
+ email: string
172
+ setEmail: (value: string) => void
173
+ name: string
174
+ setName: (value: string) => void
175
+ handleSubmit: (e: React.FormEvent) => void
176
+ isSubmitting: boolean
177
+ error: Error | null
178
+ }
179
+
180
+ export const useUserForm = (): UseUserFormReturn => {
181
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
182
+ // 1. State
183
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
184
+ const [email, setEmail] = useState('')
185
+ const [name, setName] = useState('')
186
+
187
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
188
+ // 2. Global Hooks
189
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
190
+ const queryClient = useQueryClient()
191
+
192
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
193
+ // 3. React Query
194
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
195
+ const { mutate, isPending, error } = useMutation({
196
+ mutationFn: createUser,
197
+ onSuccess: () => {
198
+ queryClient.invalidateQueries({ queryKey: ['users'] })
199
+ setEmail('')
200
+ setName('')
201
+ },
202
+ })
203
+
204
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
205
+ // 4. Event Handlers
206
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
207
+ const handleSubmit = (e: React.FormEvent) => {
208
+ e.preventDefault()
209
+ mutate({ data: { email, name } })
210
+ }
211
+
212
+ return {
213
+ email,
214
+ setEmail,
215
+ name,
216
+ setName,
217
+ handleSubmit,
218
+ isSubmitting: isPending,
219
+ error,
220
+ }
221
+ }
222
+ ```
223
+
224
+ </patterns>
225
+
226
+ ---
227
+
228
+ <anti_patterns>
229
+
230
+ ## ❌ 잘못된 순서
231
+
232
+ ```typescript
233
+ // ❌ 순서가 뒤섞인 잘못된 예시
234
+ export const useBadHook = () => {
235
+ const queryClient = useQueryClient() // ❌ Global Hook이 먼저
236
+
237
+ useEffect(() => { /* ... */ }, []) // ❌ useEffect가 중간에
238
+
239
+ const [state, setState] = useState() // ❌ State가 나중에
240
+
241
+ const { data } = useQuery({ /* ... */ }) // ❌ Query가 Effect 다음에
242
+
243
+ const computed = useMemo(() => {}, []) // ❌ useMemo 위치 잘못됨
244
+ }
245
+ ```
246
+
247
+ ## ✅ 올바른 순서
248
+
249
+ ```typescript
250
+ export const useGoodHook = () => {
251
+ // 1. State
252
+ const [state, setState] = useState()
253
+
254
+ // 2. Global Hooks
255
+ const queryClient = useQueryClient()
256
+
257
+ // 3. React Query
258
+ const { data } = useQuery({ /* ... */ })
259
+
260
+ // 4. Event Handlers
261
+ const handleClick = useCallback(() => {}, [])
262
+
263
+ // 5. useMemo
264
+ const computed = useMemo(() => {}, [])
265
+
266
+ // 6. useEffect
267
+ useEffect(() => { /* ... */ }, [])
268
+
269
+ return { state, data, handleClick, computed }
270
+ }
271
+ ```
272
+
273
+ </anti_patterns>
274
+
275
+ ---
276
+
277
+ <router_hooks>
278
+
279
+ ## TanStack Router Hooks
280
+
281
+ | Hook | 용도 | 예시 |
282
+ |------|------|------|
283
+ | `useParams` | URL 파라미터 | `const { id } = useParams({ from: '/users/$id' })` |
284
+ | `useNavigate` | 프로그래밍 방식 네비게이션 | `navigate({ to: '/users' })` |
285
+ | `useSearch` | Search params | `const { page } = useSearch({ from: '/users' })` |
286
+ | `useLoaderData` | Loader 데이터 | `const user = Route.useLoaderData()` |
287
+ | `useRouteContext` | Route context | `const { auth } = useRouteContext({ from: '__root__' })` |
288
+
289
+ ```typescript
290
+ // routes/users/$id.tsx Hook
291
+ import { useParams, useNavigate, useLoaderData } from '@tanstack/react-router'
292
+
293
+ export const useUserDetail = () => {
294
+ const { id } = useParams({ from: '/users/$id' })
295
+ const navigate = useNavigate()
296
+ const user = Route.useLoaderData()
297
+
298
+ const handleBack = () => navigate({ to: '/users' })
299
+ const handleEdit = () => navigate({ to: '/users/$id/edit', params: { id } })
300
+
301
+ return {
302
+ user,
303
+ handleBack,
304
+ handleEdit,
305
+ }
306
+ }
307
+ ```
308
+
309
+ </router_hooks>
310
+
311
+ ---
312
+
313
+ <query_hooks>
314
+
315
+ ## TanStack Query Hooks
316
+
317
+ | Hook | 용도 | 특징 |
318
+ |------|------|------|
319
+ | `useQuery` | 데이터 조회 (GET) | 자동 캐싱, 재검증 |
320
+ | `useMutation` | 데이터 변경 (POST/PUT/DELETE) | 성공 시 캐시 무효화 |
321
+ | `useQueryClient` | 캐시 제어 | `invalidateQueries`, `setQueryData` |
322
+
323
+ ```typescript
324
+ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
325
+ import { getUsers, createUser } from '@/services/user'
326
+
327
+ export const useUsers = () => {
328
+ const queryClient = useQueryClient()
329
+
330
+ const { data, isLoading, error } = useQuery({
331
+ queryKey: ['users'],
332
+ queryFn: () => getUsers(),
333
+ staleTime: 60 * 1000, // 1분
334
+ })
335
+
336
+ const { mutate, isPending } = useMutation({
337
+ mutationFn: createUser,
338
+ onSuccess: () => {
339
+ queryClient.invalidateQueries({ queryKey: ['users'] })
340
+ },
341
+ })
342
+
343
+ return { data, isLoading, error, mutate, isPending }
344
+ }
345
+ ```
346
+
347
+ </query_hooks>
348
+
349
+ ---
350
+
351
+ <best_practices>
352
+
353
+ | 원칙 | 설명 |
354
+ |------|------|
355
+ | **순서 준수** | State → Global → Query → Handlers → Memo → Effect |
356
+ | **타입 정의** | Return 타입 명시 (interface) |
357
+ | **단일 책임** | 하나의 Hook은 하나의 관심사 |
358
+ | **useCallback** | Event handler는 useCallback으로 메모이제이션 |
359
+ | **명확한 네이밍** | `use-users.ts`, `use-user-filter.ts` |
360
+
361
+ </best_practices>
362
+
363
+ ---
364
+
365
+ <sources>
366
+
367
+ - [TanStack Router Hooks](https://tanstack.com/router/latest/docs/framework/react/guide/router-hooks)
368
+ - [TanStack Query useQuery](https://tanstack.com/query/latest/docs/framework/react/guides/queries)
369
+ - [TanStack Query useMutation](https://tanstack.com/query/latest/docs/framework/react/guides/mutations)
370
+
371
+ </sources>
@@ -1,38 +1,63 @@
1
1
  # 라우트 구조
2
2
 
3
- TanStack Start 파일 기반 라우팅 패턴.
3
+ > TanStack Start 파일 기반 라우팅
4
4
 
5
- ## Route 폴더 구조
5
+ <instructions>
6
+ @../library/tanstack-router/index.md
7
+ </instructions>
6
8
 
7
- ```
8
- routes/<route-name>/
9
- ├── index.tsx # 페이지 컴포넌트
10
- ├── route.tsx # route 설정 (필요시)
11
- ├── -components/ # 페이지 전용 컴포넌트
12
- │ ├── user-card.tsx
13
- │ └── user-form.tsx
14
- ├── -sections/ # 섹션 분리 (복잡한 경우)
15
- │ ├── user-list-section.tsx
16
- │ └── user-filter-section.tsx
17
- └── -hooks/ # 페이지 전용 훅
18
- ├── use-users.ts
19
- └── use-user-filter.ts
20
- ```
9
+ ---
21
10
 
22
- ## `-` 접두사
11
+ <route_structure>
23
12
 
24
- `-` 접두사가 있는 폴더는 라우트에서 제외:
13
+ ## 라우트 폴더 구조
25
14
 
26
15
  ```
27
- routes/users/
28
- ├── index.tsx # /users ✅ 라우트
29
- ├── $id.tsx # /users/:id ✅ 라우트
30
- ├── -components/ # ❌ 라우트 아님
31
- ├── -sections/ # 라우트 아님
32
- └── -hooks/ # 라우트 아님
16
+ routes/
17
+ ├── __root.tsx # Root Layout
18
+ ├── index.tsx # / (Home)
19
+ ├── users/
20
+ ├── index.tsx # /users (List)
21
+ │ ├── $id.tsx # /users/:id (Detail)
22
+ │ ├── -components/ # 페이지 전용 컴포넌트
23
+ │ ├── -sections/ # 섹션 분리 (복잡한 경우)
24
+ │ └── -hooks/ # 페이지 전용 Hook
25
+ └── posts/
26
+ ├── index.tsx
27
+ └── $slug.tsx
33
28
  ```
34
29
 
35
- ## 기본 Route 패턴
30
+ | 접두사 | 용도 | 라우트 생성 |
31
+ |--------|------|-----------|
32
+ | `-` | 라우트 제외 폴더 | ❌ 제외 |
33
+ | `$` | 동적 파라미터 | ✅ 생성 |
34
+ | `_` | Pathless Layout | ✅ 생성 (경로 없음) |
35
+
36
+ </route_structure>
37
+
38
+ ---
39
+
40
+ <file_naming>
41
+
42
+ ## 라우트 파일명 규칙
43
+
44
+ | 경로 | 파일명 | 설명 |
45
+ |------|--------|------|
46
+ | `/` | `index.tsx` | 인덱스 라우트 |
47
+ | `/users` | `users/index.tsx` | 목록 페이지 |
48
+ | `/users/:id` | `users/$id.tsx` | 동적 파라미터 |
49
+ | `/posts/:slug` | `posts/$slug.tsx` | URL 파라미터 |
50
+ | `/dashboard/*` | `dashboard/$.tsx` | Catch-all 라우트 |
51
+ | Layout | `__root.tsx` | Root 레이아웃 |
52
+ | Pathless | `_layout.tsx` | 경로 없는 레이아웃 |
53
+
54
+ </file_naming>
55
+
56
+ ---
57
+
58
+ <patterns>
59
+
60
+ ## 기본 라우트 패턴
36
61
 
37
62
  ```tsx
38
63
  // routes/users/index.tsx
@@ -55,6 +80,105 @@ const UsersPage = (): JSX.Element => {
55
80
  }
56
81
  ```
57
82
 
83
+ ## 동적 라우트 + Loader
84
+
85
+ ```tsx
86
+ // routes/users/$id.tsx
87
+ import { createFileRoute } from '@tanstack/react-router'
88
+ import { getUserById } from '@/services/user'
89
+
90
+ export const Route = createFileRoute('/users/$id')({
91
+ loader: ({ params: { id } }) => getUserById({ data: id }),
92
+ component: UserDetailPage,
93
+ })
94
+
95
+ const UserDetailPage = (): JSX.Element => {
96
+ const user = Route.useLoaderData()
97
+
98
+ return (
99
+ <div>
100
+ <h1>{user.name}</h1>
101
+ <p>{user.email}</p>
102
+ </div>
103
+ )
104
+ }
105
+ ```
106
+
107
+ ## Loader with Dependencies
108
+
109
+ ```tsx
110
+ // routes/posts/index.tsx
111
+ import { createFileRoute } from '@tanstack/react-router'
112
+ import { getPosts } from '@/services/post'
113
+ import { z } from 'zod'
114
+
115
+ const postsSearchSchema = z.object({
116
+ offset: z.number().default(0),
117
+ limit: z.number().default(10),
118
+ })
119
+
120
+ export const Route = createFileRoute('/posts/')({
121
+ validateSearch: postsSearchSchema,
122
+ loaderDeps: ({ search: { offset, limit } }) => ({ offset, limit }),
123
+ loader: ({ deps: { offset, limit } }) => getPosts({ data: { offset, limit } }),
124
+ component: PostsPage,
125
+ })
126
+
127
+ const PostsPage = (): JSX.Element => {
128
+ const posts = Route.useLoaderData()
129
+ const { offset, limit } = Route.useSearch()
130
+
131
+ return (
132
+ <div>
133
+ <h1>Posts (offset: {offset}, limit: {limit})</h1>
134
+ {posts.map((post) => (
135
+ <div key={post.id}>{post.title}</div>
136
+ ))}
137
+ </div>
138
+ )
139
+ }
140
+ ```
141
+
142
+ ## Deferred Data Loading
143
+
144
+ ```tsx
145
+ // routes/dashboard/index.tsx
146
+ import { createFileRoute, Await } from '@tanstack/react-router'
147
+ import { Suspense } from 'react'
148
+ import { getFastData, getSlowData } from '@/services/dashboard'
149
+
150
+ export const Route = createFileRoute('/dashboard/')({
151
+ loader: async () => {
152
+ const slowDataPromise = getSlowData()
153
+ const fastData = await getFastData()
154
+
155
+ return {
156
+ fastData,
157
+ deferredSlowData: slowDataPromise,
158
+ }
159
+ },
160
+ component: DashboardPage,
161
+ })
162
+
163
+ const DashboardPage = (): JSX.Element => {
164
+ const { fastData, deferredSlowData } = Route.useLoaderData()
165
+
166
+ return (
167
+ <div>
168
+ <h1>Fast Data</h1>
169
+ <pre>{JSON.stringify(fastData, null, 2)}</pre>
170
+
171
+ <h1>Slow Data (Deferred)</h1>
172
+ <Suspense fallback={<div>Loading slow data...</div>}>
173
+ <Await promise={deferredSlowData}>
174
+ {(slowData) => <pre>{JSON.stringify(slowData, null, 2)}</pre>}
175
+ </Await>
176
+ </Suspense>
177
+ </div>
178
+ )
179
+ }
180
+ ```
181
+
58
182
  ## Section 패턴
59
183
 
60
184
  ```tsx
@@ -84,42 +208,6 @@ export const UserListSection = (): JSX.Element => {
84
208
  }
85
209
  ```
86
210
 
87
- ## Filter Section 패턴
88
-
89
- ```tsx
90
- // routes/users/-sections/user-filter-section.tsx
91
- import { useUserFilter } from '../-hooks/use-user-filter'
92
- import { Input } from '@/components/ui/input'
93
- import { Button } from '@/components/ui/button'
94
-
95
- export const UserFilterSection = (): JSX.Element => {
96
- const { search, setSearch, role, setRole, clearFilters } = useUserFilter()
97
-
98
- return (
99
- <div className="flex gap-4 mb-6">
100
- <Input
101
- placeholder="Search users..."
102
- value={search}
103
- onChange={(e) => setSearch(e.target.value)}
104
- className="max-w-xs"
105
- />
106
- <select
107
- value={role}
108
- onChange={(e) => setRole(e.target.value)}
109
- className="border rounded px-3 py-2"
110
- >
111
- <option value="">All Roles</option>
112
- <option value="USER">User</option>
113
- <option value="ADMIN">Admin</option>
114
- </select>
115
- <Button variant="outline" onClick={clearFilters}>
116
- Clear
117
- </Button>
118
- </div>
119
- )
120
- }
121
- ```
122
-
123
211
  ## 컴포넌트 패턴
124
212
 
125
213
  ```tsx
@@ -164,3 +252,67 @@ export const UserCard = ({
164
252
  )
165
253
  }
166
254
  ```
255
+
256
+ </patterns>
257
+
258
+ ---
259
+
260
+ <page_size_rules>
261
+
262
+ | 페이지 크기 | 구조 | 예시 |
263
+ |------------|------|------|
264
+ | ~100줄 | 단일 파일 | 간단한 페이지, 폼 |
265
+ | 100-200줄 | `-components/` 분리 | 목록 + 필터 |
266
+ | 200줄+ | `-sections/` + `-components/` | 대시보드, 복잡한 UI |
267
+
268
+ </page_size_rules>
269
+
270
+ ---
271
+
272
+ <loader_execution>
273
+
274
+ ## Loader 실행 순서
275
+
276
+ | 단계 | 실행 방식 | 설명 |
277
+ |------|----------|------|
278
+ | 1. `beforeLoad` | 순차 (outermost → innermost) | 인증 체크, 컨텍스트 설정 |
279
+ | 2. `loader` | 병렬 (모든 loader 동시) | 데이터 페칭 |
280
+
281
+ ```tsx
282
+ // Parent Route
283
+ export const Route = createFileRoute('/dashboard')({
284
+ beforeLoad: async () => {
285
+ // 1. 먼저 실행 (순차)
286
+ const auth = await checkAuth()
287
+ return { auth }
288
+ },
289
+ loader: async () => {
290
+ // 2. 나중에 실행 (병렬)
291
+ return getDashboardData()
292
+ },
293
+ })
294
+
295
+ // Child Route
296
+ export const Route = createFileRoute('/dashboard/users')({
297
+ beforeLoad: async () => {
298
+ // 1. Parent beforeLoad 다음 실행
299
+ return {}
300
+ },
301
+ loader: async () => {
302
+ // 2. Parent loader와 병렬 실행
303
+ return getUsers()
304
+ },
305
+ })
306
+ ```
307
+
308
+ </loader_execution>
309
+
310
+ ---
311
+
312
+ <sources>
313
+
314
+ - [TanStack Router Data Loading](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading)
315
+ - [TanStack Router Deferred Data Loading](https://tanstack.com/router/latest/docs/framework/react/guide/deferred-data-loading)
316
+ - [TanStack Router File-Based Routing](https://tanstack.com/router/latest/docs/framework/react/guide/file-based-routing)
317
+
318
+ </sources>