@einja/dev-cli 0.1.6

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 (243) hide show
  1. package/README.md +179 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +49 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/init.d.ts +3 -0
  7. package/dist/commands/init.d.ts.map +1 -0
  8. package/dist/commands/init.js +243 -0
  9. package/dist/commands/init.js.map +1 -0
  10. package/dist/commands/list.d.ts +2 -0
  11. package/dist/commands/list.d.ts.map +1 -0
  12. package/dist/commands/list.js +23 -0
  13. package/dist/commands/list.js.map +1 -0
  14. package/dist/commands/sync.d.ts +7 -0
  15. package/dist/commands/sync.d.ts.map +1 -0
  16. package/dist/commands/sync.js +294 -0
  17. package/dist/commands/sync.js.map +1 -0
  18. package/dist/commands/sync.test.d.ts +2 -0
  19. package/dist/commands/sync.test.d.ts.map +1 -0
  20. package/dist/commands/sync.test.js +593 -0
  21. package/dist/commands/sync.test.js.map +1 -0
  22. package/dist/commands/task-loop.d.ts +11 -0
  23. package/dist/commands/task-loop.d.ts.map +1 -0
  24. package/dist/commands/task-loop.js +81 -0
  25. package/dist/commands/task-loop.js.map +1 -0
  26. package/dist/index.d.ts +4 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +3 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/lib/file-system.d.ts +39 -0
  31. package/dist/lib/file-system.d.ts.map +1 -0
  32. package/dist/lib/file-system.js +79 -0
  33. package/dist/lib/file-system.js.map +1 -0
  34. package/dist/lib/mcp-config.d.ts +43 -0
  35. package/dist/lib/mcp-config.d.ts.map +1 -0
  36. package/dist/lib/mcp-config.js +109 -0
  37. package/dist/lib/mcp-config.js.map +1 -0
  38. package/dist/lib/mcp-config.test.d.ts +2 -0
  39. package/dist/lib/mcp-config.test.d.ts.map +1 -0
  40. package/dist/lib/mcp-config.test.js +285 -0
  41. package/dist/lib/mcp-config.test.js.map +1 -0
  42. package/dist/lib/merger.d.ts +41 -0
  43. package/dist/lib/merger.d.ts.map +1 -0
  44. package/dist/lib/merger.js +164 -0
  45. package/dist/lib/merger.js.map +1 -0
  46. package/dist/lib/preset-update/cli-repo-detector.d.ts +35 -0
  47. package/dist/lib/preset-update/cli-repo-detector.d.ts.map +1 -0
  48. package/dist/lib/preset-update/cli-repo-detector.js +83 -0
  49. package/dist/lib/preset-update/cli-repo-detector.js.map +1 -0
  50. package/dist/lib/preset-update/cli-repo-detector.test.d.ts +2 -0
  51. package/dist/lib/preset-update/cli-repo-detector.test.d.ts.map +1 -0
  52. package/dist/lib/preset-update/cli-repo-detector.test.js +120 -0
  53. package/dist/lib/preset-update/cli-repo-detector.test.js.map +1 -0
  54. package/dist/lib/preset-update/file-copier.d.ts +59 -0
  55. package/dist/lib/preset-update/file-copier.d.ts.map +1 -0
  56. package/dist/lib/preset-update/file-copier.js +220 -0
  57. package/dist/lib/preset-update/file-copier.js.map +1 -0
  58. package/dist/lib/preset-update/file-copier.test.d.ts +2 -0
  59. package/dist/lib/preset-update/file-copier.test.d.ts.map +1 -0
  60. package/dist/lib/preset-update/file-copier.test.js +297 -0
  61. package/dist/lib/preset-update/file-copier.test.js.map +1 -0
  62. package/dist/lib/preset-update/preset-finder.d.ts +39 -0
  63. package/dist/lib/preset-update/preset-finder.d.ts.map +1 -0
  64. package/dist/lib/preset-update/preset-finder.js +92 -0
  65. package/dist/lib/preset-update/preset-finder.js.map +1 -0
  66. package/dist/lib/preset-update/preset-finder.test.d.ts +2 -0
  67. package/dist/lib/preset-update/preset-finder.test.d.ts.map +1 -0
  68. package/dist/lib/preset-update/preset-finder.test.js +128 -0
  69. package/dist/lib/preset-update/preset-finder.test.js.map +1 -0
  70. package/dist/lib/preset.d.ts +14 -0
  71. package/dist/lib/preset.d.ts.map +1 -0
  72. package/dist/lib/preset.js +52 -0
  73. package/dist/lib/preset.js.map +1 -0
  74. package/dist/lib/sync/backup-manager.d.ts +50 -0
  75. package/dist/lib/sync/backup-manager.d.ts.map +1 -0
  76. package/dist/lib/sync/backup-manager.js +117 -0
  77. package/dist/lib/sync/backup-manager.js.map +1 -0
  78. package/dist/lib/sync/backup-manager.test.d.ts +2 -0
  79. package/dist/lib/sync/backup-manager.test.d.ts.map +1 -0
  80. package/dist/lib/sync/backup-manager.test.js +155 -0
  81. package/dist/lib/sync/backup-manager.test.js.map +1 -0
  82. package/dist/lib/sync/batch-processor.d.ts +27 -0
  83. package/dist/lib/sync/batch-processor.d.ts.map +1 -0
  84. package/dist/lib/sync/batch-processor.js +46 -0
  85. package/dist/lib/sync/batch-processor.js.map +1 -0
  86. package/dist/lib/sync/batch-processor.test.d.ts +2 -0
  87. package/dist/lib/sync/batch-processor.test.d.ts.map +1 -0
  88. package/dist/lib/sync/batch-processor.test.js +110 -0
  89. package/dist/lib/sync/batch-processor.test.js.map +1 -0
  90. package/dist/lib/sync/category-validator.d.ts +36 -0
  91. package/dist/lib/sync/category-validator.d.ts.map +1 -0
  92. package/dist/lib/sync/category-validator.js +46 -0
  93. package/dist/lib/sync/category-validator.js.map +1 -0
  94. package/dist/lib/sync/category-validator.test.d.ts +2 -0
  95. package/dist/lib/sync/category-validator.test.d.ts.map +1 -0
  96. package/dist/lib/sync/category-validator.test.js +89 -0
  97. package/dist/lib/sync/category-validator.test.js.map +1 -0
  98. package/dist/lib/sync/conflict-reporter.d.ts +57 -0
  99. package/dist/lib/sync/conflict-reporter.d.ts.map +1 -0
  100. package/dist/lib/sync/conflict-reporter.js +81 -0
  101. package/dist/lib/sync/conflict-reporter.js.map +1 -0
  102. package/dist/lib/sync/conflict-reporter.test.d.ts +2 -0
  103. package/dist/lib/sync/conflict-reporter.test.d.ts.map +1 -0
  104. package/dist/lib/sync/conflict-reporter.test.js +132 -0
  105. package/dist/lib/sync/conflict-reporter.test.js.map +1 -0
  106. package/dist/lib/sync/diff-engine.d.ts +28 -0
  107. package/dist/lib/sync/diff-engine.d.ts.map +1 -0
  108. package/dist/lib/sync/diff-engine.js +118 -0
  109. package/dist/lib/sync/diff-engine.js.map +1 -0
  110. package/dist/lib/sync/diff-engine.test.d.ts +2 -0
  111. package/dist/lib/sync/diff-engine.test.d.ts.map +1 -0
  112. package/dist/lib/sync/diff-engine.test.js +133 -0
  113. package/dist/lib/sync/diff-engine.test.js.map +1 -0
  114. package/dist/lib/sync/file-filter.d.ts +40 -0
  115. package/dist/lib/sync/file-filter.d.ts.map +1 -0
  116. package/dist/lib/sync/file-filter.js +171 -0
  117. package/dist/lib/sync/file-filter.js.map +1 -0
  118. package/dist/lib/sync/file-filter.test.d.ts +2 -0
  119. package/dist/lib/sync/file-filter.test.d.ts.map +1 -0
  120. package/dist/lib/sync/file-filter.test.js +179 -0
  121. package/dist/lib/sync/file-filter.test.js.map +1 -0
  122. package/dist/lib/sync/hash-cache.d.ts +34 -0
  123. package/dist/lib/sync/hash-cache.d.ts.map +1 -0
  124. package/dist/lib/sync/hash-cache.js +51 -0
  125. package/dist/lib/sync/hash-cache.js.map +1 -0
  126. package/dist/lib/sync/hash-cache.test.d.ts +2 -0
  127. package/dist/lib/sync/hash-cache.test.d.ts.map +1 -0
  128. package/dist/lib/sync/hash-cache.test.js +110 -0
  129. package/dist/lib/sync/hash-cache.test.js.map +1 -0
  130. package/dist/lib/sync/integration.test.d.ts +2 -0
  131. package/dist/lib/sync/integration.test.d.ts.map +1 -0
  132. package/dist/lib/sync/integration.test.js +317 -0
  133. package/dist/lib/sync/integration.test.js.map +1 -0
  134. package/dist/lib/sync/marker-processor.d.ts +54 -0
  135. package/dist/lib/sync/marker-processor.d.ts.map +1 -0
  136. package/dist/lib/sync/marker-processor.js +208 -0
  137. package/dist/lib/sync/marker-processor.js.map +1 -0
  138. package/dist/lib/sync/marker-processor.test.d.ts +2 -0
  139. package/dist/lib/sync/marker-processor.test.d.ts.map +1 -0
  140. package/dist/lib/sync/marker-processor.test.js +245 -0
  141. package/dist/lib/sync/marker-processor.test.js.map +1 -0
  142. package/dist/lib/sync/metadata-manager.d.ts +46 -0
  143. package/dist/lib/sync/metadata-manager.d.ts.map +1 -0
  144. package/dist/lib/sync/metadata-manager.js +129 -0
  145. package/dist/lib/sync/metadata-manager.js.map +1 -0
  146. package/dist/lib/sync/metadata-manager.test.d.ts +2 -0
  147. package/dist/lib/sync/metadata-manager.test.d.ts.map +1 -0
  148. package/dist/lib/sync/metadata-manager.test.js +137 -0
  149. package/dist/lib/sync/metadata-manager.test.js.map +1 -0
  150. package/dist/lib/sync/performance.test.d.ts +2 -0
  151. package/dist/lib/sync/performance.test.d.ts.map +1 -0
  152. package/dist/lib/sync/performance.test.js +126 -0
  153. package/dist/lib/sync/performance.test.js.map +1 -0
  154. package/dist/types/index.d.ts +59 -0
  155. package/dist/types/index.d.ts.map +1 -0
  156. package/dist/types/index.js +2 -0
  157. package/dist/types/index.js.map +1 -0
  158. package/dist/types/preset-update.d.ts +106 -0
  159. package/dist/types/preset-update.d.ts.map +1 -0
  160. package/dist/types/preset-update.js +5 -0
  161. package/dist/types/preset-update.js.map +1 -0
  162. package/dist/types/sync.d.ts +169 -0
  163. package/dist/types/sync.d.ts.map +1 -0
  164. package/dist/types/sync.js +19 -0
  165. package/dist/types/sync.js.map +1 -0
  166. package/package.json +72 -0
  167. package/presets/minimal/.claude/agents/einja/docs/docs-updater.md +161 -0
  168. package/presets/minimal/.claude/agents/einja/frontend/design-engineer.md +685 -0
  169. package/presets/minimal/.claude/agents/einja/frontend/frontend-architect.md +747 -0
  170. package/presets/minimal/.claude/agents/einja/frontend/frontend-coder.md +441 -0
  171. package/presets/minimal/.claude/agents/einja/git/conflict-resolver.md +148 -0
  172. package/presets/minimal/.claude/agents/einja/specs/spec-design-generator.md +462 -0
  173. package/presets/minimal/.claude/agents/einja/specs/spec-qa-generator.md +466 -0
  174. package/presets/minimal/.claude/agents/einja/specs/spec-requirements-generator.md +416 -0
  175. package/presets/minimal/.claude/agents/einja/specs/spec-tasks-generator.md +608 -0
  176. package/presets/minimal/.claude/agents/einja/task/task-committer.md +82 -0
  177. package/presets/minimal/.claude/agents/einja/task/task-executer.md +352 -0
  178. package/presets/minimal/.claude/agents/einja/task/task-modification-analyzer.md +369 -0
  179. package/presets/minimal/.claude/agents/einja/task/task-qa.md +74 -0
  180. package/presets/minimal/.claude/agents/einja/task/task-reviewer.md +169 -0
  181. package/presets/minimal/.claude/commands/einja/frontend-implement.md +322 -0
  182. package/presets/minimal/.claude/commands/einja/spec-create.md +254 -0
  183. package/presets/minimal/.claude/commands/einja/start-dev.md +98 -0
  184. package/presets/minimal/.claude/commands/einja/sync-cursor-commands.md +203 -0
  185. package/presets/minimal/.claude/commands/einja/task-exec.md +390 -0
  186. package/presets/minimal/.claude/commands/einja/update-docs-by-task-specs.md +448 -0
  187. package/presets/minimal/.claude/hooks/einja/biome-format.sh +49 -0
  188. package/presets/minimal/.claude/hooks/einja/design-doc-check.sh +61 -0
  189. package/presets/minimal/.claude/hooks/einja/detect-secrets.sh +62 -0
  190. package/presets/minimal/.claude/hooks/einja/large-file-warning.sh +42 -0
  191. package/presets/minimal/.claude/hooks/einja/playwright-resize.sh +36 -0
  192. package/presets/minimal/.claude/hooks/einja/typecheck.sh +37 -0
  193. package/presets/minimal/.claude/hooks/einja/unset-volta-recursion.sh +32 -0
  194. package/presets/minimal/.claude/hooks/einja/validate-git-commit.sh +239 -0
  195. package/presets/minimal/.claude/hooks/einja/warn-index-ts.sh +34 -0
  196. package/presets/minimal/.claude/hooks/einja/warn-relative-import.sh +48 -0
  197. package/presets/minimal/.claude/settings.json +174 -0
  198. package/presets/minimal/.claude/skills/einja/api-development/SKILL.md +14 -0
  199. package/presets/minimal/.claude/skills/einja/backend-architecture/SKILL.md +14 -0
  200. package/presets/minimal/.claude/skills/einja/coding-standards/SKILL.md +120 -0
  201. package/presets/minimal/.claude/skills/einja/coding-standards/reference/naming-conventions.md +107 -0
  202. package/presets/minimal/.claude/skills/einja/coding-standards/reference/prohibited-patterns.md +169 -0
  203. package/presets/minimal/.claude/skills/einja/coding-standards/reference/typescript-rules.md +247 -0
  204. package/presets/minimal/.claude/skills/einja/component-design/SKILL.md +109 -0
  205. package/presets/minimal/.claude/skills/einja/component-design/reference/directory-structure.md +117 -0
  206. package/presets/minimal/.claude/skills/einja/component-design/reference/props-patterns.md +159 -0
  207. package/presets/minimal/.claude/skills/einja/component-design/reference/styling-guide.md +200 -0
  208. package/presets/minimal/.claude/skills/einja/conflict-resolver/SKILL.md +190 -0
  209. package/presets/minimal/.claude/skills/einja/frontend-development/SKILL.md +14 -0
  210. package/presets/minimal/.claude/skills/einja/general-context-loader/SKILL.md +254 -0
  211. package/presets/minimal/.claude/skills/einja/output-format/SKILL.md +137 -0
  212. package/presets/minimal/.claude/skills/einja/spec-context-loader/SKILL.md +177 -0
  213. package/presets/minimal/.claude/skills/einja/task-commit/SKILL.md +269 -0
  214. package/presets/minimal/.claude/skills/einja/task-qa/SKILL.md +306 -0
  215. package/presets/minimal/.claude/skills/einja/task-qa/reference/failure-patterns.md +69 -0
  216. package/presets/minimal/.claude/skills/einja/task-qa/reference/troubleshooting.md +65 -0
  217. package/presets/minimal/.claude/skills/einja/task-qa/reference/usage-patterns.md +52 -0
  218. package/presets/minimal/.claude/skills/einja/task-qa/templates/qa-test-template.md +128 -0
  219. package/presets/minimal/preset.yaml +111 -0
  220. package/presets/minimal/symlinks.json +45 -0
  221. package/scaffolds/.mcp.json +45 -0
  222. package/scaffolds/CLAUDE.md.template +318 -0
  223. package/scaffolds/steering/README.md +170 -0
  224. package/scaffolds/steering/acceptance-criteria-and-qa-guide.md +415 -0
  225. package/scaffolds/steering/architecture.md +481 -0
  226. package/scaffolds/steering/branch-strategy.md +362 -0
  227. package/scaffolds/steering/commit-rules.md +217 -0
  228. package/scaffolds/steering/db-schema-design.md +609 -0
  229. package/scaffolds/steering/development/api-development.md +783 -0
  230. package/scaffolds/steering/development/backend-architecture.md +731 -0
  231. package/scaffolds/steering/development/frontend-development.md +1537 -0
  232. package/scaffolds/steering/development/review-guidelines.md +365 -0
  233. package/scaffolds/steering/development/testing-strategy.md +819 -0
  234. package/scaffolds/steering/development-workflow.md +429 -0
  235. package/scaffolds/steering/infrastructure/deployment.md +277 -0
  236. package/scaffolds/steering/infrastructure/environment-variables.md +298 -0
  237. package/scaffolds/steering/product.md +540 -0
  238. package/scaffolds/steering/task-management.md +367 -0
  239. package/templates/README.md +159 -0
  240. package/templates/design-simple.md.template +172 -0
  241. package/templates/design.md.template +327 -0
  242. package/templates/qa-test.md.template +125 -0
  243. package/templates/requirements.md.template +254 -0
@@ -0,0 +1,609 @@
1
+ # スキーマ設計
2
+
3
+ TODO
4
+ 以下はサンプルで、まだDBは未作成です。
5
+
6
+ ## 概要
7
+
8
+ このドキュメントでは、Prismaを使用したデータベーススキーマ設計と、テーブル定義、リレーション設計、マイグレーション戦略について説明します。
9
+
10
+ PostgreSQLをデータベースとして使用し、Prismaをグローバルキャッシュパターンで運用します。
11
+
12
+ ---
13
+
14
+ ## 目次
15
+
16
+ 1. [データベース技術スタック](#1-データベース技術スタック)
17
+ 2. [ERD(エンティティ関連図)](#2-erdエンティティ関連図)
18
+ 3. [Prismaスキーマ定義](#3-prismaスキーマ定義)
19
+ 4. [テーブル定義](#4-テーブル定義)
20
+ 5. [リレーション設計](#5-リレーション設計)
21
+ 6. [インデックス設計](#6-インデックス設計)
22
+ 7. [Prisma Client設定](#7-prisma-client設定)
23
+ 8. [マイグレーション戦略](#8-マイグレーション戦略)
24
+
25
+ ---
26
+
27
+ ## 1. データベース技術スタック
28
+
29
+ | カテゴリ | 技術 | 用途 |
30
+ |---------|------|------|
31
+ | データベース | PostgreSQL | リレーショナルデータベース |
32
+ | ORM | Prisma | データベースアクセス |
33
+ | クライアント | @prisma/client | Prisma Client |
34
+ | CLI | prisma | マイグレーション、生成 |
35
+
36
+ **Prismaの利点**:
37
+ - 型安全なデータベースアクセス
38
+ - 自動生成されたクライアント
39
+ - マイグレーション管理
40
+ - クエリの最適化
41
+
42
+ ---
43
+
44
+ ## 2. ERD(エンティティ関連図)
45
+
46
+ ```mermaid
47
+ erDiagram
48
+ User {
49
+ string id PK
50
+ string email UK
51
+ string name
52
+ datetime createdAt
53
+ datetime updatedAt
54
+ }
55
+
56
+ Account {
57
+ string id PK
58
+ string userId FK
59
+ string provider
60
+ string providerAccountId UK
61
+ string accessToken
62
+ string refreshToken
63
+ datetime expiresAt
64
+ datetime createdAt
65
+ }
66
+
67
+ Session {
68
+ string id PK
69
+ string userId FK
70
+ string token UK
71
+ datetime expiresAt
72
+ datetime createdAt
73
+ datetime lastActivity
74
+ }
75
+
76
+ Post {
77
+ string id PK
78
+ string userId FK
79
+ string title
80
+ string content
81
+ string status
82
+ datetime publishedAt
83
+ datetime createdAt
84
+ datetime updatedAt
85
+ }
86
+
87
+ User ||--o{ Account : has
88
+ User ||--o{ Session : has
89
+ User ||--o{ Post : creates
90
+ ```
91
+
92
+ **エンティティ間のリレーション**:
93
+ - **User → Account**: 1対多(1ユーザーは複数のアカウント(OAuth)を持つ)
94
+ - **User → Session**: 1対多(1ユーザーは複数のセッションを持つ)
95
+ - **User → Post**: 1対多(1ユーザーは複数の投稿を作成)
96
+
97
+ ---
98
+
99
+ ## 3. Prismaスキーマ定義
100
+
101
+ ### スキーマファイル
102
+
103
+ **配置場所**: `packages/server-core/src/infrastructure/database/prisma/schema.prisma`
104
+
105
+ ### generator設定
106
+
107
+ ```prisma
108
+ generator client {
109
+ provider = "prisma-client-js"
110
+ output = "../../../../node_modules/.prisma/client"
111
+ }
112
+ ```
113
+
114
+ **設計ポイント**:
115
+ - `provider`: Prisma Clientの生成に使用
116
+ - `output`: モノレポ対応のため、クライアント生成先を `node_modules/.prisma/client` に設定
117
+
118
+ ### datasource設定
119
+
120
+ ```prisma
121
+ datasource db {
122
+ provider = "postgresql"
123
+ url = env("DATABASE_URL")
124
+ }
125
+ ```
126
+
127
+ **設計ポイント**:
128
+ - `provider`: PostgreSQLを使用
129
+ - `url`: 環境変数 `DATABASE_URL` で接続URL指定
130
+
131
+ ### 完全なスキーマ定義
132
+
133
+ ```prisma
134
+ // packages/server-core/src/infrastructure/database/prisma/schema.prisma
135
+
136
+ generator client {
137
+ provider = "prisma-client-js"
138
+ output = "../../../../node_modules/.prisma/client"
139
+ }
140
+
141
+ datasource db {
142
+ provider = "postgresql"
143
+ url = env("DATABASE_URL")
144
+ }
145
+
146
+ model User {
147
+ id String @id @default(cuid())
148
+ email String @unique
149
+ name String?
150
+ createdAt DateTime @default(now())
151
+ updatedAt DateTime @updatedAt
152
+
153
+ accounts Account[]
154
+ sessions Session[]
155
+ posts Post[]
156
+
157
+ @@index([email])
158
+ }
159
+
160
+ model Account {
161
+ id String @id @default(cuid())
162
+ userId String
163
+ provider String
164
+ providerAccountId String
165
+ accessToken String?
166
+ refreshToken String?
167
+ expiresAt DateTime?
168
+ createdAt DateTime @default(now())
169
+
170
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
171
+
172
+ @@unique([provider, providerAccountId])
173
+ @@index([userId])
174
+ }
175
+
176
+ model Session {
177
+ id String @id @default(cuid())
178
+ userId String
179
+ token String @unique
180
+ expiresAt DateTime
181
+ createdAt DateTime @default(now())
182
+ lastActivity DateTime @default(now())
183
+
184
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
185
+
186
+ @@index([userId])
187
+ @@index([token])
188
+ @@index([expiresAt])
189
+ }
190
+
191
+ model Post {
192
+ id String @id @default(cuid())
193
+ userId String
194
+ title String
195
+ content String
196
+ status String @default("draft")
197
+ publishedAt DateTime?
198
+ createdAt DateTime @default(now())
199
+ updatedAt DateTime @updatedAt
200
+
201
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
202
+
203
+ @@index([userId])
204
+ @@index([status])
205
+ @@index([publishedAt])
206
+ }
207
+ ```
208
+
209
+ ---
210
+
211
+ ## 4. テーブル定義
212
+
213
+ ### Userテーブル
214
+
215
+ | カラム | 型 | 制約 | 説明 |
216
+ |--------|----|----|------|
217
+ | id | String | PK, @default(cuid()) | ユーザーID(CUID) |
218
+ | email | String | UNIQUE, NOT NULL | メールアドレス |
219
+ | name | String | NULLABLE | ユーザー名 |
220
+ | createdAt | DateTime | @default(now()) | 作成日時 |
221
+ | updatedAt | DateTime | @updatedAt | 更新日時 |
222
+
223
+ **インデックス**:
224
+ - `email` - ログイン時の検索を高速化
225
+
226
+ **リレーション**:
227
+ - `accounts` - Account[] (1対多)
228
+ - `sessions` - Session[] (1対多)
229
+ - `posts` - Post[] (1対多)
230
+
231
+ ### Accountテーブル
232
+
233
+ | カラム | 型 | 制約 | 説明 |
234
+ |--------|----|----|------|
235
+ | id | String | PK, @default(cuid()) | アカウントID |
236
+ | userId | String | FK, NOT NULL | ユーザーID |
237
+ | provider | String | NOT NULL | OAuth プロバイダ (google, github等) |
238
+ | providerAccountId | String | NOT NULL | プロバイダ側のアカウントID |
239
+ | accessToken | String | NULLABLE | アクセストークン |
240
+ | refreshToken | String | NULLABLE | リフレッシュトークン |
241
+ | expiresAt | DateTime | NULLABLE | トークン有効期限 |
242
+ | createdAt | DateTime | @default(now()) | 作成日時 |
243
+
244
+ **ユニーク制約**:
245
+ - `[provider, providerAccountId]` - プロバイダごとに一意
246
+
247
+ **インデックス**:
248
+ - `userId` - ユーザーのアカウント一覧取得を高速化
249
+
250
+ **リレーション**:
251
+ - `user` - User (多対1, onDelete: Cascade)
252
+
253
+ ### Sessionテーブル
254
+
255
+ | カラム | 型 | 制約 | 説明 |
256
+ |--------|----|----|------|
257
+ | id | String | PK, @default(cuid()) | セッションID |
258
+ | userId | String | FK, NOT NULL | ユーザーID |
259
+ | token | String | UNIQUE, NOT NULL | セッショントークン |
260
+ | expiresAt | DateTime | NOT NULL | セッション有効期限 |
261
+ | createdAt | DateTime | @default(now()) | 作成日時 |
262
+ | lastActivity | DateTime | @default(now()) | 最終アクティビティ日時 |
263
+
264
+ **インデックス**:
265
+ - `userId` - ユーザーのセッション一覧取得を高速化
266
+ - `token` - トークンによるセッション検索を高速化
267
+ - `expiresAt` - 期限切れセッションのクリーンアップを高速化
268
+
269
+ **リレーション**:
270
+ - `user` - User (多対1, onDelete: Cascade)
271
+
272
+ ### Postテーブル
273
+
274
+ | カラム | 型 | 制約 | 説明 |
275
+ |--------|----|----|------|
276
+ | id | String | PK, @default(cuid()) | 投稿ID |
277
+ | userId | String | FK, NOT NULL | 作成者ID |
278
+ | title | String | NOT NULL | タイトル |
279
+ | content | String | NOT NULL | 本文 |
280
+ | status | String | @default("draft") | ステータス (draft, published, archived) |
281
+ | publishedAt | DateTime | NULLABLE | 公開日時 |
282
+ | createdAt | DateTime | @default(now()) | 作成日時 |
283
+ | updatedAt | DateTime | @updatedAt | 更新日時 |
284
+
285
+ **インデックス**:
286
+ - `userId` - ユーザーの投稿一覧取得を高速化
287
+ - `status` - ステータスによる投稿検索を高速化
288
+ - `publishedAt` - 公開日時順のソートを高速化
289
+
290
+ **リレーション**:
291
+ - `user` - User (多対1, onDelete: Cascade)
292
+
293
+ ---
294
+
295
+ ## 5. リレーション設計
296
+
297
+ ### リレーションの種類
298
+
299
+ #### 1対多リレーション
300
+
301
+ **User → Post**:
302
+
303
+ ```prisma
304
+ model User {
305
+ id String @id
306
+ posts Post[]
307
+ }
308
+
309
+ model Post {
310
+ id String @id
311
+ userId String
312
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
313
+ }
314
+ ```
315
+
316
+ **削除時の動作** (`onDelete: Cascade`):
317
+ - ユーザーを削除すると、関連する投稿もすべて削除される
318
+
319
+ #### 外部キー制約
320
+
321
+ すべての外部キーには、以下のポリシーを適用:
322
+
323
+ | ポリシー | 説明 |
324
+ |---------|------|
325
+ | onDelete: Cascade | 親レコード削除時に子レコードも削除 |
326
+ | onUpdate: Cascade | 親レコード更新時に子レコードも更新(Prismaのデフォルト) |
327
+
328
+ **理由**:
329
+ - データ整合性の保証
330
+ - 孤立レコードの防止
331
+ - アプリケーションロジックの簡素化
332
+
333
+ ---
334
+
335
+ ## 6. インデックス設計
336
+
337
+ ### インデックス戦略
338
+
339
+ #### 検索頻度の高いカラム
340
+
341
+ **Userテーブル**:
342
+ - `email` - ログイン時の検索
343
+
344
+ **Sessionテーブル**:
345
+ - `token` - トークンによるセッション検索
346
+ - `userId` - ユーザーのセッション一覧
347
+ - `expiresAt` - 期限切れセッションのクリーンアップ
348
+
349
+ **Postテーブル**:
350
+ - `userId` - ユーザーの投稿一覧
351
+ - `status` - ステータスによる投稿検索
352
+ - `publishedAt` - 公開日時順のソート
353
+
354
+ #### ユニークインデックス
355
+
356
+ **Userテーブル**:
357
+ - `email` - メールアドレスの重複防止
358
+
359
+ **Accountテーブル**:
360
+ - `[provider, providerAccountId]` - プロバイダごとのアカウントID重複防止
361
+
362
+ **Sessionテーブル**:
363
+ - `token` - セッショントークンの重複防止
364
+
365
+ ### インデックスのパフォーマンス影響
366
+
367
+ | 操作 | インデックスあり | インデックスなし |
368
+ |------|---------------|--------------|
369
+ | SELECT (WHERE句) | O(log n) | O(n) |
370
+ | INSERT | O(log n) | O(1) |
371
+ | UPDATE (インデックスカラム) | O(log n) | O(1) |
372
+
373
+ **トレードオフ**:
374
+ - 検索速度の向上 vs 挿入/更新速度の低下
375
+ - 本プロジェクトでは、読み取り頻度が高いため、インデックス作成を優先
376
+
377
+ ---
378
+
379
+ ## 7. Prisma Client設定
380
+
381
+ ### グローバルキャッシュパターン
382
+
383
+ **目的**: 開発環境でのHot Reload対応
384
+
385
+ **実装ファイル**: `packages/server-core/src/infrastructure/database/client.ts`
386
+
387
+ ```typescript
388
+ import { PrismaClient } from '@prisma/client'
389
+
390
+ declare global {
391
+ // eslint-disable-next-line no-var
392
+ var prisma: PrismaClient | undefined
393
+ }
394
+
395
+ export const prisma =
396
+ global.prisma ||
397
+ new PrismaClient({
398
+ log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
399
+ })
400
+
401
+ if (process.env.NODE_ENV !== 'production') {
402
+ global.prisma = prisma
403
+ }
404
+ ```
405
+
406
+ **設計ポイント**:
407
+ - **開発環境**: globalオブジェクトにキャッシュし、Hot Reload時に再利用
408
+ - **本番環境**: 通常のインスタンス化(グローバル化しない)
409
+ - **ログレベル**: 開発環境では `query`, `error`, `warn`、本番環境では `error` のみ
410
+
411
+ ### ログ設定
412
+
413
+ | 環境 | ログレベル | 用途 |
414
+ |------|-----------|------|
415
+ | development | query, error, warn | デバッグ、パフォーマンス分析 |
416
+ | production | error | エラー監視 |
417
+
418
+ **クエリログの例**:
419
+
420
+ ```
421
+ prisma:query SELECT "User"."id", "User"."email" FROM "User" WHERE "User"."email" = $1
422
+ ```
423
+
424
+ ---
425
+
426
+ ## 8. マイグレーション戦略
427
+
428
+ ### マイグレーションコマンド
429
+
430
+ **開発環境での実行**:
431
+
432
+ ```bash
433
+ # マイグレーション作成
434
+ pnpm db:migrate:dev
435
+
436
+ # マイグレーション適用(本番環境)
437
+ pnpm db:migrate:deploy
438
+
439
+ # Prisma Client再生成
440
+ pnpm db:generate
441
+
442
+ # Prisma Studio起動(GUIでデータ確認)
443
+ pnpm db:studio
444
+ ```
445
+
446
+ **package.json定義**:
447
+
448
+ ```json
449
+ {
450
+ "scripts": {
451
+ "db:migrate:dev": "dotenv -e .env -e .env.local -- prisma migrate dev --schema=packages/server-core/src/infrastructure/database/prisma/schema.prisma",
452
+ "db:migrate:deploy": "dotenv -e .env -- prisma migrate deploy --schema=packages/server-core/src/infrastructure/database/prisma/schema.prisma",
453
+ "db:generate": "prisma generate --schema=packages/server-core/src/infrastructure/database/prisma/schema.prisma",
454
+ "db:studio": "dotenv -e .env -e .env.local -- prisma studio --schema=packages/server-core/src/infrastructure/database/prisma/schema.prisma",
455
+ "db:push": "dotenv -e .env -e .env.local -- prisma db push --schema=packages/server-core/src/infrastructure/database/prisma/schema.prisma",
456
+ "db:seed": "dotenv -e .env -e .env.local -- tsx packages/server-core/src/infrastructure/database/seed.ts"
457
+ }
458
+ }
459
+ ```
460
+
461
+ ### マイグレーションワークフロー
462
+
463
+ #### 開発環境
464
+
465
+ ```mermaid
466
+ graph LR
467
+ A[スキーマ変更] --> B[pnpm db:migrate:dev]
468
+ B --> C[マイグレーションファイル生成]
469
+ C --> D[DB適用]
470
+ D --> E[Prisma Client再生成]
471
+ ```
472
+
473
+ **実行例**:
474
+
475
+ ```bash
476
+ # 1. schema.prismaを編集
477
+
478
+ # 2. マイグレーション作成
479
+ pnpm db:migrate:dev --name add_post_table
480
+
481
+ # 3. 確認
482
+ pnpm db:studio
483
+ ```
484
+
485
+ #### 本番環境
486
+
487
+ ```mermaid
488
+ graph LR
489
+ A[マイグレーションファイル<br/>リポジトリにコミット] --> B[本番デプロイ]
490
+ B --> C[pnpm db:migrate:deploy]
491
+ C --> D[DB適用]
492
+ ```
493
+
494
+ **実行例** (CIパイプライン):
495
+
496
+ ```yaml
497
+ # .github/workflows/deploy.yml
498
+ - name: Run migrations
499
+ run: pnpm db:migrate:deploy
500
+ env:
501
+ DATABASE_URL: ${{ secrets.DATABASE_URL }}
502
+ ```
503
+
504
+ ### マイグレーションファイル
505
+
506
+ **配置場所**: `packages/server-core/src/infrastructure/database/prisma/migrations/`
507
+
508
+ **例**:
509
+
510
+ ```
511
+ migrations/
512
+ ├── 20231201120000_init/
513
+ │ └── migration.sql
514
+ ├── 20231205130000_add_post_table/
515
+ │ └── migration.sql
516
+ └── migration_lock.toml
517
+ ```
518
+
519
+ **migration.sql例**:
520
+
521
+ ```sql
522
+ -- CreateTable
523
+ CREATE TABLE "Post" (
524
+ "id" TEXT NOT NULL,
525
+ "userId" TEXT NOT NULL,
526
+ "title" TEXT NOT NULL,
527
+ "content" TEXT NOT NULL,
528
+ "status" TEXT NOT NULL DEFAULT 'draft',
529
+ "publishedAt" TIMESTAMP(3),
530
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
531
+ "updatedAt" TIMESTAMP(3) NOT NULL,
532
+
533
+ CONSTRAINT "Post_pkey" PRIMARY KEY ("id")
534
+ );
535
+
536
+ -- CreateIndex
537
+ CREATE INDEX "Post_userId_idx" ON "Post"("userId");
538
+
539
+ -- CreateIndex
540
+ CREATE INDEX "Post_status_idx" ON "Post"("status");
541
+
542
+ -- CreateIndex
543
+ CREATE INDEX "Post_publishedAt_idx" ON "Post"("publishedAt");
544
+
545
+ -- AddForeignKey
546
+ ALTER TABLE "Post" ADD CONSTRAINT "Post_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
547
+ ```
548
+
549
+ ### シード(初期データ投入)
550
+
551
+ **シードファイル**: `packages/server-core/src/infrastructure/database/seed.ts`
552
+
553
+ ```typescript
554
+ import { prisma } from './client'
555
+
556
+ async function main() {
557
+ console.log('Seeding database...')
558
+
559
+ // ユーザー作成
560
+ const user = await prisma.user.create({
561
+ data: {
562
+ email: 'admin@example.com',
563
+ name: 'Admin User',
564
+ },
565
+ })
566
+
567
+ // 投稿作成
568
+ await prisma.post.create({
569
+ data: {
570
+ userId: user.id,
571
+ title: 'Welcome Post',
572
+ content: 'This is the first post',
573
+ status: 'published',
574
+ publishedAt: new Date(),
575
+ },
576
+ })
577
+
578
+ console.log('Seeding complete!')
579
+ }
580
+
581
+ main()
582
+ .catch(e => {
583
+ console.error(e)
584
+ process.exit(1)
585
+ })
586
+ .finally(async () => {
587
+ await prisma.$disconnect()
588
+ })
589
+ ```
590
+
591
+ **実行**:
592
+
593
+ ```bash
594
+ pnpm db:seed
595
+ ```
596
+
597
+ ---
598
+
599
+ ## まとめ
600
+
601
+ このスキーマ設計ドキュメントに従うことで、以下を実現できます:
602
+
603
+ 1. **データ整合性**: 外部キー制約とCascadeポリシーによる整合性保証
604
+ 2. **パフォーマンス**: 適切なインデックス設計による高速検索
605
+ 3. **型安全性**: Prismaによる型安全なデータベースアクセス
606
+ 4. **保守性**: マイグレーション管理とシードデータによる環境再現性
607
+ 5. **スケーラビリティ**: PostgreSQLとPrismaの組み合わせによる高いスケーラビリティ
608
+
609
+ すべてのスキーマ変更は、このガイドラインに従って実装してください。