create-ai-project 1.11.2 → 1.12.1
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/.claude/agents-en/acceptance-test-generator.md +13 -13
- package/.claude/agents-en/code-reviewer.md +8 -10
- package/.claude/agents-en/design-sync.md +6 -5
- package/.claude/agents-en/document-reviewer.md +8 -7
- package/.claude/agents-en/integration-test-reviewer.md +5 -4
- package/.claude/agents-en/prd-creator.md +7 -6
- package/.claude/agents-en/quality-fixer-frontend.md +3 -14
- package/.claude/agents-en/quality-fixer.md +9 -20
- package/.claude/agents-en/requirement-analyzer.md +8 -7
- package/.claude/agents-en/rule-advisor.md +57 -128
- package/.claude/agents-en/task-decomposer.md +4 -10
- package/.claude/agents-en/task-executor-frontend.md +4 -16
- package/.claude/agents-en/task-executor.md +5 -16
- package/.claude/agents-en/technical-designer-frontend.md +17 -15
- package/.claude/agents-en/technical-designer.md +13 -15
- package/.claude/agents-en/work-planner.md +9 -14
- package/.claude/agents-ja/acceptance-test-generator.md +9 -15
- package/.claude/agents-ja/code-reviewer.md +3 -11
- package/.claude/agents-ja/design-sync.md +2 -6
- package/.claude/agents-ja/document-reviewer.md +4 -9
- package/.claude/agents-ja/integration-test-reviewer.md +2 -5
- package/.claude/agents-ja/prd-creator.md +3 -7
- package/.claude/agents-ja/quality-fixer-frontend.md +2 -13
- package/.claude/agents-ja/quality-fixer.md +7 -18
- package/.claude/agents-ja/requirement-analyzer.md +5 -8
- package/.claude/agents-ja/rule-advisor.md +57 -128
- package/.claude/agents-ja/task-decomposer.md +4 -10
- package/.claude/agents-ja/task-executor-frontend.md +3 -15
- package/.claude/agents-ja/task-executor.md +3 -17
- package/.claude/agents-ja/technical-designer-frontend.md +17 -15
- package/.claude/agents-ja/technical-designer.md +13 -15
- package/.claude/agents-ja/work-planner.md +9 -14
- package/.claude/commands-en/build.md +2 -2
- package/.claude/commands-en/design.md +1 -1
- package/.claude/commands-en/implement.md +8 -8
- package/.claude/commands-en/plan.md +3 -3
- package/.claude/commands-en/project-inject.md +4 -4
- package/.claude/commands-en/{refine-rule.md → refine-skill.md} +47 -48
- package/.claude/commands-en/{sync-rules.md → sync-skills.md} +29 -29
- package/.claude/commands-ja/build.md +2 -2
- package/.claude/commands-ja/design.md +1 -1
- package/.claude/commands-ja/implement.md +8 -8
- package/.claude/commands-ja/plan.md +3 -3
- package/.claude/commands-ja/project-inject.md +4 -4
- package/.claude/{commands/refine-rule.md → commands-ja/refine-skill.md} +25 -25
- package/.claude/{commands/sync-rules.md → commands-ja/sync-skills.md} +28 -28
- package/{docs/rules-en/coding-standards.md → .claude/skills-en/coding-standards/SKILL.md} +21 -108
- package/{docs/rules-en/documentation-criteria.md → .claude/skills-en/documentation-criteria/SKILL.md} +40 -42
- package/{docs/adr/template-en.md → .claude/skills-en/documentation-criteria/references/adr-template.md} +1 -1
- package/{docs/design/template-en.md → .claude/skills-en/documentation-criteria/references/design-template.md} +11 -31
- package/{docs/plans/template-en.md → .claude/skills-en/documentation-criteria/references/plan-template.md} +4 -4
- package/{docs/prd/template-en.md → .claude/skills-en/documentation-criteria/references/prd-template.md} +1 -1
- package/{docs/rules-en/frontend/technical-spec.md → .claude/skills-en/frontend/technical-spec/SKILL.md} +17 -13
- package/{docs/rules-en/frontend/typescript.md → .claude/skills-en/frontend/typescript-rules/SKILL.md} +17 -12
- package/{docs/rules-en/frontend/typescript-testing.md → .claude/skills-en/frontend/typescript-testing/SKILL.md} +11 -6
- package/{docs/rules-en/architecture/implementation-approach.md → .claude/skills-en/implementation-approach/SKILL.md} +7 -2
- package/{docs/rules-en/integration-e2e-testing.md → .claude/skills-en/integration-e2e-testing/SKILL.md} +15 -18
- package/{docs/rules-en/project-context.md → .claude/skills-en/project-context/SKILL.md} +7 -3
- package/.claude/skills-en/subagents-orchestration-guide/SKILL.md +224 -0
- package/.claude/skills-en/task-analyzer/SKILL.md +131 -0
- package/{docs/rules-en/rules-index.yaml → .claude/skills-en/task-analyzer/references/skills-index.yaml} +34 -20
- package/{docs/rules-en/technical-spec.md → .claude/skills-en/technical-spec/SKILL.md} +6 -6
- package/{docs/rules-en/typescript.md → .claude/skills-en/typescript-rules/SKILL.md} +15 -10
- package/{docs/rules-en/typescript-testing.md → .claude/skills-en/typescript-testing/SKILL.md} +10 -4
- package/{docs/rules-ja/coding-standards.md → .claude/skills-ja/coding-standards/SKILL.md} +12 -99
- package/{docs/rules-ja/documentation-criteria.md → .claude/skills-ja/documentation-criteria/SKILL.md} +18 -5
- package/.claude/skills-ja/documentation-criteria/references/adr-template.md +64 -0
- package/.claude/skills-ja/documentation-criteria/references/design-template.md +261 -0
- package/{docs/plans/template-ja.md → .claude/skills-ja/documentation-criteria/references/plan-template.md} +38 -38
- package/{docs/prd/template-ja.md → .claude/skills-ja/documentation-criteria/references/prd-template.md} +33 -33
- package/{docs/rules-ja/frontend/technical-spec.md → .claude/skills-ja/frontend/technical-spec/SKILL.md} +13 -9
- package/.claude/skills-ja/frontend/typescript-rules/SKILL.md +315 -0
- package/{docs/rules-ja/frontend/typescript-testing.md → .claude/skills-ja/frontend/typescript-testing/SKILL.md} +93 -5
- package/{docs/rules/architecture/implementation-approach.md → .claude/skills-ja/implementation-approach/SKILL.md} +10 -5
- package/{docs/rules-ja/integration-e2e-testing.md → .claude/skills-ja/integration-e2e-testing/SKILL.md} +5 -8
- package/{docs/rules-ja/project-context.md → .claude/skills-ja/project-context/SKILL.md} +7 -3
- package/.claude/skills-ja/subagents-orchestration-guide/SKILL.md +212 -0
- package/.claude/skills-ja/task-analyzer/SKILL.md +131 -0
- package/{docs/rules-ja/rules-index.yaml → .claude/skills-ja/task-analyzer/references/skills-index.yaml} +34 -19
- package/{docs/rules-ja/technical-spec.md → .claude/skills-ja/technical-spec/SKILL.md} +6 -6
- package/{docs/rules-ja/typescript.md → .claude/skills-ja/typescript-rules/SKILL.md} +16 -11
- package/{docs/rules-ja/typescript-testing.md → .claude/skills-ja/typescript-testing/SKILL.md} +11 -5
- package/CLAUDE.en.md +6 -6
- package/CLAUDE.ja.md +6 -6
- package/CLAUDE.md +19 -28
- package/README.ja.md +39 -10
- package/README.md +39 -10
- package/package.json +1 -1
- package/scripts/set-language.js +35 -53
- package/scripts/setup-project.js +4 -1
- package/.claude/agents/acceptance-test-generator.md +0 -316
- package/.claude/agents/code-reviewer.md +0 -193
- package/.claude/agents/document-reviewer.md +0 -182
- package/.claude/agents/prd-creator.md +0 -186
- package/.claude/agents/quality-fixer.md +0 -295
- package/.claude/agents/requirement-analyzer.md +0 -161
- package/.claude/agents/rule-advisor.md +0 -194
- package/.claude/agents/task-decomposer.md +0 -291
- package/.claude/agents/task-executor.md +0 -270
- package/.claude/agents/technical-designer.md +0 -343
- package/.claude/agents/work-planner.md +0 -181
- package/.claude/commands/build.md +0 -78
- package/.claude/commands/design.md +0 -27
- package/.claude/commands/implement.md +0 -79
- package/.claude/commands/plan.md +0 -43
- package/.claude/commands/project-inject.md +0 -76
- package/.claude/commands/review.md +0 -78
- package/.claude/commands/task.md +0 -13
- package/.claude/commands-ja/refine-rule.md +0 -206
- package/.claude/commands-ja/sync-rules.md +0 -116
- package/.claude/settings.local.json +0 -74
- package/docs/adr/template-ja.md +0 -64
- package/docs/design/template-ja.md +0 -285
- package/docs/guides/en/sub-agents.md +0 -343
- package/docs/guides/ja/sub-agents.md +0 -343
- package/docs/guides/sub-agents.md +0 -306
- package/docs/plans/20250123-integration-test-improvement.md +0 -993
- package/docs/rules/ai-development-guide.md +0 -260
- package/docs/rules/documentation-criteria.md +0 -180
- package/docs/rules/project-context.md +0 -38
- package/docs/rules/rules-index.yaml +0 -137
- package/docs/rules/technical-spec.md +0 -47
- package/docs/rules/typescript-testing.md +0 -188
- package/docs/rules/typescript.md +0 -166
- package/docs/rules-ja/architecture/implementation-approach.md +0 -136
- package/docs/rules-ja/frontend/typescript.md +0 -131
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
# TypeScript テストルール
|
|
2
|
-
|
|
3
|
-
## テストフレームワーク
|
|
4
|
-
- **Vitest**: このプロジェクトではVitestを使用
|
|
5
|
-
- テストのインポート: `import { describe, it, expect, beforeEach, vi } from 'vitest'`
|
|
6
|
-
- モックの作成: `vi.mock()` を使用
|
|
7
|
-
|
|
8
|
-
## テストの基本方針
|
|
9
|
-
|
|
10
|
-
### 品質要件
|
|
11
|
-
- **カバレッジ**: 単体テストのカバレッジは70%以上を必須
|
|
12
|
-
- **独立性**: 各テストは他のテストに依存せず実行可能
|
|
13
|
-
- **再現性**: テストは環境に依存せず、常に同じ結果を返す
|
|
14
|
-
- **可読性**: テストコードも製品コードと同様の品質を維持
|
|
15
|
-
|
|
16
|
-
### カバレッジ要件
|
|
17
|
-
**必須**: 単体テストのカバレッジは70%以上
|
|
18
|
-
**指標**: Statements(文)、Branches(分岐)、Functions(関数)、Lines(行)
|
|
19
|
-
|
|
20
|
-
### テストの種類と範囲
|
|
21
|
-
1. **単体テスト(Unit Tests)**
|
|
22
|
-
- 個々の関数やクラスの動作を検証
|
|
23
|
-
- 外部依存はすべてモック化
|
|
24
|
-
- 最も数が多く、細かい粒度で実施
|
|
25
|
-
|
|
26
|
-
2. **統合テスト(Integration Tests)**
|
|
27
|
-
- 複数のコンポーネントの連携を検証
|
|
28
|
-
- 実際の依存関係を使用(DBやAPI等)
|
|
29
|
-
- 主要な機能フローの検証
|
|
30
|
-
|
|
31
|
-
3. **E2Eテストでの機能横断検証**
|
|
32
|
-
- 新機能追加時、既存機能への影響を必ず検証
|
|
33
|
-
- Design Docの「統合ポイントマップ」で影響度「高」「中」の箇所をカバー
|
|
34
|
-
- 検証パターン: 既存機能動作 → 新機能有効化 → 既存機能の継続性確認
|
|
35
|
-
- 判定基準: レスポンス内容の変化なし、処理時間5秒以内
|
|
36
|
-
- CI/CDでの自動実行を前提とした設計
|
|
37
|
-
|
|
38
|
-
## Red-Green-Refactorプロセス(テストファースト開発)
|
|
39
|
-
|
|
40
|
-
**推奨原則**: コード変更は必ずテストから始める
|
|
41
|
-
|
|
42
|
-
**背景**:
|
|
43
|
-
- 変更前の動作を保証し、リグレッションを防止
|
|
44
|
-
- 期待する動作を明確化してから実装
|
|
45
|
-
- リファクタリング時の安全性を確保
|
|
46
|
-
|
|
47
|
-
**開発ステップ**:
|
|
48
|
-
1. **Red**: 期待する動作のテストを書く(失敗する)
|
|
49
|
-
2. **Green**: 最小限の実装でテストを通す
|
|
50
|
-
3. **Refactor**: テストが通る状態を維持しながらコード改善
|
|
51
|
-
|
|
52
|
-
**NGケース(テストファースト不要)**:
|
|
53
|
-
- 純粋な設定ファイル変更(.env、config等)
|
|
54
|
-
- ドキュメントのみの更新(README、コメント等)
|
|
55
|
-
- 緊急本番障害対応(ただし事後テスト必須)
|
|
56
|
-
|
|
57
|
-
## テストの設計原則
|
|
58
|
-
|
|
59
|
-
### テストケースの構造
|
|
60
|
-
- テストは「準備(Arrange)」「実行(Act)」「検証(Assert)」の3段階で構成
|
|
61
|
-
- 各テストの目的が明確に分かる命名
|
|
62
|
-
- 1つのテストケースでは1つの振る舞いのみを検証
|
|
63
|
-
|
|
64
|
-
### テストデータ管理
|
|
65
|
-
- テストデータは専用ディレクトリで管理
|
|
66
|
-
- 環境変数はテスト用の値を定義
|
|
67
|
-
- 機密情報は必ずモック化
|
|
68
|
-
- テストデータは最小限に保ち、テストケースの検証目的に直接関連するデータのみ使用
|
|
69
|
-
|
|
70
|
-
### モックとスタブの使用方針
|
|
71
|
-
|
|
72
|
-
✅ **推奨: 単体テストでの外部依存モック化**
|
|
73
|
-
- メリット: テストの独立性と再現性を確保
|
|
74
|
-
- 実践: DB、API、ファイルシステム等の外部依存をモック化
|
|
75
|
-
|
|
76
|
-
❌ **避けるべき: 単体テストでの実際の外部接続**
|
|
77
|
-
- 理由: テスト速度が遅くなり、環境依存の問題が発生するため
|
|
78
|
-
|
|
79
|
-
### テスト失敗時の対応判断基準
|
|
80
|
-
|
|
81
|
-
**テストを修正**: 間違った期待値、存在しない機能参照、実装詳細への依存、テストのためだけの実装
|
|
82
|
-
**実装を修正**: 妥当な仕様、ビジネスロジック、重要なエッジケース
|
|
83
|
-
**判断に迷ったら**: ユーザーに確認
|
|
84
|
-
|
|
85
|
-
## テストヘルパーの活用ルール
|
|
86
|
-
|
|
87
|
-
### 基本原則
|
|
88
|
-
テストヘルパーは、テストコードの重複を減らし、保守性を高めるために活用します。
|
|
89
|
-
|
|
90
|
-
### 判断基準
|
|
91
|
-
| モックの特性 | 対応方針 |
|
|
92
|
-
|-------------|---------|
|
|
93
|
-
| **単純で安定** | 共通ヘルパーに集約 |
|
|
94
|
-
| **複雑または変更頻度高** | 個別実装 |
|
|
95
|
-
| **3箇所以上で重複** | 共通化を検討 |
|
|
96
|
-
| **テスト固有ロジック** | 個別実装 |
|
|
97
|
-
|
|
98
|
-
### テストヘルパー活用例
|
|
99
|
-
```typescript
|
|
100
|
-
// ✅ ビルダーパターン
|
|
101
|
-
const testData = new TestDataBuilder().withDefaults().withName('Test User').build()
|
|
102
|
-
|
|
103
|
-
// ✅ カスタムアサーション
|
|
104
|
-
function assertValidUser(user: unknown): asserts user is User {}
|
|
105
|
-
|
|
106
|
-
// ❌ 重複する複雑なモックの個別実装
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## テストの実装規約
|
|
110
|
-
|
|
111
|
-
### ディレクトリ構造
|
|
112
|
-
```
|
|
113
|
-
src/
|
|
114
|
-
└── application/
|
|
115
|
-
└── services/
|
|
116
|
-
├── __tests__/
|
|
117
|
-
│ ├── service.test.ts # 単体テスト
|
|
118
|
-
│ └── service.int.test.ts # 統合テスト
|
|
119
|
-
└── service.ts
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### 命名規則
|
|
123
|
-
- テストファイル: `{対象ファイル名}.test.ts`
|
|
124
|
-
- 統合テストファイル: `{対象ファイル名}.int.test.ts`
|
|
125
|
-
- テストスイート: 対象の機能や状況を説明する名前
|
|
126
|
-
- テストケース: 期待される動作を説明する名前
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
### テストコードの品質ルール
|
|
130
|
-
|
|
131
|
-
✅ **推奨: すべてのテストを常に有効に保つ**
|
|
132
|
-
- メリット: テストスイートの完全性を保証
|
|
133
|
-
- 実践: 問題があるテストは修正して有効化
|
|
134
|
-
|
|
135
|
-
❌ **避けるべき: test.skip()やコメントアウト**
|
|
136
|
-
- 理由: テストの穴が生まれ、品質チェックが不完全になる
|
|
137
|
-
- 対処: 不要なテストは完全に削除する
|
|
138
|
-
|
|
139
|
-
## テストの粒度
|
|
140
|
-
|
|
141
|
-
### 原則:観測可能な振る舞いのみ
|
|
142
|
-
**テスト対象**:公開API、戻り値、例外、外部呼び出し、永続化された状態
|
|
143
|
-
**テスト対象外**:privateメソッド、内部状態、アルゴリズム詳細
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
// ✅ 振る舞いをテスト
|
|
147
|
-
expect(calculatePrice(100, 0.1)).toBe(110)
|
|
148
|
-
|
|
149
|
-
// ❌ 実装詳細をテスト
|
|
150
|
-
expect((calculator as any).taxRate).toBe(0.1)
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
## モックの型安全性
|
|
154
|
-
|
|
155
|
-
### 必要最小限の型定義
|
|
156
|
-
```typescript
|
|
157
|
-
// ✅ 必要な部分のみ
|
|
158
|
-
type TestRepo = Pick<Repository, 'find' | 'save'>
|
|
159
|
-
const mock: TestRepo = { find: vi.fn(), save: vi.fn() }
|
|
160
|
-
|
|
161
|
-
// やむを得ない場合のみ、理由明記
|
|
162
|
-
const sdkMock = {
|
|
163
|
-
call: vi.fn()
|
|
164
|
-
} as unknown as ExternalSDK // 外部SDKの複雑な型のため
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
## 継続性テストの範囲
|
|
168
|
-
|
|
169
|
-
新機能追加時の既存機能への影響確認に限定。長時間運用・負荷テストはインフラ層の責務のため対象外。
|
|
170
|
-
|
|
171
|
-
## Vitestの基本例
|
|
172
|
-
|
|
173
|
-
```typescript
|
|
174
|
-
import { describe, it, expect, vi } from 'vitest'
|
|
175
|
-
|
|
176
|
-
vi.mock('./userService', () => ({
|
|
177
|
-
getUserById: vi.fn(),
|
|
178
|
-
updateUser: vi.fn()
|
|
179
|
-
}))
|
|
180
|
-
|
|
181
|
-
describe('ComponentName', () => {
|
|
182
|
-
it('should follow AAA pattern', () => {
|
|
183
|
-
const input = 'test'
|
|
184
|
-
const result = someFunction(input)
|
|
185
|
-
expect(result).toBe('expected')
|
|
186
|
-
})
|
|
187
|
-
})
|
|
188
|
-
```
|
package/docs/rules/typescript.md
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
# TypeScript 開発ルール
|
|
2
|
-
|
|
3
|
-
## 基本原則
|
|
4
|
-
|
|
5
|
-
✅ **積極的なリファクタリング** - 技術的負債を防ぎ、健全性を維持
|
|
6
|
-
❌ **使われない「念のため」のコード** - YAGNI原則(Kent Beck)に反する
|
|
7
|
-
|
|
8
|
-
## コメント記述ルール
|
|
9
|
-
- **機能説明重視**: コードが「何をするか」を記述
|
|
10
|
-
- **履歴情報禁止**: 開発履歴は記載しない
|
|
11
|
-
- **タイムレス**: いつ読んでも有効な内容のみ記述
|
|
12
|
-
- **簡潔性**: 必要最小限の説明にとどめる
|
|
13
|
-
|
|
14
|
-
## 型安全性
|
|
15
|
-
|
|
16
|
-
**絶対ルール**: any型は完全禁止。型チェックが無効化され、実行時エラーの温床となる。
|
|
17
|
-
|
|
18
|
-
**any型の代替手段(優先順位順)**
|
|
19
|
-
1. **unknown型 + 型ガード**: 外部入力の検証に使用
|
|
20
|
-
2. **ジェネリクス**: 型の柔軟性が必要な場合
|
|
21
|
-
3. **ユニオン型・インターセクション型**: 複数の型の組み合わせ
|
|
22
|
-
4. **型アサーション(最終手段)**: 型が確実な場合のみ
|
|
23
|
-
|
|
24
|
-
**型ガードの実装パターン**
|
|
25
|
-
```typescript
|
|
26
|
-
function isUser(value: unknown): value is User {
|
|
27
|
-
return typeof value === 'object' && value !== null && 'id' in value && 'name' in value
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
**モダンな型機能の活用**
|
|
32
|
-
- **satisfies演算子**: `const config = { port: 3000 } satisfies Config` - 型推論維持
|
|
33
|
-
- **const assertion**: `const ROUTES = { HOME: '/' } as const satisfies Routes` - 不変かつ型安全
|
|
34
|
-
- **ブランド型**: `type UserId = string & { __brand: 'UserId' }` - 意味を区別
|
|
35
|
-
- **テンプレートリテラル型**: `type Endpoint = \`\${HttpMethod} \${Route}\`` - 文字列パターンを型で表現
|
|
36
|
-
|
|
37
|
-
**実装での型安全性**
|
|
38
|
-
- API通信: レスポンスは必ず`unknown`で受け、型ガードで検証
|
|
39
|
-
- フォーム入力: 外部入力は`unknown`、バリデーション後に型確定
|
|
40
|
-
- レガシー統合: `window as unknown as LegacyWindow`のように段階的アサーション
|
|
41
|
-
- テストコード: モックも必ず型定義、`Partial<T>`や`vi.fn<[Args], Return>()`活用
|
|
42
|
-
|
|
43
|
-
**データフローでの型安全性**
|
|
44
|
-
入力層(`unknown`) → 型ガード → ビジネス層(型保証) → 出力層(シリアライズ)
|
|
45
|
-
|
|
46
|
-
**型の複雑性管理**
|
|
47
|
-
- フィールド数: 20個まで(超えたら責務で分割、外部API型は例外)
|
|
48
|
-
- オプショナル率: 30%まで(超えたら必須/任意で分離)
|
|
49
|
-
- ネスト深さ: 3階層まで(超えたらフラット化)
|
|
50
|
-
- 型アサーション: 3回以上使用したら設計見直し
|
|
51
|
-
- **外部API型の扱い**: 制約を緩和し、実態に合わせて定義(内部では適切に変換)
|
|
52
|
-
|
|
53
|
-
## コーディング規約
|
|
54
|
-
|
|
55
|
-
**クラス使用の判断基準**
|
|
56
|
-
- **推奨:関数とinterfaceでの実装**
|
|
57
|
-
- 背景: テスタビリティと関数合成の柔軟性が向上
|
|
58
|
-
- **クラス使用を許可**:
|
|
59
|
-
- フレームワーク要求時(NestJSのController/Service、TypeORMのEntity等)
|
|
60
|
-
- カスタムエラークラス定義時
|
|
61
|
-
- 状態とビジネスロジックが密結合している場合(例: ShoppingCart、Session、StateMachine)
|
|
62
|
-
- **判断基準**: 「このデータは振る舞いを持つか?」がYesならクラス検討
|
|
63
|
-
```typescript
|
|
64
|
-
// ✅ 関数とinterface
|
|
65
|
-
interface UserService { create(data: UserData): User }
|
|
66
|
-
const userService: UserService = { create: (data) => {...} }
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
**関数設計**
|
|
70
|
-
- **引数は0-2個まで**: 3個以上はオブジェクト化
|
|
71
|
-
```typescript
|
|
72
|
-
// ✅ オブジェクト引数
|
|
73
|
-
function createUser({ name, email, role }: CreateUserParams) {}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
**依存性注入**
|
|
77
|
-
- **外部依存は引数で注入**: テスト可能性とモジュール性確保
|
|
78
|
-
```typescript
|
|
79
|
-
// ✅ 依存性を引数で受け取る
|
|
80
|
-
function createService(repository: Repository) { return {...} }
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
**非同期処理**
|
|
84
|
-
- Promise処理: 必ず`async/await`を使用
|
|
85
|
-
- エラーハンドリング: 必ず`try-catch`でハンドリング
|
|
86
|
-
- 型定義: 戻り値の型は明示的に定義(例: `Promise<Result>`)
|
|
87
|
-
|
|
88
|
-
**フォーマット規則**
|
|
89
|
-
- セミコロン省略(Biomeの設定に従う)
|
|
90
|
-
- 型は`PascalCase`、変数・関数は`camelCase`
|
|
91
|
-
- インポートは絶対パス(`src/`)
|
|
92
|
-
|
|
93
|
-
**クリーンコード原則**
|
|
94
|
-
- ✅ 使用されていないコードは即座に削除
|
|
95
|
-
- ✅ デバッグ用`console.log()`は削除
|
|
96
|
-
- ❌ コメントアウトされたコード(バージョン管理で履歴管理)
|
|
97
|
-
- ✅ コメントは「なぜ」を説明(「何」ではなく)
|
|
98
|
-
|
|
99
|
-
## エラーハンドリング
|
|
100
|
-
|
|
101
|
-
**絶対ルール**: エラーの握りつぶし禁止。すべてのエラーは必ずログ出力と適切な処理を行う。
|
|
102
|
-
|
|
103
|
-
**Fail-Fast原則**: エラー時は速やかに失敗させ、不正な状態での処理継続を防ぐ
|
|
104
|
-
```typescript
|
|
105
|
-
// ❌ 禁止: 無条件フォールバック
|
|
106
|
-
catch (error) {
|
|
107
|
-
return defaultValue // エラーを隠蔽
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// ✅ 必須: 明示的な失敗
|
|
111
|
-
catch (error) {
|
|
112
|
-
logger.error('処理失敗', error)
|
|
113
|
-
throw error // 上位層で適切に処理
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
**Result型パターン**: エラーを型で表現し、明示的に処理
|
|
118
|
-
```typescript
|
|
119
|
-
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E }
|
|
120
|
-
|
|
121
|
-
// 使用例:エラーの可能性を型で表現
|
|
122
|
-
function parseUser(data: unknown): Result<User, ValidationError> {
|
|
123
|
-
if (!isValid(data)) return { ok: false, error: new ValidationError() }
|
|
124
|
-
return { ok: true, value: data as User }
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
**カスタムエラークラス**
|
|
129
|
-
```typescript
|
|
130
|
-
export class AppError extends Error {
|
|
131
|
-
constructor(message: string, public readonly code: string, public readonly statusCode = 500) {
|
|
132
|
-
super(message)
|
|
133
|
-
this.name = this.constructor.name
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
// 用途別: ValidationError(400), BusinessRuleError(400), DatabaseError(500), ExternalServiceError(502)
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
**層別エラー処理**
|
|
140
|
-
- API層: HTTPレスポンスに変換、機密情報を除外してログ出力
|
|
141
|
-
- サービス層: ビジネスルール違反を検出、AppErrorはそのまま伝播
|
|
142
|
-
- リポジトリ層: 技術的エラーをドメインエラーに変換
|
|
143
|
-
|
|
144
|
-
**構造化ログと機密情報保護**
|
|
145
|
-
機密情報(password, token, apiKey, secret, creditCard)は絶対にログに含めない
|
|
146
|
-
|
|
147
|
-
**非同期エラーハンドリング**
|
|
148
|
-
- グローバルハンドラー設定必須: `unhandledRejection`, `uncaughtException`
|
|
149
|
-
- すべてのasync/awaitでtry-catch使用
|
|
150
|
-
- エラーは必ずログと再スロー
|
|
151
|
-
|
|
152
|
-
## リファクタリング手法
|
|
153
|
-
|
|
154
|
-
**基本方針**
|
|
155
|
-
- 小さなステップ: 段階的改善により、常に動作する状態を維持
|
|
156
|
-
- 安全な変更: 一度に変更する範囲を最小限に抑制
|
|
157
|
-
- 動作保証: 既存の動作を変えないことを確認しながら進める
|
|
158
|
-
|
|
159
|
-
**実施手順**: 現状把握 → 段階的変更 → 動作確認 → 最終検証
|
|
160
|
-
|
|
161
|
-
**優先順位**: 重複コード削除 > 長大な関数分割 > 複雑な条件分岐簡素化 > 型安全性向上
|
|
162
|
-
|
|
163
|
-
## パフォーマンス最適化
|
|
164
|
-
|
|
165
|
-
- ストリーミング処理: 大きなデータセットはストリームで処理
|
|
166
|
-
- メモリリーク防止: 不要なオブジェクトは明示的に解放
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
# 実装戦略選択フレームワーク(メタ認知的アプローチ)
|
|
2
|
-
|
|
3
|
-
## メタ認知的戦略選択プロセス
|
|
4
|
-
|
|
5
|
-
### Phase 1: 現状の包括的分析
|
|
6
|
-
|
|
7
|
-
**核心質問**: 「既存の実装はどうなっているのか?」
|
|
8
|
-
|
|
9
|
-
#### 分析フレームワーク
|
|
10
|
-
```yaml
|
|
11
|
-
アーキテクチャ分析: 責務分離、データフロー、依存関係、技術的負債
|
|
12
|
-
実装品質評価: コード品質、テストカバレッジ、パフォーマンス、セキュリティ
|
|
13
|
-
歴史的文脈理解: 現在の形の理由、過去判断の妥当性、制約の変化、要求の進化
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
#### メタ認知質問リスト
|
|
17
|
-
- この実装の真の責務は何か?
|
|
18
|
-
- どの部分がビジネス本質で、どの部分が技術的制約由来か?
|
|
19
|
-
- コードから明確でない依存関係や暗黙の前提条件は何か?
|
|
20
|
-
- 現在の設計がもたらしている利点と制約は?
|
|
21
|
-
|
|
22
|
-
### Phase 2: 戦略探索と創造
|
|
23
|
-
|
|
24
|
-
**核心質問**: 「before → after を判断する時に、参考にすべき実装パターンや戦略は何なのか?」
|
|
25
|
-
|
|
26
|
-
#### 戦略発見プロセス
|
|
27
|
-
```yaml
|
|
28
|
-
調査・探索: 技術スタック事例(WebSearch活用)、同種プロジェクト、OSS実装、文献・ブログ
|
|
29
|
-
創造的思考: 戦略組み合わせ、制約前提設計、フェーズ分け、拡張ポイント設計
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
#### 参考戦略パターン(創造的組み合わせを推奨)
|
|
33
|
-
|
|
34
|
-
**レガシー対応戦略**:
|
|
35
|
-
- ストラングラーパターン: 段階的置換による漸進的移行
|
|
36
|
-
- ファサードパターン: 統一インターフェースによる複雑性の隠蔽
|
|
37
|
-
- アダプターパターン: 既存システムとの橋渡し
|
|
38
|
-
|
|
39
|
-
**新規開発戦略**:
|
|
40
|
-
- 機能駆動開発: ユーザー価値重視の縦断実装
|
|
41
|
-
- 基盤駆動開発: 安定性重視の基盤優先構築
|
|
42
|
-
- リスク駆動開発: 最大リスク要素から優先的に対処
|
|
43
|
-
|
|
44
|
-
**統合・移行戦略**:
|
|
45
|
-
- プロキシパターン: 透過的な機能拡張
|
|
46
|
-
- デコレーターパターン: 既存機能の段階的強化
|
|
47
|
-
- ブリッジパターン: 抽象化による柔軟性確保
|
|
48
|
-
|
|
49
|
-
**重要**: 最適解は各プロジェクトの文脈に応じた創造的思考により発見される。
|
|
50
|
-
|
|
51
|
-
### Phase 3: リスク評価とコントロール
|
|
52
|
-
|
|
53
|
-
**核心質問**: 「既存の実装にそれを当てはめた時にどういうリスクが発生し、それをどうコントロールするのが最良なのか?」
|
|
54
|
-
|
|
55
|
-
#### リスク分析マトリクス
|
|
56
|
-
```yaml
|
|
57
|
-
技術的リスク: 既存システム影響、データ整合性、パフォーマンス劣化、統合複雑性
|
|
58
|
-
運用リスク: サービス可用性、デプロイダウンタイム、運用プロセス変更、切り戻し手順
|
|
59
|
-
プロジェクトリスク: スケジュール遅延、技術習得コスト、品質達成度、チーム連携
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
#### リスクコントロール戦略
|
|
63
|
-
```yaml
|
|
64
|
-
予防的対策: 段階的移行、並行動作検証、統合・回帰テスト追加、監視設定
|
|
65
|
-
発生時対応: 切り戻し手順、ログ・メトリクス準備、連絡体制定義、サービス継続手順
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Phase 4: 制約適合性検証
|
|
69
|
-
|
|
70
|
-
**核心質問**: 「このプロジェクトの制約は何か?」
|
|
71
|
-
|
|
72
|
-
#### 制約チェックリスト
|
|
73
|
-
```yaml
|
|
74
|
-
技術的制約: ライブラリ互換性、リソース容量、義務要件、数値目標
|
|
75
|
-
時間的制約: 期限・優先度、依存関係、マイルストーン、学習期間
|
|
76
|
-
リソース制約: チーム・スキル、作業時間・体制、予算、外部契約
|
|
77
|
-
ビジネス制約: 市場投入時期、顧客影響、法規制・標準
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Phase 5: 実装アプローチ決定
|
|
81
|
-
|
|
82
|
-
基本的な実装アプローチから最適解を選択(創造的組み合わせも推奨):
|
|
83
|
-
|
|
84
|
-
#### 垂直スライス(機能駆動)
|
|
85
|
-
**特徴**: 機能単位で全層を縦断実装
|
|
86
|
-
**適用条件**: 機能間の依存が少ない、ユーザーが利用可能な形で出力、アーキテクチャ全層への変更が必要
|
|
87
|
-
**確認方法**: 各機能完成時のエンドユーザー価値提供
|
|
88
|
-
|
|
89
|
-
#### 水平スライス(基盤駆動)
|
|
90
|
-
**特徴**: アーキテクチャ層別の段階的構築
|
|
91
|
-
**適用条件**: 基盤システムの安定性が重要、複数機能が共通基盤に依存、層別の段階的確認が有効
|
|
92
|
-
**確認方法**: 全基盤層完成時の統合動作確認
|
|
93
|
-
|
|
94
|
-
#### ハイブリッド(創造的組み合わせ)
|
|
95
|
-
**特徴**: プロジェクト特性に応じた柔軟な組み合わせ
|
|
96
|
-
**適用条件**: 要件が明確でない、フェーズごとにアプローチ変更が必要、プロトタイピングから本格実装への移行
|
|
97
|
-
**確認方法**: 各フェーズの目標に応じてL1/L2/L3の適切なレベルで確認
|
|
98
|
-
|
|
99
|
-
### Phase 6: 判断根拠の文書化
|
|
100
|
-
|
|
101
|
-
**Design Docでの記載**:実装戦略の選択理由と根拠を明記する。
|
|
102
|
-
|
|
103
|
-
## 確認レベル定義
|
|
104
|
-
|
|
105
|
-
各タスクの完了確認における優先順位:
|
|
106
|
-
|
|
107
|
-
- **L1: 機能動作確認** - エンドユーザー機能として動作(例:検索実行可能)
|
|
108
|
-
- **L2: テスト動作確認** - 新規テストが追加されパス(例:型定義テスト)
|
|
109
|
-
- **L3: ビルド成功確認** - コンパイルエラーなし(例:インターフェース定義)
|
|
110
|
-
|
|
111
|
-
**優先順位**: L1 > L2 > L3 の順で確認可能性を重視
|
|
112
|
-
|
|
113
|
-
## 統合ポイントの定義
|
|
114
|
-
|
|
115
|
-
選択した戦略に応じて統合ポイントを定義:
|
|
116
|
-
- **ストラングラー系**: 各機能の新旧システム切り替え時
|
|
117
|
-
- **機能駆動**: ユーザーが実際に機能を利用可能になった時
|
|
118
|
-
- **基盤駆動**: 全アーキテクチャ層が揃いE2Eテストが通った時
|
|
119
|
-
- **ハイブリッド**: 各フェーズで定義した個別目標達成時
|
|
120
|
-
|
|
121
|
-
## アンチパターン
|
|
122
|
-
|
|
123
|
-
- **パターン固執**: リスト内の戦略のみで選択し、独自の組み合わせを検討しない
|
|
124
|
-
- **分析不足**: Phase 1の分析フレームワークを飛ばして戦略選択
|
|
125
|
-
- **リスク軽視**: Phase 3のリスク分析マトリクスを省略して実装着手
|
|
126
|
-
- **制約無視**: Phase 4の制約チェックリストを確認せず戦略決定
|
|
127
|
-
- **根拠省略**: Phase 6の文書化テンプレートを使用せず戦略選択
|
|
128
|
-
|
|
129
|
-
## メタ認知的実行のための指針
|
|
130
|
-
|
|
131
|
-
1. **既知パターンの活用**: 出発点として参考し、創造的組み合わせを探索
|
|
132
|
-
2. **WebSearch積極活用**: 同種技術スタックの実装事例を調査
|
|
133
|
-
3. **5 Whys適用**: 根本理由を追求し本質を把握
|
|
134
|
-
4. **複数観点評価**: Phase 1-4の各観点から網羅的に評価
|
|
135
|
-
5. **創造的思考**: 複数戦略の順序適用やプロジェクト固有の制約を活かした設計を検討
|
|
136
|
-
6. **判断根拠明示**: 設計ドキュメントでの戦略選択根拠を明示化
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
# TypeScript開発ルール
|
|
2
|
-
|
|
3
|
-
## フロントエンド固有のアンチパターン
|
|
4
|
-
|
|
5
|
-
coding-standards.mdの普遍的アンチパターンに加え、以下のフロントエンド固有の問題に注意:
|
|
6
|
-
|
|
7
|
-
- **3階層以上のProp drilling** - Context APIまたは状態管理を使用すべき
|
|
8
|
-
- **巨大なコンポーネント(300行以上)** - 小さなコンポーネントに分割
|
|
9
|
-
|
|
10
|
-
## Frontend実装における型安全性
|
|
11
|
-
|
|
12
|
-
**データフローにおける型安全性**
|
|
13
|
-
- **Frontend → Backend**: Props/State(型保証済み) → APIリクエスト(シリアライゼーション)
|
|
14
|
-
- **Backend → Frontend**: APIレスポンス(`unknown`) → 型ガード → State(型保証済み)
|
|
15
|
-
|
|
16
|
-
**Frontend固有の型シナリオ**:
|
|
17
|
-
- **React Props/State**: TypeScriptが型管理、unknown不要
|
|
18
|
-
- **外部APIレスポンス**: 常に`unknown`として受け取り、型ガードで検証
|
|
19
|
-
- **localStorage/sessionStorage**: `unknown`として扱い、検証
|
|
20
|
-
- **URLパラメータ**: `unknown`として扱い、検証
|
|
21
|
-
- **Form入力(Controlled Components)**: React合成イベントで型安全
|
|
22
|
-
|
|
23
|
-
**型の複雑性管理(Frontend)**
|
|
24
|
-
- **Props設計**:
|
|
25
|
-
- Props数: 3-7個が理想(10個超えたらコンポーネント分割検討)
|
|
26
|
-
- Optional Props: 50%以下(多すぎる場合はデフォルト値やContext使用検討)
|
|
27
|
-
- ネスト: 2レベルまで(深いネストはFlatten推奨)
|
|
28
|
-
- 型アサーション: 3回以上使用で設計見直し
|
|
29
|
-
- **外部API型**: 制約を緩和し実態に応じて定義(内部で適切に変換)
|
|
30
|
-
|
|
31
|
-
## コーディング規約
|
|
32
|
-
|
|
33
|
-
**コンポーネント設計基準**
|
|
34
|
-
- **Function Components(必須)**: React公式推奨、モダンツールで最適化可能
|
|
35
|
-
- **Classes禁止**: Class componentsは完全非推奨(例外: Error Boundary)
|
|
36
|
-
- **Custom Hooks**: ロジック再利用の標準パターン
|
|
37
|
-
|
|
38
|
-
**関数設計**
|
|
39
|
-
- **0-2パラメータまで**: 3個以上はオブジェクト使用
|
|
40
|
-
```typescript
|
|
41
|
-
// ✅ オブジェクトパラメータ
|
|
42
|
-
function createUser({ name, email, role }: CreateUserParams) {}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
**Props設計(Props-drivenアプローチ)**
|
|
46
|
-
- Propsはインターフェース: 必要な情報を全てPropsとして定義
|
|
47
|
-
- 暗黙的依存を避ける: 必要なくグローバルstateやcontextに依存しない
|
|
48
|
-
- 型安全性: Props型を常に明示的に定義
|
|
49
|
-
|
|
50
|
-
**環境変数**
|
|
51
|
-
- **ビルドツールの環境変数システムを使用**: `process.env`はブラウザで動作しない
|
|
52
|
-
- **クライアントサイドに秘密情報なし**: フロントエンドコードは全て公開、秘密情報はバックエンドで管理
|
|
53
|
-
|
|
54
|
-
**依存性注入**
|
|
55
|
-
- **カスタムフックで依存性注入**: テスト可能性とモジュール性を確保
|
|
56
|
-
|
|
57
|
-
**非同期処理**
|
|
58
|
-
- Promise処理: 常に`async/await`使用
|
|
59
|
-
- エラーハンドリング: 常に`try-catch`またはError Boundaryで処理
|
|
60
|
-
- 型定義: 戻り値の型を明示的に定義(例: `Promise<Result>`)
|
|
61
|
-
|
|
62
|
-
**フォーマットルール**
|
|
63
|
-
- セミコロン省略(Biome設定に従う)
|
|
64
|
-
- 型は`PascalCase`、変数・関数は`camelCase`
|
|
65
|
-
- importは絶対パス使用(`src/`)
|
|
66
|
-
|
|
67
|
-
**Clean Code原則**
|
|
68
|
-
- ✅ 未使用コードは即座に削除
|
|
69
|
-
- ✅ デバッグ用`console.log()`削除
|
|
70
|
-
- ❌ コメントアウトされたコード(履歴はバージョン管理で)
|
|
71
|
-
- ✅ コメントは「理由」を説明(「何を」ではない)
|
|
72
|
-
|
|
73
|
-
## エラーハンドリング
|
|
74
|
-
|
|
75
|
-
**絶対ルール**: エラー抑制禁止。全てのエラーはログ出力と適切な処理が必須。
|
|
76
|
-
|
|
77
|
-
**Fail-Fast原則**: エラー時は速やかに失敗し、無効な状態での処理継続を防ぐ
|
|
78
|
-
```typescript
|
|
79
|
-
// ❌ 禁止: 無条件フォールバック
|
|
80
|
-
catch (error) {
|
|
81
|
-
return defaultValue // エラーを隠蔽
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// ✅ 必須: 明示的な失敗
|
|
85
|
-
catch (error) {
|
|
86
|
-
logger.error('処理失敗', error)
|
|
87
|
-
throw error // Error Boundaryまたは上位層で処理
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
**Result型パターン**: エラーを型で表現し明示的にハンドリング
|
|
92
|
-
```typescript
|
|
93
|
-
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E }
|
|
94
|
-
|
|
95
|
-
// 例: エラーの可能性を型で表現
|
|
96
|
-
function parseUser(data: unknown): Result<User, ValidationError> {
|
|
97
|
-
if (!isValid(data)) return { ok: false, error: new ValidationError() }
|
|
98
|
-
return { ok: true, value: data as User }
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
**カスタムエラークラス**
|
|
103
|
-
```typescript
|
|
104
|
-
export class AppError extends Error {
|
|
105
|
-
constructor(message: string, public readonly code: string, public readonly statusCode = 500) {
|
|
106
|
-
super(message)
|
|
107
|
-
this.name = this.constructor.name
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
// 目的別: ValidationError(400), ApiError(502), NotFoundError(404)
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
**レイヤー別エラーハンドリング(React)**
|
|
114
|
-
- Error Boundary: Reactコンポーネントエラーをキャッチ、フォールバックUI表示
|
|
115
|
-
- Custom Hook: ビジネスルール違反を検出、AppErrorをそのまま伝播
|
|
116
|
-
- API層: fetchエラーをドメインエラーに変換
|
|
117
|
-
|
|
118
|
-
**構造化ロギングと機密情報保護**
|
|
119
|
-
ログに機密情報(password、token、apiKey、secret、creditCard)を絶対含めない
|
|
120
|
-
|
|
121
|
-
**Reactでの非同期エラーハンドリング**
|
|
122
|
-
- Error Boundaryセットアップ必須: レンダリングエラーをキャッチ
|
|
123
|
-
- イベントハンドラ内の全async/awaitでtry-catch使用
|
|
124
|
-
- エラーは常にログ記録し、再スローまたはerror stateで表示
|
|
125
|
-
|
|
126
|
-
## パフォーマンス最適化
|
|
127
|
-
|
|
128
|
-
- コンポーネントメモ化: 高コストコンポーネントにReact.memo使用
|
|
129
|
-
- State最適化: 適切なstate構造で再レンダリングを最小化
|
|
130
|
-
- 遅延読み込み: React.lazyとSuspenseでコード分割
|
|
131
|
-
- バンドルサイズ: `build`スクリプト(package.jsonの`packageManager`フィールドに応じた実行コマンドを使用)で監視し最適化
|