takt 0.1.4 → 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 (82) hide show
  1. package/dist/agents/runner.d.ts +1 -1
  2. package/dist/agents/runner.d.ts.map +1 -1
  3. package/dist/agents/runner.js +13 -34
  4. package/dist/agents/runner.js.map +1 -1
  5. package/dist/claude/client.d.ts.map +1 -1
  6. package/dist/claude/client.js +4 -1
  7. package/dist/claude/client.js.map +1 -1
  8. package/dist/claude/executor.d.ts.map +1 -1
  9. package/dist/claude/executor.js +1 -0
  10. package/dist/claude/executor.js.map +1 -1
  11. package/dist/claude/types.d.ts +2 -0
  12. package/dist/claude/types.d.ts.map +1 -1
  13. package/dist/cli.d.ts +2 -3
  14. package/dist/cli.d.ts.map +1 -1
  15. package/dist/cli.js +5 -8
  16. package/dist/cli.js.map +1 -1
  17. package/dist/commands/help.d.ts.map +1 -1
  18. package/dist/commands/help.js +4 -8
  19. package/dist/commands/help.js.map +1 -1
  20. package/dist/commands/index.d.ts +1 -1
  21. package/dist/commands/index.d.ts.map +1 -1
  22. package/dist/commands/index.js.map +1 -1
  23. package/dist/commands/taskExecution.d.ts +1 -6
  24. package/dist/commands/taskExecution.d.ts.map +1 -1
  25. package/dist/commands/taskExecution.js +2 -6
  26. package/dist/commands/taskExecution.js.map +1 -1
  27. package/dist/commands/workflowExecution.d.ts +0 -2
  28. package/dist/commands/workflowExecution.d.ts.map +1 -1
  29. package/dist/commands/workflowExecution.js +34 -13
  30. package/dist/commands/workflowExecution.js.map +1 -1
  31. package/dist/mock/client.d.ts +27 -0
  32. package/dist/mock/client.d.ts.map +1 -0
  33. package/dist/mock/client.js +56 -0
  34. package/dist/mock/client.js.map +1 -0
  35. package/dist/models/schemas.d.ts +6 -0
  36. package/dist/models/schemas.d.ts.map +1 -1
  37. package/dist/models/schemas.js +4 -4
  38. package/dist/models/schemas.js.map +1 -1
  39. package/dist/models/types.d.ts +6 -4
  40. package/dist/models/types.d.ts.map +1 -1
  41. package/dist/providers/claude.d.ts +11 -0
  42. package/dist/providers/claude.d.ts.map +1 -0
  43. package/dist/providers/claude.js +37 -0
  44. package/dist/providers/claude.js.map +1 -0
  45. package/dist/providers/codex.d.ts +11 -0
  46. package/dist/providers/codex.d.ts.map +1 -0
  47. package/dist/providers/codex.js +29 -0
  48. package/dist/providers/codex.js.map +1 -0
  49. package/dist/providers/index.d.ts +39 -0
  50. package/dist/providers/index.d.ts.map +1 -0
  51. package/dist/providers/index.js +32 -0
  52. package/dist/providers/index.js.map +1 -0
  53. package/dist/providers/mock.d.ts +11 -0
  54. package/dist/providers/mock.d.ts.map +1 -0
  55. package/dist/providers/mock.js +24 -0
  56. package/dist/providers/mock.js.map +1 -0
  57. package/dist/workflow/engine.d.ts.map +1 -1
  58. package/dist/workflow/engine.js +6 -3
  59. package/dist/workflow/engine.js.map +1 -1
  60. package/dist/workflow/instruction-builder.d.ts +5 -2
  61. package/dist/workflow/instruction-builder.d.ts.map +1 -1
  62. package/dist/workflow/instruction-builder.js +4 -2
  63. package/dist/workflow/instruction-builder.js.map +1 -1
  64. package/dist/workflow/state-manager.d.ts +4 -0
  65. package/dist/workflow/state-manager.d.ts.map +1 -1
  66. package/dist/workflow/state-manager.js +10 -0
  67. package/dist/workflow/state-manager.js.map +1 -1
  68. package/package.json +1 -1
  69. package/resources/global/en/agents/default/architect.md +67 -6
  70. package/resources/global/en/agents/default/coder.md +155 -1
  71. package/resources/global/en/workflows/default.yaml +36 -16
  72. package/resources/global/en/workflows/expert-review.yaml +47 -23
  73. package/resources/global/en/workflows/magi.yaml +10 -0
  74. package/resources/global/en/workflows/research.yaml +16 -3
  75. package/resources/global/ja/agents/default/architect.md +62 -1
  76. package/resources/global/ja/agents/default/coder.md +156 -2
  77. package/resources/global/ja/agents/expert-review/cqrs-es-reviewer.md +328 -8
  78. package/resources/global/ja/agents/expert-review/frontend-reviewer.md +303 -33
  79. package/resources/global/ja/workflows/default.yaml +36 -16
  80. package/resources/global/ja/workflows/expert-review.yaml +47 -23
  81. package/resources/global/ja/workflows/magi.yaml +10 -0
  82. package/resources/global/ja/workflows/research.yaml +16 -3
@@ -9,6 +9,16 @@
9
9
  # Fix destination is determined by Coder based on change impact:
10
10
  # - fix_security: MINOR→security_review, MAJOR→cqrs_es_review
11
11
  # - fix_qa: MINOR→qa_review, SECURITY→security_review, MAJOR→cqrs_es_review
12
+ #
13
+ # Template Variables:
14
+ # {iteration} - Workflow-wide turn count (total steps executed across all agents)
15
+ # {max_iterations} - Maximum iterations allowed for the workflow
16
+ # {step_iteration} - Per-step iteration count (how many times THIS step has been executed)
17
+ # {task} - Original user request
18
+ # {previous_response} - Output from the previous step
19
+ # {git_diff} - Current uncommitted changes (git diff)
20
+ # {user_inputs} - Accumulated user inputs during workflow
21
+ # {report_dir} - Report directory name (e.g., "20250126-143052-task-summary")
12
22
 
13
23
  name: expert-review
14
24
  description: CQRS+ES, Frontend, Security, QA Expert Review
@@ -44,7 +54,8 @@ steps:
44
54
  | Requirements unclear | `[PLANNER:BLOCKED]` |
45
55
  instruction_template: |
46
56
  ## Workflow Context
47
- - Iteration: {iteration}/{max_iterations}
57
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
58
+ - Step Iteration: {step_iteration} (times this step has run)
48
59
  - Step: plan (Task Analysis)
49
60
  - Report Directory: .takt/reports/{report_dir}/
50
61
  - Report File: .takt/reports/{report_dir}/00-plan.md
@@ -68,7 +79,7 @@ steps:
68
79
 
69
80
  **Report output:** Output to the `Report File` specified above.
70
81
  - If file does not exist: Create new file
71
- - If file exists: Append with `## Iteration {iteration}` section
82
+ - If file exists: Append with `## Iteration {step_iteration}` section
72
83
 
73
84
  **Report format:**
74
85
  ```markdown
@@ -129,7 +140,8 @@ steps:
129
140
  | Cannot proceed | `[CODER:BLOCKED]` |
130
141
  instruction_template: |
131
142
  ## Workflow Context
132
- - Iteration: {iteration}/{max_iterations}
143
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
144
+ - Step Iteration: {step_iteration} (times this step has run)
133
145
  - Step: implement
134
146
  - Report Directory: .takt/reports/{report_dir}/
135
147
  - Report Files:
@@ -148,7 +160,7 @@ steps:
148
160
 
149
161
  **Report output:** Output to the `Report Files` specified above.
150
162
  - If file does not exist: Create new file
151
- - If file exists: Append with `## Iteration {iteration}` section
163
+ - If file exists: Append with `## Iteration {step_iteration}` section
152
164
 
153
165
  **Scope report format (create at implementation start):**
154
166
  ```markdown
@@ -213,7 +225,8 @@ steps:
213
225
  | Design issues found | `[CQRS-ES:REJECT]` |
214
226
  instruction_template: |
215
227
  ## Workflow Context
216
- - Iteration: {iteration}/{max_iterations}
228
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
229
+ - Step Iteration: {step_iteration} (times this step has run)
217
230
  - Step: cqrs_es_review (CQRS+ES Expert Review)
218
231
  - Report Directory: .takt/reports/{report_dir}/
219
232
  - Report File: .takt/reports/{report_dir}/03-cqrs-es-review.md
@@ -242,7 +255,7 @@ steps:
242
255
 
243
256
  **Report output:** Output to the `Report File` specified above.
244
257
  - If file does not exist: Create new file
245
- - If file exists: Append with `## Iteration {iteration}` section
258
+ - If file exists: Append with `## Iteration {step_iteration}` section
246
259
 
247
260
  **Report format:**
248
261
  ```markdown
@@ -302,7 +315,8 @@ steps:
302
315
  | Cannot proceed | `[CODER:BLOCKED]` |
303
316
  instruction_template: |
304
317
  ## Workflow Context
305
- - Iteration: {iteration}/{max_iterations}
318
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
319
+ - Step Iteration: {step_iteration} (times this step has run)
306
320
  - Step: fix_cqrs_es
307
321
 
308
322
  ## CQRS+ES Review Feedback (This is the latest instruction - prioritize this)
@@ -358,7 +372,8 @@ steps:
358
372
  | Design issues found | `[FRONTEND:REJECT]` |
359
373
  instruction_template: |
360
374
  ## Workflow Context
361
- - Iteration: {iteration}/{max_iterations}
375
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
376
+ - Step Iteration: {step_iteration} (times this step has run)
362
377
  - Step: frontend_review (Frontend Expert Review)
363
378
  - Report Directory: .takt/reports/{report_dir}/
364
379
  - Report File: .takt/reports/{report_dir}/04-frontend-review.md
@@ -387,7 +402,7 @@ steps:
387
402
 
388
403
  **Report output:** Output to the `Report File` specified above.
389
404
  - If file does not exist: Create new file
390
- - If file exists: Append with `## Iteration {iteration}` section
405
+ - If file exists: Append with `## Iteration {step_iteration}` section
391
406
 
392
407
  **Report format:**
393
408
  ```markdown
@@ -447,7 +462,8 @@ steps:
447
462
  | Cannot proceed | `[CODER:BLOCKED]` |
448
463
  instruction_template: |
449
464
  ## Workflow Context
450
- - Iteration: {iteration}/{max_iterations}
465
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
466
+ - Step Iteration: {step_iteration} (times this step has run)
451
467
  - Step: fix_frontend
452
468
 
453
469
  ## Frontend Review Feedback (This is the latest instruction - prioritize this)
@@ -503,7 +519,8 @@ steps:
503
519
  | Issues found | `[AI_REVIEW:REJECT]` |
504
520
  instruction_template: |
505
521
  ## Workflow Context
506
- - Iteration: {iteration}/{max_iterations}
522
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
523
+ - Step Iteration: {step_iteration} (times this step has run)
507
524
  - Step: ai_review (AI-Generated Code Review)
508
525
  - Report Directory: .takt/reports/{report_dir}/
509
526
  - Report File: .takt/reports/{report_dir}/05-ai-review.md
@@ -525,7 +542,7 @@ steps:
525
542
 
526
543
  **Report output:** Output to the `Report File` specified above.
527
544
  - If file does not exist: Create new file
528
- - If file exists: Append with `## Iteration {iteration}` section
545
+ - If file exists: Append with `## Iteration {step_iteration}` section
529
546
 
530
547
  **Report format:**
531
548
  ```markdown
@@ -588,7 +605,8 @@ steps:
588
605
  | Cannot proceed | `[CODER:BLOCKED]` |
589
606
  instruction_template: |
590
607
  ## Workflow Context
591
- - Iteration: {iteration}/{max_iterations}
608
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
609
+ - Step Iteration: {step_iteration} (times this step has run)
592
610
  - Step: ai_fix
593
611
 
594
612
  ## AI Review Feedback (This is the latest instruction - prioritize this)
@@ -613,7 +631,7 @@ steps:
613
631
  pass_previous_response: true
614
632
  transitions:
615
633
  - condition: done
616
- next_step: cqrs_es_review
634
+ next_step: ai_review
617
635
  - condition: blocked
618
636
  next_step: plan
619
637
 
@@ -642,7 +660,8 @@ steps:
642
660
  | Vulnerabilities found | `[SECURITY:REJECT]` |
643
661
  instruction_template: |
644
662
  ## Workflow Context
645
- - Iteration: {iteration}/{max_iterations}
663
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
664
+ - Step Iteration: {step_iteration} (times this step has run)
646
665
  - Step: security_review (Security Expert Review)
647
666
  - Report Directory: .takt/reports/{report_dir}/
648
667
  - Report File: .takt/reports/{report_dir}/06-security-review.md
@@ -667,7 +686,7 @@ steps:
667
686
 
668
687
  **Report output:** Output to the `Report File` specified above.
669
688
  - If file does not exist: Create new file
670
- - If file exists: Append with `## Iteration {iteration}` section
689
+ - If file exists: Append with `## Iteration {step_iteration}` section
671
690
 
672
691
  **Report format:**
673
692
  ```markdown
@@ -729,7 +748,8 @@ steps:
729
748
  | Cannot proceed | `[CODER:BLOCKED]` |
730
749
  instruction_template: |
731
750
  ## Workflow Context
732
- - Iteration: {iteration}/{max_iterations}
751
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
752
+ - Step Iteration: {step_iteration} (times this step has run)
733
753
  - Step: fix_security
734
754
 
735
755
  ## Security Review Feedback (This is the latest instruction - prioritize this)
@@ -794,7 +814,8 @@ steps:
794
814
  | Quality issues found | `[QA:REJECT]` |
795
815
  instruction_template: |
796
816
  ## Workflow Context
797
- - Iteration: {iteration}/{max_iterations}
817
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
818
+ - Step Iteration: {step_iteration} (times this step has run)
798
819
  - Step: qa_review (QA Expert Review)
799
820
  - Report Directory: .takt/reports/{report_dir}/
800
821
  - Report File: .takt/reports/{report_dir}/07-qa-review.md
@@ -820,7 +841,7 @@ steps:
820
841
 
821
842
  **Report output:** Output to the `Report File` specified above.
822
843
  - If file does not exist: Create new file
823
- - If file exists: Append with `## Iteration {iteration}` section
844
+ - If file exists: Append with `## Iteration {step_iteration}` section
824
845
 
825
846
  **Report format:**
826
847
  ```markdown
@@ -882,7 +903,8 @@ steps:
882
903
  | Cannot proceed | `[CODER:BLOCKED]` |
883
904
  instruction_template: |
884
905
  ## Workflow Context
885
- - Iteration: {iteration}/{max_iterations}
906
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
907
+ - Step Iteration: {step_iteration} (times this step has run)
886
908
  - Step: fix_qa
887
909
 
888
910
  ## QA Review Feedback (This is the latest instruction - prioritize this)
@@ -951,7 +973,8 @@ steps:
951
973
  | Issues found | `[SUPERVISOR:REJECT]` |
952
974
  instruction_template: |
953
975
  ## Workflow Context
954
- - Iteration: {iteration}/{max_iterations}
976
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
977
+ - Step Iteration: {step_iteration} (times this step has run)
955
978
  - Step: supervise (Final Review)
956
979
  - Report Directory: .takt/reports/{report_dir}/
957
980
  - Report Files:
@@ -987,7 +1010,7 @@ steps:
987
1010
 
988
1011
  **Report output:** Output to the `Report Files` specified above.
989
1012
  - If file does not exist: Create new file
990
- - If file exists: Append with `## Iteration {iteration}` section
1013
+ - If file exists: Append with `## Iteration {step_iteration}` section
991
1014
 
992
1015
  **Validation report format:**
993
1016
  ```markdown
@@ -1079,7 +1102,8 @@ steps:
1079
1102
  | Cannot proceed | `[CODER:BLOCKED]` |
1080
1103
  instruction_template: |
1081
1104
  ## Workflow Context
1082
- - Iteration: {iteration}/{max_iterations}
1105
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
1106
+ - Step Iteration: {step_iteration} (times this step has run)
1083
1107
  - Step: fix_supervisor
1084
1108
 
1085
1109
  ## Supervisor Feedback (This is the latest instruction - prioritize this)
@@ -1,6 +1,16 @@
1
1
  # MAGI System Workflow
2
2
  # A deliberation workflow modeled after Evangelion's MAGI system
3
3
  # Three personas (scientist, nurturer, pragmatist) analyze from different perspectives and vote
4
+ #
5
+ # Template Variables:
6
+ # {iteration} - Workflow-wide turn count (total steps executed across all agents)
7
+ # {max_iterations} - Maximum iterations allowed for the workflow
8
+ # {step_iteration} - Per-step iteration count (how many times THIS step has been executed)
9
+ # {task} - Original user request
10
+ # {previous_response} - Output from the previous step
11
+ # {git_diff} - Current uncommitted changes (git diff)
12
+ # {user_inputs} - Accumulated user inputs during workflow
13
+ # {report_dir} - Report directory name (e.g., "20250126-143052-task-summary")
4
14
 
5
15
  name: magi
6
16
  description: MAGI Deliberation System - Analyze from 3 perspectives and decide by majority
@@ -5,6 +5,16 @@
5
5
  # Flow:
6
6
  # plan -> dig -> supervise -> COMPLETE (approved)
7
7
  # -> plan (rejected: restart from planning)
8
+ #
9
+ # Template Variables:
10
+ # {iteration} - Workflow-wide turn count (total steps executed across all agents)
11
+ # {max_iterations} - Maximum iterations allowed for the workflow
12
+ # {step_iteration} - Per-step iteration count (how many times THIS step has been executed)
13
+ # {task} - Original user request
14
+ # {previous_response} - Output from the previous step
15
+ # {git_diff} - Current uncommitted changes (git diff)
16
+ # {user_inputs} - Accumulated user inputs during workflow
17
+ # {report_dir} - Report directory name (e.g., "20250126-143052-task-summary")
8
18
 
9
19
  name: research
10
20
  description: Research workflow - autonomously executes research without asking questions
@@ -49,7 +59,8 @@ steps:
49
59
  ```
50
60
  instruction_template: |
51
61
  ## Workflow Status
52
- - Iteration: {iteration}/{max_iterations}
62
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
63
+ - Step Iteration: {step_iteration} (times this step has run)
53
64
  - Step: plan
54
65
 
55
66
  ## Research Request
@@ -111,7 +122,8 @@ steps:
111
122
  ```
112
123
  instruction_template: |
113
124
  ## Workflow Status
114
- - Iteration: {iteration}/{max_iterations}
125
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
126
+ - Step Iteration: {step_iteration} (times this step has run)
115
127
  - Step: dig
116
128
 
117
129
  ## Original Research Request
@@ -188,7 +200,8 @@ steps:
188
200
  ```
189
201
  instruction_template: |
190
202
  ## Workflow Status
191
- - Iteration: {iteration}/{max_iterations}
203
+ - Iteration: {iteration}/{max_iterations} (workflow-wide)
204
+ - Step Iteration: {step_iteration} (times this step has run)
192
205
  - Step: supervise (research quality evaluation)
193
206
 
194
207
  ## Original Research Request
@@ -159,7 +159,68 @@ Vertical Slice の判定基準:
159
159
  | 隠れた依存 | 子コンポーネントが暗黙的にAPIを呼ぶ等 |
160
160
  | 非イディオマティック | 言語・FWの作法を無視した独自実装 |
161
161
 
162
- ### 6. 不要な後方互換コードの検出
162
+ ### 6. 抽象化レベルの評価
163
+
164
+ **条件分岐の肥大化検出:**
165
+
166
+ | パターン | 判定 |
167
+ |---------|------|
168
+ | 同じif-elseパターンが3箇所以上 | ポリモーフィズムで抽象化 → **REJECT** |
169
+ | switch/caseが5分岐以上 | Strategy/Mapパターンを検討 |
170
+ | フラグ引数で挙動を変える | 別関数に分割 → **REJECT** |
171
+ | 型による分岐(instanceof/typeof) | ポリモーフィズムに置換 → **REJECT** |
172
+ | ネストした条件分岐(3段以上) | 早期リターンまたは抽出 → **REJECT** |
173
+
174
+ **抽象度の不一致検出:**
175
+
176
+ | パターン | 問題 | 修正案 |
177
+ |---------|------|--------|
178
+ | 高レベル処理の中に低レベル詳細 | 読みにくい | 詳細を関数に抽出 |
179
+ | 1関数内で抽象度が混在 | 認知負荷 | 同じ粒度に揃える |
180
+ | ビジネスロジックにDB操作が混在 | 責務違反 | Repository層に分離 |
181
+ | 設定値と処理ロジックが混在 | 変更困難 | 設定を外部化 |
182
+
183
+ **良い抽象化の例:**
184
+
185
+ ```typescript
186
+ // ❌ 条件分岐の肥大化
187
+ function process(type: string) {
188
+ if (type === 'A') { /* 処理A */ }
189
+ else if (type === 'B') { /* 処理B */ }
190
+ else if (type === 'C') { /* 処理C */ }
191
+ // ...続く
192
+ }
193
+
194
+ // ✅ Mapパターンで抽象化
195
+ const processors: Record<string, () => void> = {
196
+ A: processA,
197
+ B: processB,
198
+ C: processC,
199
+ };
200
+ function process(type: string) {
201
+ processors[type]?.();
202
+ }
203
+ ```
204
+
205
+ ```typescript
206
+ // ❌ 抽象度の混在
207
+ function createUser(data: UserData) {
208
+ // 高レベル: ビジネスロジック
209
+ validateUser(data);
210
+ // 低レベル: DB操作の詳細
211
+ const conn = await pool.getConnection();
212
+ await conn.query('INSERT INTO users...');
213
+ conn.release();
214
+ }
215
+
216
+ // ✅ 抽象度を揃える
217
+ function createUser(data: UserData) {
218
+ validateUser(data);
219
+ await userRepository.save(data); // 詳細は隠蔽
220
+ }
221
+ ```
222
+
223
+ ### 7. 不要な後方互換コードの検出
163
224
 
164
225
  **AIは「後方互換のために」不要なコードを残しがちである。これを見逃さない。**
165
226
 
@@ -105,7 +105,45 @@
105
105
  | ボーイスカウト | 触った箇所は少し改善して去る |
106
106
  | Fail Fast | エラーは早期に検出。握りつぶさない |
107
107
 
108
- **迷ったら**: Simple を選ぶ。抽象化は後からでもできる。
108
+ **迷ったら**: Simple を選ぶ。
109
+
110
+ ## 抽象化の原則
111
+
112
+ **条件分岐を追加する前に考える:**
113
+ - 同じ条件が他にもあるか → あればパターンで抽象化
114
+ - 今後も分岐が増えそうか → Strategy/Mapパターンを使う
115
+ - 型で分岐しているか → ポリモーフィズムで置換
116
+
117
+ ```typescript
118
+ // ❌ 条件分岐を増やす
119
+ if (type === 'A') { ... }
120
+ else if (type === 'B') { ... }
121
+ else if (type === 'C') { ... } // また増えた
122
+
123
+ // ✅ Mapで抽象化
124
+ const handlers = { A: handleA, B: handleB, C: handleC };
125
+ handlers[type]?.();
126
+ ```
127
+
128
+ **抽象度を揃える:**
129
+ - 1つの関数内では同じ粒度の処理を並べる
130
+ - 詳細な処理は別関数に切り出す
131
+ - 「何をするか」と「どうやるか」を混ぜない
132
+
133
+ ```typescript
134
+ // ❌ 抽象度が混在
135
+ function processOrder(order) {
136
+ validateOrder(order); // 高レベル
137
+ const conn = pool.getConnection(); // 低レベル詳細
138
+ conn.query('INSERT...'); // 低レベル詳細
139
+ }
140
+
141
+ // ✅ 抽象度を揃える
142
+ function processOrder(order) {
143
+ validateOrder(order);
144
+ saveOrder(order); // 詳細は隠蔽
145
+ }
146
+ ```
109
147
 
110
148
  **言語・フレームワークの作法に従う:**
111
149
  - Pythonなら Pythonic に、KotlinならKotlinらしく
@@ -134,6 +172,121 @@
134
172
  - 子は状態を直接変更しない(イベントを親に通知)
135
173
  - 状態の流れは単方向
136
174
 
175
+ ## エラーハンドリング
176
+
177
+ **原則: エラーは一元管理する。各所でtry-catchしない。**
178
+
179
+ ```typescript
180
+ // ❌ 各所でtry-catch
181
+ async function createUser(data) {
182
+ try {
183
+ const user = await userService.create(data)
184
+ return user
185
+ } catch (e) {
186
+ console.error(e)
187
+ throw new Error('ユーザー作成に失敗しました')
188
+ }
189
+ }
190
+
191
+ // ✅ 上位層で一元処理
192
+ // Controller/Handler層でまとめてキャッチ
193
+ // または @ControllerAdvice / ErrorBoundary で処理
194
+ async function createUser(data) {
195
+ return await userService.create(data) // 例外はそのまま上に投げる
196
+ }
197
+ ```
198
+
199
+ **エラー処理の配置:**
200
+
201
+ | 層 | 責務 |
202
+ |----|------|
203
+ | ドメイン/サービス層 | ビジネスルール違反時に例外をスロー |
204
+ | Controller/Handler層 | 例外をキャッチしてレスポンスに変換 |
205
+ | グローバルハンドラ | 共通例外(NotFound, 認証エラー等)を処理 |
206
+
207
+ ## 変換処理の配置
208
+
209
+ **原則: 変換メソッドはDTO側に持たせる。**
210
+
211
+ ```typescript
212
+ // ✅ Request/Response DTOに変換メソッド
213
+ interface CreateUserRequest {
214
+ name: string
215
+ email: string
216
+ }
217
+
218
+ function toUseCaseInput(req: CreateUserRequest): CreateUserInput {
219
+ return { name: req.name, email: req.email }
220
+ }
221
+
222
+ // Controller
223
+ const input = toUseCaseInput(request)
224
+ const output = await useCase.execute(input)
225
+ return UserResponse.from(output)
226
+ ```
227
+
228
+ **変換の方向:**
229
+ ```
230
+ Request → toInput() → UseCase/Service → Output → Response.from()
231
+ ```
232
+
233
+ ## 共通化の判断
234
+
235
+ **3回ルール:**
236
+ - 1回目: そのまま書く
237
+ - 2回目: まだ共通化しない(様子見)
238
+ - 3回目: 共通化を検討
239
+
240
+ **共通化すべきもの:**
241
+ - 同じ処理が3箇所以上
242
+ - 同じスタイル/UIパターン
243
+ - 同じバリデーションロジック
244
+ - 同じフォーマット処理
245
+
246
+ **共通化すべきでないもの:**
247
+ - 似ているが微妙に違うもの(無理に汎用化すると複雑化)
248
+ - 1-2箇所しか使わないもの
249
+ - 「将来使うかも」という予測に基づくもの
250
+
251
+ ```typescript
252
+ // ❌ 過度な汎用化
253
+ function formatValue(value, type, options) {
254
+ if (type === 'currency') { ... }
255
+ else if (type === 'date') { ... }
256
+ else if (type === 'percentage') { ... }
257
+ }
258
+
259
+ // ✅ 用途別に関数を分ける
260
+ function formatCurrency(amount: number): string { ... }
261
+ function formatDate(date: Date): string { ... }
262
+ function formatPercentage(value: number): string { ... }
263
+ ```
264
+
265
+ ## テストの書き方
266
+
267
+ **原則: テストは「Given-When-Then」で構造化する。**
268
+
269
+ ```typescript
270
+ test('ユーザーが存在しない場合、NotFoundエラーを返す', async () => {
271
+ // Given: 存在しないユーザーID
272
+ const nonExistentId = 'non-existent-id'
273
+
274
+ // When: ユーザー取得を試みる
275
+ const result = await getUser(nonExistentId)
276
+
277
+ // Then: NotFoundエラーが返る
278
+ expect(result.error).toBe('NOT_FOUND')
279
+ })
280
+ ```
281
+
282
+ **テストの優先度:**
283
+
284
+ | 優先度 | 対象 |
285
+ |--------|------|
286
+ | 高 | ビジネスロジック、状態遷移 |
287
+ | 中 | エッジケース、エラーハンドリング |
288
+ | 低 | 単純なCRUD、UIの見た目 |
289
+
137
290
  ## 禁止事項
138
291
 
139
292
  - **フォールバック値の乱用** - `?? 'unknown'`、`|| 'default'` で問題を隠さない
@@ -142,4 +295,5 @@
142
295
  - **any型** - 型安全を破壊しない
143
296
  - **オブジェクト/配列の直接変更** - スプレッド演算子で新規作成
144
297
  - **console.log** - 本番コードに残さない
145
- - **機密情報のハードコーディング**
298
+ - **機密情報のハードコーディング**
299
+ - **各所でのtry-catch** - エラーは上位層で一元処理