@kood/claude-code 0.1.5 → 0.1.7
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 +21 -243
- package/package.json +1 -1
- package/templates/hono/CLAUDE.md +10 -6
- package/templates/hono/docs/deployment/index.md +5 -0
- package/templates/hono/docs/library/hono/index.md +6 -0
- package/templates/hono/docs/library/prisma/index.md +3 -0
- package/templates/npx/CLAUDE.md +8 -2
- package/templates/tanstack-start/CLAUDE.md +105 -259
- package/templates/tanstack-start/docs/deployment/cloudflare.md +37 -424
- package/templates/tanstack-start/docs/deployment/index.md +57 -286
- package/templates/tanstack-start/docs/deployment/nitro.md +36 -318
- package/templates/tanstack-start/docs/deployment/railway.md +40 -409
- package/templates/tanstack-start/docs/deployment/vercel.md +43 -465
- package/templates/tanstack-start/docs/design/accessibility.md +56 -326
- package/templates/tanstack-start/docs/design/color.md +37 -179
- package/templates/tanstack-start/docs/design/components.md +77 -311
- package/templates/tanstack-start/docs/design/index.md +24 -87
- package/templates/tanstack-start/docs/design/safe-area.md +51 -250
- package/templates/tanstack-start/docs/design/spacing.md +57 -276
- package/templates/tanstack-start/docs/design/tailwind-setup.md +45 -359
- package/templates/tanstack-start/docs/design/typography.md +40 -284
- package/templates/tanstack-start/docs/guides/best-practices.md +3 -8
- package/templates/tanstack-start/docs/guides/env-setup.md +3 -3
- package/templates/tanstack-start/docs/library/better-auth/2fa.md +27 -115
- package/templates/tanstack-start/docs/library/better-auth/advanced.md +22 -105
- package/templates/tanstack-start/docs/library/better-auth/index.md +17 -66
- package/templates/tanstack-start/docs/library/better-auth/plugins.md +11 -88
- package/templates/tanstack-start/docs/library/better-auth/session.md +12 -92
- package/templates/tanstack-start/docs/library/better-auth/setup.md +9 -91
- package/templates/tanstack-start/docs/library/prisma/cloudflare-d1.md +30 -358
- package/templates/tanstack-start/docs/library/prisma/config.md +27 -327
- package/templates/tanstack-start/docs/library/prisma/crud.md +46 -174
- package/templates/tanstack-start/docs/library/prisma/index.md +23 -113
- package/templates/tanstack-start/docs/library/prisma/relations.md +31 -153
- package/templates/tanstack-start/docs/library/prisma/schema.md +40 -217
- package/templates/tanstack-start/docs/library/prisma/setup.md +13 -113
- package/templates/tanstack-start/docs/library/prisma/transactions.md +20 -110
- package/templates/tanstack-start/docs/library/tanstack-query/index.md +12 -99
- package/templates/tanstack-start/docs/library/tanstack-query/invalidation.md +28 -107
- package/templates/tanstack-start/docs/library/tanstack-query/optimistic-updates.md +44 -146
- package/templates/tanstack-start/docs/library/tanstack-query/setup.md +11 -73
- package/templates/tanstack-start/docs/library/tanstack-query/use-mutation.md +33 -127
- package/templates/tanstack-start/docs/library/tanstack-query/use-query.md +49 -149
- package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +19 -112
- package/templates/tanstack-start/docs/library/tanstack-start/index.md +33 -80
- package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +28 -106
- package/templates/tanstack-start/docs/library/tanstack-start/routing.md +21 -118
- package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +41 -172
- package/templates/tanstack-start/docs/library/tanstack-start/setup.md +6 -39
- package/templates/tanstack-start/docs/library/zod/basic-types.md +33 -145
- package/templates/tanstack-start/docs/library/zod/complex-types.md +32 -156
- package/templates/tanstack-start/docs/library/zod/index.md +22 -150
- package/templates/tanstack-start/docs/library/zod/transforms.md +20 -129
- package/templates/tanstack-start/docs/library/zod/validation.md +39 -155
- package/templates/hono/docs/commands/git.md +0 -145
- package/templates/hono/docs/mcp/context7.md +0 -106
- package/templates/hono/docs/mcp/index.md +0 -176
- package/templates/hono/docs/mcp/sequential-thinking.md +0 -101
- package/templates/hono/docs/mcp/serena.md +0 -269
- package/templates/hono/docs/mcp/sgrep.md +0 -105
- package/templates/hono/docs/skills/gemini-review/SKILL.md +0 -220
- package/templates/hono/docs/skills/gemini-review/references/checklists.md +0 -136
- package/templates/hono/docs/skills/gemini-review/references/prompt-templates.md +0 -303
- package/templates/npx/docs/commands/git.md +0 -145
- package/templates/npx/docs/mcp/index.md +0 -60
- package/templates/npx/docs/skills/gemini-review/SKILL.md +0 -220
- package/templates/npx/docs/skills/gemini-review/references/checklists.md +0 -134
- package/templates/npx/docs/skills/gemini-review/references/prompt-templates.md +0 -301
- package/templates/tanstack-start/docs/commands/git.md +0 -145
- package/templates/tanstack-start/docs/mcp/context7.md +0 -204
- package/templates/tanstack-start/docs/mcp/index.md +0 -177
- package/templates/tanstack-start/docs/mcp/sequential-thinking.md +0 -180
- package/templates/tanstack-start/docs/mcp/serena.md +0 -269
- package/templates/tanstack-start/docs/mcp/sgrep.md +0 -174
- package/templates/tanstack-start/docs/skills/gemini-review/SKILL.md +0 -220
- package/templates/tanstack-start/docs/skills/gemini-review/references/checklists.md +0 -144
- package/templates/tanstack-start/docs/skills/gemini-review/references/prompt-templates.md +0 -292
|
@@ -2,14 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
> **Version**: 7.x | Node.js/TypeScript ORM
|
|
4
4
|
|
|
5
|
+
@setup.md
|
|
6
|
+
@config.md
|
|
7
|
+
@schema.md
|
|
8
|
+
@crud.md
|
|
9
|
+
@relations.md
|
|
10
|
+
@transactions.md
|
|
11
|
+
@cloudflare-d1.md
|
|
12
|
+
|
|
5
13
|
---
|
|
6
14
|
|
|
7
|
-
##
|
|
15
|
+
## Quick Reference
|
|
8
16
|
|
|
9
17
|
```typescript
|
|
10
|
-
// Prisma Client 설정
|
|
11
18
|
import { PrismaClient } from './generated/prisma' // v7 경로!
|
|
12
|
-
|
|
13
19
|
export const prisma = new PrismaClient()
|
|
14
20
|
|
|
15
21
|
// CRUD
|
|
@@ -36,128 +42,32 @@ generator client {
|
|
|
36
42
|
|
|
37
43
|
### ⛔ Claude Code 금지
|
|
38
44
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
| 금지 사항 |
|
|
46
|
+
|----------|
|
|
47
|
+
| prisma db push 자동 실행 |
|
|
48
|
+
| prisma migrate 자동 실행 |
|
|
49
|
+
| prisma generate 자동 실행 |
|
|
50
|
+
| schema.prisma 임의 변경 |
|
|
45
51
|
|
|
46
52
|
---
|
|
47
53
|
|
|
48
|
-
##
|
|
49
|
-
|
|
50
|
-
- [Config 파일](./config.md) - prisma.config.ts 설정 ⭐
|
|
51
|
-
- [설치 및 설정](./setup.md) - Prisma Client 설정
|
|
52
|
-
- [스키마 정의 (Multi-File)](./schema.md) - 모델, 관계, Enum 정의
|
|
53
|
-
- [CRUD 작업](./crud.md) - Create, Read, Update, Delete
|
|
54
|
-
- [관계 쿼리](./relations.md) - 중첩 생성, 관계 포함 조회
|
|
55
|
-
- [트랜잭션](./transactions.md) - 배열 기반 트랜잭션, 인터랙티브 트랜잭션
|
|
56
|
-
- [Cloudflare D1](./cloudflare-d1.md) - D1 서버리스 데이터베이스 연동
|
|
57
|
-
|
|
58
|
-
## 빠른 시작
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
# npm
|
|
62
|
-
npm install @prisma/client@7
|
|
63
|
-
npm install -D prisma@7
|
|
64
|
-
|
|
65
|
-
# yarn
|
|
66
|
-
yarn add @prisma/client@7
|
|
67
|
-
yarn add -D prisma@7
|
|
68
|
-
|
|
69
|
-
# 초기화
|
|
70
|
-
npx prisma init
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## v7 주요 변경사항
|
|
74
|
-
|
|
75
|
-
### 새로운 Generator Provider
|
|
76
|
-
|
|
77
|
-
```prisma
|
|
78
|
-
// schema.prisma
|
|
79
|
-
generator client {
|
|
80
|
-
provider = "prisma-client" // prisma-client-js → prisma-client
|
|
81
|
-
output = "../generated/prisma" // output 필드 필수
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### 새로운 옵션들
|
|
86
|
-
|
|
87
|
-
```prisma
|
|
88
|
-
generator client {
|
|
89
|
-
provider = "prisma-client"
|
|
90
|
-
output = "../generated/prisma"
|
|
91
|
-
runtime = "nodejs" // nodejs, deno, bun, workerd, vercel-edge, react-native
|
|
92
|
-
moduleFormat = "esm" // esm 또는 cjs
|
|
93
|
-
previewFeatures = ["queryCompiler", "driverAdapters"]
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## 핵심 개념
|
|
98
|
-
|
|
99
|
-
### Prisma Client 설정
|
|
54
|
+
## Prisma Client 설정
|
|
100
55
|
|
|
101
56
|
```typescript
|
|
102
57
|
// lib/prisma.ts
|
|
103
58
|
import { PrismaClient } from './generated/prisma'
|
|
104
59
|
|
|
105
|
-
const globalForPrisma = globalThis as unknown as {
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export const prisma =
|
|
110
|
-
globalForPrisma.prisma ??
|
|
111
|
-
new PrismaClient({
|
|
112
|
-
log: ['query'],
|
|
113
|
-
})
|
|
114
|
-
|
|
60
|
+
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient | undefined }
|
|
61
|
+
export const prisma = globalForPrisma.prisma ?? new PrismaClient({ log: ['query'] })
|
|
115
62
|
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
|
|
116
63
|
```
|
|
117
64
|
|
|
118
|
-
### 기본 쿼리
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
// 조회
|
|
122
|
-
const users = await prisma.user.findMany()
|
|
123
|
-
|
|
124
|
-
// 생성
|
|
125
|
-
const user = await prisma.user.create({
|
|
126
|
-
data: { email: 'alice@prisma.io', name: 'Alice' },
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
// 수정
|
|
130
|
-
const updated = await prisma.user.update({
|
|
131
|
-
where: { id: 1 },
|
|
132
|
-
data: { name: 'Updated Name' },
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
// 삭제
|
|
136
|
-
const deleted = await prisma.user.delete({
|
|
137
|
-
where: { id: 1 },
|
|
138
|
-
})
|
|
139
|
-
```
|
|
140
|
-
|
|
141
65
|
## 마이그레이션 명령어
|
|
142
66
|
|
|
143
67
|
```bash
|
|
144
|
-
# 개발
|
|
145
|
-
npx prisma migrate
|
|
146
|
-
|
|
147
|
-
#
|
|
148
|
-
npx prisma
|
|
149
|
-
|
|
150
|
-
# 스키마 동기화 (개발용)
|
|
151
|
-
npx prisma db push
|
|
152
|
-
|
|
153
|
-
# Prisma Client 생성
|
|
154
|
-
npx prisma generate
|
|
155
|
-
|
|
156
|
-
# Prisma Studio (GUI)
|
|
157
|
-
npx prisma studio
|
|
68
|
+
npx prisma migrate dev --name init # 개발 마이그레이션
|
|
69
|
+
npx prisma migrate deploy # 프로덕션 마이그레이션
|
|
70
|
+
npx prisma db push # 스키마 동기화 (개발용)
|
|
71
|
+
npx prisma generate # Client 생성
|
|
72
|
+
npx prisma studio # GUI
|
|
158
73
|
```
|
|
159
|
-
|
|
160
|
-
## 참고 자료
|
|
161
|
-
|
|
162
|
-
- [Prisma 공식 문서](https://www.prisma.io/docs)
|
|
163
|
-
- [Prisma GitHub](https://github.com/prisma/prisma)
|
|
@@ -1,191 +1,69 @@
|
|
|
1
1
|
# Prisma - 관계 쿼리
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## 중첩 생성 (Nested Create)
|
|
3
|
+
## 중첩 생성
|
|
6
4
|
|
|
7
5
|
```typescript
|
|
8
|
-
const
|
|
6
|
+
const user = await prisma.user.create({
|
|
9
7
|
data: {
|
|
10
|
-
email: '
|
|
11
|
-
|
|
12
|
-
posts: {
|
|
13
|
-
create: [
|
|
14
|
-
{ title: 'How to make an omelette' },
|
|
15
|
-
{ title: 'How to eat an omelette' },
|
|
16
|
-
],
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
include: {
|
|
20
|
-
posts: true,
|
|
8
|
+
email: 'user@prisma.io',
|
|
9
|
+
posts: { create: [{ title: 'Post 1' }, { title: 'Post 2' }] },
|
|
21
10
|
},
|
|
11
|
+
include: { posts: true },
|
|
22
12
|
})
|
|
23
13
|
```
|
|
24
14
|
|
|
25
15
|
## 관계 연결
|
|
26
16
|
|
|
27
|
-
### connect - 기존 레코드 연결
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
const post = await prisma.post.create({
|
|
31
|
-
data: {
|
|
32
|
-
title: 'New Post',
|
|
33
|
-
author: {
|
|
34
|
-
connect: { id: 1 },
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
})
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### connectOrCreate - 있으면 연결, 없으면 생성
|
|
41
|
-
|
|
42
17
|
```typescript
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
title: 'New Post',
|
|
46
|
-
categories: {
|
|
47
|
-
connectOrCreate: {
|
|
48
|
-
where: { name: 'Technology' },
|
|
49
|
-
create: { name: 'Technology' },
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
})
|
|
54
|
-
```
|
|
18
|
+
// connect - 기존 연결
|
|
19
|
+
author: { connect: { id: 1 } }
|
|
55
20
|
|
|
56
|
-
|
|
21
|
+
// connectOrCreate - 있으면 연결, 없으면 생성
|
|
22
|
+
categories: { connectOrCreate: { where: { name: 'Tech' }, create: { name: 'Tech' } } }
|
|
57
23
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
where: { id: 1 },
|
|
61
|
-
data: {
|
|
62
|
-
author: {
|
|
63
|
-
disconnect: true,
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
})
|
|
24
|
+
// disconnect - 관계 해제
|
|
25
|
+
author: { disconnect: true }
|
|
67
26
|
```
|
|
68
27
|
|
|
69
28
|
## 관계 포함 조회
|
|
70
29
|
|
|
71
|
-
### include 사용
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
74
|
-
const users = await prisma.user.findMany({
|
|
75
|
-
include: {
|
|
76
|
-
posts: true,
|
|
77
|
-
profile: true,
|
|
78
|
-
},
|
|
79
|
-
})
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### 중첩 include
|
|
83
|
-
|
|
84
30
|
```typescript
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
posts: {
|
|
88
|
-
include: {
|
|
89
|
-
categories: true,
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
})
|
|
94
|
-
```
|
|
31
|
+
// include
|
|
32
|
+
const users = await prisma.user.findMany({ include: { posts: true, profile: true } })
|
|
95
33
|
|
|
96
|
-
|
|
34
|
+
// 중첩
|
|
35
|
+
include: { posts: { include: { categories: true } } }
|
|
97
36
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
include: {
|
|
101
|
-
posts: {
|
|
102
|
-
where: { published: true },
|
|
103
|
-
orderBy: { createdAt: 'desc' },
|
|
104
|
-
take: 5,
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
})
|
|
37
|
+
// 필터 + 정렬
|
|
38
|
+
include: { posts: { where: { published: true }, orderBy: { createdAt: 'desc' }, take: 5 } }
|
|
108
39
|
```
|
|
109
40
|
|
|
110
41
|
## 관계로 필터링
|
|
111
42
|
|
|
112
|
-
### some - 하나라도 조건 만족
|
|
113
|
-
|
|
114
|
-
```typescript
|
|
115
|
-
const users = await prisma.user.findMany({
|
|
116
|
-
where: {
|
|
117
|
-
posts: {
|
|
118
|
-
some: { published: true },
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
})
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### every - 모두 조건 만족
|
|
125
|
-
|
|
126
43
|
```typescript
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
posts: {
|
|
130
|
-
every: { published: true },
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
})
|
|
134
|
-
```
|
|
44
|
+
// some - 하나라도 만족
|
|
45
|
+
where: { posts: { some: { published: true } } }
|
|
135
46
|
|
|
136
|
-
|
|
47
|
+
// every - 모두 만족
|
|
48
|
+
where: { posts: { every: { published: true } } }
|
|
137
49
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
where: {
|
|
141
|
-
posts: {
|
|
142
|
-
none: { published: false },
|
|
143
|
-
},
|
|
144
|
-
},
|
|
145
|
-
})
|
|
50
|
+
// none - 만족 없음
|
|
51
|
+
where: { posts: { none: { published: false } } }
|
|
146
52
|
```
|
|
147
53
|
|
|
148
|
-
##
|
|
54
|
+
## 카운트
|
|
149
55
|
|
|
150
56
|
```typescript
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
_count: {
|
|
154
|
-
select: { posts: true },
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
// 결과: { id: 1, name: 'Alice', _count: { posts: 5 } }
|
|
57
|
+
include: { _count: { select: { posts: true } } }
|
|
58
|
+
// 결과: { _count: { posts: 5 } }
|
|
160
59
|
```
|
|
161
60
|
|
|
162
|
-
## 중첩
|
|
61
|
+
## 중첩 수정/삭제
|
|
163
62
|
|
|
164
63
|
```typescript
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
data: {
|
|
168
|
-
posts: {
|
|
169
|
-
updateMany: {
|
|
170
|
-
where: { published: false },
|
|
171
|
-
data: { published: true },
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
})
|
|
176
|
-
```
|
|
64
|
+
// updateMany
|
|
65
|
+
posts: { updateMany: { where: { published: false }, data: { published: true } } }
|
|
177
66
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
```typescript
|
|
181
|
-
const user = await prisma.user.update({
|
|
182
|
-
where: { id: 1 },
|
|
183
|
-
data: {
|
|
184
|
-
posts: {
|
|
185
|
-
deleteMany: {
|
|
186
|
-
where: { published: false },
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
},
|
|
190
|
-
})
|
|
67
|
+
// deleteMany
|
|
68
|
+
posts: { deleteMany: { where: { published: false } } }
|
|
191
69
|
```
|
|
@@ -1,275 +1,98 @@
|
|
|
1
1
|
# Prisma - 스키마 정의 (Multi-File)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## ⚠️ 필수 규칙
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
1. **Multi-File 구조** 사용
|
|
6
|
+
2. **모든 요소에 한글 주석** (파일, 모델, 필드, enum)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
## 구조
|
|
8
9
|
|
|
9
10
|
```
|
|
10
|
-
prisma/
|
|
11
|
-
├──
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
│ ├── post.prisma # Post 모델
|
|
16
|
-
│ ├── category.prisma # Category 모델
|
|
17
|
-
│ └── profile.prisma # Profile 모델
|
|
11
|
+
prisma/schema/
|
|
12
|
+
├── +base.prisma # datasource, generator
|
|
13
|
+
├── +enum.prisma # 모든 enum
|
|
14
|
+
├── user.prisma # User 모델
|
|
15
|
+
└── post.prisma # Post 모델
|
|
18
16
|
```
|
|
19
17
|
|
|
20
|
-
##
|
|
21
|
-
|
|
22
|
-
**Prisma Multi-File의 모든 요소에 한글 주석을 작성해야 합니다.**
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
✅ 파일별 목적 주석
|
|
26
|
-
✅ 모델별 설명 주석
|
|
27
|
-
✅ 필드별 설명 주석 (용도가 명확하지 않은 경우)
|
|
28
|
-
✅ 관계 설명 주석
|
|
29
|
-
✅ enum 값 설명 주석
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Multi-File 스키마 예시
|
|
35
|
-
|
|
36
|
-
### +base.prisma (기본 설정)
|
|
18
|
+
## 예시
|
|
37
19
|
|
|
38
20
|
```prisma
|
|
39
|
-
//
|
|
40
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
41
|
-
// Prisma 기본 설정 파일
|
|
42
|
-
// datasource 및 generator 설정
|
|
43
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
44
|
-
|
|
45
|
-
// 데이터베이스 연결 설정
|
|
21
|
+
// +base.prisma
|
|
46
22
|
datasource db {
|
|
47
23
|
provider = "postgresql"
|
|
48
24
|
url = env("DATABASE_URL")
|
|
49
25
|
}
|
|
50
26
|
|
|
51
|
-
// Prisma Client 생성 설정
|
|
52
27
|
generator client {
|
|
53
|
-
provider = "prisma-client"
|
|
28
|
+
provider = "prisma-client"
|
|
54
29
|
output = "../generated/prisma"
|
|
55
30
|
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### +enum.prisma (열거형 정의)
|
|
59
|
-
|
|
60
|
-
```prisma
|
|
61
|
-
// prisma/schema/+enum.prisma
|
|
62
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
63
|
-
// 모든 열거형(enum) 정의 파일
|
|
64
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
65
31
|
|
|
66
|
-
//
|
|
32
|
+
// +enum.prisma
|
|
67
33
|
enum Role {
|
|
68
34
|
USER // 일반 사용자
|
|
69
35
|
ADMIN // 관리자
|
|
70
36
|
}
|
|
71
37
|
|
|
72
|
-
//
|
|
73
|
-
enum PostStatus {
|
|
74
|
-
DRAFT // 임시저장
|
|
75
|
-
PUBLISHED // 공개됨
|
|
76
|
-
ARCHIVED // 보관됨
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### user.prisma (User 모델)
|
|
81
|
-
|
|
82
|
-
```prisma
|
|
83
|
-
// prisma/schema/user.prisma
|
|
84
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
85
|
-
// 사용자 모델
|
|
86
|
-
// 시스템의 모든 사용자 정보를 저장
|
|
87
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
88
|
-
|
|
38
|
+
// user.prisma
|
|
89
39
|
model User {
|
|
90
|
-
id
|
|
91
|
-
email
|
|
92
|
-
name
|
|
93
|
-
role
|
|
94
|
-
posts
|
|
95
|
-
profile
|
|
96
|
-
createdAt
|
|
97
|
-
updatedAt
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### post.prisma (Post 모델)
|
|
102
|
-
|
|
103
|
-
```prisma
|
|
104
|
-
// prisma/schema/post.prisma
|
|
105
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
106
|
-
// 게시글 모델
|
|
107
|
-
// 사용자가 작성한 게시글 정보
|
|
108
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
109
|
-
|
|
110
|
-
model Post {
|
|
111
|
-
id Int @id @default(autoincrement())
|
|
112
|
-
title String // 게시글 제목
|
|
113
|
-
content String? // 게시글 본문 (선택)
|
|
114
|
-
published Boolean @default(false) // 공개 여부
|
|
115
|
-
status PostStatus @default(DRAFT) // 게시글 상태
|
|
116
|
-
author User @relation(fields: [authorId], references: [id]) // 작성자 관계
|
|
117
|
-
authorId Int // 작성자 ID (외래키)
|
|
118
|
-
categories Category[] // 소속 카테고리 목록 (M:N)
|
|
119
|
-
createdAt DateTime @default(now())
|
|
120
|
-
updatedAt DateTime @updatedAt
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### category.prisma (Category 모델)
|
|
125
|
-
|
|
126
|
-
```prisma
|
|
127
|
-
// prisma/schema/category.prisma
|
|
128
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
129
|
-
// 카테고리 모델
|
|
130
|
-
// 게시글 분류를 위한 카테고리
|
|
131
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
132
|
-
|
|
133
|
-
model Category {
|
|
134
|
-
id Int @id @default(autoincrement())
|
|
135
|
-
name String @unique // 카테고리명 (중복 불가)
|
|
136
|
-
posts Post[] // 소속 게시글 목록 (M:N)
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### profile.prisma (Profile 모델)
|
|
141
|
-
|
|
142
|
-
```prisma
|
|
143
|
-
// prisma/schema/profile.prisma
|
|
144
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
145
|
-
// 확장 프로필 모델
|
|
146
|
-
// 사용자의 추가 정보 (1:1 관계)
|
|
147
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
148
|
-
|
|
149
|
-
model ExtendedProfile {
|
|
150
|
-
id Int @id @default(autoincrement())
|
|
151
|
-
biography String // 자기소개
|
|
152
|
-
user User @relation(fields: [userId], references: [id]) // 사용자 관계
|
|
153
|
-
userId Int @unique // 사용자 ID (외래키, 유니크)
|
|
154
|
-
}
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
## 선택적 관계
|
|
160
|
-
|
|
161
|
-
```prisma
|
|
162
|
-
model Post {
|
|
163
|
-
id Int @id @default(autoincrement())
|
|
164
|
-
author User? @relation(fields: [authorId], references: [id])
|
|
165
|
-
authorId Int?
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
## 커스텀 필드/모델명 매핑
|
|
170
|
-
|
|
171
|
-
```prisma
|
|
172
|
-
model User {
|
|
173
|
-
id Int @id @default(autoincrement()) @map("user_id")
|
|
174
|
-
email String @unique
|
|
175
|
-
|
|
176
|
-
@@map("users")
|
|
40
|
+
id Int @id @default(autoincrement())
|
|
41
|
+
email String @unique // 로그인 이메일
|
|
42
|
+
name String? // 표시 이름
|
|
43
|
+
role Role @default(USER)
|
|
44
|
+
posts Post[] // 작성 게시글 (1:N)
|
|
45
|
+
profile Profile? // 프로필 (1:1)
|
|
46
|
+
createdAt DateTime @default(now())
|
|
47
|
+
updatedAt DateTime @updatedAt
|
|
177
48
|
}
|
|
178
49
|
```
|
|
179
50
|
|
|
180
51
|
## 관계 유형
|
|
181
52
|
|
|
182
|
-
### 1:1 관계
|
|
183
|
-
|
|
184
53
|
```prisma
|
|
185
|
-
|
|
186
|
-
id Int @id @default(autoincrement())
|
|
187
|
-
profile Profile?
|
|
188
|
-
}
|
|
189
|
-
|
|
54
|
+
// 1:1
|
|
190
55
|
model Profile {
|
|
191
56
|
id Int @id @default(autoincrement())
|
|
192
57
|
user User @relation(fields: [userId], references: [id])
|
|
193
58
|
userId Int @unique
|
|
194
59
|
}
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### 1:N 관계
|
|
198
|
-
|
|
199
|
-
```prisma
|
|
200
|
-
model User {
|
|
201
|
-
id Int @id @default(autoincrement())
|
|
202
|
-
posts Post[]
|
|
203
|
-
}
|
|
204
60
|
|
|
61
|
+
// 1:N
|
|
205
62
|
model Post {
|
|
206
|
-
id Int @id @default(autoincrement())
|
|
207
63
|
author User @relation(fields: [authorId], references: [id])
|
|
208
64
|
authorId Int
|
|
209
65
|
}
|
|
210
|
-
```
|
|
211
66
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
model Post {
|
|
216
|
-
id Int @id @default(autoincrement())
|
|
217
|
-
categories Category[]
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
model Category {
|
|
221
|
-
id Int @id @default(autoincrement())
|
|
222
|
-
posts Post[]
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### M:N 관계 (명시적)
|
|
227
|
-
|
|
228
|
-
```prisma
|
|
229
|
-
model Post {
|
|
230
|
-
id Int @id @default(autoincrement())
|
|
231
|
-
categories CategoriesOnPosts[]
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
model Category {
|
|
235
|
-
id Int @id @default(autoincrement())
|
|
236
|
-
posts CategoriesOnPosts[]
|
|
237
|
-
}
|
|
67
|
+
// M:N (암묵적)
|
|
68
|
+
model Post { categories Category[] }
|
|
69
|
+
model Category { posts Post[] }
|
|
238
70
|
|
|
71
|
+
// M:N (명시적)
|
|
239
72
|
model CategoriesOnPosts {
|
|
240
73
|
post Post @relation(fields: [postId], references: [id])
|
|
241
74
|
postId Int
|
|
242
75
|
category Category @relation(fields: [categoryId], references: [id])
|
|
243
76
|
categoryId Int
|
|
244
|
-
assignedAt DateTime @default(now())
|
|
245
|
-
|
|
246
77
|
@@id([postId, categoryId])
|
|
247
78
|
}
|
|
248
79
|
```
|
|
249
80
|
|
|
250
|
-
##
|
|
81
|
+
## 기타
|
|
251
82
|
|
|
252
83
|
```prisma
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
content String?
|
|
257
|
-
authorId Int
|
|
258
|
-
createdAt DateTime @default(now())
|
|
84
|
+
// 선택적 관계
|
|
85
|
+
author User? @relation(fields: [authorId], references: [id])
|
|
86
|
+
authorId Int?
|
|
259
87
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
```
|
|
88
|
+
// 인덱스
|
|
89
|
+
@@index([authorId])
|
|
90
|
+
@@index([createdAt])
|
|
265
91
|
|
|
266
|
-
|
|
92
|
+
// 복합 키
|
|
93
|
+
@@id([postId, tagId])
|
|
267
94
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
tagId Int
|
|
272
|
-
|
|
273
|
-
@@id([postId, tagId])
|
|
274
|
-
}
|
|
95
|
+
// 매핑
|
|
96
|
+
@map("user_id")
|
|
97
|
+
@@map("users")
|
|
275
98
|
```
|