EY-Office ブログ

これは使える! 遅ればせながらSpec Driven Developmentに入門してみた (3)

今週も 遅ればせながらSpec Driven Developmentに入門してみた (1)遅ればせながらSpec Driven Developmentに入門してみた (2) 続きです。

今週は、予告通りステアリングを使ったり、実際の開発でもよく起こる実装フェーズになってからの仕様変更を行ったりしました。

結論としては Spec Driven Development(cc-sdd)は使えるぞ! です。
(お急ぎの方は前半はざっと読み、開発開始❗から読んでください)

SpecDrivenDevelopment Bing Image Creatorが生成した画像を使っています

ステアリングについて

cc-sddのREADMEには、

重要な基盤コマンド: ステアリングは永続的プロジェクトメモリを作成 - AIが全セッションで使用するコンテキスト、ルール、アーキテクチャ。既存プロジェクトでは最初に実行して仕様品質を劇的に向上。

と簡単な解説しかありませんが、既存プロジェクトでcc-sddを使う場合に最初に/kiro:steeringコマンドを実行し既存プロジェクトの情報を調べ文書化しています。以下のようなファイルはファイルが.kiro/steering以下に生成されます。

.kiro/
├── settings
│   └─ ・・・
├── specs
│   └─ ・・・
└── steering
    ├── product.md
    ├── structure.md
    └── tech.md

先週作ったワイン販売のECサイトで/kiro:steeringを実行すると以下のようなファイルが生成されます(かなり省略)。

product.md プロダクトの目的、価値、主要機能

# プロダクト概要

ワインに特化したECサイト。ワイン愛好家に向けて、種類・産地・価格帯などの豊富なフィルタリング機能を備えたオンラインショッピング体験を提供する。

## コア機能

- **商品カタログ**: ワイン商品の検索・フィルタリング・詳細表示(種類、産地、ヴィンテージ、価格帯)
- **ユーザー認証**: JWT ベースの認証・認可(一般ユーザー / 管理者ロール)
- **ショッピングカート**: カート管理と数量調整
- **注文・決済**: Stripe 連携による決済処理、注文管理
- **メール通知**: 注文確認・パスワードリセットなどのメール送信

## ターゲットユースケース

   ・・・

structure.md プロジェクト構成、命名規則、インポート慣習

# プロジェクト構造

## 構成方針

モノレポ構成で `backend/``frontend/` を分離。バックエンドはレイヤードアーキテクチャ、フロントエンドは機能ベースのコンポーネント構成。

## ディレクトリパターン

### バックエンド (`backend/`)

#### API レイヤー
**場所**: `app/api/v1/`
**目的**: HTTPリクエスト/レスポンス処理、ルーター定義
****: `auth.py`(認証エンドポイント), `products.py`(商品エンドポイント)
**パターン**: `router.py` で各ルーターを集約し、`/api/v1` プレフィックスで統一

  ・・・

tech.md 技術スタック、フレームワーク、設計方針

# 技術スタック

## アーキテクチャ

フロントエンドとバックエンドを分離したSPA構成。Docker Composeによるローカル開発環境。

## コア技術

### バックエンド
- **言語**: Python 3.12+
- **フレームワーク**: FastAPI
- **ORM**: SQLAlchemy 2.0(非同期、Mapped型)
- **データベース**: PostgreSQL 16(asyncpg ドライバ)
- **マイグレーション**: Alembic

  ・・・

## 開発環境

### 必要ツール
- Docker / Docker Compose
- Node.js(フロントエンド開発時)
- Python 3.12+(バックエンドローカル開発時)

  ・・・

ステアリング作成

先週の制作では、cc-sddは最初Next.jsのReact Server Functionを使うアーキテクチャで設計したので、設計後にアーキテクチャの変更を依頼しました。新規プロジェクトでも最初にステアリングを作っておけばこのような余分な手間が省けまるはずです。またステアリングはノウハウとして次のプロジェクトでも利用できそうです。

今回のステアリングは上にあげた先週のものをベースに作りました。細かい点までは指定しなくてもClaudeは同じように作ると思うので、大きな選択や必須な項目のみ書きました。

product.md プロダクトの目的、価値、主要機能

ほぼ、先週のものを利用しました

# プロダクト概要

ワインに特化したECサイト。ワイン愛好家に向けて、種類・産地・価格帯などの豊富なフィルタリング機能を備えたオンラインショッピング体験を提供する。

## コア機能

- **商品カタログ**: ワイン商品の検索・フィルタリング・詳細表示(種類、産地、ヴィンテージ、価格帯)
- **ユーザー認証**: 認証・認可(一般ユーザー / 管理者ロール)
- **ショッピングカート**: カート管理と数量調整
- **注文・決済**: カード決済処理
- **メール通知**: 注文確認・パスワードリセットなどのメール送信
- **管理ダッシュボード**: 商品・注文の包括的な管理画面


## ターゲットユースケース

- ワインの検索・閲覧(種類、産地、価格帯、在庫状況でのフィルタリング)
- ユーザー登録・ログインによるパーソナライズされた購買体験
- カートへの追加からカード決済までのシームレスな購入フロー
- 管理者による商品・注文の管理

## バリュープロポジション

ワインに特化したフィルタリング(赤・白・ロゼ・スパークリング、産地、ヴィンテージなど)と、モダンなUI/UXを組み合わせたECプラットフォーム。日本語ロケール対応。

structure.md プロジェクト構成、命名規則、インポート慣習

先週のstructure.mdには詳細な指定がありましたが、今回は重要なポイントのみ指定しました。

# プロジェクト構造

## 構成方針

モノレポ構成で `backend/``frontend/` を分離。バックエンドはレイヤードアーキテクチャ、フロントエンドは機能ベースのコンポーネント構成。

## ディレクトリパターン

### バックエンド (`backend/`)

### フロントエンド (`frontend/`)

## コード構成の原則

- **バックエンドのリクエストフロー**: Router → Service → Model
- **フロントエンドのデータフロー**: Route → Hook(TanStack Query) → API Client → コンポーネント

## 開発確認用データ

開発や確認のために100件程度のワインデータを準備する、ワインの画像データも必須。

tech.md 技術スタック、フレームワーク、設計方針

アーキテクチャや使って欲しいツール・ライブラリーにはこだわりがあるので、細かく指定しました。
また、コードには適度な日本語コメントを付ける のようなコーディングルールの指定も行いました。

# 技術スタック

## アーキテクチャ

フロントエンドとバックエンドを分離したSPA構成。

- バックエンド、データベースはDocker化
- フロントエンドはDocker化せず
- Docker Composeによるローカル開発環境

## コア技術

### バックエンド

- **言語**: Python
- **フレームワーク**: FastAPI
- **ORM**: SQLAlchemy 2.0
- **マイグレーション**: Alembic
- **認証**: JWT
- **決済**: Stripe

### データベース

- PostgreSQL 16
- 日本語ロケールを指定
- 複数データベースを準備
  - 本番/開発用
  - テスト用

### フロントエンド

- **言語**: TypeScript
- **フレームワーク**: React 19
- **ルーティング**: TanStack Router(ファイルベース)
- **サーバー状態管理**: TanStack Query
- **UIライブラリ**:daisyUI
- **スタイリング**: Tailwind CSS 4
- **ビルドツール**: Vite 6

## 開発標準

### テスト

#### バックエンド

- pytest
- APIエンドポイントのテストは必須                      <!--  ここは後で追加  -->
- ロジックを持つサービスやモデルにはテストを書く          <!--  ここは後で追加  -->
- テスト用データベースを使う

#### フロントエンド

- コンポーネント: Vitest + Testing Library(React)
- E2Eテスト: Playwright

## 開発環境

### 必要ツール

- Docker / Docker Compose
- Node.js
- Python

## 主要な技術的決定

- **完全非同期スタック**: FastAPI + asyncpg + aiosmtplib
- **主キー**: 主キーはPostgreSQLのSERIAL型を使う
- **ファイルベースルーティング**: TanStack Routerの自動ルート生成を活用
- **APIバージョニング**: `/api/v1/` プレフィックスによるバージョン管理
- **コメント**: コードには適度な日本語コメントを付ける

開発開始❗

プロジェクト作成

$ mkdir cc-sdd-trial-3
$ cd cc-sdd-trial-3
$ npx npx cc-sdd@latest --claude --lang ja
$ claude

空のステアリング作成を作成氏、内容を(人間が)書き換える

> `/kiro:steering`

要件定義、設計、タスク分解

❯ /kiro:spec-init ワイン販売のECサイト
  ....
> /kiro:spec-requirements wine-ec-site

要件定義ファイルrequirements.mdを確認しましたが、ステアリングがあるので問題なしでした!

> /kiro:spec-design wine-ec-site -y
> /kiro:spec-tasks wine-ec-site -y

設計書design.mdを確認しましたが問題ないので、タスク分解も実行。

ここで、ステアリングのバックエンドのテスト設定に以下が抜けている事を思い出し追加。 (ステアリングは実装でも読み込まれるので、まだ間に合うはずです)

- pytest
- APIエンドポイントのテストは必須                      <!--  ここを追加  -->
- ロジックを持つサービスやモデルにはテストを書く          <!--  ここを追加  -->
- テスト用データベースを使う

実装

1.プロジェクト基盤セットアップ を実行

❯ /kiro:spec-impl wine-ec-site 1 -y

PostgreSQLの日本語ロケール指定が失敗していたので手動で修正 。 やはりインフラ系は難しいですね。

2. データモデルとマイグレーション14. (P) 開発用シードデータの作成 を実行

❯ /kiro:spec-impl wine-ec-site 2
❯ /kiro:spec-impl wine-ec-site 14

データベースが出来て、シードデータが挿入されている事を確認

4. 商品カタログ(バックエンド)7. 商品カタログ(フロントエンド) を実行

途中でコンテキスト残容量が0%になって、/compact を実行しました。

❯ /kiro:spec-impl wine-ec-site 4

> /compact

❯ /kiro:spec-impl wine-ec-site 7

豆知識: Claude CodeはデフォルトではAuto-compactがtrueになっていて、コンテキスト残容量が0%になると勝手に/compact を実行されます。その際にMac iTerm2を使っているとコンソールログが消されてしまいます。私はこれが嫌いなので/configコマンドでfalseに設定しています。

動作確認

この時点でワインカタログ(一覧)が表示されるはずなので、cd frontend; npm run devフロントエンドを起動し、ブラウザーでアクセスしてみました。 ん?

「ワインカタログを見る」ボタンを押すとワインカタログが表示されました。素晴らしい 🥂

ここで、簡単な仕様変更を依頼
トップページをアクセスしたらワイン一覧を表示するように変更してください
難なくトップページがワインカタログになりました。🎉

さらなる仕様変更

ここで、気まぐれなお客様のように私は思いつきました 😄 「トップページはお薦めワインの一覧が表示されるようにしよう!」 そこで、以下のようにプロンプトしました。

「お薦めワインページ」を作成し、トップページにする仕様変更を行いたいです。今からdesign.mdを変更できますか?

変更の詳細:
 - winesテーブルに「お薦め」カラム boolean型を追加してください
 - お薦めワインページは「お薦め」カラムがtrueのワインのみ表示します
 - 「お薦め」のデザインはワインカタログと同じです
 - 「お薦め」カラムの設定は商品追加、商品編集で行います
 - 開発用に適当に20件ほどを「お薦め」にしてください

すると、cc-sdd(Claude Code)は変更点を検討を開始し

⏺ はい、design.mdを変更できます。まず現在の関連箇所を確認して、変更案を作成します。 
 
⏺ Read 1 file (ctrl+o to expand) 
 
⏺ Now let me read the Data Contracts section and the Frontend pages section. 
 
⏺ Read 1 file (ctrl+o to expand) 
 
⏺ 全体像を把握しました。design.mdに以下の変更を加えます。 
 
  変更箇所一覧: 
  1. Wine ER図に is_recommended カラム追加 
  2. Physical Data Model の wines テーブルに is_recommended 追加 
  3. WineFilterParams に is_recommended 追加 
  4. WineResponse に is_recommended 追加 
  5. WineCreateRequest / WineUpdateRequest に is_recommended 追加 
  6. Components テーブルに RecommendedPage 追加 
  7. Frontend Pages に RecommendedPage 記述追加 

  ・・・

⏺ design.md の変更は完了です。変更箇所をまとめます。 
 
  --- 
  design.md 変更サマリー(7箇所): 
  ┌─────┬───────────────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────┐ 
  │  #  │          セクション             │                                          変更内容                                          │ 
  ├─────┼───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤ 
  │ 1   │ Domain Model (ER図)           │ Wine に boolean is_recommended カラム追加                                                  │ 
  ├─────┼───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤ 
  │ 2   │ Business Rules                │ Wine.is_recommended のルール説明追加                                                       │ 
  ├─────┼───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤ 
  │ 3   │ Physical Data Model           │ wines テーブルに is_recommended BOOLEAN DEFAULT FALSE 追加                                 │ 
  ├─────┼───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤ 
  │ 4   │ Indexes                       │ wines に (is_recommended) インデックス追加                                                 │ 
  ├─────┼───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤ 
  │ 5   │ Data Contracts                │ WineFilterParams に is_recommended: bool | None、WineResponse に is_recommended: bool 追加 │ 
  ├─────┼───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤ 
  │ 6   │ Components テーブル           │ RecommendedPage (Frontend/Page) 追加                                                       │ 
  ├─────┼───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤ 
  │ 7   │ Frontend Implementation Notes │ トップページ(/)を RecommendedPage にする記述追加                                           │ 
  ├─────┼───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤ 
  │ 8   │ Requirements Traceability     │ 要件 1.9(お薦めワイントップページ)追加                                                   │ 
  ├─────┼───────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤ 
  │ 9   │ WineService Responsibilities  │ フィルタリング条件に「お薦め」追加                                                         │ 
  └─────┴───────────────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────┘ 
  requirements.md と tasks.md も更新が必要ですが、続けて変更しますか? 

❯ はい  

   ・・・

⏺ 更新完了です。変更サマリー: 
 
  requirements.md 
 
  - 1.9 追加: トップページにお薦めワインを表示する要件 
  - 6.2 / 6.3 更新: 商品追加・編集にお薦めフラグを含める 
 
  tasks.md 
 
  - 13.2 更新: 商品管理フォームにお薦めフラグの追加・編集を含める 
  - タスク16 新規追加 (3サブタスク): 
    - 16.1 バックエンド — is_recommendedカラム追加、マイグレーション、スキーマ/サービス/API拡張、テスト 
    - 16.2 シードデータ — 約20件にお薦めフラグ設定 
    - 16.3 フロントエンド — トップページをお薦みワインページに変更 
 
  実装に進みますか?(/kiro:spec-impl wine-ec-site 16) 
 
✻ Worked for 58s 
 
❯ はい  

変更タスク16が追加され、実行してくれました❗❗

 
⏺ 実行結果サマリー 
 
  タスク16.3: お薦めワインページの実装(フロントエンド) — 完了 
 
  実施内容: 
  - Wine型にis_recommendedフィールド、WineFilterParamsにis_recommendedフィルターを追加 
  - WineCardを共有コンポーネントとしてWineListPageから抽出 
  - RecommendedPageコンポーネントを新規作成(is_recommended=trueでAPI呼び出し、カタログリンク付き) 
  - トップページ(/)のルートをRecommendedPageに変更 
 
  テスト結果: 
  - フロントエンド: 31テスト全パス(新規7テスト + 既存24テスト) 
  - バックエンド: 86テスト全パス(リグレッションなし) 
 
  ステータス: タスク16(お薦めワイン機能)の全サブタスク(16.1, 16.2, 16.3)が完了 

画面を確認するとお薦めワインページが表示されていまいました 🎊🎊🎊

もちろん、要件定義書(requirements.md) 、 設計書(design.md)も更新されていました。😍

まとめ

cc-sddで、ステアリングを書く事でアーキテクチャや開発基板を固定でき、自社(自分)の持っているノウハウを生かす事ができます。しかも厳密に事細かに書かなくても良いのです。

また、今回の実験では実装段階になってからの仕様変更にも対応できました❗
仕様変更を依頼すると、要件定義、設計書、実装計画・・・が変更され、そこからコードが生成されています。これは長年ソフトウェア開発を行っている人間としては、とても安心感のあるアプローチでした。この感じでは比較的大きなシステムも作れそうですね。

プロンプトのみでコードが作成されるバイブコーディングに不安を感じる方は、是非Spec Driven Developmentを試してみてください❗

- about -

EY-Office代表取締役
・プログラマー
吉田裕美の
開発者向けブログ