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.
- package/dist/agents/runner.d.ts +1 -1
- package/dist/agents/runner.d.ts.map +1 -1
- package/dist/agents/runner.js +13 -34
- package/dist/agents/runner.js.map +1 -1
- package/dist/claude/client.d.ts.map +1 -1
- package/dist/claude/client.js +4 -1
- package/dist/claude/client.js.map +1 -1
- package/dist/claude/executor.d.ts.map +1 -1
- package/dist/claude/executor.js +1 -0
- package/dist/claude/executor.js.map +1 -1
- package/dist/claude/types.d.ts +2 -0
- package/dist/claude/types.d.ts.map +1 -1
- package/dist/cli.d.ts +2 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +5 -8
- package/dist/cli.js.map +1 -1
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +4 -8
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/index.d.ts +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/taskExecution.d.ts +1 -6
- package/dist/commands/taskExecution.d.ts.map +1 -1
- package/dist/commands/taskExecution.js +2 -6
- package/dist/commands/taskExecution.js.map +1 -1
- package/dist/commands/workflowExecution.d.ts +0 -2
- package/dist/commands/workflowExecution.d.ts.map +1 -1
- package/dist/commands/workflowExecution.js +34 -13
- package/dist/commands/workflowExecution.js.map +1 -1
- package/dist/mock/client.d.ts +27 -0
- package/dist/mock/client.d.ts.map +1 -0
- package/dist/mock/client.js +56 -0
- package/dist/mock/client.js.map +1 -0
- package/dist/models/schemas.d.ts +6 -0
- package/dist/models/schemas.d.ts.map +1 -1
- package/dist/models/schemas.js +4 -4
- package/dist/models/schemas.js.map +1 -1
- package/dist/models/types.d.ts +6 -4
- package/dist/models/types.d.ts.map +1 -1
- package/dist/providers/claude.d.ts +11 -0
- package/dist/providers/claude.d.ts.map +1 -0
- package/dist/providers/claude.js +37 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/codex.d.ts +11 -0
- package/dist/providers/codex.d.ts.map +1 -0
- package/dist/providers/codex.js +29 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/providers/index.d.ts +39 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +32 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/mock.d.ts +11 -0
- package/dist/providers/mock.d.ts.map +1 -0
- package/dist/providers/mock.js +24 -0
- package/dist/providers/mock.js.map +1 -0
- package/dist/workflow/engine.d.ts.map +1 -1
- package/dist/workflow/engine.js +6 -3
- package/dist/workflow/engine.js.map +1 -1
- package/dist/workflow/instruction-builder.d.ts +5 -2
- package/dist/workflow/instruction-builder.d.ts.map +1 -1
- package/dist/workflow/instruction-builder.js +4 -2
- package/dist/workflow/instruction-builder.js.map +1 -1
- package/dist/workflow/state-manager.d.ts +4 -0
- package/dist/workflow/state-manager.d.ts.map +1 -1
- package/dist/workflow/state-manager.js +10 -0
- package/dist/workflow/state-manager.js.map +1 -1
- package/package.json +1 -1
- package/resources/global/en/agents/default/architect.md +67 -6
- package/resources/global/en/agents/default/coder.md +155 -1
- package/resources/global/en/workflows/default.yaml +36 -16
- package/resources/global/en/workflows/expert-review.yaml +47 -23
- package/resources/global/en/workflows/magi.yaml +10 -0
- package/resources/global/en/workflows/research.yaml +16 -3
- package/resources/global/ja/agents/default/architect.md +62 -1
- package/resources/global/ja/agents/default/coder.md +156 -2
- package/resources/global/ja/agents/expert-review/cqrs-es-reviewer.md +328 -8
- package/resources/global/ja/agents/expert-review/frontend-reviewer.md +303 -33
- package/resources/global/ja/workflows/default.yaml +36 -16
- package/resources/global/ja/workflows/expert-review.yaml +47 -23
- package/resources/global/ja/workflows/magi.yaml +10 -0
- 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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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:
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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** - エラーは上位層で一元処理
|