@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,731 @@
1
+ # バックエンドアーキテクチャ
2
+
3
+ ## タスク: Turborepo Next.js モノレポ構築 (20251104)
4
+
5
+ **反映日時**: 2025-11-17
6
+ **ソース**: docs/specs/tasks/monorepo/20251104-monorepo-turborepo-nextjs-setup/
7
+ **抽出元**: design/architecture.md, design/implementation.md
8
+
9
+ ---
10
+
11
+ ## 概要
12
+
13
+ Vercel TurborepoとNext.jsをベースとしたエンタープライズグレードのモノレポアーキテクチャです。
14
+
15
+ 複数のアプリケーション(Web、Admin、Cron Worker)と1つの共有パッケージ(@repo/server-core)を統合し、**4層レイヤードアーキテクチャ**と**Result型パターン**による型安全なバックエンド開発を実現します。
16
+
17
+ ### 主要な技術的課題と解決方針
18
+
19
+ 1. **コードの重複と保守性**
20
+ - 解決策: @repo/server-core による DRY 原則の徹底
21
+ - Repositoryパターンでドメイン層とインフラ層を分離
22
+ - Mapperパターンで Prisma ⇔ Domain の変換を Infrastructure層に集約
23
+
24
+ 2. **型安全性とエラーハンドリング**
25
+ - 解決策: Result型パターンによる例外を使わないエラーハンドリング
26
+ - Hono + zValidatorによるリクエストバリデーションの型安全性
27
+ - ApplicationErrorクラス階層による構造化されたエラー表現
28
+
29
+ 3. **モジュールエクスポート管理**
30
+ - 解決策: **index.ts完全不使用方針**
31
+ - package.jsonのワイルドカードexports (`"./*": "./src/*.ts"`)
32
+ - ファイル追加時のpackage.json更新不要(自動対応)
33
+
34
+ ---
35
+
36
+ ## 1. ディレクトリ構造
37
+
38
+ ### モノレポ全体構造
39
+
40
+ ```
41
+ project-root/
42
+ ├── apps/
43
+ │ ├── web/ # メインWebアプリ(Next.js 14 App Router)
44
+ │ ├── admin/ # 管理画面(Next.js 14 App Router)
45
+ │ └── cron-worker/ # バッチ処理(CLI型)
46
+
47
+ ├── packages/
48
+ │ └── server-core/ # 共有バックエンドロジック⭐
49
+ │ ├── core/ # アーキテクチャのコア(Result型等)
50
+ │ ├── domain/ # Domain層
51
+ │ └── infrastructure/ # Infrastructure層
52
+
53
+ ├── apps/
54
+ │ ├── web/src/application/ # Application層(webアプリ固有)⭐
55
+ │ ├── admin/src/application/ # Application層(adminアプリ固有)⭐
56
+ │ └── cron-worker/src/application/ # Application層(cron-worker固有)⭐
57
+
58
+ ├── biome.json # ルートLinter設定
59
+ ├── tsconfig.base.json # ベースTS設定
60
+ ├── turbo.json # Turborepo設定
61
+ ├── pnpm-workspace.yaml # ワークスペース定義
62
+ └── docker-compose.yml # PostgreSQL動的ポート設定
63
+ ```
64
+
65
+ ### apps/ の役割
66
+
67
+ | アプリ | ポート | 用途 | 技術スタック |
68
+ |-------|-------|------|------------|
69
+ | **web** | 3000 | メインWebアプリケーション | Next.js 14 App Router + Hono API |
70
+ | **admin** | 4000 | 管理画面 | Next.js 14 App Router + Hono API |
71
+ | **cron-worker** | 5000 | バッチ処理(CLI型) | Next.js + tsx実行 |
72
+
73
+ **Worktree環境対応**: ブランチ名のMD5ハッシュから動的にポート番号を計算し、複数ブランチの並行開発をサポート。
74
+
75
+ ---
76
+
77
+ ### @repo/server-core の内部構造(4層アーキテクチャ)
78
+
79
+ ```
80
+ packages/server-core/
81
+ ├── src/
82
+ │ ├── domain/ # 📗 Domain層(ビジネスロジック)
83
+ │ │ ├── entities/ # エンティティ
84
+ │ │ │ ├── User.ts
85
+ │ │ │ ├── Post.ts
86
+ │ │ │ └── Session.ts
87
+ │ │ │
88
+ │ │ ├── value-objects/ # 値オブジェクト
89
+ │ │ │ ├── Email.ts
90
+ │ │ │ └── Password.ts
91
+ │ │ │
92
+ │ │ ├── repository-interfaces/ # リポジトリインターフェース⭐
93
+ │ │ │ ├── IUserRepository.ts
94
+ │ │ │ ├── IPostRepository.ts
95
+ │ │ │ └── ISessionRepository.ts
96
+ │ │ │
97
+ │ │ └── validators/ # Zodバリデーター
98
+ │ │ ├── user.ts
99
+ │ │ ├── post.ts
100
+ │ │ └── session.ts
101
+ │ │
102
+ │ ├── infrastructure/ # 📙 Infrastructure層(実装)
103
+ │ │ ├── database/
104
+ │ │ │ ├── prisma/
105
+ │ │ │ │ ├── schema.prisma
106
+ │ │ │ │ └── migrations/
107
+ │ │ │ │
108
+ │ │ │ ├── client.ts # Prismaクライアント⭐
109
+ │ │ │ │
110
+ │ │ │ ├── repositories/ # リポジトリ実装⭐
111
+ │ │ │ │ ├── UserRepository.ts
112
+ │ │ │ │ ├── PostRepository.ts
113
+ │ │ │ │ └── SessionRepository.ts
114
+ │ │ │ │
115
+ │ │ │ └── mappers/ # Prisma ⇔ Domain変換⭐
116
+ │ │ │ ├── UserMapper.ts
117
+ │ │ │ ├── PostMapper.ts
118
+ │ │ │ └── SessionMapper.ts
119
+ │ │ │
120
+ │ │ ├── email/ # メール送信
121
+ │ │ │ ├── EmailService.ts
122
+ │ │ │ └── ResendEmailService.ts
123
+ │ │ │
124
+ │ │ └── storage/ # ストレージ
125
+ │ │ ├── StorageService.ts
126
+ │ │ └── S3StorageService.ts
127
+ │ │
128
+ │ └── core/ # アーキテクチャのコア
129
+ │ └── result.ts # Result型定義⭐
130
+
131
+ └── package.json
132
+ └── "exports": { "./*": "./src/*.ts" } # index.ts不使用⭐
133
+ ```
134
+
135
+ ---
136
+
137
+ ## 2. 4層レイヤードアーキテクチャ
138
+
139
+ ### アーキテクチャ図
140
+
141
+ ```mermaid
142
+ graph TD
143
+ subgraph "Frontend (React)"
144
+ UI[UI Components]
145
+ TQ[Tanstack Query]
146
+ HC[Hono Client]
147
+ end
148
+
149
+ subgraph "📕 Presentation層 (API Routes)"
150
+ Router[Hono Router]
151
+ Validator[zValidator + Zod]
152
+ Handler[Route Handler]
153
+ end
154
+
155
+ subgraph "📘 Application層 (UseCases)"
156
+ UC[UseCase<br/>Object Literal]
157
+ ResultCompose[Result Composition<br/>flatMap / map]
158
+ end
159
+
160
+ subgraph "📗 Domain層"
161
+ Entity[Domain Entities]
162
+ VO[Value Objects]
163
+ RepoIF[Repository<br/>Interfaces ⭐]
164
+ end
165
+
166
+ subgraph "📙 Infrastructure層"
167
+ Mapper[Mapper Classes<br/>Prisma ⇔ Domain]
168
+ RepoImpl[Repository<br/>Implementation]
169
+ PrismaClient[Prisma Client]
170
+ end
171
+
172
+ subgraph "Database"
173
+ DB[(PostgreSQL)]
174
+ end
175
+
176
+ UI --> TQ
177
+ TQ --> HC
178
+ HC --> Router
179
+ Router --> Validator
180
+ Validator --> Handler
181
+ Handler --> UC
182
+ UC --> ResultCompose
183
+ ResultCompose --> RepoIF
184
+ RepoIF -.implements.-> RepoImpl
185
+ RepoImpl --> Mapper
186
+ RepoImpl --> PrismaClient
187
+ Mapper --> Entity
188
+ UC --> Entity
189
+ PrismaClient --> DB
190
+ ```
191
+
192
+ ### 各層の責務と配置
193
+
194
+ #### 📕 Presentation層(API Routes)
195
+
196
+ **配置**: `apps/web/src/app/api/`, `apps/admin/src/app/api/`
197
+
198
+ **責務**:
199
+ - HTTPリクエスト/レスポンスの処理
200
+ - Zodバリデーション(zValidator)
201
+ - UseCaseの呼び出し
202
+ - エラーのHTTPステータスコードへのマッピング
203
+
204
+ **技術**: Hono、zValidator、Zod
205
+
206
+ **実装例**:
207
+ ```typescript
208
+ // apps/web/src/app/api/posts/route.ts
209
+ import { Hono } from "hono"
210
+ import { zValidator } from "@hono/zod-validator"
211
+ import { postSchema } from "@repo/server-core/domain/validators/post"
212
+ import { postUseCases } from "@/application/use-cases/PostUseCases" // アプリ内のApplication層
213
+
214
+ const app = new Hono()
215
+ .post("/", zValidator("json", postSchema), async (c) => {
216
+ const data = c.req.valid("json")
217
+ const result = await postUseCases.create(data)
218
+
219
+ if (!result.isSuccess) {
220
+ return c.json({ error: result.error.message }, result.error.statusCode)
221
+ }
222
+
223
+ return c.json(result.value, 201)
224
+ })
225
+
226
+ export const GET = app.fetch
227
+ export const POST = app.fetch
228
+ ```
229
+
230
+ ---
231
+
232
+ #### 📘 Application層(UseCases)
233
+
234
+ **配置**: `apps/*/src/application/use-cases/` (各アプリケーション固有)⭐
235
+
236
+ **重要**: Application層は各アプリケーション(web、admin、cron-worker)に配置します。@repo/server-coreには配置しません。
237
+
238
+ **責務**:
239
+ - ビジネスフロー(複数Repositoryの調整)
240
+ - トランザクション管理
241
+ - Result型による安全なエラー伝播
242
+
243
+ **技術**: Result型、UseCase統合パターン
244
+
245
+ **設計パターン: UseCase統合パターン**
246
+
247
+ 従来のCRUD操作ごとにファイルを分けるのではなく、**リソース単位で1ファイルに統合**します。
248
+
249
+ ```typescript
250
+ // ❌ 旧パターン: CRUD操作ごとにファイル分割(過度な細分化)
251
+ // - ListPostsUseCase.ts
252
+ // - CreatePostUseCase.ts
253
+ // - UpdatePostUseCase.ts
254
+ // - DeletePostUseCase.ts
255
+
256
+ // ✅ 新パターン: リソース単位で統合(シンプル)
257
+ // apps/web/src/application/use-cases/PostUseCases.ts
258
+
259
+ // 型定義例
260
+ export type PostSearchCriteria = {
261
+ userId?: string
262
+ published?: boolean
263
+ createdAfter?: Date
264
+ }
265
+
266
+ export type CreatePostInput = {
267
+ title: string
268
+ content: string
269
+ userId: string
270
+ }
271
+
272
+ export type UpdatePostInput = {
273
+ title?: string
274
+ content?: string
275
+ published?: boolean
276
+ }
277
+
278
+ export const postUseCases = {
279
+ list: async (criteria: PostSearchCriteria) => {
280
+ // ...
281
+ },
282
+
283
+ create: async (data: CreatePostInput) => {
284
+ // ...
285
+ },
286
+
287
+ update: async (id: string, data: UpdatePostInput) => {
288
+ // ...
289
+ },
290
+
291
+ delete: async (id: string) => {
292
+ // ...
293
+ },
294
+ }
295
+ ```
296
+
297
+ **メリット**:
298
+ - 各ファイル150行程度で十分に可読性が高い
299
+ - 関連操作が1箇所にまとまり、変更が容易
300
+ - 呼び出しがシンプル: `postUseCases.create()` vs `createPostUseCase(repo).execute()`
301
+
302
+ ---
303
+
304
+ #### 📗 Domain層(ビジネスロジック)
305
+
306
+ **配置**: `packages/server-core/src/domain/`
307
+
308
+ **責務**:
309
+ - ビジネスルールの定義
310
+ - エンティティと値オブジェクトの管理
311
+ - リポジトリインターフェースの定義⭐
312
+ - ドメインバリデーション(Zod)
313
+
314
+ **技術**: TypeScript、Zod
315
+
316
+ **重要な原則**:
317
+ - **インフラ層に依存しない**(Prismaを知らない)
318
+ - リポジトリは**インターフェース**のみ定義
319
+ - データベースの実装詳細から独立
320
+
321
+ **実装例: Entity**
322
+
323
+ ```typescript
324
+ // packages/server-core/src/domain/entities/User.ts
325
+ export class User {
326
+ constructor(
327
+ public readonly id: string,
328
+ public readonly email: Email, // 値オブジェクト
329
+ public readonly name: string,
330
+ public readonly createdAt: Date,
331
+ ) {}
332
+
333
+ // ビジネスロジック
334
+ canDelete(): boolean {
335
+ // 作成後30日以内は削除不可
336
+ const daysSinceCreation = (Date.now() - this.createdAt.getTime()) / (1000 * 60 * 60 * 24)
337
+ return daysSinceCreation > 30
338
+ }
339
+ }
340
+ ```
341
+
342
+ **実装例: Repository Interface**
343
+
344
+ ```typescript
345
+ // packages/server-core/src/domain/repository-interfaces/IUserRepository.ts
346
+
347
+ // SearchCriteria型: すべてのフィールドはオプショナル
348
+ export type UserSearchCriteria = {
349
+ id?: string
350
+ email?: string
351
+ name?: string
352
+ createdAfter?: Date
353
+ createdBefore?: Date
354
+ }
355
+
356
+ export interface IUserRepository {
357
+ find(criteria: UserSearchCriteria): Promise<Result<User | null, DatabaseError>>
358
+ search(criteria: UserSearchCriteria): Promise<Result<User[], DatabaseError>>
359
+ create(user: User): Promise<Result<User, DatabaseError>>
360
+ update(id: string, user: Partial<User>): Promise<Result<User, DatabaseError>>
361
+ delete(id: string): Promise<Result<void, DatabaseError>>
362
+ }
363
+ ```
364
+
365
+ ---
366
+
367
+ #### 📙 Infrastructure層(実装)
368
+
369
+ **配置**: `packages/server-core/src/infrastructure/`
370
+
371
+ **責務**:
372
+ - データベースアクセス(Prisma)
373
+ - 外部サービス連携(メール、ストレージ)
374
+ - リポジトリインターフェースの**実装**⭐
375
+ - Prismaモデル ⇔ Domainエンティティの変換(Mapper)⭐
376
+
377
+ **技術**: Prisma、Mapper、外部API
378
+
379
+ **実装例: Repository Implementation**
380
+
381
+ ```typescript
382
+ // packages/server-core/src/infrastructure/database/repositories/UserRepository.ts
383
+ import type { IUserRepository, UserSearchCriteria } from "@repo/server-core/domain/repository-interfaces/IUserRepository"
384
+ import { UserMapper } from "../mappers/UserMapper"
385
+ import { prisma } from "../client"
386
+
387
+ export const userRepository: IUserRepository = {
388
+ find: async (criteria: UserSearchCriteria) => {
389
+ const prismaUser = await prisma.user.findFirst({
390
+ where: {
391
+ id: criteria.id,
392
+ email: criteria.email,
393
+ createdAt: {
394
+ gte: criteria.createdAfter,
395
+ lte: criteria.createdBefore,
396
+ },
397
+ },
398
+ })
399
+
400
+ if (!prismaUser) {
401
+ return { isSuccess: true, value: null }
402
+ }
403
+
404
+ const user = UserMapper.toDomain(prismaUser)
405
+ return { isSuccess: true, value: user }
406
+ },
407
+
408
+ create: async (user) => {
409
+ const createInput = UserMapper.toPrismaCreate(user)
410
+ const prismaUser = await prisma.user.create({ data: createInput })
411
+ const domainUser = UserMapper.toDomain(prismaUser)
412
+ return { isSuccess: true, value: domainUser }
413
+ },
414
+
415
+ // ...
416
+ }
417
+ ```
418
+
419
+ **実装例: Mapper**
420
+
421
+ ```typescript
422
+ // packages/server-core/src/infrastructure/database/mappers/UserMapper.ts
423
+ import type { User as PrismaUser } from "@prisma/client"
424
+ import { User } from "@repo/server-core/domain/entities/User"
425
+ import { Email } from "@repo/server-core/domain/value-objects/Email"
426
+
427
+ export class UserMapper {
428
+ static toDomain(prismaUser: PrismaUser): User {
429
+ return new User(
430
+ prismaUser.id,
431
+ new Email(prismaUser.email),
432
+ prismaUser.name,
433
+ prismaUser.createdAt,
434
+ )
435
+ }
436
+
437
+ static toPrismaCreate(user: User): Prisma.UserCreateInput {
438
+ return {
439
+ id: user.id,
440
+ email: user.email.value,
441
+ name: user.name,
442
+ }
443
+ }
444
+
445
+ static toPrismaUpdate(user: Partial<User>): Prisma.UserUpdateInput {
446
+ return {
447
+ email: user.email?.value,
448
+ name: user.name,
449
+ }
450
+ }
451
+ }
452
+ ```
453
+
454
+ ---
455
+
456
+ ### 層間の依存関係ルール
457
+
458
+ ```
459
+ 上位層 → 下位層のみ依存可能
460
+
461
+ Presentation → Application → Domain ← Infrastructure
462
+
463
+ インターフェースに依存
464
+ ```
465
+
466
+ **重要な原則**:
467
+ 1. **Presentation層**: Application層のUseCaseを呼び出す
468
+ 2. **Application層**: Domain層のエンティティとリポジトリ**インターフェース**を使用
469
+ 3. **Domain層**: どの層にも依存しない(最も純粋)
470
+ 4. **Infrastructure層**: Domain層の**インターフェース**を実装
471
+
472
+ この設計により:
473
+ - ✅ テストが容易(モックRepositoryで差し替え可能)
474
+ - ✅ データベースの変更がドメイン層に影響しない
475
+ - ✅ ビジネスロジックが永続化の詳細から独立
476
+
477
+ ---
478
+
479
+ ## 3. デザインパターン
480
+
481
+ ### 3.1 Repositoryパターン
482
+
483
+ **目的**: データアクセスロジックの抽象化
484
+
485
+ **設計の特徴**:
486
+ - **検索条件ベース設計**: `find(criteria)`, `search(criteria)` で統一
487
+ - **Result型**: すべてのメソッドがResult型を返す
488
+ - **SearchCriteria**: 柔軟な検索条件(すべてのフィールドはオプショナル)
489
+
490
+ **SearchCriteria型の設計原則**:
491
+ ```typescript
492
+ // ✅ すべてのフィールドはオプショナル
493
+ export type UserSearchCriteria = {
494
+ id?: string
495
+ email?: string
496
+ name?: string
497
+ createdAfter?: Date
498
+ createdBefore?: Date
499
+ }
500
+
501
+ // ❌ 必須フィールドを設けない
502
+ export type UserSearchCriteria = {
503
+ email: string // NG: 必須にすると柔軟性が失われる
504
+ name?: string
505
+ }
506
+ ```
507
+
508
+ **重要な原則**:
509
+ - すべての検索条件フィールドは**オプショナル**とする
510
+ - これにより、同一のRepositoryメソッドで多様な検索パターンに対応可能
511
+ - 必須パラメータはメソッドの引数として別途定義する(例: `update(id: string, data)`)
512
+
513
+ **主要メソッド**:
514
+
515
+ | メソッド | 説明 | 返り値 |
516
+ |---------|------|--------|
517
+ | `find(criteria)` | 単一レコード検索 | `Result<T \| null, E>` |
518
+ | `search(criteria, options)` | 複数レコード検索 | `Result<T[], E>` |
519
+ | `create(entity)` | 作成 | `Result<T, E>` |
520
+ | `update(id, data)` | 更新 | `Result<T, E>` |
521
+ | `delete(id)` | 削除 | `Result<void, E>` |
522
+ | `exists(criteria)` | 存在確認 | `Result<boolean, E>` |
523
+ | `count(criteria)` | カウント | `Result<number, E>` |
524
+
525
+ ---
526
+
527
+ ### 3.2 Mapperパターン
528
+
529
+ **目的**: Prismaモデル ⇔ Domainエンティティの変換
530
+
531
+ **設計のポイント**:
532
+ - Infrastructure層に配置
533
+ - 変換ロジックを一箇所に集約
534
+ - Domain層をPrismaの実装詳細から保護
535
+
536
+ **変換方向**:
537
+ 1. **toDomain**: PrismaモデルからDomainエンティティへ
538
+ 2. **toPrismaCreate**: DomainエンティティからPrisma CreateInputへ
539
+ 3. **toPrismaUpdate**: DomainエンティティからPrisma UpdateInputへ
540
+
541
+ ---
542
+
543
+ ### 3.3 Result型パターン
544
+
545
+ **目的**: 例外を使わないエラー表現
546
+
547
+ **型定義**:
548
+ ```typescript
549
+ // packages/server-core/src/core/result.ts
550
+ type Success<T> = { isSuccess: true; value: T }
551
+ type Failure<E> = { isSuccess: false; error: E }
552
+ type Result<T, E> = Success<T> | Failure<E>
553
+
554
+ // ヘルパー関数
555
+ export function success<T>(value: T): Success<T> {
556
+ return { isSuccess: true, value }
557
+ }
558
+
559
+ export function failure<E>(error: E): Failure<E> {
560
+ return { isSuccess: false, error }
561
+ }
562
+ ```
563
+
564
+ **使用例**:
565
+ ```typescript
566
+ // UseCase
567
+ const userResult = await userRepository.find({ email })
568
+ if (!userResult.isSuccess) {
569
+ return failure(userResult.error) // エラーを伝播
570
+ }
571
+
572
+ const user = userResult.value
573
+ // 型安全: userResult.isSuccessのチェック後は、user は User型として扱える
574
+ ```
575
+
576
+ **メリット**:
577
+ - ✅ 型レベルでエラーハンドリングを強制
578
+ - ✅ try-catchが不要
579
+ - ✅ flatMap/mapでエラーをチェーン可能
580
+
581
+ ---
582
+
583
+ ## 4. パッケージエクスポート戦略
584
+
585
+ ### ⛔ index.ts 完全禁止(絶対厳守)
586
+
587
+ > **警告**: このプロジェクトでは `index.ts` ファイルの作成を**一切禁止**しています。
588
+ > いかなる理由があっても `index.ts` を作成してはいけません。
589
+ > 詳細は [CLAUDE.md の index.ts 完全禁止ルール](../../../CLAUDE.md) を参照してください。
590
+
591
+ 従来のindex.tsパターンは、ファイル追加のたびにindex.tsとpackage.jsonの両方を更新する必要があり、メンテナンス負担が大きいため、**完全に禁止**しています。
592
+
593
+ **package.json設定**:
594
+ ```json
595
+ {
596
+ "exports": {
597
+ "./*": "./src/*.ts"
598
+ }
599
+ }
600
+ ```
601
+
602
+ **インポート例**:
603
+ ```typescript
604
+ // ✅ 推奨: 直接ファイルパス指定
605
+ import { User } from "@repo/server-core/domain/entities/User"
606
+ import { userRepository } from "@repo/server-core/infrastructure/database/repositories/UserRepository"
607
+ import { postUseCases } from "@/application/use-cases/PostUseCases" // Application層は各アプリ内
608
+
609
+ // ❌ 非推奨: index.ts経由(使用不可)
610
+ import { User } from "@repo/server-core"
611
+ import { User } from "@repo/server-core/domain/entities" // index.tsなし
612
+ ```
613
+
614
+ **メリット**:
615
+ - ✅ ファイル追加時にpackage.json更新不要(ワイルドカードで自動対応)
616
+ - ✅ index.tsの管理コストゼロ
617
+ - ✅ インポート元が明確
618
+ - ✅ IDEのジャンプ機能が正確に動作
619
+
620
+ ---
621
+
622
+ ## 5. 技術スタック
623
+
624
+ | カテゴリ | 技術 | バージョン | 用途 |
625
+ |---------|------|-----------|------|
626
+ | **モノレポ管理** | Turborepo | 1.x | ビルドオーケストレーション |
627
+ | **パッケージマネージャー** | pnpm | 8.x | ワークスペース管理 |
628
+ | **フレームワーク** | Next.js | 14.x | Web/Admin/Cron Worker |
629
+ | **APIフレームワーク** | Hono | 4.x | 型安全なWebフレームワーク |
630
+ | **言語** | TypeScript | 5.x | 型安全性 |
631
+ | **環境変数管理** | dotenv-cli | 7.3.0 | 階層的env読み込み |
632
+ | **データベース** | Prisma | 5.x | ORM |
633
+ | **DB本体** | PostgreSQL | 15.x | データストア |
634
+ | **Linter & Formatter** | Biome | 1.9.4+ | コード品質・フォーマット |
635
+ | **バリデーション** | Zod | 3.x | スキーマ検証 |
636
+ | **日付処理** | date-fns | 3.x | 日付ユーティリティ |
637
+
638
+ ---
639
+
640
+ ## 6. Prisma Client設定
641
+
642
+ ### グローバル化パターン(Hot Reload対応)
643
+
644
+ **配置**: `packages/server-core/src/infrastructure/database/client.ts`
645
+
646
+ **設計の要点**:
647
+ - 開発環境でのHot Reload時にPrismaクライアントの再作成を防ぐ
648
+ - `global`オブジェクトにPrismaインスタンスをキャッシュ
649
+ - ログレベルを環境別に設定
650
+
651
+ ```typescript
652
+ // packages/server-core/src/infrastructure/database/client.ts
653
+ import { PrismaClient } from "@prisma/client"
654
+
655
+ const globalForPrisma = global as unknown as { prisma: PrismaClient }
656
+
657
+ export const prisma =
658
+ globalForPrisma.prisma ||
659
+ new PrismaClient({
660
+ log: process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"],
661
+ })
662
+
663
+ if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma
664
+ ```
665
+
666
+ ---
667
+
668
+ ## 7. 環境変数管理
669
+
670
+ ### 階層的環境変数読み込み
671
+
672
+ ```
673
+ ルート.env (共通設定、コミット可能)
674
+
675
+ ルート.env.local (ローカル固有、gitignore)
676
+
677
+ 各アプリ.env.local (アプリ固有、gitignore、オプション)
678
+ ```
679
+
680
+ ### dotenv-cli による自動読み込み
681
+
682
+ **ルートpackage.json**:
683
+ ```json
684
+ {
685
+ "scripts": {
686
+ "dev": "dotenv -e .env -e .env.local -- turbo run dev"
687
+ }
688
+ }
689
+ ```
690
+
691
+ **各アプリのpackage.json**:
692
+ ```json
693
+ {
694
+ "scripts": {
695
+ "dev": "dotenv -e ../../.env -e ../../.env.local -e .env.local -- next dev"
696
+ }
697
+ }
698
+ ```
699
+
700
+ ---
701
+
702
+ ## 8. 参照ドキュメント
703
+
704
+ ### 開発ガイド
705
+ - **[API開発ガイド](api-development.md)** - Hono API実装ルール、エンドポイント設計、**Server Actions vs Hono Clientの使い分け**
706
+ - **[フロントエンド開発ガイド](frontend-development.md)** - Server/Client Component、Tanstack Query、React Hook Form、Hono Client
707
+
708
+ ### データベース
709
+ - **[スキーマ設計](../schema-design.md)** - Prismaスキーマ、テーブル定義、ERD
710
+
711
+ ### インフラ
712
+ - **[CI/CDパイプライン](../infrastructure/ci-cd.md)** - GitHub Actions、Turborepoキャッシュ
713
+ - **[デプロイメント戦略](../infrastructure/deployment.md)** - Vercel、Docker、環境変数管理
714
+
715
+ ### 品質管理
716
+ - **[コードレビューガイドライン](../review-guidelines.md)** - 品質基準とチェックリスト
717
+ - **[テスト戦略](../testing-strategy.md)** - テストの書き方
718
+
719
+ ---
720
+
721
+ ## まとめ
722
+
723
+ このバックエンドアーキテクチャは、以下を実現します:
724
+
725
+ ✅ **4層アーキテクチャ**: 責務の明確化と保守性の向上
726
+ ✅ **Result型パターン**: 型安全なエラーハンドリング
727
+ ✅ **Repositoryパターン**: テスト容易性とドメイン独立性
728
+ ✅ **Mapperパターン**: 永続化層からのドメイン保護
729
+ ✅ **index.ts不使用**: シンプルで拡張しやすいモジュール管理
730
+
731
+ すべての開発者は、この設計原則に従ってバックエンド開発を行ってください。