@kood/claude-code 0.3.6 → 0.3.8
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 +1 -1
- package/package.json +1 -1
- package/templates/.claude/agents/code-reviewer.md +124 -124
- package/templates/.claude/agents/dependency-manager.md +85 -85
- package/templates/.claude/agents/deployment-validator.md +56 -56
- package/templates/.claude/agents/git-operator.md +64 -64
- package/templates/.claude/agents/implementation-executor.md +95 -95
- package/templates/.claude/agents/ko-to-en-translator.md +74 -0
- package/templates/.claude/agents/lint-fixer.md +78 -78
- package/templates/.claude/agents/refactor-advisor.md +122 -122
- package/templates/.claude/commands/agent-creator.md +185 -185
- package/templates/.claude/commands/bug-fix.md +193 -193
- package/templates/.claude/commands/command-creator.md +54 -54
- package/templates/.claude/commands/docs-creator.md +57 -57
- package/templates/.claude/commands/docs-refactor.md +26 -26
- package/templates/.claude/commands/execute.md +12 -12
- package/templates/.claude/commands/git-all.md +32 -32
- package/templates/.claude/commands/git-session.md +42 -42
- package/templates/.claude/commands/git.md +34 -34
- package/templates/.claude/commands/lint-fix.md +138 -138
- package/templates/.claude/commands/lint-init.md +61 -61
- package/templates/.claude/commands/plan.md +260 -260
- package/templates/.claude/commands/prd.md +24 -24
- package/templates/.claude/commands/pre-deploy.md +109 -109
- package/templates/.claude/commands/refactor.md +147 -147
- package/templates/.claude/commands/version-update.md +17 -17
- package/templates/hono/CLAUDE.md +27 -27
- package/templates/hono/docs/architecture.md +24 -24
- package/templates/hono/docs/deployment/cloudflare.md +18 -18
- package/templates/hono/docs/deployment/docker.md +13 -13
- package/templates/hono/docs/deployment/index.md +19 -19
- package/templates/hono/docs/deployment/railway.md +32 -32
- package/templates/hono/docs/deployment/vercel.md +29 -29
- package/templates/hono/docs/guides/conventions.md +57 -57
- package/templates/hono/docs/guides/env-setup.md +47 -47
- package/templates/hono/docs/guides/getting-started.md +27 -27
- package/templates/hono/docs/library/hono/error-handling.md +11 -11
- package/templates/hono/docs/library/hono/index.md +4 -4
- package/templates/hono/docs/library/hono/middleware.md +18 -18
- package/templates/hono/docs/library/hono/rpc.md +7 -7
- package/templates/hono/docs/library/hono/validation.md +6 -6
- package/templates/hono/docs/library/prisma/cloudflare-d1.md +29 -29
- package/templates/hono/docs/library/prisma/config.md +16 -16
- package/templates/hono/docs/library/prisma/index.md +32 -32
- package/templates/hono/docs/library/t3-env/index.md +22 -22
- package/templates/hono/docs/library/zod/index.md +31 -31
- package/templates/nextjs/CLAUDE.md +228 -0
- package/templates/nextjs/docs/design.md +558 -0
- package/templates/nextjs/docs/guides/conventions.md +343 -0
- package/templates/nextjs/docs/guides/getting-started.md +367 -0
- package/templates/nextjs/docs/guides/routes.md +342 -0
- package/templates/nextjs/docs/library/better-auth/index.md +541 -0
- package/templates/nextjs/docs/library/nextjs/app-router.md +269 -0
- package/templates/nextjs/docs/library/nextjs/caching.md +351 -0
- package/templates/nextjs/docs/library/nextjs/index.md +291 -0
- package/templates/nextjs/docs/library/nextjs/middleware.md +391 -0
- package/templates/nextjs/docs/library/nextjs/route-handlers.md +382 -0
- package/templates/nextjs/docs/library/nextjs/server-actions.md +366 -0
- package/templates/nextjs/docs/library/prisma/cloudflare-d1.md +76 -0
- package/templates/nextjs/docs/library/prisma/config.md +77 -0
- package/templates/nextjs/docs/library/prisma/crud.md +90 -0
- package/templates/nextjs/docs/library/prisma/index.md +73 -0
- package/templates/nextjs/docs/library/prisma/relations.md +69 -0
- package/templates/nextjs/docs/library/prisma/schema.md +98 -0
- package/templates/nextjs/docs/library/prisma/setup.md +49 -0
- package/templates/nextjs/docs/library/prisma/transactions.md +50 -0
- package/templates/nextjs/docs/library/tanstack-query/index.md +66 -0
- package/templates/nextjs/docs/library/tanstack-query/invalidation.md +54 -0
- package/templates/nextjs/docs/library/tanstack-query/optimistic-updates.md +77 -0
- package/templates/nextjs/docs/library/tanstack-query/use-mutation.md +63 -0
- package/templates/nextjs/docs/library/tanstack-query/use-query.md +70 -0
- package/templates/nextjs/docs/library/zod/complex-types.md +61 -0
- package/templates/nextjs/docs/library/zod/index.md +56 -0
- package/templates/nextjs/docs/library/zod/transforms.md +51 -0
- package/templates/nextjs/docs/library/zod/validation.md +70 -0
- package/templates/npx/CLAUDE.md +37 -37
- package/templates/npx/docs/library/commander/index.md +12 -12
- package/templates/npx/docs/library/fs-extra/index.md +9 -9
- package/templates/npx/docs/library/prompts/index.md +3 -3
- package/templates/npx/docs/references/patterns.md +12 -12
- package/templates/tanstack-start/CLAUDE.md +53 -49
- package/templates/tanstack-start/docs/architecture.md +128 -128
- package/templates/tanstack-start/docs/design.md +169 -169
- package/templates/tanstack-start/docs/guides/conventions.md +43 -43
- package/templates/tanstack-start/docs/guides/env-setup.md +35 -35
- package/templates/tanstack-start/docs/guides/getting-started.md +19 -19
- package/templates/tanstack-start/docs/guides/hooks.md +63 -35
- package/templates/tanstack-start/docs/guides/routes.md +61 -42
- package/templates/tanstack-start/docs/guides/services.md +45 -45
- package/templates/tanstack-start/docs/library/better-auth/index.md +68 -68
- package/templates/tanstack-start/docs/library/prisma/cloudflare-d1.md +19 -19
- package/templates/tanstack-start/docs/library/prisma/config.md +16 -16
- package/templates/tanstack-start/docs/library/prisma/crud.md +17 -17
- package/templates/tanstack-start/docs/library/prisma/index.md +17 -17
- package/templates/tanstack-start/docs/library/prisma/relations.md +16 -16
- package/templates/tanstack-start/docs/library/prisma/schema.md +23 -23
- package/templates/tanstack-start/docs/library/prisma/setup.md +6 -6
- package/templates/tanstack-start/docs/library/prisma/transactions.md +10 -10
- package/templates/tanstack-start/docs/library/t3-env/index.md +21 -160
- package/templates/tanstack-start/docs/library/tanstack-query/index.md +6 -6
- package/templates/tanstack-start/docs/library/tanstack-query/invalidation.md +19 -19
- package/templates/tanstack-start/docs/library/tanstack-query/optimistic-updates.md +4 -4
- package/templates/tanstack-start/docs/library/tanstack-query/use-mutation.md +14 -14
- package/templates/tanstack-start/docs/library/tanstack-query/use-query.md +21 -21
- package/templates/tanstack-start/docs/library/tanstack-router/error-handling.md +9 -9
- package/templates/tanstack-start/docs/library/tanstack-router/hooks.md +11 -11
- package/templates/tanstack-start/docs/library/tanstack-router/index.md +18 -18
- package/templates/tanstack-start/docs/library/tanstack-router/navigation.md +17 -17
- package/templates/tanstack-start/docs/library/tanstack-router/route-context.md +5 -5
- package/templates/tanstack-start/docs/library/tanstack-router/search-params.md +10 -10
- package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +8 -8
- package/templates/tanstack-start/docs/library/tanstack-start/index.md +15 -15
- package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +9 -9
- package/templates/tanstack-start/docs/library/tanstack-start/routing.md +6 -6
- package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +18 -18
- package/templates/tanstack-start/docs/library/tanstack-start/setup.md +4 -4
- package/templates/tanstack-start/docs/library/zod/complex-types.md +11 -11
- package/templates/tanstack-start/docs/library/zod/index.md +8 -8
- package/templates/tanstack-start/docs/library/zod/transforms.md +11 -11
- package/templates/tanstack-start/docs/library/zod/validation.md +9 -9
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Code Conventions
|
|
2
2
|
|
|
3
|
-
> TanStack Start
|
|
3
|
+
> TanStack Start project coding rules
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<naming>
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## File Naming
|
|
10
10
|
|
|
11
|
-
> ⚠️ **camelCase
|
|
11
|
+
> ⚠️ **No camelCase filenames** - All filenames must use **kebab-case**
|
|
12
12
|
|
|
13
|
-
|
|
|
13
|
+
| Type | Rule | Example |
|
|
14
14
|
|------|------|------|
|
|
15
|
-
|
|
|
16
|
-
| **Route
|
|
17
|
-
| **Hook
|
|
18
|
-
| **Component** | PascalCase
|
|
15
|
+
| **General Files** | kebab-case | `user-profile.tsx`, `auth-service.ts` |
|
|
16
|
+
| **Route Files** | TanStack Router rules | `__root.tsx`, `index.tsx`, `$id.tsx` |
|
|
17
|
+
| **Hook Files** | `use-` prefix + kebab-case | `use-user-filter.ts`, `use-auth.ts` |
|
|
18
|
+
| **Component** | PascalCase component, kebab-case file | `UserCard` in `user-card.tsx` |
|
|
19
19
|
| **Server Function** | kebab-case | `get-users.ts`, `create-post.ts` |
|
|
20
20
|
|
|
21
21
|
```
|
|
22
|
-
❌ camelCase
|
|
23
|
-
✅ kebab-case
|
|
22
|
+
❌ No camelCase: getUserById.ts, authService.ts, useUserFilter.ts
|
|
23
|
+
✅ kebab-case required: get-user-by-id.ts, auth-service.ts, use-user-filter.ts
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
</naming>
|
|
@@ -29,39 +29,39 @@
|
|
|
29
29
|
|
|
30
30
|
<typescript>
|
|
31
31
|
|
|
32
|
-
## TypeScript
|
|
32
|
+
## TypeScript Rules
|
|
33
33
|
|
|
34
|
-
|
|
|
34
|
+
| Rule | Description | Example |
|
|
35
35
|
|------|------|------|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
| **any
|
|
39
|
-
| **Import
|
|
36
|
+
| **Function Declaration** | const function, explicit return type | `const fn = (): ReturnType => {}` |
|
|
37
|
+
| **Type Definition** | interface (objects), type (unions) | `interface User {}`, `type Status = 'a' \| 'b'` |
|
|
38
|
+
| **No any** | Use unknown | `const data: unknown = JSON.parse(str)` |
|
|
39
|
+
| **Import Types** | Separate type imports | `import type { User } from '@/types'` |
|
|
40
40
|
|
|
41
|
-
##
|
|
41
|
+
## Patterns
|
|
42
42
|
|
|
43
43
|
```typescript
|
|
44
|
-
// ✅ const
|
|
44
|
+
// ✅ const function, explicit type
|
|
45
45
|
const getUserById = async (id: string): Promise<User> => {
|
|
46
46
|
return prisma.user.findUnique({ where: { id } })
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
// ✅
|
|
49
|
+
// ✅ Simple functions also need explicit types
|
|
50
50
|
const formatDate = (date: Date): string => {
|
|
51
51
|
return date.toISOString()
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
// ✅ any
|
|
54
|
+
// ✅ No any → use unknown
|
|
55
55
|
const parseJSON = (data: string): unknown => {
|
|
56
56
|
return JSON.parse(data)
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
// ❌ any
|
|
59
|
+
// ❌ No any
|
|
60
60
|
const badParse = (data: string): any => { // ❌
|
|
61
61
|
return JSON.parse(data)
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
// ❌ function
|
|
64
|
+
// ❌ No function keyword
|
|
65
65
|
function badFunction() { // ❌
|
|
66
66
|
return 'use const arrow function'
|
|
67
67
|
}
|
|
@@ -73,7 +73,7 @@ function badFunction() { // ❌
|
|
|
73
73
|
|
|
74
74
|
<imports>
|
|
75
75
|
|
|
76
|
-
## Import
|
|
76
|
+
## Import Order
|
|
77
77
|
|
|
78
78
|
```typescript
|
|
79
79
|
// 1. External libraries
|
|
@@ -101,19 +101,19 @@ import type { UseUsersReturn } from './-hooks/use-users'
|
|
|
101
101
|
|
|
102
102
|
<comments>
|
|
103
103
|
|
|
104
|
-
##
|
|
104
|
+
## Korean Comments (Code Blocks)
|
|
105
105
|
|
|
106
106
|
```typescript
|
|
107
|
-
// ✅
|
|
107
|
+
// ✅ Comments per code block
|
|
108
108
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
109
|
-
//
|
|
109
|
+
// User-related state
|
|
110
110
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
111
111
|
const [user, setUser] = useState<User | null>(null)
|
|
112
112
|
const [isLoading, setIsLoading] = useState(false)
|
|
113
113
|
const [error, setError] = useState<Error | null>(null)
|
|
114
114
|
|
|
115
115
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
116
|
-
//
|
|
116
|
+
// Data fetching
|
|
117
117
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
118
118
|
const { data: users } = useQuery({
|
|
119
119
|
queryKey: ['users'],
|
|
@@ -122,10 +122,10 @@ const { data: users } = useQuery({
|
|
|
122
122
|
```
|
|
123
123
|
|
|
124
124
|
```typescript
|
|
125
|
-
// ❌
|
|
126
|
-
const [user, setUser] = useState(null) //
|
|
127
|
-
const [isLoading, setIsLoading] = useState(false) //
|
|
128
|
-
const [error, setError] = useState(null) //
|
|
125
|
+
// ❌ Line-by-line comments (forbidden)
|
|
126
|
+
const [user, setUser] = useState(null) // User state
|
|
127
|
+
const [isLoading, setIsLoading] = useState(false) // Loading state
|
|
128
|
+
const [error, setError] = useState(null) // Error state
|
|
129
129
|
```
|
|
130
130
|
|
|
131
131
|
</comments>
|
|
@@ -134,7 +134,7 @@ const [error, setError] = useState(null) // 에러 상태
|
|
|
134
134
|
|
|
135
135
|
<error_handling>
|
|
136
136
|
|
|
137
|
-
##
|
|
137
|
+
## Error Handling Pattern
|
|
138
138
|
|
|
139
139
|
```typescript
|
|
140
140
|
// lib/errors.ts
|
|
@@ -168,7 +168,7 @@ export class UnauthorizedError extends AppError {
|
|
|
168
168
|
}
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
-
##
|
|
171
|
+
## Usage Example
|
|
172
172
|
|
|
173
173
|
```typescript
|
|
174
174
|
// services/user/queries.ts
|
|
@@ -188,9 +188,9 @@ export const getUserById = createServerFn({ method: 'GET' })
|
|
|
188
188
|
|
|
189
189
|
<examples>
|
|
190
190
|
|
|
191
|
-
##
|
|
191
|
+
## Filename Examples
|
|
192
192
|
|
|
193
|
-
|
|
|
193
|
+
| Type | ❌ Wrong | ✅ Correct |
|
|
194
194
|
|------|---------------|---------------|
|
|
195
195
|
| Component | `UserProfile.tsx` | `user-profile.tsx` |
|
|
196
196
|
| Service | `authService.ts` | `auth-service.ts` |
|
|
@@ -198,14 +198,14 @@ export const getUserById = createServerFn({ method: 'GET' })
|
|
|
198
198
|
| Utility | `formatUtils.ts` | `format-utils.ts` |
|
|
199
199
|
| Type | `UserTypes.ts` | `user-types.ts` |
|
|
200
200
|
|
|
201
|
-
## Route
|
|
201
|
+
## Route Filenames
|
|
202
202
|
|
|
203
|
-
|
|
|
203
|
+
| Path | Filename | Description |
|
|
204
204
|
|------|--------|------|
|
|
205
|
-
| `/` | `index.tsx` |
|
|
206
|
-
| `/users` | `users/index.tsx` |
|
|
207
|
-
| `/users/:id` | `users/$id.tsx` |
|
|
208
|
-
| `/posts/:slug` | `posts/$slug.tsx` | URL
|
|
209
|
-
| Layout | `__root.tsx` | Root
|
|
205
|
+
| `/` | `index.tsx` | Index route |
|
|
206
|
+
| `/users` | `users/index.tsx` | User list |
|
|
207
|
+
| `/users/:id` | `users/$id.tsx` | Dynamic route |
|
|
208
|
+
| `/posts/:slug` | `posts/$slug.tsx` | URL parameter |
|
|
209
|
+
| Layout | `__root.tsx` | Root layout |
|
|
210
210
|
|
|
211
211
|
</examples>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Environment Variables Setup
|
|
2
2
|
|
|
3
|
-
> TanStack Start (Vite
|
|
3
|
+
> TanStack Start (Vite-based) Environment Variables Management
|
|
4
4
|
|
|
5
5
|
<instructions>
|
|
6
6
|
@../library/t3-env/index.md
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
|
|
11
11
|
<environment_types>
|
|
12
12
|
|
|
13
|
-
|
|
|
14
|
-
|
|
15
|
-
| `process.env.*` | Server Function | DB, API
|
|
16
|
-
| `import.meta.env.VITE_*` |
|
|
13
|
+
| Access Method | Location | Purpose | Exposure |
|
|
14
|
+
|---------------|----------|---------|----------|
|
|
15
|
+
| `process.env.*` | Server Function | DB, API keys, secrets | ❌ Server only |
|
|
16
|
+
| `import.meta.env.VITE_*` | Client + Server | Public configuration | ✅ Browser exposed |
|
|
17
17
|
|
|
18
18
|
</environment_types>
|
|
19
19
|
|
|
@@ -21,22 +21,22 @@
|
|
|
21
21
|
|
|
22
22
|
<file_structure>
|
|
23
23
|
|
|
24
|
-
##
|
|
24
|
+
## Environment File Structure
|
|
25
25
|
|
|
26
26
|
```
|
|
27
|
-
├── .env #
|
|
28
|
-
├── .env.development #
|
|
29
|
-
├── .env.production #
|
|
30
|
-
├── .env.local #
|
|
31
|
-
└── src/lib/env.ts #
|
|
27
|
+
├── .env # Default (commit ✓)
|
|
28
|
+
├── .env.development # Development (commit ✓)
|
|
29
|
+
├── .env.production # Production (commit ✓)
|
|
30
|
+
├── .env.local # Local override (commit ✗)
|
|
31
|
+
└── src/lib/env.ts # Validation and types (t3-env)
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
|
|
|
35
|
-
|
|
36
|
-
| 1 | `.env.{mode}.local` |
|
|
37
|
-
| 2 | `.env.local` |
|
|
38
|
-
| 3 | `.env.{mode}` |
|
|
39
|
-
| 4 | `.env` |
|
|
34
|
+
| Priority | File | Description |
|
|
35
|
+
|----------|------|-------------|
|
|
36
|
+
| 1 | `.env.{mode}.local` | Highest priority (gitignore) |
|
|
37
|
+
| 2 | `.env.local` | Local override |
|
|
38
|
+
| 3 | `.env.{mode}` | Environment-specific config |
|
|
39
|
+
| 4 | `.env` | Default config |
|
|
40
40
|
|
|
41
41
|
</file_structure>
|
|
42
42
|
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
|
|
45
45
|
<patterns>
|
|
46
46
|
|
|
47
|
-
##
|
|
47
|
+
## Environment File Examples
|
|
48
48
|
|
|
49
|
-
### .env.local (gitignore,
|
|
49
|
+
### .env.local (gitignore, secrets)
|
|
50
50
|
|
|
51
51
|
```env
|
|
52
52
|
DATABASE_URL=postgresql://user:password@localhost:5432/myapp
|
|
@@ -70,7 +70,7 @@ VITE_APP_NAME=My App
|
|
|
70
70
|
VITE_API_URL=https://api.myapp.com
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
##
|
|
73
|
+
## Type-Safe Environment Variables (t3-env)
|
|
74
74
|
|
|
75
75
|
```typescript
|
|
76
76
|
// src/lib/env.ts
|
|
@@ -106,7 +106,7 @@ export const env = createEnv({
|
|
|
106
106
|
})
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
##
|
|
109
|
+
## Usage Examples
|
|
110
110
|
|
|
111
111
|
### Server Function
|
|
112
112
|
|
|
@@ -118,13 +118,13 @@ import { prisma } from '@/database/prisma'
|
|
|
118
118
|
|
|
119
119
|
export const getUsers = createServerFn({ method: 'GET' })
|
|
120
120
|
.handler(async () => {
|
|
121
|
-
// env.DATABASE_URL
|
|
121
|
+
// env.DATABASE_URL is only available on server
|
|
122
122
|
console.log('DB URL:', env.DATABASE_URL)
|
|
123
123
|
return prisma.user.findMany()
|
|
124
124
|
})
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
###
|
|
127
|
+
### Client Component
|
|
128
128
|
|
|
129
129
|
```tsx
|
|
130
130
|
// components/app-header.tsx
|
|
@@ -149,11 +149,11 @@ export const AppHeader = (): JSX.Element => {
|
|
|
149
149
|
## .gitignore
|
|
150
150
|
|
|
151
151
|
```gitignore
|
|
152
|
-
#
|
|
152
|
+
# Contains secrets (never commit)
|
|
153
153
|
.env.local
|
|
154
154
|
.env.*.local
|
|
155
155
|
|
|
156
|
-
#
|
|
156
|
+
# Public config (safe to commit)
|
|
157
157
|
!.env
|
|
158
158
|
!.env.development
|
|
159
159
|
!.env.production
|
|
@@ -165,7 +165,7 @@ export const AppHeader = (): JSX.Element => {
|
|
|
165
165
|
|
|
166
166
|
<typescript_types>
|
|
167
167
|
|
|
168
|
-
## TypeScript
|
|
168
|
+
## TypeScript Types (Vite)
|
|
169
169
|
|
|
170
170
|
```typescript
|
|
171
171
|
// src/vite-env.d.ts
|
|
@@ -181,7 +181,7 @@ interface ImportMeta {
|
|
|
181
181
|
}
|
|
182
182
|
```
|
|
183
183
|
|
|
184
|
-
|
|
184
|
+
**Note:** Types are automatically inferred when using t3-env
|
|
185
185
|
|
|
186
186
|
</typescript_types>
|
|
187
187
|
|
|
@@ -189,13 +189,13 @@ interface ImportMeta {
|
|
|
189
189
|
|
|
190
190
|
<best_practices>
|
|
191
191
|
|
|
192
|
-
|
|
|
193
|
-
|
|
194
|
-
|
|
|
195
|
-
|
|
|
196
|
-
|
|
|
197
|
-
|
|
|
198
|
-
|
|
|
192
|
+
| Principle | Description |
|
|
193
|
+
|-----------|-------------|
|
|
194
|
+
| **Separate Secrets** | Store secrets only in `.env.local`, never commit |
|
|
195
|
+
| **Public Variables** | Use `VITE_` prefix, safe for browser exposure |
|
|
196
|
+
| **Type Safety** | Validate with t3-env or Zod |
|
|
197
|
+
| **Default Values** | Set safe defaults in `.env` |
|
|
198
|
+
| **Documentation** | Provide required variable list in `.env.example` |
|
|
199
199
|
|
|
200
200
|
</best_practices>
|
|
201
201
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Getting Started
|
|
2
2
|
|
|
3
|
-
> TanStack Start
|
|
3
|
+
> TanStack Start project quick start
|
|
4
4
|
|
|
5
5
|
<instructions>
|
|
6
6
|
@conventions.md
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
|
|
13
13
|
<prerequisites>
|
|
14
14
|
|
|
15
|
-
|
|
|
15
|
+
| Requirement | Version |
|
|
16
16
|
|----------|------|
|
|
17
17
|
| Node.js | 18+ |
|
|
18
|
-
|
|
|
18
|
+
| Package Manager | Yarn / npm / pnpm |
|
|
19
19
|
|
|
20
20
|
</prerequisites>
|
|
21
21
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
<installation>
|
|
25
25
|
|
|
26
|
-
##
|
|
26
|
+
## Create Project
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
29
|
npx create-tsrouter-app@latest my-app --template start
|
|
@@ -31,7 +31,7 @@ cd my-app
|
|
|
31
31
|
yarn install
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
##
|
|
34
|
+
## Required Packages
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
37
|
# Database (Prisma 7.x)
|
|
@@ -51,7 +51,7 @@ yarn add @tanstack/react-query
|
|
|
51
51
|
|
|
52
52
|
<project_setup>
|
|
53
53
|
|
|
54
|
-
##
|
|
54
|
+
## Project Structure
|
|
55
55
|
|
|
56
56
|
```
|
|
57
57
|
src/
|
|
@@ -59,8 +59,8 @@ src/
|
|
|
59
59
|
│ ├── __root.tsx # Root Layout
|
|
60
60
|
│ └── index.tsx # Home Page
|
|
61
61
|
├── lib/
|
|
62
|
-
│ └── query-client.ts # Query Client
|
|
63
|
-
└── app.config.ts # TanStack Start
|
|
62
|
+
│ └── query-client.ts # Query Client setup
|
|
63
|
+
└── app.config.ts # TanStack Start config
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
## app.config.ts
|
|
@@ -121,7 +121,7 @@ const HomePage = (): JSX.Element => {
|
|
|
121
121
|
}
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
## Query Client
|
|
124
|
+
## Query Client Setup
|
|
125
125
|
|
|
126
126
|
```typescript
|
|
127
127
|
// src/lib/query-client.ts
|
|
@@ -131,7 +131,7 @@ export const createQueryClient = (): QueryClient => {
|
|
|
131
131
|
return new QueryClient({
|
|
132
132
|
defaultOptions: {
|
|
133
133
|
queries: {
|
|
134
|
-
staleTime: 60 * 1000, // 1
|
|
134
|
+
staleTime: 60 * 1000, // 1 minute
|
|
135
135
|
retry: 1,
|
|
136
136
|
},
|
|
137
137
|
},
|
|
@@ -147,9 +147,9 @@ export const createQueryClient = (): QueryClient => {
|
|
|
147
147
|
|
|
148
148
|
| Command | Description |
|
|
149
149
|
|---------|-------------|
|
|
150
|
-
| `yarn dev` |
|
|
151
|
-
| `yarn build` |
|
|
152
|
-
| `yarn start` |
|
|
150
|
+
| `yarn dev` | Start development server (http://localhost:3000) |
|
|
151
|
+
| `yarn build` | Production build |
|
|
152
|
+
| `yarn start` | Start production server |
|
|
153
153
|
|
|
154
154
|
</commands>
|
|
155
155
|
|
|
@@ -157,13 +157,13 @@ export const createQueryClient = (): QueryClient => {
|
|
|
157
157
|
|
|
158
158
|
<next_steps>
|
|
159
159
|
|
|
160
|
-
|
|
|
160
|
+
| Document | Content |
|
|
161
161
|
|------|------|
|
|
162
|
-
| [conventions.md](./conventions.md) |
|
|
163
|
-
| [env-setup.md](./env-setup.md) |
|
|
164
|
-
| [routes.md](./routes.md) |
|
|
165
|
-
| [services.md](./services.md) | Server Functions,
|
|
166
|
-
| [hooks.md](./hooks.md) | Custom Hook
|
|
162
|
+
| [conventions.md](./conventions.md) | Code conventions, naming rules |
|
|
163
|
+
| [env-setup.md](./env-setup.md) | Environment variable setup |
|
|
164
|
+
| [routes.md](./routes.md) | Route structure, file-based routing |
|
|
165
|
+
| [services.md](./services.md) | Server Functions, data layer |
|
|
166
|
+
| [hooks.md](./hooks.md) | Custom Hook patterns |
|
|
167
167
|
|
|
168
168
|
</next_steps>
|
|
169
169
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Custom Hook
|
|
1
|
+
# Custom Hook Patterns
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Centralize all logic, state, and lifecycle for pages/sections
|
|
4
4
|
|
|
5
5
|
<instructions>
|
|
6
6
|
@../library/tanstack-router/hooks.md
|
|
@@ -10,18 +10,46 @@
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
<mandatory_separation>
|
|
14
|
+
|
|
15
|
+
## ⚠️ Required Rule: Custom Hook Separation
|
|
16
|
+
|
|
17
|
+
**All pages must separate Custom Hooks into `-hooks/` folder.**
|
|
18
|
+
|
|
19
|
+
- Must be separated **regardless of page size** (line count)
|
|
20
|
+
- Even simple 10-line pages require Hook separation
|
|
21
|
+
- Page components should only handle UI rendering
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// ✅ Correct structure
|
|
25
|
+
routes/users/
|
|
26
|
+
├── index.tsx // UI only
|
|
27
|
+
├── -hooks/
|
|
28
|
+
│ └── use-users.ts // All logic
|
|
29
|
+
├── -components/
|
|
30
|
+
└── -functions/
|
|
31
|
+
|
|
32
|
+
// ❌ Wrong structure
|
|
33
|
+
routes/users/
|
|
34
|
+
└── index.tsx // UI + logic mixed
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
</mandatory_separation>
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
13
41
|
<hook_order>
|
|
14
42
|
|
|
15
|
-
## Hook
|
|
43
|
+
## Hook Internal Order (Required)
|
|
16
44
|
|
|
17
|
-
|
|
|
18
|
-
|
|
45
|
+
| Order | Hook Type | Examples |
|
|
46
|
+
|-------|-----------|----------|
|
|
19
47
|
| 1 | State | `useState`, zustand store |
|
|
20
48
|
| 2 | Global Hooks | `useParams`, `useNavigate`, `useQueryClient` |
|
|
21
49
|
| 3 | React Query | `useQuery` → `useMutation` |
|
|
22
50
|
| 4 | Event Handlers | `handleCreate`, `handleDelete` |
|
|
23
|
-
| 5 | useMemo |
|
|
24
|
-
| 6 | useEffect |
|
|
51
|
+
| 5 | useMemo | Computed values |
|
|
52
|
+
| 6 | useEffect | Side effects |
|
|
25
53
|
|
|
26
54
|
</hook_order>
|
|
27
55
|
|
|
@@ -29,7 +57,7 @@
|
|
|
29
57
|
|
|
30
58
|
<patterns>
|
|
31
59
|
|
|
32
|
-
## Page Hook
|
|
60
|
+
## Page Hook Pattern
|
|
33
61
|
|
|
34
62
|
```typescript
|
|
35
63
|
// routes/users/-hooks/use-users.ts
|
|
@@ -131,7 +159,7 @@ export const useUsers = (): UseUsersReturn => {
|
|
|
131
159
|
}
|
|
132
160
|
```
|
|
133
161
|
|
|
134
|
-
## Filter Hook
|
|
162
|
+
## Filter Hook Pattern
|
|
135
163
|
|
|
136
164
|
```typescript
|
|
137
165
|
// routes/users/-hooks/use-user-filter.ts
|
|
@@ -158,7 +186,7 @@ export const useUserFilter = (): UseUserFilterReturn => {
|
|
|
158
186
|
}
|
|
159
187
|
```
|
|
160
188
|
|
|
161
|
-
## Form Hook
|
|
189
|
+
## Form Hook Pattern
|
|
162
190
|
|
|
163
191
|
```typescript
|
|
164
192
|
// routes/users/-hooks/use-user-form.ts
|
|
@@ -227,24 +255,24 @@ export const useUserForm = (): UseUserFormReturn => {
|
|
|
227
255
|
|
|
228
256
|
<anti_patterns>
|
|
229
257
|
|
|
230
|
-
## ❌
|
|
258
|
+
## ❌ Wrong Order
|
|
231
259
|
|
|
232
260
|
```typescript
|
|
233
|
-
// ❌
|
|
261
|
+
// ❌ Mixed order (wrong example)
|
|
234
262
|
export const useBadHook = () => {
|
|
235
|
-
const queryClient = useQueryClient() // ❌ Global Hook
|
|
263
|
+
const queryClient = useQueryClient() // ❌ Global Hook first
|
|
236
264
|
|
|
237
|
-
useEffect(() => { /* ... */ }, []) // ❌ useEffect
|
|
265
|
+
useEffect(() => { /* ... */ }, []) // ❌ useEffect in the middle
|
|
238
266
|
|
|
239
|
-
const [state, setState] = useState() // ❌ State
|
|
267
|
+
const [state, setState] = useState() // ❌ State later
|
|
240
268
|
|
|
241
|
-
const { data } = useQuery({ /* ... */ }) // ❌ Query
|
|
269
|
+
const { data } = useQuery({ /* ... */ }) // ❌ Query after Effect
|
|
242
270
|
|
|
243
|
-
const computed = useMemo(() => {}, []) // ❌ useMemo
|
|
271
|
+
const computed = useMemo(() => {}, []) // ❌ useMemo wrong position
|
|
244
272
|
}
|
|
245
273
|
```
|
|
246
274
|
|
|
247
|
-
## ✅
|
|
275
|
+
## ✅ Correct Order
|
|
248
276
|
|
|
249
277
|
```typescript
|
|
250
278
|
export const useGoodHook = () => {
|
|
@@ -278,12 +306,12 @@ export const useGoodHook = () => {
|
|
|
278
306
|
|
|
279
307
|
## TanStack Router Hooks
|
|
280
308
|
|
|
281
|
-
| Hook |
|
|
282
|
-
|
|
283
|
-
| `useParams` | URL
|
|
284
|
-
| `useNavigate` |
|
|
309
|
+
| Hook | Purpose | Example |
|
|
310
|
+
|------|---------|---------|
|
|
311
|
+
| `useParams` | URL parameters | `const { id } = useParams({ from: '/users/$id' })` |
|
|
312
|
+
| `useNavigate` | Programmatic navigation | `navigate({ to: '/users' })` |
|
|
285
313
|
| `useSearch` | Search params | `const { page } = useSearch({ from: '/users' })` |
|
|
286
|
-
| `useLoaderData` | Loader
|
|
314
|
+
| `useLoaderData` | Loader data | `const user = Route.useLoaderData()` |
|
|
287
315
|
| `useRouteContext` | Route context | `const { auth } = useRouteContext({ from: '__root__' })` |
|
|
288
316
|
|
|
289
317
|
```typescript
|
|
@@ -314,11 +342,11 @@ export const useUserDetail = () => {
|
|
|
314
342
|
|
|
315
343
|
## TanStack Query Hooks
|
|
316
344
|
|
|
317
|
-
| Hook |
|
|
318
|
-
|
|
319
|
-
| `useQuery` |
|
|
320
|
-
| `useMutation` |
|
|
321
|
-
| `useQueryClient` |
|
|
345
|
+
| Hook | Purpose | Features |
|
|
346
|
+
|------|---------|----------|
|
|
347
|
+
| `useQuery` | Data fetching (GET) | Auto caching, revalidation |
|
|
348
|
+
| `useMutation` | Data modification (POST/PUT/DELETE) | Cache invalidation on success |
|
|
349
|
+
| `useQueryClient` | Cache control | `invalidateQueries`, `setQueryData` |
|
|
322
350
|
|
|
323
351
|
```typescript
|
|
324
352
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
|
@@ -350,13 +378,13 @@ export const useUsers = () => {
|
|
|
350
378
|
|
|
351
379
|
<best_practices>
|
|
352
380
|
|
|
353
|
-
|
|
|
354
|
-
|
|
355
|
-
|
|
|
356
|
-
|
|
|
357
|
-
|
|
|
358
|
-
| **useCallback** |
|
|
359
|
-
|
|
|
381
|
+
| Principle | Description |
|
|
382
|
+
|-----------|-------------|
|
|
383
|
+
| **Order Compliance** | State → Global → Query → Handlers → Memo → Effect |
|
|
384
|
+
| **Type Definition** | Explicit return type (interface) |
|
|
385
|
+
| **Single Responsibility** | One Hook, one concern |
|
|
386
|
+
| **useCallback** | Memoize event handlers with useCallback |
|
|
387
|
+
| **Clear Naming** | `use-users.ts`, `use-user-filter.ts` |
|
|
360
388
|
|
|
361
389
|
</best_practices>
|
|
362
390
|
|