@careerchain/stdd 0.1.0
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/README.md +44 -0
- package/assets/.claude/agents/code-reviewer.md +170 -0
- package/assets/.claude/agents/implementer.md +96 -0
- package/assets/.claude/agents/plan-writer.md +124 -0
- package/assets/.claude/agents/qa-engineer.md +133 -0
- package/assets/.claude/agents/spec-reviewer.md +173 -0
- package/assets/.claude/agents/spec-writer.md +194 -0
- package/assets/.claude/agents/test-reviewer.md +218 -0
- package/assets/.claude/docs/spec-driven-development-guide.md +436 -0
- package/assets/.claude/hooks/pre-push-check.sh +160 -0
- package/assets/.claude/settings.json +67 -0
- package/assets/.claude/skills/auto-implement/SKILL.md +168 -0
- package/assets/.claude/skills/auto-implement/references/github-project.md +54 -0
- package/assets/.claude/skills/auto-implement/references/phases.md +244 -0
- package/assets/.claude/skills/create-pr/SKILL.md +112 -0
- package/assets/.claude/skills/documenting-plans/SKILL.md +217 -0
- package/assets/.claude/skills/documenting-plans/templates/plan.md +182 -0
- package/assets/.claude/skills/documenting-specifications/SKILL.md +300 -0
- package/assets/.claude/skills/documenting-specifications/guides/error-handling.md +78 -0
- package/assets/.claude/skills/documenting-specifications/guides/stdd-violations.md +237 -0
- package/assets/.claude/skills/documenting-specifications/templates/requirements.md +184 -0
- package/assets/.claude/skills/documenting-specifications/templates/screen-items-definition.md +179 -0
- package/assets/.claude/skills/documenting-specifications/templates/tech-design.md +241 -0
- package/assets/.claude/skills/generating-wireframes/SKILL.md +121 -0
- package/assets/.claude/skills/generating-wireframes/examples/tob-form.html +497 -0
- package/assets/.claude/skills/generating-wireframes/examples/tob-list.html +536 -0
- package/assets/.claude/skills/generating-wireframes/examples/toc-form.html +493 -0
- package/assets/.claude/skills/generating-wireframes/examples/toc-list.html +538 -0
- package/assets/.claude/skills/generating-wireframes/guides/from-requirements.md +53 -0
- package/assets/.claude/skills/generating-wireframes/templates/index.html +472 -0
- package/assets/.claude/skills/generating-wireframes/templates/screen.html +480 -0
- package/assets/.claude/skills/introducing-stdd/SKILL.md +185 -0
- package/assets/.claude/skills/introducing-stdd/templates/introduction-plan.md +64 -0
- package/assets/.claude/skills/kaizen/SKILL.md +129 -0
- package/assets/.claude/skills/kaizen/references/code-examples.md +233 -0
- package/assets/.claude/skills/reverse-engineering-common-spec/SKILL.md +137 -0
- package/assets/.claude/skills/reverse-engineering-feature-spec/SKILL.md +463 -0
- package/assets/.claude/skills/reverse-engineering-feature-spec/guides/accuracy.md +215 -0
- package/assets/.claude/skills/reverse-engineering-feature-spec/guides/figma-capture.md +313 -0
- package/assets/.claude/skills/review-pr-with-agents/SKILL.md +159 -0
- package/assets/.claude/skills/searching-existing-solutions/SKILL.md +110 -0
- package/assets/.claude/skills/setup-stdd/SKILL.md +82 -0
- package/assets/.claude/skills/software-architecture/SKILL.md +260 -0
- package/assets/.claude/skills/starting-new-with-stdd/SKILL.md +142 -0
- package/assets/.claude/skills/starting-new-with-stdd/templates/bootstrap-plan.md +73 -0
- package/assets/.claude/skills/tailoring-spec-format/SKILL.md +103 -0
- package/assets/.claude/skills/verifying-consistency/SKILL.md +90 -0
- package/assets/stdd.config.yml.tpl +34 -0
- package/dist/cli.js +148 -0
- package/dist/cli.js.map +1 -0
- package/dist/install.js +121 -0
- package/dist/install.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
導入PLAN — STDD 導入の進捗を保持するプロジェクト単位の生きたチェックリスト。
|
|
3
|
+
|
|
4
|
+
位置づけ:
|
|
5
|
+
- feature/session 単位の通常 PLAN とは別。プロジェクト全体の「導入」進捗を 1 ファイルで追跡する。
|
|
6
|
+
- introducing-stdd スキルがこのファイルを読み書きしながら導入を駆動する。
|
|
7
|
+
- 導入が一巡(順行運用へ移行)したら役目を終える。
|
|
8
|
+
|
|
9
|
+
配置:
|
|
10
|
+
docs/common/plans/stdd-introduction.md
|
|
11
|
+
|
|
12
|
+
書き換え方:
|
|
13
|
+
プレースホルダを実値に置換。機能は step 1.5 で洗い出した一覧を優先順(P0→P1→P2)で並べる。
|
|
14
|
+
完了した項目は [ ] → [x] にする。フォーマット決定は「決定ログ」に追記する。
|
|
15
|
+
-->
|
|
16
|
+
|
|
17
|
+
# STDD 導入PLAN — [サービス名]
|
|
18
|
+
|
|
19
|
+
> 進捗トラッカー。詳細手順は `introducing-stdd` スキル / `guide-for-existing-project.md` を参照。
|
|
20
|
+
> **開始**: [yyyy-mm-dd] / **基準ブランチ**: [main / develop 等]
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 進捗
|
|
25
|
+
|
|
26
|
+
### 基盤
|
|
27
|
+
|
|
28
|
+
- [ ] step 0: `.stdd.config.yml` 作成・テンプレ/skill 配置
|
|
29
|
+
- [ ] step 1: common ティア生成(`docs/common/REQUIREMENTS.md` + `ARCHITECTURE.md`)
|
|
30
|
+
- [ ] `<!-- 要確認 -->` の解消(人間確認)
|
|
31
|
+
- [ ] step 1.5: 機能インベントリ + 優先順を確定(下記「機能ループ」へ反映)
|
|
32
|
+
- [ ] step 2: 代表機能のリバース([機能名])
|
|
33
|
+
- [ ] step 3-4: フォーマット策定 → テンプレ特化(下記「決定ログ」へ)
|
|
34
|
+
|
|
35
|
+
### 機能ループ(step 5)
|
|
36
|
+
|
|
37
|
+
優先順(P0 → P1 → P2)。各機能 = `reverse-engineering-feature-spec` → `verifying-consistency`。
|
|
38
|
+
|
|
39
|
+
- [ ] [機能A] (P0)
|
|
40
|
+
- [ ] [機能B] (P0)
|
|
41
|
+
- [ ] [機能C] (P1)
|
|
42
|
+
- [ ] [機能D] (P2)
|
|
43
|
+
|
|
44
|
+
### 移行
|
|
45
|
+
|
|
46
|
+
- [ ] step 6: 既存機能の spec が一巡 → 以降は `auto-implement`(順行運用)へ
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## フォーマット決定ログ(step 3-4 / 7)
|
|
51
|
+
|
|
52
|
+
このプロジェクト固有に決めた spec フォーマットの方針を記録する。
|
|
53
|
+
|
|
54
|
+
- 必須 spec ファイル: [REQUIREMENTS / TECH_DESIGN / ...]
|
|
55
|
+
- common ARCHITECTURE に追加した固有セクション: [認証・認可 / RLS / ...]
|
|
56
|
+
- docs.layout パス規約: [docs/<app>/<feature>/...]
|
|
57
|
+
- Priority 基準: [このプロジェクトでの P0/P1/P2 の定義]
|
|
58
|
+
- テスト層の責務分担: [E2E は P0 のみ 等]
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## メモ・引き継ぎ
|
|
63
|
+
|
|
64
|
+
- (セッションを跨ぐ際の注意点・保留事項)
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kaizen
|
|
3
|
+
description: |-
|
|
4
|
+
継続的改善・過剰設計回避のための開発原則。Poka-Yoke(エラー防止)、YAGNI、Rule of Three、段階的リファクタリングを提供する。
|
|
5
|
+
when_to_use: |-
|
|
6
|
+
「リファクタリング」「改善」「過剰設計」「YAGNI」「シンプル」「エラー防止」「コード品質」「設計改善」「段階的改善」に関する作業のとき。
|
|
7
|
+
allowed-tools: Read, Edit, Grep, Glob
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Kaizen: 継続的改善
|
|
11
|
+
|
|
12
|
+
小さな改善を継続的に。設計段階でエラーを防止。実績あるパターンに従う。必要なものだけを作る。
|
|
13
|
+
|
|
14
|
+
**核心**: 大きな一発勝負より、小さな改善の積み重ねが大きな成果を生む。
|
|
15
|
+
|
|
16
|
+
## 適用タイミング
|
|
17
|
+
|
|
18
|
+
- コード実装とリファクタリング
|
|
19
|
+
- アーキテクチャ・設計判断
|
|
20
|
+
- エラーハンドリング・バリデーション設計
|
|
21
|
+
|
|
22
|
+
## 4つの柱
|
|
23
|
+
|
|
24
|
+
### 1. 継続的改善(Kaizen)
|
|
25
|
+
|
|
26
|
+
小さく頻繁な改善が、大きな成果に複利的に積み上がる。
|
|
27
|
+
|
|
28
|
+
**段階的に進める**:
|
|
29
|
+
- 品質を改善する最小限の変更を行う
|
|
30
|
+
- 一度に1つの改善のみ
|
|
31
|
+
- 各変更を検証してから次へ
|
|
32
|
+
|
|
33
|
+
**コードは見つけた時より良くする**:
|
|
34
|
+
- 小さな問題を見つけたらその場で修正(スコープ内で)
|
|
35
|
+
- 古いコメントを更新、デッドコードを削除
|
|
36
|
+
|
|
37
|
+
**反復的に洗練する**:
|
|
38
|
+
1. まず動くものを作る
|
|
39
|
+
2. 次に明確にする
|
|
40
|
+
3. 最後に効率化する
|
|
41
|
+
4. 一度に3つ全部はやらない
|
|
42
|
+
|
|
43
|
+
**実践**: 機能実装時は最もシンプルなバージョンから始める。リファクタリング時は1つずつコードの匂いを修正し、各改善後にコミット。テストを常にパスさせる。
|
|
44
|
+
|
|
45
|
+
### 2. Poka-Yoke(エラー防止)
|
|
46
|
+
|
|
47
|
+
実行時ではなく、コンパイル時・設計時にエラーを防止するシステムを設計する。
|
|
48
|
+
|
|
49
|
+
**エラーを不可能にする**:
|
|
50
|
+
- 型システムで間違いを検知
|
|
51
|
+
- 無効な状態を表現不可能にする(Discriminated Union)
|
|
52
|
+
- エラーは早期に(本番ではなく開発時に)検出
|
|
53
|
+
|
|
54
|
+
**防御の層**:
|
|
55
|
+
1. **型システム**(コンパイル時) - Union TypeでStringを避ける
|
|
56
|
+
2. **バリデーション**(実行時、早期) - 境界で1回検証すれば内部は安全
|
|
57
|
+
3. **ガード節**(前提条件) - Early returnで前提を明示
|
|
58
|
+
4. **エラー境界**(グレースフルデグレード)
|
|
59
|
+
|
|
60
|
+
**実践**:
|
|
61
|
+
- API設計時: 型で入力を制約し、無効な状態を表現不可能に
|
|
62
|
+
- エラー処理時: システム境界でバリデーション、ガード節で前提条件チェック、明確なメッセージで失敗
|
|
63
|
+
- 設定管理時: optionalよりrequired、起動時に全設定を検証
|
|
64
|
+
|
|
65
|
+
### 3. 標準化された作業
|
|
66
|
+
|
|
67
|
+
既存パターンに従う。うまくいくものを文書化する。良い慣行を簡単に従えるようにする。
|
|
68
|
+
|
|
69
|
+
**一貫性は賢さに勝る**:
|
|
70
|
+
- 既存のコードベースパターンに従う
|
|
71
|
+
- 解決済みの問題を再発明しない
|
|
72
|
+
- 新パターンは大幅に改善される場合のみ導入
|
|
73
|
+
|
|
74
|
+
**標準を自動化する**:
|
|
75
|
+
- リンターでスタイルを強制
|
|
76
|
+
- 型チェックで契約を強制
|
|
77
|
+
- テストで挙動を検証
|
|
78
|
+
- CI/CDで品質ゲートを強制
|
|
79
|
+
|
|
80
|
+
**実践**:
|
|
81
|
+
- 新パターン追加前: コードベースで類似問題の解決策を検索し、CLAUDE.mdの規約を確認
|
|
82
|
+
- コード記述時: 既存のファイル構造、命名規則、エラーハンドリングパターンに合わせる
|
|
83
|
+
|
|
84
|
+
### 4. Just-In-Time(JIT)
|
|
85
|
+
|
|
86
|
+
今必要なものだけを作る。それ以上も以下もなく。
|
|
87
|
+
|
|
88
|
+
**YAGNI(You Aren't Gonna Need It)**:
|
|
89
|
+
- 現在の要件のみ実装
|
|
90
|
+
- 「念のため」の機能は不要
|
|
91
|
+
- 「将来必要になるかも」のコードは不要
|
|
92
|
+
- 推測的コードは削除
|
|
93
|
+
|
|
94
|
+
**動く最もシンプルなもの**:
|
|
95
|
+
- 直接的な解決策から始める
|
|
96
|
+
- 必要になった時にのみ複雑さを追加
|
|
97
|
+
- 要件変更時にリファクタリング
|
|
98
|
+
|
|
99
|
+
**抽象化のタイミング(Rule of Three)**:
|
|
100
|
+
- 3箇所以上で同じパターンが出現してから抽象化
|
|
101
|
+
- 間違った抽象化より重複のほうがマシ
|
|
102
|
+
- パターンが明確になってからリファクタリング
|
|
103
|
+
|
|
104
|
+
**実践**:
|
|
105
|
+
- 実装時: 目の前の問題を解決、「もし〜だったら」思考に抵抗
|
|
106
|
+
- 最適化時: まず計測、次に最適化
|
|
107
|
+
- 抽象化時: 3箇所以上の類似ケースを待つ
|
|
108
|
+
|
|
109
|
+
## 危険信号
|
|
110
|
+
|
|
111
|
+
| 柱 | 危険信号 |
|
|
112
|
+
|---|---------|
|
|
113
|
+
| 継続的改善 | 「後でリファクタリングする」(実行されない) |
|
|
114
|
+
| Poka-Yoke | 「ユーザーが気をつければいい」 |
|
|
115
|
+
| 標準化 | 「自分のやり方でやりたい」 |
|
|
116
|
+
| JIT | 「いつか必要になるかも」 |
|
|
117
|
+
|
|
118
|
+
## コード例
|
|
119
|
+
|
|
120
|
+
詳細なコード例は [references/code-examples.md](references/code-examples.md) を参照:
|
|
121
|
+
- 段階的リファクタリングの例
|
|
122
|
+
- 型システムによるエラー防止の例
|
|
123
|
+
- 過剰設計 vs 適切な設計の例
|
|
124
|
+
|
|
125
|
+
## まとめ
|
|
126
|
+
|
|
127
|
+
**Kaizenの本質**: 今日十分に良いものを作り、明日さらに良くする。これを繰り返す。
|
|
128
|
+
|
|
129
|
+
完璧を一発で目指すのではなく、小さな改善を積み重ねる。大規模リファクタリングより段階的改善。巧妙な抽象化より明快なコード。
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# Kaizen コード例集
|
|
2
|
+
|
|
3
|
+
SKILL.md本体の4つの柱に対応する詳細なコード例。
|
|
4
|
+
|
|
5
|
+
## 目次
|
|
6
|
+
|
|
7
|
+
- [継続的改善のコード例](#継続的改善のコード例)
|
|
8
|
+
- [Poka-Yokeのコード例](#poka-yokeのコード例)
|
|
9
|
+
- [JIT/YAGNIのコード例](#jityagniのコード例)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 継続的改善のコード例
|
|
14
|
+
|
|
15
|
+
### 段階的リファクタリング
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// Iteration 1: まず動くものを作る
|
|
19
|
+
const calculateTotal = (items: Item[]) => {
|
|
20
|
+
let total = 0;
|
|
21
|
+
for (let i = 0; i < items.length; i++) {
|
|
22
|
+
total += items[i].price * items[i].quantity;
|
|
23
|
+
}
|
|
24
|
+
return total;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Iteration 2: 明確にする(リファクタ)
|
|
28
|
+
const calculateTotal = (items: Item[]): number => {
|
|
29
|
+
return items.reduce((total, item) => {
|
|
30
|
+
return total + (item.price * item.quantity);
|
|
31
|
+
}, 0);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Iteration 3: 堅牢にする(バリデーション追加)
|
|
35
|
+
const calculateTotal = (items: Item[]): number => {
|
|
36
|
+
if (!items?.length) return 0;
|
|
37
|
+
|
|
38
|
+
return items.reduce((total, item) => {
|
|
39
|
+
if (item.price < 0 || item.quantity < 0) {
|
|
40
|
+
throw new Error('Price and quantity must be non-negative');
|
|
41
|
+
}
|
|
42
|
+
return total + (item.price * item.quantity);
|
|
43
|
+
}, 0);
|
|
44
|
+
};
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
各ステップが完結しており、テスト可能。一度にすべてやろうとしない。
|
|
48
|
+
|
|
49
|
+
### 悪い例: 一度にすべてやろうとする
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
const calculateTotal = (items: Item[]): number => {
|
|
53
|
+
if (!items?.length) return 0;
|
|
54
|
+
const validItems = items.filter(item => {
|
|
55
|
+
if (item.price < 0) throw new Error('Negative price');
|
|
56
|
+
if (item.quantity < 0) throw new Error('Negative quantity');
|
|
57
|
+
return item.quantity > 0;
|
|
58
|
+
});
|
|
59
|
+
// キャッシュも、ロギングも、通貨変換も一度に…
|
|
60
|
+
return validItems.reduce(...);
|
|
61
|
+
};
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Poka-Yokeのコード例
|
|
67
|
+
|
|
68
|
+
### 型システムによるエラー防止
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// 悪い例: stringで状態管理
|
|
72
|
+
type OrderBad = {
|
|
73
|
+
status: string; // "pending", "PENDING", "pnding" 何でも入る
|
|
74
|
+
total: number;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// 良い例: Union Typeで制約
|
|
78
|
+
type OrderStatus = 'pending' | 'processing' | 'shipped' | 'delivered';
|
|
79
|
+
type Order = {
|
|
80
|
+
status: OrderStatus;
|
|
81
|
+
total: number;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// より良い例: 状態に応じたデータを強制
|
|
85
|
+
type Order =
|
|
86
|
+
| { status: 'pending'; createdAt: Date }
|
|
87
|
+
| { status: 'processing'; startedAt: Date; estimatedCompletion: Date }
|
|
88
|
+
| { status: 'shipped'; trackingNumber: string; shippedAt: Date }
|
|
89
|
+
| { status: 'delivered'; deliveredAt: Date; signature: string };
|
|
90
|
+
// shipped状態ではtrackingNumberが必須になる
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### バリデーションの境界防御
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// 悪い例: バリデーション前に使用
|
|
97
|
+
const processPayment = (amount: number) => {
|
|
98
|
+
const fee = amount * 0.03; // バリデーション前に使っている
|
|
99
|
+
if (amount <= 0) throw new Error('Invalid amount');
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// 良い例: 境界でバリデーション、以降は安全
|
|
103
|
+
const processPayment = (amount: number) => {
|
|
104
|
+
if (amount <= 0) {
|
|
105
|
+
throw new Error('Payment amount must be positive');
|
|
106
|
+
}
|
|
107
|
+
const fee = amount * 0.03;
|
|
108
|
+
};
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### ガード節(Early Return)
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
const processUser = (user: User | null) => {
|
|
115
|
+
if (!user) {
|
|
116
|
+
logger.error('User not found');
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!user.email) {
|
|
121
|
+
logger.error('User email missing');
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (!user.isActive) {
|
|
126
|
+
logger.info('User inactive, skipping');
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ここに到達 = userは有効かつアクティブであることが保証される
|
|
131
|
+
sendEmail(user.email, 'Welcome!');
|
|
132
|
+
};
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 設定のエラー防止
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// 悪い例: optionalで起動時にチェックしない
|
|
139
|
+
type ConfigBad = {
|
|
140
|
+
apiKey?: string;
|
|
141
|
+
timeout?: number;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// 良い例: 必須にして起動時に検証
|
|
145
|
+
type Config = {
|
|
146
|
+
apiKey: string;
|
|
147
|
+
timeout: number;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const loadConfig = (): Config => {
|
|
151
|
+
const apiKey = process.env.API_KEY;
|
|
152
|
+
if (!apiKey) {
|
|
153
|
+
throw new Error('API_KEY environment variable required');
|
|
154
|
+
}
|
|
155
|
+
return { apiKey, timeout: 5000 };
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// アプリ起動時に失敗する(リクエスト中ではなく)
|
|
159
|
+
const config = loadConfig();
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## JIT/YAGNIのコード例
|
|
165
|
+
|
|
166
|
+
### 過剰設計の例
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
// 悪い例: 「将来必要かもしれない」で過剰設計
|
|
170
|
+
interface LogTransport {
|
|
171
|
+
write(level: LogLevel, message: string, meta?: LogMetadata): Promise<void>;
|
|
172
|
+
}
|
|
173
|
+
class ConsoleTransport implements LogTransport { /* ... */ }
|
|
174
|
+
class FileTransport implements LogTransport { /* ... */ }
|
|
175
|
+
class RemoteTransport implements LogTransport { /* ... */ }
|
|
176
|
+
class Logger {
|
|
177
|
+
private transports: LogTransport[] = [];
|
|
178
|
+
private queue: LogEntry[] = [];
|
|
179
|
+
// 200行のコード…
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// 良い例: 今必要なものだけ
|
|
183
|
+
const logError = (error: Error) => {
|
|
184
|
+
console.error(error.message);
|
|
185
|
+
};
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### 段階的な複雑化
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// Step 1: シンプルに始める
|
|
192
|
+
const formatCurrency = (amount: number): string => {
|
|
193
|
+
return `$${amount.toFixed(2)}`;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
// Step 2: 要件が増えたら対応(複数通貨)
|
|
197
|
+
const formatCurrency = (amount: number, currency: string): string => {
|
|
198
|
+
const symbols = { USD: '$', EUR: '€', GBP: '£' };
|
|
199
|
+
return `${symbols[currency]}${amount.toFixed(2)}`;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
// Step 3: さらに要件が増えたら(ロケール対応)
|
|
203
|
+
const formatCurrency = (amount: number, locale: string): string => {
|
|
204
|
+
return new Intl.NumberFormat(locale, {
|
|
205
|
+
style: 'currency',
|
|
206
|
+
currency: locale === 'en-US' ? 'USD' : 'EUR',
|
|
207
|
+
}).format(amount);
|
|
208
|
+
};
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### 早すぎる抽象化
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
// 悪い例: 使用箇所1つで汎用フレームワーク構築
|
|
215
|
+
abstract class BaseCRUDService<T> {
|
|
216
|
+
abstract getAll(): Promise<T[]>;
|
|
217
|
+
abstract getById(id: string): Promise<T>;
|
|
218
|
+
abstract create(data: Partial<T>): Promise<T>;
|
|
219
|
+
abstract update(id: string, data: Partial<T>): Promise<T>;
|
|
220
|
+
abstract delete(id: string): Promise<void>;
|
|
221
|
+
}
|
|
222
|
+
class GenericRepository<T> { /* 300行 */ }
|
|
223
|
+
|
|
224
|
+
// 良い例: 今必要な関数だけ
|
|
225
|
+
const getUsers = async (): Promise<User[]> => {
|
|
226
|
+
return db.query('SELECT * FROM users');
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const getUserById = async (id: string): Promise<User | null> => {
|
|
230
|
+
return db.query('SELECT * FROM users WHERE id = $1', [id]);
|
|
231
|
+
};
|
|
232
|
+
// 3箇所以上で同じパターンが出てきたら抽象化を検討する
|
|
233
|
+
```
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reverse-engineering-common-spec
|
|
3
|
+
description: |-
|
|
4
|
+
既存プロジェクトに STDD を導入する際、コードベース全体をリバースエンジニアリングして common ティアの Spec(docs/common/REQUIREMENTS.md + docs/common/ARCHITECTURE.md)を作成する。サービス概要・システム構成・リポジトリ構成・レイヤ規約・データモデルを俯瞰する正典を、導入時に一度だけ生成する。機能/ページ単位のリバースエンジニアリングには reverse-engineering-feature-spec を使用する。
|
|
5
|
+
when_to_use: |-
|
|
6
|
+
「STDD導入」「stdd導入」「共通spec生成」「commonティア」「プロジェクト全体のリバースエンジニアリング」「ARCHITECTURE.md作成」「アーキテクチャのドキュメント化」「既存プロジェクトにstdd」に関する作業のとき。
|
|
7
|
+
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# common spec のリバースエンジニアリング
|
|
11
|
+
|
|
12
|
+
既存(稼働中)プロジェクトに STDD を導入する際、コードベース全体を input にして **common ティア**の Spec を作成する。
|
|
13
|
+
|
|
14
|
+
| 出力 | 内容 |
|
|
15
|
+
| ---- | ---- |
|
|
16
|
+
| `docs/common/REQUIREMENTS.md` | サービス概要・登場アクター・アプリ構成(プロジェクト全体のビジネス要件) |
|
|
17
|
+
| `docs/common/ARCHITECTURE.md` | システム構成・リポジトリ構成・レイヤ規約・データモデル(プロジェクト全体の技術設計) |
|
|
18
|
+
|
|
19
|
+
テンプレートは `packages/core/templates/common/REQUIREMENTS.md` / `ARCHITECTURE.md` を参照する。
|
|
20
|
+
|
|
21
|
+
## 位置づけ — 導入時に一度だけ
|
|
22
|
+
|
|
23
|
+
common ティアはプロジェクト全体で 1 組しか存在しない正典であり、本スキルは **STDD 導入時に一度だけ**実行する想定。
|
|
24
|
+
作成後の更新(アーキテクチャ変更時など)は本スキルではなく、通常の Spec 更新として `documenting-specifications` で扱う。
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
STDD 導入フロー(既存プロジェクト)
|
|
28
|
+
|
|
29
|
+
1. reverse-engineering-common-spec ← 本スキル(一度だけ)
|
|
30
|
+
↓ common ティアが揃う
|
|
31
|
+
2. reverse-engineering-feature-spec ← 機能ごとに繰り返す
|
|
32
|
+
↓
|
|
33
|
+
3. auto-implement ← 以降の新機能は順行 STDD
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**順序の理由**: 先に common ティア(レイヤ規約・共有ドメインモデル・テーブル一覧)を固定しておくと、後続の機能単位リバース(`reverse-engineering-feature-spec`)の精度と速度が上がる。
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 最重要原則 — 実装・設定が真実
|
|
41
|
+
|
|
42
|
+
common ティアでも **実装が真実(Source of Truth)** である。推測や理想論で書かず、必ず一次情報を確認してから書く。
|
|
43
|
+
feature ティアと違い、確認する一次情報は **UI 文言ではなく構成・設定・型定義** である。
|
|
44
|
+
|
|
45
|
+
| 記述する内容 | 確認元(一次情報) | よくある間違い |
|
|
46
|
+
| ------------ | ------------------ | -------------- |
|
|
47
|
+
| アプリ構成・責務 | トップレベルディレクトリ / README | 想像でアプリ名・責務を書く |
|
|
48
|
+
| パッケージ分割 | `package.json` の workspaces / 依存定義 | モジュール境界を推測で書く |
|
|
49
|
+
| レイヤ規約・依存方向 | `domain/` 配下の実構成・lint ルール | 一般論の Clean Architecture を書く |
|
|
50
|
+
| 外部サービス連携 | 環境変数・SDK の import 箇所 | 使っていないサービスを書く/使用中を漏らす |
|
|
51
|
+
| テーブル一覧・ER | 生成された DB 型定義(`database.types.ts` 等) | テーブル名・カラム名を想像で書く |
|
|
52
|
+
| デプロイ・環境 | CI/CD 設定(`.github/workflows` 等) | ブランチ→環境マッピングを推測で書く |
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 読む順序とチェックリスト
|
|
57
|
+
|
|
58
|
+
`ARCHITECTURE.md` の目次がそのまま読む順序になる。
|
|
59
|
+
|
|
60
|
+
### 1. システム構成(`REQUIREMENTS.md` のサービス概要・アクターもここで把握)
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
□ README / トップレベルディレクトリ構成 → サービスの目的・アプリ構成
|
|
64
|
+
□ デプロイ設定 (vercel.json / Dockerfile / .github/workflows) → 環境とブランチ戦略
|
|
65
|
+
□ 環境変数・SDK の import → 外部サービス連携 (認証 / DB / ストレージ / メール / 監視 等)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 2. リポジトリ構成
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
□ package.json の workspaces / モジュール分割
|
|
72
|
+
□ 依存管理ルール (どの依存がどこに置かれているか、アプリ間 import 制限の有無)
|
|
73
|
+
□ 共有パッケージ (packages/shared 等) の責務
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 3. レイヤードアーキテクチャ
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
□ domain/ 配下の構成 (models / repository / service / ports)
|
|
80
|
+
□ 依存方向ルール (UI → Service → Repository → DB 等)、禁止依存
|
|
81
|
+
□ 代表的なデータフロー 1 本 (Server Action / API → Service → Repository)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 4. データモデル・DB設計
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
□ 生成された DB 型定義 (database.types.ts 等) を正としてテーブルを列挙
|
|
88
|
+
□ ドメイングループへの分類、中心テーブルごとの ER 図
|
|
89
|
+
□ 設計方針 (論理削除 / 主キー / 時系列カラム / マイグレーション規約)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 確信が持てない箇所は要確認マーカーを残す
|
|
95
|
+
|
|
96
|
+
実装からの読み取りに確信が持てない箇所は `<!-- 要確認: ... -->` のインラインコメントで明示する。
|
|
97
|
+
これは**一時的な注記**であり、人間レビューで確定したら除去する(恒久的に残さない)。SSoT 原則上、確定済みの Spec に作成プロセスや未確定メモを残してはならない。
|
|
98
|
+
|
|
99
|
+
```markdown
|
|
100
|
+
- **外部ウォレット連携**: 関連テーブルと RPC が存在する。<!-- 要確認: 現行稼働範囲(本番で有効か) -->
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 完了条件
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
□ docs/common/REQUIREMENTS.md を作成(サービス概要 / アクター / アプリ構成)
|
|
109
|
+
□ docs/common/ARCHITECTURE.md を作成(システム構成 / リポジトリ / レイヤ / データモデル)
|
|
110
|
+
□ テーブル一覧は生成された型定義ファイルと一致している
|
|
111
|
+
□ 固有名詞・社外秘の値を不要に含めていない(公開を想定する場合)
|
|
112
|
+
□ 要確認マーカーは「人間に確認すべき項目」としてレビュー依頼にまとめた
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## When NOT to Use This Skill
|
|
118
|
+
|
|
119
|
+
- **機能 / ページ単位のリバースエンジニアリング**: `reverse-engineering-feature-spec` を使用
|
|
120
|
+
- **新規機能の仕様策定**: `documenting-specifications` を使用
|
|
121
|
+
- **common ティア作成後のアーキテクチャ更新**: 通常の Spec 更新として `documenting-specifications` で扱う
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 次のステップ
|
|
126
|
+
|
|
127
|
+
1. **機能単位のリバース** → `reverse-engineering-feature-spec`(common ティアを前提に、機能ごとに繰り返す)
|
|
128
|
+
2. **新機能の実装** → `auto-implement`(以降は Spec → Test → 実装 の順行 STDD)
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 参照ファイル
|
|
133
|
+
|
|
134
|
+
- **common テンプレート**: `packages/core/templates/common/REQUIREMENTS.md` / `ARCHITECTURE.md`
|
|
135
|
+
- **2 ティア構造の解説**: `packages/core/docs/stdd-methodology.md` §3.0
|
|
136
|
+
- **機能単位リバース**: [reverse-engineering-feature-spec skill](../reverse-engineering-feature-spec/SKILL.md)
|
|
137
|
+
- **Specテンプレート**: [documenting-specifications skill](../documenting-specifications/SKILL.md)
|