@kood/claude-code 0.1.6 → 0.1.9

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 (107) hide show
  1. package/dist/index.js +109 -216
  2. package/package.json +8 -2
  3. package/templates/hono/CLAUDE.md +59 -328
  4. package/templates/hono/docs/architecture/architecture.md +93 -747
  5. package/templates/hono/docs/deployment/cloudflare.md +59 -513
  6. package/templates/hono/docs/deployment/docker.md +41 -356
  7. package/templates/hono/docs/deployment/index.md +54 -190
  8. package/templates/hono/docs/deployment/railway.md +36 -306
  9. package/templates/hono/docs/deployment/vercel.md +49 -434
  10. package/templates/hono/docs/library/ai-sdk/index.md +53 -290
  11. package/templates/hono/docs/library/ai-sdk/openrouter.md +19 -387
  12. package/templates/hono/docs/library/ai-sdk/providers.md +28 -394
  13. package/templates/hono/docs/library/ai-sdk/streaming.md +52 -353
  14. package/templates/hono/docs/library/ai-sdk/structured-output.md +63 -395
  15. package/templates/hono/docs/library/ai-sdk/tools.md +62 -431
  16. package/templates/hono/docs/library/hono/env-setup.md +24 -313
  17. package/templates/hono/docs/library/hono/error-handling.md +34 -295
  18. package/templates/hono/docs/library/hono/index.md +29 -121
  19. package/templates/hono/docs/library/hono/middleware.md +21 -188
  20. package/templates/hono/docs/library/hono/rpc.md +40 -341
  21. package/templates/hono/docs/library/hono/validation.md +35 -195
  22. package/templates/hono/docs/library/pino/index.md +42 -333
  23. package/templates/hono/docs/library/prisma/cloudflare-d1.md +64 -367
  24. package/templates/hono/docs/library/prisma/config.md +19 -260
  25. package/templates/hono/docs/library/prisma/index.md +67 -320
  26. package/templates/hono/docs/library/zod/index.md +53 -257
  27. package/templates/npx/CLAUDE.md +62 -274
  28. package/templates/npx/docs/references/patterns.md +160 -0
  29. package/templates/tanstack-start/CLAUDE.md +100 -256
  30. package/templates/tanstack-start/docs/architecture/architecture.md +44 -589
  31. package/templates/tanstack-start/docs/deployment/cloudflare.md +37 -424
  32. package/templates/tanstack-start/docs/deployment/index.md +57 -286
  33. package/templates/tanstack-start/docs/deployment/nitro.md +36 -318
  34. package/templates/tanstack-start/docs/deployment/railway.md +40 -409
  35. package/templates/tanstack-start/docs/deployment/vercel.md +43 -465
  36. package/templates/tanstack-start/docs/design/components.md +77 -311
  37. package/templates/tanstack-start/docs/design/index.md +113 -69
  38. package/templates/tanstack-start/docs/design/safe-area.md +51 -250
  39. package/templates/tanstack-start/docs/design/tailwind-setup.md +45 -359
  40. package/templates/tanstack-start/docs/guides/conventions.md +103 -0
  41. package/templates/tanstack-start/docs/guides/env-setup.md +34 -340
  42. package/templates/tanstack-start/docs/guides/getting-started.md +22 -209
  43. package/templates/tanstack-start/docs/guides/hooks.md +166 -0
  44. package/templates/tanstack-start/docs/guides/routes.md +166 -0
  45. package/templates/tanstack-start/docs/guides/services.md +143 -0
  46. package/templates/tanstack-start/docs/library/better-auth/2fa.md +27 -115
  47. package/templates/tanstack-start/docs/library/better-auth/advanced.md +22 -105
  48. package/templates/tanstack-start/docs/library/better-auth/index.md +17 -66
  49. package/templates/tanstack-start/docs/library/better-auth/plugins.md +11 -88
  50. package/templates/tanstack-start/docs/library/better-auth/session.md +12 -92
  51. package/templates/tanstack-start/docs/library/better-auth/setup.md +9 -91
  52. package/templates/tanstack-start/docs/library/prisma/cloudflare-d1.md +30 -358
  53. package/templates/tanstack-start/docs/library/prisma/config.md +27 -327
  54. package/templates/tanstack-start/docs/library/prisma/crud.md +46 -174
  55. package/templates/tanstack-start/docs/library/prisma/index.md +23 -113
  56. package/templates/tanstack-start/docs/library/prisma/relations.md +31 -153
  57. package/templates/tanstack-start/docs/library/prisma/schema.md +40 -217
  58. package/templates/tanstack-start/docs/library/prisma/setup.md +12 -112
  59. package/templates/tanstack-start/docs/library/prisma/transactions.md +20 -110
  60. package/templates/tanstack-start/docs/library/tanstack-query/index.md +26 -97
  61. package/templates/tanstack-start/docs/library/tanstack-query/invalidation.md +28 -107
  62. package/templates/tanstack-start/docs/library/tanstack-query/optimistic-updates.md +44 -146
  63. package/templates/tanstack-start/docs/library/tanstack-query/use-mutation.md +33 -127
  64. package/templates/tanstack-start/docs/library/tanstack-query/use-query.md +49 -149
  65. package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +19 -112
  66. package/templates/tanstack-start/docs/library/tanstack-start/index.md +33 -80
  67. package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +28 -106
  68. package/templates/tanstack-start/docs/library/tanstack-start/routing.md +21 -118
  69. package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +34 -246
  70. package/templates/tanstack-start/docs/library/tanstack-start/setup.md +6 -39
  71. package/templates/tanstack-start/docs/library/zod/complex-types.md +32 -156
  72. package/templates/tanstack-start/docs/library/zod/index.md +31 -144
  73. package/templates/tanstack-start/docs/library/zod/transforms.md +20 -129
  74. package/templates/tanstack-start/docs/library/zod/validation.md +39 -155
  75. package/templates/hono/docs/commands/git.md +0 -145
  76. package/templates/hono/docs/mcp/context7.md +0 -106
  77. package/templates/hono/docs/mcp/index.md +0 -176
  78. package/templates/hono/docs/mcp/sequential-thinking.md +0 -101
  79. package/templates/hono/docs/mcp/serena.md +0 -269
  80. package/templates/hono/docs/mcp/sgrep.md +0 -105
  81. package/templates/hono/docs/skills/gemini-review/SKILL.md +0 -220
  82. package/templates/hono/docs/skills/gemini-review/references/checklists.md +0 -136
  83. package/templates/hono/docs/skills/gemini-review/references/prompt-templates.md +0 -303
  84. package/templates/npx/docs/commands/git.md +0 -145
  85. package/templates/npx/docs/mcp/index.md +0 -60
  86. package/templates/npx/docs/skills/gemini-review/SKILL.md +0 -220
  87. package/templates/npx/docs/skills/gemini-review/references/checklists.md +0 -134
  88. package/templates/npx/docs/skills/gemini-review/references/prompt-templates.md +0 -301
  89. package/templates/tanstack-start/docs/commands/git.md +0 -145
  90. package/templates/tanstack-start/docs/design/accessibility.md +0 -433
  91. package/templates/tanstack-start/docs/design/color.md +0 -235
  92. package/templates/tanstack-start/docs/design/spacing.md +0 -341
  93. package/templates/tanstack-start/docs/design/typography.md +0 -324
  94. package/templates/tanstack-start/docs/guides/best-practices.md +0 -950
  95. package/templates/tanstack-start/docs/guides/husky-lint-staged.md +0 -303
  96. package/templates/tanstack-start/docs/guides/prettier.md +0 -189
  97. package/templates/tanstack-start/docs/guides/project-templates.md +0 -710
  98. package/templates/tanstack-start/docs/library/tanstack-query/setup.md +0 -107
  99. package/templates/tanstack-start/docs/library/zod/basic-types.md +0 -186
  100. package/templates/tanstack-start/docs/mcp/context7.md +0 -204
  101. package/templates/tanstack-start/docs/mcp/index.md +0 -177
  102. package/templates/tanstack-start/docs/mcp/sequential-thinking.md +0 -180
  103. package/templates/tanstack-start/docs/mcp/serena.md +0 -269
  104. package/templates/tanstack-start/docs/mcp/sgrep.md +0 -174
  105. package/templates/tanstack-start/docs/skills/gemini-review/SKILL.md +0 -220
  106. package/templates/tanstack-start/docs/skills/gemini-review/references/checklists.md +0 -144
  107. package/templates/tanstack-start/docs/skills/gemini-review/references/prompt-templates.md +0 -292
@@ -1,127 +1,47 @@
1
1
  # Better Auth - 세션 관리
2
2
 
3
- > **상위 문서**: [Better Auth](./index.md)
4
-
5
- ## 세션 설정
6
-
7
- ```typescript
8
- import { betterAuth } from 'better-auth'
9
-
10
- export const auth = betterAuth({
11
- session: {
12
- modelName: 'sessions',
13
- fields: {
14
- userId: 'user_id',
15
- },
16
- expiresIn: 604800, // 7일 (초 단위)
17
- updateAge: 86400, // 1일마다 갱신
18
- additionalFields: {
19
- customField: {
20
- type: 'string',
21
- },
22
- },
23
- },
24
- })
25
- ```
26
-
27
- ## 쿠키 캐시
28
-
29
- 세션 조회 성능 최적화를 위한 쿠키 캐시:
3
+ ## 설정
30
4
 
31
5
  ```typescript
32
6
  export const auth = betterAuth({
33
7
  session: {
8
+ expiresIn: 604800, // 7일 (초)
9
+ updateAge: 86400, // 1일마다 갱신
34
10
  cookieCache: {
35
11
  enabled: true,
36
- maxAge: 5 * 60, // 5분
37
- strategy: 'compact', // 'compact' | 'jwt' | 'jwe'
38
- refreshCache: true,
12
+ maxAge: 5 * 60, // 5분
13
+ strategy: 'compact', // 'compact' | 'jwt' | 'jwe'
39
14
  },
40
15
  },
41
16
  })
42
17
  ```
43
18
 
44
- ## 세션 가져오기
45
-
46
- ### 클라이언트
19
+ ## 세션 조회
47
20
 
48
21
  ```typescript
49
- // 기본
22
+ // 클라이언트
50
23
  const session = await authClient.getSession()
24
+ const session = await authClient.getSession({ query: { disableCookieCache: true } })
51
25
 
52
- // 쿠키 캐시 우회 (DB에서 직접 가져오기)
53
- const session = await authClient.getSession({
54
- query: {
55
- disableCookieCache: true,
56
- },
57
- })
58
- ```
59
-
60
- ### 서버
61
-
62
- ```typescript
63
- await auth.api.getSession({
64
- query: {
65
- disableCookieCache: true,
66
- },
67
- headers: req.headers,
68
- })
26
+ // 서버
27
+ await auth.api.getSession({ headers: req.headers })
69
28
  ```
70
29
 
71
30
  ## Custom Session Plugin
72
31
 
73
- 세션 스키마 확장 및 커스텀 로직 구현:
74
-
75
32
  ```typescript
76
- import { betterAuth } from 'better-auth'
77
33
  import { customSession } from 'better-auth/plugins'
78
34
 
79
35
  export const auth = betterAuth({
80
36
  plugins: [
81
37
  customSession({
82
- // 세션 스키마 확장
83
38
  schema: {
84
- session: {
85
- fields: {
86
- ipAddress: {
87
- type: 'string',
88
- required: false,
89
- },
90
- userAgent: {
91
- type: 'string',
92
- required: false,
93
- },
94
- metadata: {
95
- type: 'json',
96
- required: false,
97
- },
98
- },
99
- },
39
+ session: { fields: { ipAddress: { type: 'string' }, metadata: { type: 'json' } } },
100
40
  },
101
-
102
- // 세션 생성 시 커스터마이즈
103
41
  async onSessionCreate(session, context) {
104
- return {
105
- ...session,
106
- ipAddress: context.request.headers.get('x-forwarded-for'),
107
- userAgent: context.request.headers.get('user-agent'),
108
- metadata: { loginMethod: 'email' },
109
- }
110
- },
111
-
112
- // 세션 조회 시 커스터마이즈
113
- async onSessionGet(session, context) {
114
- return {
115
- ...session,
116
- activeDevices: await getActiveDevices(session.userId),
117
- }
42
+ return { ...session, ipAddress: context.request.headers.get('x-forwarded-for') }
118
43
  },
119
44
  }),
120
45
  ],
121
46
  })
122
-
123
- // 타입 안전한 커스텀 세션 데이터 접근
124
- const session = await auth.api.getSession({ headers })
125
- console.log('IP Address:', session?.ipAddress)
126
- console.log('Metadata:', session?.metadata)
127
47
  ```
@@ -1,123 +1,41 @@
1
1
  # Better Auth - 설치 및 설정
2
2
 
3
- > **상위 문서**: [Better Auth](./index.md)
4
-
5
3
  ## 설치
6
4
 
7
5
  ```bash
8
6
  yarn add better-auth
9
7
  ```
10
8
 
11
- ## 서버 설정
12
-
13
- ### 기본 설정
9
+ ## 서버
14
10
 
15
11
  ```typescript
16
- // lib/auth.ts
17
12
  import { betterAuth } from 'better-auth'
18
13
  import { prismaAdapter } from 'better-auth/adapters/prisma'
19
- import { prisma } from './prisma'
20
-
21
- export const auth = betterAuth({
22
- database: prismaAdapter(prisma),
23
-
24
- // 이메일/비밀번호 인증 활성화
25
- emailAndPassword: {
26
- enabled: true,
27
- requireEmailVerification: false,
28
- },
29
- })
30
- ```
31
-
32
- ### 소셜 로그인 설정
33
-
34
- ```typescript
35
- import { betterAuth } from 'better-auth'
36
14
 
37
15
  export const auth = betterAuth({
38
16
  database: prismaAdapter(prisma),
17
+ emailAndPassword: { enabled: true },
39
18
  socialProviders: {
40
- google: {
41
- clientId: process.env.GOOGLE_CLIENT_ID as string,
42
- clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
43
- },
44
- github: {
45
- clientId: process.env.GITHUB_CLIENT_ID as string,
46
- clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
47
- },
48
- spotify: {
49
- clientId: process.env.SPOTIFY_CLIENT_ID as string,
50
- clientSecret: process.env.SPOTIFY_CLIENT_SECRET as string,
51
- },
19
+ google: { clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET },
20
+ github: { clientId: process.env.GITHUB_CLIENT_ID, clientSecret: process.env.GITHUB_CLIENT_SECRET },
52
21
  },
53
22
  })
54
23
  ```
55
24
 
56
- ## 클라이언트 설정
57
-
58
- ### 기본 클라이언트
59
-
60
- ```typescript
61
- // lib/auth-client.ts
62
- import { createAuthClient } from 'better-auth/client'
63
-
64
- export const authClient = createAuthClient({
65
- // 옵션
66
- })
67
- ```
68
-
69
- ### React 클라이언트
25
+ ## 클라이언트
70
26
 
71
27
  ```typescript
72
28
  import { createAuthClient } from 'better-auth/react'
73
-
74
- export const authClient = createAuthClient({
75
- // 옵션
76
- })
77
- ```
78
-
79
- ### 플러그인 포함 클라이언트
80
-
81
- ```typescript
82
- import { createAuthClient } from 'better-auth/client'
83
29
  import { twoFactorClient } from 'better-auth/client/plugins'
84
30
 
85
- const authClient = createAuthClient({
86
- plugins: [
87
- twoFactorClient({
88
- twoFactorPage: '/two-factor',
89
- onTwoFactorRedirect() {
90
- router.push('/two-factor')
91
- },
92
- }),
93
- ],
31
+ export const authClient = createAuthClient({
32
+ plugins: [twoFactorClient({ twoFactorPage: '/two-factor' })],
94
33
  })
95
34
  ```
96
35
 
97
- ## TanStack Start 통합
36
+ ## TanStack Start 연동
98
37
 
99
38
  ```typescript
100
- // lib/auth.ts
101
- import { betterAuth } from 'better-auth'
102
- import { prismaAdapter } from 'better-auth/adapters/prisma'
103
- import { prisma } from './prisma'
104
-
105
- export const auth = betterAuth({
106
- database: prismaAdapter(prisma),
107
- emailAndPassword: {
108
- enabled: true,
109
- },
110
- })
111
-
112
- // Server Function에서 사용
113
- import { createServerFn } from '@tanstack/react-start'
114
- import { auth } from '@/lib/auth'
115
-
116
39
  export const getSession = createServerFn({ method: 'GET' })
117
- .handler(async ({ request }) => {
118
- const session = await auth.api.getSession({
119
- headers: request.headers,
120
- })
121
- return session
122
- })
40
+ .handler(async ({ request }) => auth.api.getSession({ headers: request.headers }))
123
41
  ```
@@ -1,404 +1,76 @@
1
1
  # Prisma - Cloudflare D1
2
2
 
3
- > **상위 문서**: [Prisma](./index.md)
3
+ SQLite 기반 서버리스 DB. 일반 Prisma 마이그레이션과 다른 워크플로우.
4
4
 
5
- ---
5
+ ⚠️ 트랜잭션 미지원 | prisma migrate 불가 - wrangler 사용 | Preview 상태
6
6
 
7
- ## ⚠️ 주의사항
8
-
9
- Cloudflare D1은 **SQLite 기반 서버리스 데이터베이스**입니다. 일반 Prisma 마이그레이션과 **다른 워크플로우**를 사용합니다.
10
-
11
- ```
12
- ⚠️ D1은 트랜잭션을 지원하지 않음 (ACID 보장 X)
13
- ⚠️ prisma migrate dev 사용 불가 - wrangler CLI 사용
14
- ⚠️ Prisma ORM D1 지원은 Preview 상태
15
- ```
16
-
17
- ---
18
-
19
- ## 🚀 Quick Reference
20
-
21
- ```typescript
22
- // D1 Adapter 설정
23
- import { PrismaClient } from './generated/prisma'
24
- import { PrismaD1 } from '@prisma/adapter-d1'
25
-
26
- export interface Env {
27
- DB: D1Database
28
- }
29
-
30
- export default {
31
- async fetch(request: Request, env: Env): Promise<Response> {
32
- const adapter = new PrismaD1(env.DB)
33
- const prisma = new PrismaClient({ adapter })
34
-
35
- const users = await prisma.user.findMany()
36
- return new Response(JSON.stringify(users))
37
- },
38
- }
39
- ```
40
-
41
- ### schema.prisma (D1용)
7
+ ## 설정
42
8
 
43
9
  ```prisma
10
+ // schema.prisma
44
11
  generator client {
45
12
  provider = "prisma-client"
46
13
  output = "../src/generated/prisma"
47
- runtime = "cloudflare" // D1 필수!
14
+ runtime = "cloudflare" // 필수
48
15
  }
49
16
 
50
17
  datasource db {
51
- provider = "sqlite" // D1은 SQLite 기반
52
- }
53
-
54
- model User {
55
- id Int @id @default(autoincrement())
56
- email String @unique
57
- name String?
18
+ provider = "sqlite"
58
19
  }
59
20
  ```
60
21
 
61
- ---
62
-
63
- ## 설치
64
-
65
- ```bash
66
- # 필수 패키지
67
- npm install @prisma/client @prisma/adapter-d1
68
- npm install -D prisma wrangler
69
-
70
- # Prisma 초기화
71
- npx prisma init --datasource-provider sqlite
72
- ```
73
-
74
- ---
75
-
76
- ## D1 데이터베이스 생성
77
-
78
- ```bash
79
- # Cloudflare D1 데이터베이스 생성
80
- npx wrangler d1 create my-database
81
-
82
- # 출력 예시:
83
- # ✅ Successfully created DB 'my-database'
84
- # database_id = "xxxx-xxxx-xxxx-xxxx"
85
- ```
86
-
87
- ---
88
-
89
- ## wrangler.jsonc 설정
90
-
91
22
  ```jsonc
23
+ // wrangler.jsonc
92
24
  {
93
- "$schema": "node_modules/wrangler/config-schema.json",
94
- "name": "my-worker",
95
- "main": "src/index.ts",
96
- "compatibility_date": "2025-01-01",
97
- "d1_databases": [
98
- {
99
- "binding": "DB",
100
- "database_name": "my-database",
101
- "database_id": "YOUR_DATABASE_ID"
102
- }
103
- ]
25
+ "d1_databases": [{ "binding": "DB", "database_name": "my-db", "database_id": "ID" }]
104
26
  }
105
27
  ```
106
28
 
107
- ---
108
-
109
- ## Schema 설정
110
-
111
- ### schema.prisma
112
-
113
- ```prisma
114
- generator client {
115
- provider = "prisma-client"
116
- output = "../src/generated/prisma"
117
- runtime = "cloudflare"
118
- }
119
-
120
- datasource db {
121
- provider = "sqlite"
122
- }
123
-
124
- model User {
125
- id Int @id @default(autoincrement())
126
- email String @unique
127
- name String?
128
- posts Post[]
129
- }
130
-
131
- model Post {
132
- id Int @id @default(autoincrement())
133
- title String
134
- content String?
135
- published Boolean @default(false)
136
- author User @relation(fields: [authorId], references: [id])
137
- authorId Int
138
- }
139
- ```
140
-
141
- ---
142
-
143
- ## 마이그레이션 워크플로우
144
-
145
- D1은 일반 Prisma 마이그레이션(`prisma migrate dev`)을 사용하지 않습니다.
146
-
147
- ### 1단계: 마이그레이션 디렉토리 생성
148
-
149
- ```bash
150
- mkdir -p prisma/migrations
151
- ```
152
-
153
- ### 2단계: 마이그레이션 파일 생성 (wrangler)
154
-
155
- ```bash
156
- npx wrangler d1 migrations create my-database create_user_table
157
- ```
158
-
159
- ### 3단계: SQL 생성 (prisma migrate diff)
160
-
161
- ```bash
162
- # 초기 마이그레이션 (빈 스키마에서)
163
- npx prisma migrate diff \
164
- --from-empty \
165
- --to-schema-datamodel prisma/schema.prisma \
166
- --script \
167
- --output prisma/migrations/0001_create_user_table.sql
168
-
169
- # 후속 마이그레이션 (로컬 D1에서)
170
- npx prisma migrate diff \
171
- --from-local-d1 \
172
- --to-schema-datamodel prisma/schema.prisma \
173
- --script \
174
- --output prisma/migrations/0002_add_post_table.sql
175
- ```
176
-
177
- ### 4단계: 마이그레이션 적용
178
-
179
- ```bash
180
- # 로컬 데이터베이스에 적용
181
- npx wrangler d1 migrations apply my-database --local
182
-
183
- # 원격(프로덕션) 데이터베이스에 적용
184
- npx wrangler d1 migrations apply my-database --remote
185
- ```
186
-
187
- ### 생성된 SQL 예시
188
-
189
- ```sql
190
- -- 0001_create_user_table.sql
191
- -- CreateTable
192
- CREATE TABLE "User" (
193
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
194
- "email" TEXT NOT NULL,
195
- "name" TEXT
196
- );
197
-
198
- -- CreateIndex
199
- CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
200
- ```
201
-
202
- ---
203
-
204
- ## Prisma Client 설정
205
-
206
- ### Cloudflare Worker에서 사용
29
+ ## 사용법
207
30
 
208
31
  ```typescript
209
- // src/index.ts
210
32
  import { PrismaClient } from './generated/prisma'
211
33
  import { PrismaD1 } from '@prisma/adapter-d1'
212
34
 
213
- export interface Env {
214
- DB: D1Database
215
- }
35
+ export interface Env { DB: D1Database }
216
36
 
217
37
  export default {
218
- async fetch(
219
- request: Request,
220
- env: Env,
221
- ctx: ExecutionContext
222
- ): Promise<Response> {
38
+ async fetch(request: Request, env: Env): Promise<Response> {
223
39
  const adapter = new PrismaD1(env.DB)
224
40
  const prisma = new PrismaClient({ adapter })
225
-
226
- const url = new URL(request.url)
227
-
228
- if (url.pathname === '/users' && request.method === 'GET') {
229
- const users = await prisma.user.findMany()
230
- return new Response(JSON.stringify(users), {
231
- headers: { 'Content-Type': 'application/json' },
232
- })
233
- }
234
-
235
- if (url.pathname === '/users' && request.method === 'POST') {
236
- const body = await request.json()
237
- const user = await prisma.user.create({
238
- data: body,
239
- })
240
- return new Response(JSON.stringify(user), {
241
- status: 201,
242
- headers: { 'Content-Type': 'application/json' },
243
- })
244
- }
245
-
246
- return new Response('Not Found', { status: 404 })
41
+ const users = await prisma.user.findMany()
42
+ return new Response(JSON.stringify(users))
247
43
  },
248
44
  }
249
45
  ```
250
46
 
251
- ---
252
-
253
- ## TanStack Start + D1 통합
254
-
255
- D1은 Cloudflare Workers 환경에서 실행되므로, TanStack Start의 Cloudflare 배포와 함께 사용합니다.
256
-
257
- ### Server Function에서 사용
258
-
259
- ```typescript
260
- // lib/prisma.ts
261
- import { PrismaClient } from './generated/prisma'
262
- import { PrismaD1 } from '@prisma/adapter-d1'
263
-
264
- export const createPrismaClient = (db: D1Database) => {
265
- const adapter = new PrismaD1(db)
266
- return new PrismaClient({ adapter })
267
- }
268
-
269
- // Server Function
270
- import { createServerFn } from '@tanstack/react-start'
271
-
272
- export const getUsers = createServerFn({ method: 'GET' })
273
- .handler(async ({ context }) => {
274
- // context에서 D1 바인딩 접근 필요
275
- const prisma = createPrismaClient(context.env.DB)
276
- return prisma.user.findMany()
277
- })
278
- ```
279
-
280
- ---
281
-
282
- ## 로컬 개발
283
-
284
- ### 로컬 D1로 개발
285
-
286
- ```bash
287
- # 로컬 Worker 실행 (D1 포함)
288
- npx wrangler dev
289
-
290
- # 로컬 D1에 데이터 삽입
291
- npx wrangler d1 execute my-database --local \
292
- --command "INSERT INTO User (email, name) VALUES ('test@example.com', 'Test User');"
293
-
294
- # 로컬 D1 조회
295
- npx wrangler d1 execute my-database --local \
296
- --command "SELECT * FROM User;"
297
- ```
298
-
299
- ---
300
-
301
- ## 배포
302
-
303
- ```bash
304
- # Prisma Client 생성
305
- npx prisma generate
306
-
307
- # 원격 D1에 마이그레이션 적용
308
- npx wrangler d1 migrations apply my-database --remote
309
-
310
- # Worker 배포
311
- npx wrangler deploy
312
- ```
313
-
314
- ---
315
-
316
- ## ⚠️ 제한사항
317
-
318
- ### 트랜잭션 미지원
319
-
320
- ```typescript
321
- // ❌ 트랜잭션이 무시됨 - ACID 보장 안됨
322
- await prisma.$transaction([
323
- prisma.user.create({ data: { email: 'user1@example.com' } }),
324
- prisma.post.create({ data: { title: 'Post', authorId: 1 } }),
325
- ])
326
-
327
- // ❌ Interactive 트랜잭션도 미지원
328
- await prisma.$transaction(async (tx) => {
329
- // 각 쿼리가 독립적으로 실행됨
330
- })
331
- ```
332
-
333
- ### D1 vs 일반 SQLite 차이점
334
-
335
- | 항목 | 일반 SQLite | Cloudflare D1 |
336
- |------|-------------|---------------|
337
- | 마이그레이션 | `prisma migrate dev` | `wrangler d1 migrations` |
338
- | 트랜잭션 | ✅ 지원 | ❌ 미지원 |
339
- | 데이터베이스 위치 | 로컬 파일 | Cloudflare Edge |
340
- | 접속 방식 | 직접 연결 | HTTP (어댑터) |
341
- | 환경 | 로컬 `.wrangler/state` | 원격 Cloudflare |
342
-
343
- ---
344
-
345
- ## prisma.config.ts (선택사항)
346
-
347
- Prisma CLI에서 D1에 직접 접근이 필요한 경우:
348
-
349
- ```typescript
350
- // prisma.config.ts
351
- import path from 'node:path'
352
- import type { PrismaConfig } from 'prisma'
353
- import { PrismaD1 } from '@prisma/adapter-d1'
354
-
355
- export default {
356
- experimental: {
357
- adapter: true,
358
- },
359
- engine: 'js',
360
- schema: path.join('prisma', 'schema.prisma'),
361
- async adapter() {
362
- return new PrismaD1({
363
- CLOUDFLARE_D1_TOKEN: process.env.CLOUDFLARE_D1_TOKEN,
364
- CLOUDFLARE_ACCOUNT_ID: process.env.CLOUDFLARE_ACCOUNT_ID,
365
- CLOUDFLARE_DATABASE_ID: process.env.CLOUDFLARE_DATABASE_ID,
366
- })
367
- },
368
- } satisfies PrismaConfig
369
- ```
370
-
371
- ---
372
-
373
- ## 마이그레이션 명령어 요약
47
+ ## 마이그레이션 워크플로우
374
48
 
375
49
  ```bash
376
- # D1 데이터베이스 생성
50
+ # 1. D1 생성
377
51
  npx wrangler d1 create my-database
378
52
 
379
- # 마이그레이션 파일 생성
380
- npx wrangler d1 migrations create my-database migration_name
53
+ # 2. 마이그레이션 생성
54
+ npx wrangler d1 migrations create my-database init
381
55
 
382
- # SQL 생성 (초기)
383
- npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script
56
+ # 3. SQL 생성 (초기)
57
+ npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script --output prisma/migrations/0001.sql
384
58
 
385
- # SQL 생성 (후속)
59
+ # 4. SQL 생성 (후속)
386
60
  npx prisma migrate diff --from-local-d1 --to-schema-datamodel prisma/schema.prisma --script
387
61
 
388
- # 로컬 적용
389
- npx wrangler d1 migrations apply my-database --local
62
+ # 5. 적용
63
+ npx wrangler d1 migrations apply my-database --local # 로컬
64
+ npx wrangler d1 migrations apply my-database --remote # 프로덕션
390
65
 
391
- # 원격 적용
392
- npx wrangler d1 migrations apply my-database --remote
393
-
394
- # Prisma Client 생성
66
+ # 6. Client 생성
395
67
  npx prisma generate
396
68
  ```
397
69
 
398
- ---
399
-
400
- ## 참고 자료
70
+ ## 제한사항
401
71
 
402
- - [Prisma D1 공식 문서](https://www.prisma.io/docs/orm/overview/databases/cloudflare-d1)
403
- - [Cloudflare D1 문서](https://developers.cloudflare.com/d1/)
404
- - [Prisma D1 가이드](https://www.prisma.io/guides/cloudflare-d1)
72
+ | 항목 | 일반 SQLite | D1 |
73
+ |------|-------------|-----|
74
+ | 마이그레이션 | prisma migrate | wrangler d1 |
75
+ | 트랜잭션 | ✅ | ❌ |
76
+ | 접속 | 직접 | HTTP 어댑터 |