@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,463 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reverse-engineering-feature-spec
|
|
3
|
+
description: |-
|
|
4
|
+
既存の機能/ページの実装から feature ティアの Spec ドキュメント(REQUIREMENTS.md + TECH_DESIGN.md)とテスト(E2E / Unit / Integration)をリバースエンジニアリングで作成するためのガイドライン。新規機能の仕様策定ではなく、既に動いている機能を正確にドキュメント化・テスト化する場合に使う。プロジェクト全体(common ティア)のリバースには reverse-engineering-common-spec を使用する。
|
|
5
|
+
when_to_use: |-
|
|
6
|
+
「リバースエンジニアリング」「既存コードからspec」「既存機能のドキュメント化」「機能のドキュメント化」「実装からテスト作成」「specカバー率向上」に関する作業のとき。
|
|
7
|
+
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# feature spec のリバースエンジニアリング
|
|
11
|
+
|
|
12
|
+
既に動いている **機能 / ページ単位**の実装コードを精読し、その挙動を正確に反映した feature ティアの Spec ドキュメント(REQUIREMENTS.md + TECH_DESIGN.md)とテスト(E2E / Unit / Integration)を作成する。
|
|
13
|
+
|
|
14
|
+
> **前提(推奨)**: プロジェクト全体の **common ティア**(`docs/common/REQUIREMENTS.md` + `ARCHITECTURE.md`)が未作成なら、先に `reverse-engineering-common-spec` スキルで作成しておくと、レイヤ規約・共有ドメインモデル・テーブル一覧を踏まえられて精度が上がる。既にある場合は本スキルから始める。
|
|
15
|
+
|
|
16
|
+
## 最重要原則
|
|
17
|
+
|
|
18
|
+
### Specに記載する文言は正確に実装を反映すること
|
|
19
|
+
|
|
20
|
+
リバースエンジニアリングでは、**実装が真実(Source of Truth)**である。Specは実装の挙動を忠実にドキュメント化したものであり、理想論や推測で書いてはならない。
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
❌ 悪い例: 実装を確認せずに一般的な仕様を書く
|
|
24
|
+
- 「電話番号は10〜11桁の数字」 ← Zodスキーマを確認していない
|
|
25
|
+
- 「戻るボタンで前のステップに戻る」 ← 実際のボタンラベルは「前へ」
|
|
26
|
+
|
|
27
|
+
✅ 良い例: 実装を確認してから書く
|
|
28
|
+
- 「電話番号は10文字以上(数字とハイフンのみ許可)」 ← schema.tsのZodルールを確認
|
|
29
|
+
- 「「前へ」ボタンで前のステップに戻る」 ← JSXのボタンテキストを確認
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**具体的な確認項目**:
|
|
33
|
+
|
|
34
|
+
| 項目 | 確認元 | よくある間違い |
|
|
35
|
+
|------|--------|--------------|
|
|
36
|
+
| ボタンラベル | JSX内のテキスト | 「送信」と書いたが実際は「保存」 |
|
|
37
|
+
| バリデーションルール | Zodスキーマ(schema.ts) | 桁数・形式を想像で書く |
|
|
38
|
+
| エラーメッセージ | Zodのmessageプロパティ | 一般的なメッセージを推測で書く |
|
|
39
|
+
| フォーム項目名 | `<label>` / `getByLabel` / `aria-label` | 項目名を想像で書く |
|
|
40
|
+
| ページ遷移先 | `router.push()` / `redirect()` | パスを想像で書く |
|
|
41
|
+
| API呼び出し | Server Actions / fetch | エンドポイントを想像で書く |
|
|
42
|
+
| DB操作 | repository層のメソッド | テーブル名・カラム名を想像で書く |
|
|
43
|
+
| 型定義 | domain/models配下の型 | フィールド名を想像で書く |
|
|
44
|
+
|
|
45
|
+
詳細: [正確性ガイド](guides/accuracy.md)
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Quick Start
|
|
50
|
+
|
|
51
|
+
### 前提条件
|
|
52
|
+
|
|
53
|
+
- 対象機能が既に動いている実装コードがある
|
|
54
|
+
- 対応するSpecドキュメント(REQUIREMENTS.md / TECH_DESIGN.md)が存在しない、または不十分
|
|
55
|
+
|
|
56
|
+
### 作業フロー
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
1. 実装コードリーディング(精読)
|
|
60
|
+
↓
|
|
61
|
+
2. REQUIREMENTS.md作成(ユーザー視点の挙動を記述)
|
|
62
|
+
↓
|
|
63
|
+
3. Playwright MCPでUIキャプチャ → Figmaファイル作成
|
|
64
|
+
↓
|
|
65
|
+
4. TECH_DESIGN.md作成(技術設計 + テスト戦略)
|
|
66
|
+
↓
|
|
67
|
+
5. E2Eテスト作成
|
|
68
|
+
↓
|
|
69
|
+
6. Unit / Integrationテスト作成(必要に応じて)
|
|
70
|
+
↓
|
|
71
|
+
7. /verifying-consistency で整合性チェック
|
|
72
|
+
↓
|
|
73
|
+
8. 不整合の修正(Specを実装に合わせる)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Phase 1: 実装コードリーディング
|
|
79
|
+
|
|
80
|
+
### 読む順序
|
|
81
|
+
|
|
82
|
+
以下の順序で実装を精読し、機能の全体像を把握する。
|
|
83
|
+
|
|
84
|
+
**1. ページコンポーネント**(エントリーポイント)
|
|
85
|
+
```
|
|
86
|
+
<app>/app/<path>/page.tsx
|
|
87
|
+
```
|
|
88
|
+
- サーバーコンポーネント or クライアントコンポーネントの判定
|
|
89
|
+
- データ取得方法(Server Component直接 / Server Actions)
|
|
90
|
+
- レイアウト構成
|
|
91
|
+
|
|
92
|
+
**2. クライアントコンポーネント**(UIとインタラクション)
|
|
93
|
+
```
|
|
94
|
+
<app>/app/<path>/*Client.tsx
|
|
95
|
+
<app>/components/<name>.tsx
|
|
96
|
+
```
|
|
97
|
+
- フォーム項目、ボタンラベル、表示テキストを**正確に**読み取る
|
|
98
|
+
- 状態管理(useState, useForm)
|
|
99
|
+
- 条件分岐によるUI出し分け
|
|
100
|
+
|
|
101
|
+
**3. バリデーションスキーマ**(入力ルール)
|
|
102
|
+
```
|
|
103
|
+
<app>/app/<path>/schema.ts
|
|
104
|
+
<app>/lib/schemas/<name>.ts
|
|
105
|
+
```
|
|
106
|
+
- Zodスキーマの各フィールドのルールを**正確に**読み取る
|
|
107
|
+
- `min()`, `max()`, `regex()`, `refine()` の具体値
|
|
108
|
+
- `message` プロパティのエラーメッセージ文言
|
|
109
|
+
- `optional()`, `nullable()` の有無
|
|
110
|
+
|
|
111
|
+
**4. Server Actions**(ビジネスロジック)
|
|
112
|
+
```
|
|
113
|
+
<app>/app/<path>/actions.ts
|
|
114
|
+
<app>/actions/<name>.ts
|
|
115
|
+
```
|
|
116
|
+
- 入力→処理→出力のフロー
|
|
117
|
+
- エラーハンドリング
|
|
118
|
+
|
|
119
|
+
**5. Domain層**(データモデルとDB操作)
|
|
120
|
+
```
|
|
121
|
+
<app>/domain/models/<name>.ts
|
|
122
|
+
<app>/domain/repository/<name>.ts
|
|
123
|
+
<app>/domain/service/<name>.ts
|
|
124
|
+
```
|
|
125
|
+
- Entity型定義
|
|
126
|
+
- CRUD操作の実装
|
|
127
|
+
- ビジネスルール
|
|
128
|
+
|
|
129
|
+
**6. DBスキーマ**(テーブル定義)
|
|
130
|
+
```
|
|
131
|
+
supabase/generated/database.types.ts
|
|
132
|
+
```
|
|
133
|
+
- テーブル名、カラム名を**正確に**確認
|
|
134
|
+
- リレーション
|
|
135
|
+
|
|
136
|
+
### コードリーディング時のメモ取り
|
|
137
|
+
|
|
138
|
+
以下の情報を収集しながら読む:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
□ ページURL・ルーティング構成
|
|
142
|
+
□ 画面遷移フロー
|
|
143
|
+
□ フォーム項目(名前、型、必須/任意、バリデーションルール)
|
|
144
|
+
□ ボタンラベル・アクション
|
|
145
|
+
□ 条件分岐(表示/非表示、有効/無効)
|
|
146
|
+
□ エラーハンドリング(エラーメッセージ文言)
|
|
147
|
+
□ 使用しているDB テーブル・カラム
|
|
148
|
+
□ 外部サービス連携(API呼び出し等)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Phase 2: REQUIREMENTS.md作成
|
|
154
|
+
|
|
155
|
+
`documenting-specifications` skillのテンプレートに従って作成する。
|
|
156
|
+
|
|
157
|
+
### リバースエンジニアリング固有のルール
|
|
158
|
+
|
|
159
|
+
**1. ユーザージャーニーは実装の挙動から抽出する**
|
|
160
|
+
|
|
161
|
+
実装コードの条件分岐・状態遷移を元に、ユーザーが辿るパスを網羅的に洗い出す。
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
# コードの条件分岐 → User Journey
|
|
165
|
+
if (form.isValid) → 正常系ジャーニー
|
|
166
|
+
if (error.type === 'validation') → バリデーションエラージャーニー
|
|
167
|
+
if (error.type === 'network') → ネットワークエラージャーニー
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**2. UIテキストは実装から正確に転記する**
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// 実装コード
|
|
174
|
+
<Button>保存して次へ</Button>
|
|
175
|
+
|
|
176
|
+
// ❌ REQUIREMENTS.md に書いてはいけない
|
|
177
|
+
「次へ」ボタンをクリック
|
|
178
|
+
|
|
179
|
+
// ✅ REQUIREMENTS.md に書くべき内容
|
|
180
|
+
「保存して次へ」ボタンをクリック
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**3. Priority判定の基準**
|
|
184
|
+
|
|
185
|
+
リバースエンジニアリングの場合、以下の基準でPriorityを判断する:
|
|
186
|
+
|
|
187
|
+
| Priority | 判断基準 |
|
|
188
|
+
|----------|---------|
|
|
189
|
+
| P0 | 主要な正常系フロー、ビジネスの中核機能 |
|
|
190
|
+
| P1 | 重要なエラーハンドリング、バリデーション |
|
|
191
|
+
| P2 | エッジケース、低頻度の操作 |
|
|
192
|
+
|
|
193
|
+
**4. 「備考」セクションにリバースエンジニアリングの注記を追加**
|
|
194
|
+
|
|
195
|
+
```markdown
|
|
196
|
+
## 7. 備考
|
|
197
|
+
|
|
198
|
+
このドキュメントは既存実装からリバースエンジニアリングで作成されました。
|
|
199
|
+
|
|
200
|
+
**確認が必要な項目**:
|
|
201
|
+
- [ ] ビジネス目標がビジネス要件と合致しているか
|
|
202
|
+
- [ ] Priority判断がビジネス優先度と合っているか
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Phase 3: UIキャプチャ → Figmaファイル作成
|
|
208
|
+
|
|
209
|
+
REQUIREMENTS.md作成後、Playwright MCPを使って実装済みUIのスクリーンショットを取得し、Figmaデザインファイルとして整理する。
|
|
210
|
+
|
|
211
|
+
### 作業手順
|
|
212
|
+
|
|
213
|
+
1. **キャプチャ計画作成**: コードリーディング結果を元に、キャプチャすべき画面と状態を一覧化
|
|
214
|
+
2. **Playwright MCPで操作・キャプチャ**: テストユーザーでログイン → 各画面を操作 → スクリーンショット取得 → ログアウト
|
|
215
|
+
3. **Figmaファイル作成**: スクリーンショットをFigmaに取り込み、フレームとして整理
|
|
216
|
+
4. **REQUIREMENTS.md更新**: 「UI/UXデザイン」セクションにFigmaファイルのnode-id付きリンクを記載
|
|
217
|
+
|
|
218
|
+
### キャプチャすべき画面状態
|
|
219
|
+
|
|
220
|
+
| カテゴリ | 状態例 |
|
|
221
|
+
|---------|--------|
|
|
222
|
+
| 初期状態 | データなし(空)、ローディング中 |
|
|
223
|
+
| データあり | 1件表示、複数件表示 |
|
|
224
|
+
| フォーム | 未入力、入力済み、バリデーションエラー |
|
|
225
|
+
| モーダル | 開いた状態(新規追加/編集) |
|
|
226
|
+
| 操作結果 | 成功トースト、削除確認ダイアログ |
|
|
227
|
+
| レスポンシブ | デスクトップ(1280px)、モバイル(375px) |
|
|
228
|
+
|
|
229
|
+
### REQUIREMENTS.mdへの記載フォーマット
|
|
230
|
+
|
|
231
|
+
既存のSpec(例: `docs/<app.id>/<feature_path>/REQUIREMENTS.md`、`.stdd.config.yml` の `docs.layout.requirements` テンプレートに従う)の「Figmaデザイン」セクションを参考にする:
|
|
232
|
+
|
|
233
|
+
```markdown
|
|
234
|
+
### Figmaデザイン
|
|
235
|
+
|
|
236
|
+
**Figmaファイル**: [ファイル名](FigmaファイルURL)
|
|
237
|
+
|
|
238
|
+
#### [画面名1]
|
|
239
|
+
|
|
240
|
+
- [状態A](FigmaファイルURL?node-id=X-Y)
|
|
241
|
+
- [状態B](FigmaファイルURL?node-id=X-Y)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
詳細: [Figmaキャプチャガイド](guides/figma-capture.md)
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Phase 4: TECH_DESIGN.md作成
|
|
249
|
+
|
|
250
|
+
`documenting-specifications` skillのテンプレートに従って作成する。
|
|
251
|
+
|
|
252
|
+
### リバースエンジニアリング固有のルール
|
|
253
|
+
|
|
254
|
+
**1. 型定義は実装から正確にコピーする**
|
|
255
|
+
|
|
256
|
+
domain/models配下のEntity型、スキーマの型をそのまま記載する。推測で型を書かない。
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
// ❌ 想像で書いた型
|
|
260
|
+
interface UserProfile {
|
|
261
|
+
name: string; // ← 実際は first_name + last_name
|
|
262
|
+
phone: string; // ← 実際は phone: string(nullable)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// ✅ 実装から正確にコピーした型
|
|
266
|
+
// <app.path>/domain/models/user.ts から転記(app.path は .stdd.config.yml の apps[].path)
|
|
267
|
+
interface UserEntity {
|
|
268
|
+
first_name: string | null;
|
|
269
|
+
last_name: string | null;
|
|
270
|
+
phone: string;
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**2. バリデーションルールはZodスキーマから正確に転記する**
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
// schema.ts の実際のコード
|
|
278
|
+
const phoneSchema = z.string()
|
|
279
|
+
.min(10, { message: '電話番号は10文字以上で入力してください' })
|
|
280
|
+
.regex(/^[0-9-]+$/, { message: '数字とハイフンのみ入力可能です' });
|
|
281
|
+
|
|
282
|
+
// ✅ TECH_DESIGN.md に書く内容
|
|
283
|
+
// - `phone`: 10文字以上、数字とハイフンのみ許可
|
|
284
|
+
// - エラー: 「電話番号は10文字以上で入力してください」「数字とハイフンのみ入力可能です」
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**3. テスト総数は作成後に正確にカウントする**
|
|
288
|
+
|
|
289
|
+
TECH_DESIGN.mdにはテスト総数を記載するが、テストを実際に書いた後にitブロック数を正確にカウントして更新する。
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
# カウント方法(Jest)
|
|
293
|
+
grep -c "it(" path/to/test.test.tsx
|
|
294
|
+
|
|
295
|
+
# カウント方法(Playwright)
|
|
296
|
+
grep -c "test(" e2e/tests/user-app/feature.spec.ts
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**4. ER図はdatabase.types.tsを正確に反映する**
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
❌ テーブル名やカラム名を想像で書く
|
|
303
|
+
✅ supabase/generated/database.types.ts の定義を参照して書く
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Phase 5: テスト作成
|
|
309
|
+
|
|
310
|
+
### E2Eテスト
|
|
311
|
+
|
|
312
|
+
`e2e-testing` skillに従い、TECH_DESIGN.mdのテスト戦略に基づいて作成する。
|
|
313
|
+
|
|
314
|
+
**リバースエンジニアリング固有のポイント**:
|
|
315
|
+
|
|
316
|
+
1. **実際の画面を操作して動作確認してからテストを書く**
|
|
317
|
+
- テストデータ(seedデータ)がどのユーザー・どの状態で入っているか確認
|
|
318
|
+
- 実際のUI操作で画面遷移・表示を確認
|
|
319
|
+
|
|
320
|
+
2. **Locatorは実装のJSXから正確に取得する**
|
|
321
|
+
```typescript
|
|
322
|
+
// 実装を確認
|
|
323
|
+
<button aria-label="保存">保存して次へ</button>
|
|
324
|
+
|
|
325
|
+
// ✅ テストのLocator
|
|
326
|
+
await page.getByRole('button', { name: '保存して次へ' });
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
3. **テストデータはseedファイルから確認する**
|
|
330
|
+
```
|
|
331
|
+
supabase/seeds/*.sql
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Unit / Integrationテスト
|
|
335
|
+
|
|
336
|
+
TECH_DESIGN.mdのテスト戦略で定めたテストレベルに従って作成する。
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Phase 6: 整合性チェック
|
|
341
|
+
|
|
342
|
+
### `/verifying-consistency` の実行
|
|
343
|
+
|
|
344
|
+
すべてのドキュメント・テスト作成後、`/verifying-consistency` コマンドで整合性を確認する。
|
|
345
|
+
|
|
346
|
+
### 不整合発見時の修正方針
|
|
347
|
+
|
|
348
|
+
リバースエンジニアリングの場合、**Specを実装に合わせる**のが原則。
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
❌ 実装をSpecに合わせて変更する(リバースエンジニアリングでは原則禁止)
|
|
352
|
+
✅ Specを実装の実際の挙動に合わせて修正する
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**例外**: 実装に明らかなバグがある場合は、バグとして記録し別途修正する。
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Spec粒度の基本方針
|
|
360
|
+
|
|
361
|
+
| 原則 | ルール | 例 |
|
|
362
|
+
|------|--------|------|
|
|
363
|
+
| **A: 1フロー = 1 Spec** | 開始〜完了まで一連の操作は1 Spec | パスワードリセット、新規登録 |
|
|
364
|
+
| **B: 関連画面はまとめる** | 同一データの一覧+詳細等は1 Spec | 通知一覧+詳細 |
|
|
365
|
+
| **C: 複雑時はサブ分割** | User Journey 7つ以上 or 実装1000行超で分割 | ダッシュボード(タブ別) |
|
|
366
|
+
| **D: 機能追加は独立Spec可** | 既存画面への追加機能は独立Specとして配置可 | 評価ボタン追加 |
|
|
367
|
+
|
|
368
|
+
**⚠️ 作業開始前の確認**: 上記方針を踏まえたうえで、必ず開発者にSpec粒度(どの画面・機能を1 Specにまとめるか)とスコープ(どこまでを対象とするか)を確認してから作業を開始すること。
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## チェックリスト
|
|
373
|
+
|
|
374
|
+
### コードリーディング完了時
|
|
375
|
+
|
|
376
|
+
```
|
|
377
|
+
□ ページコンポーネントを読んだ
|
|
378
|
+
□ クライアントコンポーネントを読んだ
|
|
379
|
+
□ バリデーションスキーマを読んだ
|
|
380
|
+
□ Server Actionsを読んだ
|
|
381
|
+
□ Domain層(models, repository, service)を読んだ
|
|
382
|
+
□ database.types.tsで関連テーブルを確認した
|
|
383
|
+
□ seedデータを確認した
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### REQUIREMENTS.md作成時
|
|
387
|
+
|
|
388
|
+
```
|
|
389
|
+
□ ボタンラベル・リンクテキストは実装のJSXから転記した
|
|
390
|
+
□ フォーム項目名は実装の<label>やaria-labelから転記した
|
|
391
|
+
□ エラーメッセージはZodスキーマのmessageから転記した
|
|
392
|
+
□ 画面遷移はrouter.push/redirectの実際のパスを記載した
|
|
393
|
+
□ すべてのUser JourneyにPriority(P0/P1/P2)を付与した
|
|
394
|
+
□ 「備考」セクションにリバースエンジニアリング注記を追加した
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### UIキャプチャ → Figma作成時
|
|
398
|
+
|
|
399
|
+
```
|
|
400
|
+
□ キャプチャ計画を作成した(全画面・全状態を洗い出し)
|
|
401
|
+
□ Playwright MCPでテストユーザーを使用してログインした
|
|
402
|
+
□ デスクトップ(1280px)・モバイル(375px)の両方をキャプチャした
|
|
403
|
+
□ データが表示されたことを確認してからキャプチャした
|
|
404
|
+
□ フォーム・モーダルの各状態(空/入力済み/エラー)を網羅した
|
|
405
|
+
□ 操作完了後にログアウトした
|
|
406
|
+
□ Figmaファイルを作成し、フレームとして整理した
|
|
407
|
+
□ REQUIREMENTS.mdの「UI/UXデザイン」セクションにnode-id付きリンクを記載した
|
|
408
|
+
□ スクリーンショットを削除した(gitにはコミットしない)
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### TECH_DESIGN.md作成時
|
|
412
|
+
|
|
413
|
+
```
|
|
414
|
+
□ 型定義はdomain/models配下から正確にコピーした
|
|
415
|
+
□ バリデーションルールはschema.tsから正確に転記した
|
|
416
|
+
□ ER図はdatabase.types.tsを参照して作成した
|
|
417
|
+
□ テスト戦略を記載した(ジャーニー別テストマッピング)
|
|
418
|
+
□ テスト総数と内訳を記載した
|
|
419
|
+
□ 実装例・コード例が含まれていないことを確認した(型定義・I/Fは除く)
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### テスト作成時
|
|
423
|
+
|
|
424
|
+
```
|
|
425
|
+
□ E2EテストのLocatorは実装のJSXテキストから取得した
|
|
426
|
+
□ テストデータはseedファイルの内容を確認した
|
|
427
|
+
□ TECH_DESIGN.mdのテスト戦略に記載されたテストケースを網羅した
|
|
428
|
+
□ テスト実行して全件パスした
|
|
429
|
+
□ TECH_DESIGN.mdのテスト総数を実際のitブロック数で更新した
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### 最終確認
|
|
433
|
+
|
|
434
|
+
```
|
|
435
|
+
□ /verifying-consistency を実行した
|
|
436
|
+
□ 検出された不整合をすべて修正した(Specを実装に合わせる方向で)
|
|
437
|
+
□ TypeScript型チェック(`.stdd.config.yml` の `commands.typecheck`)がクリーン
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## When NOT to Use This Skill
|
|
443
|
+
|
|
444
|
+
以下の場合はこのスキルを使用しない:
|
|
445
|
+
|
|
446
|
+
- **プロジェクト全体 / common ティアのリバース**(STDD 導入時の `docs/common/` 作成): `reverse-engineering-common-spec` skillを使用
|
|
447
|
+
- **新規機能の仕様策定**: `documenting-specifications` skillを使用
|
|
448
|
+
- **実装タスクの計画**: `documenting-plans` skillを使用
|
|
449
|
+
- **E2Eテストのみの作成**(Specドキュメントが既に存在する場合): `e2e-testing` skillを使用
|
|
450
|
+
- **バグ修正**: リバースエンジニアリングではなく直接修正
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## 参照ファイル
|
|
455
|
+
|
|
456
|
+
- **共通spec(commonティア)リバース**: [reverse-engineering-common-spec skill](../reverse-engineering-common-spec/SKILL.md)
|
|
457
|
+
- **Specテンプレート**: [documenting-specifications skill](../documenting-specifications/SKILL.md)
|
|
458
|
+
- **E2Eテストガイド**: [e2e-testing skill](../../../plugins/playwright/skills/e2e-testing/SKILL.md)(`playwright` プラグイン)
|
|
459
|
+
- **PLANドキュメント**: [documenting-plans skill](../documenting-plans/SKILL.md)
|
|
460
|
+
- **STDD違反例**: [stdd-violations guide](../documenting-specifications/guides/stdd-violations.md)
|
|
461
|
+
- **正確性ガイド**: [accuracy guide](guides/accuracy.md)
|
|
462
|
+
- **Figmaキャプチャガイド**: [figma-capture guide](guides/figma-capture.md)
|
|
463
|
+
- **DB型定義**: `supabase/generated/database.types.ts`
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# 正確性ガイド - Specに記載する文言は正確に実装を反映すること
|
|
2
|
+
|
|
3
|
+
リバースエンジニアリングにおける最重要原則。既存実装からSpecを作成する場合、**推測や一般化で書かず、必ず実装コードを確認してから書く**こと。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 原則
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
実装のコードが真実(Single Source of Truth)
|
|
11
|
+
Specはその真実を忠実にドキュメント化したもの
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
一般的なSTDDではSpecが先でSpec→テスト→実装の順序だが、リバースエンジニアリングでは実装が既にあるため、**実装→Spec→テスト**の順序で、実装に忠実なSpecを作る。
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## カテゴリ別の確認ポイント
|
|
19
|
+
|
|
20
|
+
### 1. UIテキスト(ボタンラベル、見出し、プレースホルダー)
|
|
21
|
+
|
|
22
|
+
**確認元**: JSXのテキストノード、`aria-label`、`placeholder`
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// 実装コード例
|
|
26
|
+
<Button type="submit">保存して次へ</Button>
|
|
27
|
+
<h1>プロフィール登録</h1>
|
|
28
|
+
<Input placeholder="例: 090-1234-5678" />
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| 書くべき内容 | 書いてはいけない内容 |
|
|
32
|
+
|------------|-------------------|
|
|
33
|
+
| 「保存して次へ」ボタン | 「次へ」ボタン |
|
|
34
|
+
| 「プロフィール登録」見出し | 「プロフィール入力」見出し |
|
|
35
|
+
| プレースホルダー「例: 090-1234-5678」 | プレースホルダー「電話番号」 |
|
|
36
|
+
|
|
37
|
+
### 2. バリデーションルール
|
|
38
|
+
|
|
39
|
+
**確認元**: Zodスキーマ(`schema.ts` / `lib/schemas/*.ts`)
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// 実装コード例
|
|
43
|
+
const schema = z.object({
|
|
44
|
+
phone: z.string()
|
|
45
|
+
.min(10, { message: '電話番号は10文字以上で入力してください' })
|
|
46
|
+
.regex(/^[0-9-]+$/, { message: '数字とハイフンのみ入力可能です' }),
|
|
47
|
+
email: z.string()
|
|
48
|
+
.email({ message: '有効なメールアドレスを入力してください' }),
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
| 書くべき内容 | 書いてはいけない内容 |
|
|
53
|
+
|------------|-------------------|
|
|
54
|
+
| 10文字以上、数字とハイフンのみ | 10〜11桁の数字(ハイフン許可) |
|
|
55
|
+
| エラー: 「電話番号は10文字以上で入力してください」 | エラー: 「電話番号の形式が不正です」 |
|
|
56
|
+
|
|
57
|
+
**特に注意**: `min()` / `max()` の値、`regex()` のパターン、`message` の文言を正確に転記すること。
|
|
58
|
+
|
|
59
|
+
### 3. エラーメッセージ
|
|
60
|
+
|
|
61
|
+
**確認元**: Zodスキーマの`message`、Server Actionsの`return { error: '...' }`、toast/Snackbarの文言
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// Server Actions
|
|
65
|
+
if (!user) {
|
|
66
|
+
return { error: 'ユーザーが見つかりません' };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Snackbar
|
|
70
|
+
showSnackbar('プロフィールを更新しました', 'success');
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
| 書くべき内容 | 書いてはいけない内容 |
|
|
74
|
+
|------------|-------------------|
|
|
75
|
+
| 「ユーザーが見つかりません」 | 「ユーザーが存在しません」 |
|
|
76
|
+
| 「プロフィールを更新しました」 | 「保存しました」 |
|
|
77
|
+
|
|
78
|
+
### 4. 画面遷移・URL
|
|
79
|
+
|
|
80
|
+
**確認元**: `router.push()`, `redirect()`, `<Link href="...">`, `useRouter`
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// 実装コード例
|
|
84
|
+
router.push('/dashboard');
|
|
85
|
+
redirect('/onboarding?step=2');
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
| 書くべき内容 | 書いてはいけない内容 |
|
|
89
|
+
|------------|-------------------|
|
|
90
|
+
| `/dashboard` に遷移 | ダッシュボードに遷移(パスが不明) |
|
|
91
|
+
| `/onboarding?step=2` に遷移 | ステップ2に遷移 |
|
|
92
|
+
|
|
93
|
+
### 5. フォーム項目
|
|
94
|
+
|
|
95
|
+
**確認元**: `<label>`, `<FormLabel>`, `aria-label`, React Hook Formの`register`名
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
// 実装コード例
|
|
99
|
+
<FormField name="last_name" label="姓" required />
|
|
100
|
+
<FormField name="first_name" label="名" required />
|
|
101
|
+
<FormField name="nickname" label="ニックネーム" />
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
| 書くべき内容 | 書いてはいけない内容 |
|
|
105
|
+
|------------|-------------------|
|
|
106
|
+
| 姓(必須)、名(必須) | 氏名(必須) |
|
|
107
|
+
| ニックネーム(任意) | ニックネーム(必須) |
|
|
108
|
+
|
|
109
|
+
### 6. 型定義・データモデル
|
|
110
|
+
|
|
111
|
+
**確認元**: `domain/models/*.ts`, `database.types.ts`
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// 実装コード例 - domain/models/user.ts
|
|
115
|
+
export interface UserEntity {
|
|
116
|
+
id: string;
|
|
117
|
+
last_name: string | null;
|
|
118
|
+
first_name: string | null;
|
|
119
|
+
nickname: string | null;
|
|
120
|
+
phone: string;
|
|
121
|
+
email: string;
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
| 書くべき内容 | 書いてはいけない内容 |
|
|
126
|
+
|------------|-------------------|
|
|
127
|
+
| `last_name: string \| null` | `lastName: string` |
|
|
128
|
+
| `phone: string` | `phone: string \| null` |
|
|
129
|
+
|
|
130
|
+
**注意**: Entity型(DB層)はsnake_case、UI型はcamelCase。混同しないこと。
|
|
131
|
+
|
|
132
|
+
### 7. DB操作・テーブル名
|
|
133
|
+
|
|
134
|
+
**確認元**: `database.types.ts`, repository層の`.from('table_name')`
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// 実装コード例 - repository
|
|
138
|
+
const { data } = await supabase
|
|
139
|
+
.from('users')
|
|
140
|
+
.select('id, last_name, first_name')
|
|
141
|
+
.eq('id', userId);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
| 書くべき内容 | 書いてはいけない内容 |
|
|
145
|
+
|------------|-------------------|
|
|
146
|
+
| `users`テーブル | `user`テーブル(単数形) |
|
|
147
|
+
| `last_name`カラム | `lastName`カラム |
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## よくある間違いパターン
|
|
152
|
+
|
|
153
|
+
### パターン1: 一般的な知識で書いてしまう
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
❌ 「電話番号は10〜11桁の数字」(日本の一般常識)
|
|
157
|
+
✅ 「電話番号は10文字以上、数字とハイフンのみ」(実際のZodスキーマ)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### パターン2: 似ているが違う文言
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
❌ 「戻る」ボタン(一般的なUI用語)
|
|
164
|
+
✅ 「前へ」ボタン(実際のJSXテキスト)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### パターン3: カラム名の推測
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
❌ career テーブル(単数形で推測)
|
|
171
|
+
✅ careers テーブル(database.types.tsで確認)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### パターン4: nullable の見落とし
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
❌ first_name: string(nullableを見落とし)
|
|
178
|
+
✅ first_name: string | null(database.types.tsで確認)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### パターン5: テスト総数の不正確
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
❌ Unit 9件(describeブロック数を数えた)
|
|
185
|
+
✅ Unit 41件(itブロック数を正確にカウントした)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 検証方法
|
|
191
|
+
|
|
192
|
+
### 1. Spec作成後のセルフレビュー
|
|
193
|
+
|
|
194
|
+
Specに記載した各文言について、以下を確認する:
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
□ この文言は、どのファイルの何行目から取得したか説明できるか?
|
|
198
|
+
□ 実装コードを見ずに書いた推測的な記述はないか?
|
|
199
|
+
□ 「〜だろう」「〜と思われる」という曖昧な表現はないか?
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### 2. /verifying-consistency の活用
|
|
203
|
+
|
|
204
|
+
Spec・テスト・実装の3点整合性を自動チェックする。不整合が見つかった場合、原則としてSpecを実装に合わせて修正する。
|
|
205
|
+
|
|
206
|
+
### 3. grep での文言一致確認
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
# REQUIREMENTS.mdに書いたボタンラベルが実装に存在するか確認
|
|
210
|
+
# <app.path> は .stdd.config.yml の apps[].path(複数アプリは apps[] をループ)
|
|
211
|
+
grep -r "保存して次へ" <app.path>/app/
|
|
212
|
+
|
|
213
|
+
# TECH_DESIGN.mdに書いたバリデーションルールが実装に存在するか確認
|
|
214
|
+
grep -r "min(10" <app.path>/app/
|
|
215
|
+
```
|