@kood/claude-code 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -404,7 +404,7 @@ var init = async (options) => {
404
404
 
405
405
  // src/index.ts
406
406
  var program = new Command();
407
- program.name("claude-code").description("Claude Code documentation installer for projects").version("0.2.2");
407
+ program.name("claude-code").description("Claude Code documentation installer for projects").version("0.2.4");
408
408
  program.option(
409
409
  "-t, --template <names>",
410
410
  "template names (comma-separated: tanstack-start,hono)"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kood/claude-code",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Claude Code documentation installer for projects",
5
5
  "type": "module",
6
6
  "bin": "./dist/index.js",
@@ -2,6 +2,19 @@
2
2
 
3
3
  TanStack Start 애플리케이션 아키텍처 가이드.
4
4
 
5
+ ## 목차
6
+
7
+ - [System Overview](#system-overview)
8
+ - [Layer Architecture](#layer-architecture)
9
+ - [Routes Layer](#1-routes-layer)
10
+ - [Services Layer](#2-services-layer)
11
+ - [Server Functions Layer](#3-server-functions-layer)
12
+ - [Database Layer](#4-database-layer)
13
+ - [Data Flow](#data-flow)
14
+ - [Technology Stack](#technology-stack)
15
+
16
+ ---
17
+
5
18
  ## System Overview
6
19
 
7
20
  ```
@@ -39,12 +52,110 @@ TanStack Start 애플리케이션 아키텍처 가이드.
39
52
 
40
53
  ```
41
54
  routes/<route-name>/
42
- ├── index.tsx # 페이지 컴포넌트
55
+ ├── (main)/ # route group (목록 페이지)
56
+ │ ├── index.tsx # 페이지 컴포넌트
57
+ │ ├── -components/ # 페이지 전용 컴포넌트
58
+ │ ├── -sections/ # UI 섹션 분리 (200줄+ 페이지)
59
+ │ ├── -tabs/ # 탭 콘텐츠 분리
60
+ │ ├── -hooks/ # 페이지 전용 훅
61
+ │ └── -utils/ # 상수, 헬퍼
62
+ ├── new/ # 생성 페이지 (route group 외부)
63
+ │ └── index.tsx
43
64
  ├── route.tsx # route 설정 (loader, beforeLoad)
44
- ├── -functions/ # 페이지 전용 서버 함수
45
- ├── -components/ # 페이지 전용 컴포넌트
46
- ├── -sections/ # 섹션 분리
47
- └── -hooks/ # 페이지 전용
65
+ └── -functions/ # 페이지 전용 서버 함수
66
+ ```
67
+
68
+ #### Route Group 패턴 `(main)`
69
+
70
+ 목록 페이지는 반드시 `(main)` route group으로 감싸야 한다:
71
+
72
+ ```
73
+ routes/dashboard/companies/
74
+ ├── (main)/ # /dashboard/companies (목록)
75
+ │ ├── index.tsx
76
+ │ └── -components/
77
+ └── new/ # /dashboard/companies/new (생성)
78
+ └── index.tsx
79
+ ```
80
+
81
+ **규칙:**
82
+ - 목록 페이지 → `(main)/` 내부
83
+ - 생성/편집 페이지 → `(main)/` 외부
84
+ - URL에 `(main)`은 포함되지 않음
85
+
86
+ #### 페이지 크기 기준
87
+
88
+ | 줄 수 | 권장 조치 |
89
+ |-------|----------|
90
+ | ~100줄 | 단일 파일 OK |
91
+ | 100-200줄 | -components 분리 검토 |
92
+ | 200줄+ | -sections 분리 필수 |
93
+ | 탭 UI | -tabs 분리 권장 |
94
+
95
+ #### `-sections/` 패턴 (200줄+ 페이지)
96
+
97
+ 큰 페이지는 논리적 섹션으로 분리:
98
+
99
+ ```tsx
100
+ // routes/settings/(main)/index.tsx
101
+ import { GeneralSection } from './-sections/general-section'
102
+ import { SecuritySection } from './-sections/security-section'
103
+ import { NotificationSection } from './-sections/notification-section'
104
+
105
+ function SettingsPage() {
106
+ return (
107
+ <div className="space-y-8">
108
+ <GeneralSection />
109
+ <SecuritySection />
110
+ <NotificationSection />
111
+ </div>
112
+ )
113
+ }
114
+ ```
115
+
116
+ ```
117
+ routes/settings/(main)/
118
+ ├── index.tsx
119
+ └── -sections/
120
+ ├── general-section.tsx
121
+ ├── security-section.tsx
122
+ └── notification-section.tsx
123
+ ```
124
+
125
+ #### `-tabs/` 패턴 (탭 UI)
126
+
127
+ 탭 기반 페이지는 각 탭을 별도 파일로 분리:
128
+
129
+ ```tsx
130
+ // routes/project-settings/(main)/index.tsx
131
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
132
+ import { GeneralTab } from './-tabs/general-tab'
133
+ import { MembersTab } from './-tabs/members-tab'
134
+ import { DangerTab } from './-tabs/danger-tab'
135
+
136
+ function ProjectSettingsPage() {
137
+ return (
138
+ <Tabs defaultValue="general">
139
+ <TabsList>
140
+ <TabsTrigger value="general">일반</TabsTrigger>
141
+ <TabsTrigger value="members">멤버</TabsTrigger>
142
+ <TabsTrigger value="danger">위험</TabsTrigger>
143
+ </TabsList>
144
+ <TabsContent value="general"><GeneralTab /></TabsContent>
145
+ <TabsContent value="members"><MembersTab /></TabsContent>
146
+ <TabsContent value="danger"><DangerTab /></TabsContent>
147
+ </Tabs>
148
+ )
149
+ }
150
+ ```
151
+
152
+ ```
153
+ routes/project-settings/(main)/
154
+ ├── index.tsx
155
+ └── -tabs/
156
+ ├── general-tab.tsx
157
+ ├── members-tab.tsx
158
+ └── danger-tab.tsx
48
159
  ```
49
160
 
50
161
  ### 2. Services Layer
@@ -129,4 +240,4 @@ Form Submit → useMutation → Server Function (POST)
129
240
  - [conventions.md](../guides/conventions.md) - 코드 컨벤션
130
241
  - [routes.md](../guides/routes.md) - 라우트 구조
131
242
  - [hooks.md](../guides/hooks.md) - Custom Hook 패턴
132
- - [services.md](../guides/services.md) - Service Layer
243
+ - [services.md](../guides/services.md) - Service Layer
@@ -79,6 +79,7 @@ export default {
79
79
  import { createServerFn } from '@tanstack/react-start'
80
80
  import { drizzle } from 'drizzle-orm/d1'
81
81
  import { eq } from 'drizzle-orm'
82
+ import { z } from 'zod'
82
83
  import * as schema from '@/db/schema'
83
84
 
84
85
  // D1 바인딩 접근 (Cloudflare Pages/Workers)
@@ -94,7 +95,7 @@ export const getUsers = createServerFn({ method: 'GET' })
94
95
  })
95
96
 
96
97
  export const createUser = createServerFn({ method: 'POST' })
97
- .validator((data: { email: string; name?: string }) => data)
98
+ .inputValidator(z.object({ email: z.email(), name: z.string().optional() }))
98
99
  .handler(async ({ data }) => {
99
100
  const db = getDb()
100
101
  const [user] = await db.insert(schema.users).values(data).returning()
@@ -64,6 +64,7 @@ import { createServerFn } from '@tanstack/react-start'
64
64
  import { db } from '@/lib/db'
65
65
  import { users } from '@/db/schema'
66
66
  import { eq } from 'drizzle-orm'
67
+ import { z } from 'zod'
67
68
 
68
69
  export const getUsers = createServerFn({ method: 'GET' })
69
70
  .handler(async () => {
@@ -71,14 +72,14 @@ export const getUsers = createServerFn({ method: 'GET' })
71
72
  })
72
73
 
73
74
  export const getUserById = createServerFn({ method: 'GET' })
74
- .validator((id: number) => id)
75
+ .inputValidator(z.coerce.number())
75
76
  .handler(async ({ data: id }) => {
76
77
  const [user] = await db.select().from(users).where(eq(users.id, id))
77
78
  return user
78
79
  })
79
80
 
80
81
  export const createUser = createServerFn({ method: 'POST' })
81
- .validator((data: { email: string; name: string }) => data)
82
+ .inputValidator(z.object({ email: z.email(), name: z.string() }))
82
83
  .handler(async ({ data }) => {
83
84
  const [user] = await db.insert(users).values(data).returning()
84
85
  return user
@@ -21,7 +21,7 @@ const createUserSchema = z.object({
21
21
  })
22
22
 
23
23
  export const createUser = createServerFn({ method: 'POST' })
24
- .inputValidator(zodValidator(createUserSchema))
24
+ .inputValidator(createUserSchema)
25
25
  .handler(async ({ data }) => prisma.user.create({ data }))
26
26
  ```
27
27