@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,16 +1,16 @@
|
|
|
1
1
|
# t3-env - Type-Safe Environment Variables
|
|
2
2
|
|
|
3
|
-
> Zod
|
|
3
|
+
> Zod-based type-safe environment variable management
|
|
4
4
|
|
|
5
5
|
<context>
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**Purpose:** Server environment variable validation, runtime type safety
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
- Transform &
|
|
12
|
-
-
|
|
13
|
-
-
|
|
9
|
+
**Features:**
|
|
10
|
+
- Validation + type inference with Zod schemas
|
|
11
|
+
- Transform & default value support
|
|
12
|
+
- Runtime validation
|
|
13
|
+
- Framework agnostic
|
|
14
14
|
|
|
15
15
|
</context>
|
|
16
16
|
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
|
|
19
19
|
<forbidden>
|
|
20
20
|
|
|
21
|
-
|
|
|
22
|
-
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
21
|
+
| Category | Prohibited |
|
|
22
|
+
|----------|------------|
|
|
23
|
+
| **Direct Access** | Using `process.env` directly (env object required) |
|
|
24
|
+
| **Types** | Accessing env variables with any type |
|
|
25
|
+
| **Bypass Validation** | Using environment variables without schema definition |
|
|
26
26
|
|
|
27
27
|
</forbidden>
|
|
28
28
|
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
|
|
31
31
|
<required>
|
|
32
32
|
|
|
33
|
-
|
|
|
34
|
-
|
|
35
|
-
|
|
|
36
|
-
|
|
|
33
|
+
| Category | Required |
|
|
34
|
+
|----------|----------|
|
|
35
|
+
| **Installation** | `@t3-oss/env-core zod` |
|
|
36
|
+
| **Structure** | Create `src/env.ts` file |
|
|
37
37
|
| **Import** | `import { env } from '@/env'` |
|
|
38
38
|
|
|
39
39
|
</required>
|
|
@@ -114,7 +114,7 @@ import { env } from '@/env'
|
|
|
114
114
|
|
|
115
115
|
export const prisma = new PrismaClient({
|
|
116
116
|
datasourceUrl: env.DATABASE_URL,
|
|
117
|
-
// ^? string (
|
|
117
|
+
// ^? string (type-safe)
|
|
118
118
|
})
|
|
119
119
|
```
|
|
120
120
|
|
|
@@ -329,7 +329,7 @@ import { createMiddleware } from 'hono/factory'
|
|
|
329
329
|
import { env } from '@/env'
|
|
330
330
|
|
|
331
331
|
export const envMiddleware = createMiddleware(async (c, next) => {
|
|
332
|
-
// env
|
|
332
|
+
// Check if env object is initialized
|
|
333
333
|
if (!env.DATABASE_URL) {
|
|
334
334
|
return c.json({ error: 'Server misconfigured' }, 500)
|
|
335
335
|
}
|
|
@@ -363,10 +363,10 @@ app.use(
|
|
|
363
363
|
|
|
364
364
|
## Tips
|
|
365
365
|
|
|
366
|
-
|
|
|
367
|
-
|
|
368
|
-
| **Cloudflare** | `createWorkerEnv(env)`
|
|
369
|
-
| **Monorepo** |
|
|
366
|
+
| Scenario | Method |
|
|
367
|
+
|----------|--------|
|
|
368
|
+
| **Cloudflare** | Use `createWorkerEnv(env)` pattern |
|
|
369
|
+
| **Monorepo** | Separate `env.ts` per package |
|
|
370
370
|
| **Testing** | `.env.test` + `NODE_ENV=test` |
|
|
371
371
|
| **Docker** | `docker run -e DATABASE_URL=...` |
|
|
372
372
|
| **CI/CD** | GitHub Secrets → Environment Variables |
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
# Zod v4 - Schema Validation
|
|
2
2
|
|
|
3
|
-
> TypeScript-first
|
|
3
|
+
> TypeScript-first schema validation
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Version Notice
|
|
8
8
|
|
|
9
9
|
```typescript
|
|
10
|
-
// ✅ v4
|
|
10
|
+
// ✅ v4 syntax
|
|
11
11
|
z.email()
|
|
12
12
|
z.url()
|
|
13
13
|
z.uuid()
|
|
14
14
|
|
|
15
|
-
// ❌ v3
|
|
15
|
+
// ❌ v3 syntax (prohibited)
|
|
16
16
|
z.string().email()
|
|
17
17
|
z.string().url()
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## Installation
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
npm install zod
|
|
@@ -27,7 +27,7 @@ npm install zod
|
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
##
|
|
30
|
+
## Basic Types
|
|
31
31
|
|
|
32
32
|
```typescript
|
|
33
33
|
import { z } from 'zod'
|
|
@@ -40,28 +40,28 @@ z.undefined()
|
|
|
40
40
|
z.null()
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
###
|
|
43
|
+
### Strings (v4)
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
z.email() //
|
|
46
|
+
z.email() // Email
|
|
47
47
|
z.url() // URL
|
|
48
48
|
z.uuid() // UUID
|
|
49
|
-
z.string().min(1).max(100) //
|
|
50
|
-
z.string().trim() //
|
|
51
|
-
z.string().regex(/^[a-z]+$/) //
|
|
49
|
+
z.string().min(1).max(100) // Length
|
|
50
|
+
z.string().trim() // Trim whitespace
|
|
51
|
+
z.string().regex(/^[a-z]+$/) // Regex
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
###
|
|
54
|
+
### Numbers
|
|
55
55
|
|
|
56
56
|
```typescript
|
|
57
|
-
z.number().int() //
|
|
58
|
-
z.number().positive() //
|
|
57
|
+
z.number().int() // Integer
|
|
58
|
+
z.number().positive() // Positive
|
|
59
59
|
z.number().min(1).max(100)
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
---
|
|
63
63
|
|
|
64
|
-
##
|
|
64
|
+
## Objects
|
|
65
65
|
|
|
66
66
|
```typescript
|
|
67
67
|
const userSchema = z.object({
|
|
@@ -82,7 +82,7 @@ z.string().nullable() // string | null
|
|
|
82
82
|
z.string().nullish() // string | null | undefined
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
###
|
|
85
|
+
### Defaults
|
|
86
86
|
|
|
87
87
|
```typescript
|
|
88
88
|
z.string().default('Anonymous')
|
|
@@ -92,8 +92,8 @@ z.enum(['user', 'admin']).default('user')
|
|
|
92
92
|
### Partial / Pick / Omit
|
|
93
93
|
|
|
94
94
|
```typescript
|
|
95
|
-
userSchema.partial() //
|
|
96
|
-
userSchema.partial({ email: true }) //
|
|
95
|
+
userSchema.partial() // All fields optional
|
|
96
|
+
userSchema.partial({ email: true }) // Specific fields only
|
|
97
97
|
userSchema.pick({ id: true, name: true })
|
|
98
98
|
userSchema.omit({ password: true })
|
|
99
99
|
```
|
|
@@ -118,7 +118,7 @@ z.discriminatedUnion('type', [
|
|
|
118
118
|
|
|
119
119
|
---
|
|
120
120
|
|
|
121
|
-
## Coerce (
|
|
121
|
+
## Coerce (Type Conversion)
|
|
122
122
|
|
|
123
123
|
```typescript
|
|
124
124
|
z.coerce.number() // string → number
|
|
@@ -137,27 +137,27 @@ z.string().transform((s) => s.split(','))
|
|
|
137
137
|
|
|
138
138
|
---
|
|
139
139
|
|
|
140
|
-
## Refine (
|
|
140
|
+
## Refine (Custom Validation)
|
|
141
141
|
|
|
142
142
|
```typescript
|
|
143
|
-
//
|
|
143
|
+
// Single field
|
|
144
144
|
z.string().refine((val) => val.length >= 8, {
|
|
145
|
-
message: '8
|
|
145
|
+
message: 'Must be at least 8 characters',
|
|
146
146
|
})
|
|
147
147
|
|
|
148
|
-
//
|
|
148
|
+
// Entire object
|
|
149
149
|
z.object({
|
|
150
150
|
password: z.string().min(8),
|
|
151
151
|
confirmPassword: z.string(),
|
|
152
152
|
}).refine((data) => data.password === data.confirmPassword, {
|
|
153
|
-
message: '
|
|
153
|
+
message: 'Passwords do not match',
|
|
154
154
|
path: ['confirmPassword'],
|
|
155
155
|
})
|
|
156
156
|
```
|
|
157
157
|
|
|
158
158
|
---
|
|
159
159
|
|
|
160
|
-
##
|
|
160
|
+
## Error Handling
|
|
161
161
|
|
|
162
162
|
```typescript
|
|
163
163
|
const result = schema.safeParse(input)
|
|
@@ -170,16 +170,16 @@ if (result.success) {
|
|
|
170
170
|
}
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
-
###
|
|
173
|
+
### Custom Errors
|
|
174
174
|
|
|
175
175
|
```typescript
|
|
176
|
-
z.email({ message: '
|
|
177
|
-
z.string().min(1, { message: '
|
|
176
|
+
z.email({ message: 'Please enter a valid email' })
|
|
177
|
+
z.string().min(1, { message: 'Required field' })
|
|
178
178
|
```
|
|
179
179
|
|
|
180
180
|
---
|
|
181
181
|
|
|
182
|
-
## Hono
|
|
182
|
+
## Usage with Hono
|
|
183
183
|
|
|
184
184
|
```typescript
|
|
185
185
|
import { zValidator } from '@hono/zod-validator'
|
|
@@ -204,6 +204,6 @@ app.post('/users',
|
|
|
204
204
|
|
|
205
205
|
---
|
|
206
206
|
|
|
207
|
-
##
|
|
207
|
+
## Related Documentation
|
|
208
208
|
|
|
209
|
-
- [Hono
|
|
209
|
+
- [Hono Validation](../hono/validation.md)
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# CLAUDE.md - Next.js
|
|
2
|
+
|
|
3
|
+
> React Full-stack Framework
|
|
4
|
+
|
|
5
|
+
<context>
|
|
6
|
+
|
|
7
|
+
**Purpose:** Next.js App Router-based web application development guidelines
|
|
8
|
+
|
|
9
|
+
**Scope:** Full-stack React application implementation
|
|
10
|
+
|
|
11
|
+
**Key Features:**
|
|
12
|
+
- App Router (file-based routing)
|
|
13
|
+
- Server Actions (type-safe API)
|
|
14
|
+
- Server/Client Components
|
|
15
|
+
- Route Handlers (REST API)
|
|
16
|
+
- Middleware
|
|
17
|
+
- Built-in Optimization (images, fonts, scripts)
|
|
18
|
+
- Deployment (Vercel, Docker, Node.js)
|
|
19
|
+
|
|
20
|
+
</context>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
<instructions>
|
|
25
|
+
@../../commands/git.md
|
|
26
|
+
@docs/library/nextjs/index.md
|
|
27
|
+
@docs/library/tanstack-query/index.md
|
|
28
|
+
@docs/library/prisma/index.md
|
|
29
|
+
@docs/library/next-auth/index.md
|
|
30
|
+
@docs/library/zod/index.md
|
|
31
|
+
@docs/design.md
|
|
32
|
+
</instructions>
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
<forbidden>
|
|
37
|
+
|
|
38
|
+
| Category | Forbidden Actions |
|
|
39
|
+
|----------|-------------------|
|
|
40
|
+
| **Git Commits** | AI markers (`Generated with Claude Code`, `🤖`, `Co-Authored-By:`), multi-line messages, emojis |
|
|
41
|
+
| **Prisma** | Auto-running `db push/migrate/generate`, unauthorized `schema.prisma` modifications |
|
|
42
|
+
| **Server Actions** | Direct definition in client components, usage without try-catch, missing Zod validation (POST/PUT/PATCH) |
|
|
43
|
+
| **Route Handlers** | Creation outside `/app/api/`, creation when Server Actions are suitable |
|
|
44
|
+
| **Client** | Direct Server Action calls (use TanStack Query), missing `"use client"` |
|
|
45
|
+
| **Code Search** | Bash grep/rg/find commands (use ast-grep or dedicated tools) |
|
|
46
|
+
|
|
47
|
+
</forbidden>
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
<required>
|
|
52
|
+
|
|
53
|
+
| Task | Required Actions |
|
|
54
|
+
|------|------------------|
|
|
55
|
+
| **Before Starting** | Read relevant docs (UI → design, API → nextjs, DB → prisma, auth → next-auth) |
|
|
56
|
+
| **Code Search** | Use ast-grep (function/component/pattern search) |
|
|
57
|
+
| **Complex Tasks** | Sequential Thinking MCP (5+ step tasks) |
|
|
58
|
+
| **Large Changes** | gemini-review (3+ file changes, architectural decisions) |
|
|
59
|
+
| **Server Actions** | `"use server"` declaration, Zod validation (POST/PUT/PATCH), try-catch + revalidatePath/redirect |
|
|
60
|
+
| **Client API** | Call Server Actions via TanStack Query (`useQuery`/`useMutation`) |
|
|
61
|
+
| **Custom Hook Order** | State → Global Hooks (useParams, useRouter, useSearchParams) → React Query → Handlers → Memo → Effect |
|
|
62
|
+
| **Code Writing** | UTF-8 encoding, comments per code block, const function declarations |
|
|
63
|
+
| **Prisma** | Multi-File structure (`prisma/schema/`), all elements require comments |
|
|
64
|
+
|
|
65
|
+
</required>
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
<tech_stack>
|
|
70
|
+
|
|
71
|
+
| Technology | Version | Note |
|
|
72
|
+
|------------|---------|------|
|
|
73
|
+
| Next.js | **15.x** | App Router only |
|
|
74
|
+
| React | **19.x** | Server Components |
|
|
75
|
+
| TypeScript | 5.x | strict |
|
|
76
|
+
| Tailwind CSS | 4.x | @theme |
|
|
77
|
+
| Prisma | **7.x** | `prisma-client`, output required |
|
|
78
|
+
| Zod | **4.x** | `z.email()`, `z.url()` |
|
|
79
|
+
| NextAuth.js | **5.x** (Auth.js) | App Router support |
|
|
80
|
+
| TanStack Query | 5.x | - |
|
|
81
|
+
|
|
82
|
+
</tech_stack>
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
<structure>
|
|
87
|
+
```
|
|
88
|
+
src/
|
|
89
|
+
├── app/
|
|
90
|
+
│ ├── layout.tsx # Root layout (required)
|
|
91
|
+
│ ├── page.tsx # Home page
|
|
92
|
+
│ ├── [slug]/
|
|
93
|
+
│ │ ├── page.tsx # Dynamic route
|
|
94
|
+
│ │ └── -components/ # Page-specific Client Components
|
|
95
|
+
│ ├── api/
|
|
96
|
+
│ │ └── [endpoint]/
|
|
97
|
+
│ │ └── route.ts # Route Handler (REST API)
|
|
98
|
+
│ └── _components/ # Shared Client Components
|
|
99
|
+
├── actions/ # Server Actions (shared)
|
|
100
|
+
├── components/ui/ # UI components (Server Components)
|
|
101
|
+
├── middleware.ts # Middleware
|
|
102
|
+
├── database/prisma.ts
|
|
103
|
+
└── lib/
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Required Rules:**
|
|
107
|
+
- Recommended `-components/` folder per page (page-specific Client Components)
|
|
108
|
+
- Server Components by default → use `"use client"` only when necessary
|
|
109
|
+
- Server Actions in `actions/` folder or at file top (`"use server"`)
|
|
110
|
+
- Route Handlers only in `/app/api/` path
|
|
111
|
+
</structure>
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
<conventions>
|
|
116
|
+
|
|
117
|
+
File names: kebab-case, Routes: `page.tsx`, `layout.tsx`, `[slug]/page.tsx`
|
|
118
|
+
TypeScript: const declarations, explicit return types, interface (objects)/type (unions), any→unknown
|
|
119
|
+
Import order: external → @/ → relative → type
|
|
120
|
+
|
|
121
|
+
Prisma Multi-File:
|
|
122
|
+
```
|
|
123
|
+
prisma/schema/
|
|
124
|
+
├── +base.prisma # datasource, generator
|
|
125
|
+
├── +enum.prisma # enum
|
|
126
|
+
└── [model].prisma # per model (with comments!)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
</conventions>
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
<quick_patterns>
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// Server Action (file top)
|
|
137
|
+
"use server"
|
|
138
|
+
|
|
139
|
+
export async function createPost(formData: FormData) {
|
|
140
|
+
const parsed = createPostSchema.parse({
|
|
141
|
+
title: formData.get("title"),
|
|
142
|
+
content: formData.get("content"),
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
const post = await prisma.post.create({ data: parsed })
|
|
146
|
+
revalidatePath("/posts")
|
|
147
|
+
return post
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Server Action (with auth)
|
|
151
|
+
"use server"
|
|
152
|
+
|
|
153
|
+
import { auth } from "@/lib/auth"
|
|
154
|
+
|
|
155
|
+
export async function deletePost(id: string) {
|
|
156
|
+
const session = await auth()
|
|
157
|
+
if (!session?.user) throw new Error("Unauthorized")
|
|
158
|
+
|
|
159
|
+
await prisma.post.delete({ where: { id } })
|
|
160
|
+
revalidatePath("/posts")
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Route Handler (GET)
|
|
164
|
+
export async function GET(request: Request) {
|
|
165
|
+
const { searchParams } = new URL(request.url)
|
|
166
|
+
const id = searchParams.get("id")
|
|
167
|
+
|
|
168
|
+
const posts = await prisma.post.findMany({ where: { id } })
|
|
169
|
+
return Response.json(posts)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Client Component with TanStack Query
|
|
173
|
+
"use client"
|
|
174
|
+
|
|
175
|
+
import { useMutation, useQueryClient } from "@tanstack/react-query"
|
|
176
|
+
import { createPost } from "@/actions/posts"
|
|
177
|
+
|
|
178
|
+
export function CreatePostForm() {
|
|
179
|
+
const queryClient = useQueryClient()
|
|
180
|
+
|
|
181
|
+
const mutation = useMutation({
|
|
182
|
+
mutationFn: createPost,
|
|
183
|
+
onSuccess: () => queryClient.invalidateQueries({ queryKey: ["posts"] }),
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
return <form action={mutation.mutate}>...</form>
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Zod v4
|
|
190
|
+
const schema = z.object({
|
|
191
|
+
email: z.email(),
|
|
192
|
+
name: z.string().min(1).trim(),
|
|
193
|
+
website: z.url().optional(),
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
// Page with Server Component
|
|
197
|
+
export default async function PostsPage() {
|
|
198
|
+
const posts = await prisma.post.findMany()
|
|
199
|
+
return <PostsList posts={posts} />
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
</quick_patterns>
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
<ui_ux>
|
|
208
|
+
|
|
209
|
+
| Principle | Value |
|
|
210
|
+
|-----------|-------|
|
|
211
|
+
| Color | 60-30-10 (background-secondary-accent) |
|
|
212
|
+
| Spacing | 8px grid |
|
|
213
|
+
| Accessibility | WCAG AA (contrast 4.5:1+) |
|
|
214
|
+
| Fonts | 2-3 types |
|
|
215
|
+
| Safe Area | tailwindcss-safe-area |
|
|
216
|
+
|
|
217
|
+
</ui_ux>
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
<docs_structure>
|
|
222
|
+
```
|
|
223
|
+
docs/
|
|
224
|
+
├── guides/ # Getting started, conventions, patterns
|
|
225
|
+
├── library/ # nextjs, prisma, next-auth, tanstack-query, zod
|
|
226
|
+
└── design.md # UI/UX guide
|
|
227
|
+
```
|
|
228
|
+
</docs_structure>
|