はじめに
前回の【モダンWeb開発 シリーズ 第4回】では、第3回で確定した設計書とtest-cases.mdをCodexへ引き継ぎ、プロジェクト全体・Frontend・Backendの開発ルールをAGENTS.md に整理しました。さらに、実装後に繰り返し利用する検証手順をCodex Skillsとして作成しました。
今回から、いよいよCodexを使ってショッピングサイトの実装を開始します。
ただし、設計書に書かれた機能を一度にすべて実装させるのではありません。Backend、Database、Frontendを小さな実装単位に分け、各段階でCodexに実装を依頼し、Skillsで検証し、人間が結果を確認しながら進めます。
設計書
↓
今回の実装範囲を決める
↓
対応するtest-cases.mdを確認
↓
Codexへ実装を依頼
↓
AGENTS.mdに従って実装
↓
Skillsで検証
↓
★ 人間が確認
↓
次の実装へ
本記事では、ショッピングサイト一次開発を段階的に実装する流れと、Codexへどのように指示すればよいかを中心に解説します。
この記事で分かること
- 確定した設計書からCodexで実装を開始する方法
- 設計書・test-cases.md・AGENTS.md・Skillsを実装時にどう使い分けるか
- 大きな機能を小さな実装単位へ分割する考え方
- Codexへ実装を依頼するときのプロンプトの作り方
- CodexのYes / No確認を省略し、実装・検証後に事後報告させる設定
- Backendを
handler / service / repositoryに分けて実装する考え方 - PostgreSQLのテーブル・初期データを実装する流れ
- 商品一覧・検索・詳細APIを実装する流れ
- React + TypeScriptからREST APIを呼び出す流れ
- Backend / Frontend変更後にSkillsで検証する方法
- Codexの実装結果を人間が確認するポイント
- 設計ブロッカーと実装時決定事項を区別しながら実装を進める方法
今回の前提
使用するプロジェクトは、これまでと同じです。
C:\work\shopping-site
技術構成は次のとおりです。
| 項目 | 技術 |
|---|---|
| Frontend | React + TypeScript + Vite |
| Backend | Go |
| Database | PostgreSQL |
| 開発環境 | Docker / Docker Compose / VS Code Dev Containers |
| Coding Agent | Codex |
Codex CLIは、第2回・第4回と同じDev Containerの app コンテナ内で実行します。Goやnpmのコマンドも同じDev Container内で実行し、Docker Compose自体の起動・停止などはWindows PowerShellから行います。
プロジェクトには、第4回までに次のファイルを配置しています。
C:\work\shopping-site
│
├─ docs
│ ├─ requirements.md
│ ├─ use-cases.md
│ ├─ screen-design.md
│ ├─ database-design.md
│ ├─ api-design.md
│ ├─ open-questions.md
│ └─ test-cases.md
│
├─ AGENTS.md
├─ .codex
│ └─ skills
│ ├─ backend-verify
│ │ └─ SKILL.md
│ └─ frontend-verify
│ └─ SKILL.md
│
├─ frontend
│ ├─ AGENTS.md
│ ├─ src
│ └─ package.json
│
├─ backend
│ ├─ AGENTS.md
│ ├─ go.mod
│ └─ main.go
│
├─ compose.yml
├─ .env
├─ .env.example
├─ .gitignore
└─ .devcontainer
└─ devcontainer.json
第2回で、PostgreSQLの接続情報はプロジェクトルートの .env で管理し、compose.yml から環境変数として app コンテナと db コンテナへ渡す構成にしています。Backendの通常接続には DATABASE_URL、Repository / Integration Testには TEST_DATABASE_URL を使用します。接続先はDocker Compose内のPostgreSQLなので、ホスト名は localhost ではなく db です。
.env
↓
compose.yml
↓
app Container
├─ DATABASE_URL
└─ TEST_DATABASE_URL
↓
db:5432
第5回の実装では、この第2回で作成した環境設定をそのまま利用します。DBのユーザー名、パスワード、接続URLをGoのソースコードへ直接記述したり、別の接続情報を新しく追加したりしません。
一次開発では、商品閲覧、ユーザー登録・ログイン、カート、注文確定、注文履歴までを対象とします。
外部決済、配送、住所管理、送料、割引、クーポン、キャンセル・返品、メール確認、パスワード再設定、退会、ゲストカート、商品管理画面などは一次開発では実装しません。
一度に全部実装させない
設計書が完成すると、Codexへ次のように依頼したくなります。
設計書に従ってショッピングサイトを全部実装してください。
しかし、今回のようにFrontend、Backend、Database、認証、カート、注文処理まで含むシステムでは、一度に大きな変更を行うと確認範囲も大きくなります。
そこで、実装を段階的に進めます。
Step 1
Backendの基本構成
↓
Step 2
DBスキーマ・初期データ
↓
Step 3
商品一覧・検索・詳細API
↓
Step 4
ユーザー登録・認証
↓
Step 5
カート
↓
Step 6
注文確認・注文確定
↓
Step 7
注文履歴
↓
Step 8
Frontendから各APIを利用
↓
Step 9
全体確認
各Stepで、
実装
↓
検証
↓
人間が確認
↓
次へ
を繰り返します。
この進め方なら、不具合が発生した場合も、どの変更で問題が入ったのか追いやすくなります。
Codexの確認を省略して事後報告にする
今回の実装では、Codexがファイル変更や検証コマンドの実行ごとにYes / Noの確認を求めるのではなく、通常の実装作業はそのまま進め、完了後に変更内容と検証結果をまとめて報告する運用にします。
ただし、PC全体へ無制限にアクセスさせるのではなく、プロジェクトのワークスペース内で作業できる構成にします。
Codexの config.toml に、次の設定を追加します。
今回の環境ではCodex CLIをWindows側ではなくDev Container内で実行するため、設定ファイルもDev Container内のCodex設定を使用します。
Dev Container内のターミナルで、まずホームディレクトリを確認します。
echo $HOME
今回の構成では、次のように表示されます。
/home/vscode
Codexの設定ファイルは、次の場所です。
/home/vscode/.codex/config.toml
Dev Container内のターミナルから確認する場合は、次のコマンドを実行します。
cat ~/.codex/config.toml
config.toml がまだ存在しない場合は、.codex ディレクトリを作成します。
mkdir -p ~/.codex
config.toml に、次の設定を追加します。
approval_policy = "never"
sandbox_mode = "workspace-write"
approval_policy と sandbox_mode は、トップレベルの設定として記述します。
approval_policy = "never" にすることで、Codexは通常の処理を承認待ちで停止せずに進めます。
workspace-write は、Codexがワークスペース内のファイルを変更できるようにしつつ、PC全体へ無制限な書き込み権限を与えないための設定です。
今回の記事ではDev Container内のCodexを使用しているため、Windows側の次の設定ファイルは使用しません。
ちなみにWindows側の次の設定ファイルのパスは以下です。
「C:\Users\user.codex\config.toml」
設定を保存したら、起動中のCodexをいったん終了し、Dev Container内のプロジェクトルートから起動し直します。
cd /workspaces/shopping-site
codex
今回のイメージは次のようになります。
Codex
↓
設計書・AGENTS.mdを確認
↓
ファイルを変更
↓
Skillsで検証
↓
途中のYes / No確認なし
↓
変更内容・検証結果を事後報告
↓
★ 人間が確認
承認設定と開発ルールは役割が異なります。
config.toml
↓
Codexの実行・承認方法
AGENTS.md
↓
プロジェクト内で守る開発ルール
そのため、ルートの AGENTS.md にも、通常の実装・検証では逐次確認を求めず、作業完了後にまとめて報告するルールを追加します。
## Execution Policy
- 実装中の通常のファイル変更や検証について、逐次確認を求めず作業を進める
- 実装・検証が完了した後に、変更内容と検証結果をまとめて報告する
- 設計ブロッカーを発見した場合は、既存仕様を独断で変更せず報告する
ここで重要なのは、「確認を省略する」ことと「設計を自由に変更してよい」ことは別だという点です。
通常のファイル変更やテスト・ビルドは途中確認なしで進めますが、API契約、DB構造、セキュリティ要件、データ整合性など、確定済み設計そのものを変更する必要が生じた場合は、Codexが独断で変更せず人間へ報告します。
通常の実装・検証
↓
途中確認なし
↓
実装継続
↓
事後報告
設計ブロッカー
↓
既存仕様を勝手に変更しない
↓
人間へ報告
これにより、実装中の細かなYes / No確認を減らしながら、重要な設計判断は人間が行う運用にできます。
Codexを起動する
VS CodeでDev Containerを開きます。Codex CLIはWindows PowerShellではなく、Dev Container内で実行します。
Dev Container内のターミナルでプロジェクトルートへ移動します。
cd /workspaces/shopping-site
Codexを起動します。
codex
Codexはプロジェクトに配置した AGENTS.md を参照しながら作業します。
Backend配下を変更する場合は、
shopping-site/AGENTS.md
+
backend/AGENTS.md
Frontend配下を変更する場合は、
shopping-site/AGENTS.md
+
frontend/AGENTS.md
のルールが適用される構成です。
最初に実装計画を確認する
いきなりファイルを変更させる前に、まずCodexへ実装順序を確認させます。
docs/ 配下の確定済み設計書とtest-cases.md、
適用されるAGENTS.mdを確認してください。
一次開発の実装をこれから開始します。
今回はまだファイルを変更せず、
一次開発を小さな実装単位へ分割してください。
以下を整理してください。
・実装Step
・各Stepで実装する機能
・主に参照する設計書
・各Stepに対応するtest-cases.mdのテストケース
・変更が想定されるFrontend / Backend / DB
・各Stepの完了条件
・実行する検証
設計書に記載された仕様を正として扱ってください。
open-questions.mdで「実装時決定」とされた内容は、
既存の設計契約を変更しない範囲で実装時に決定してください。
二次開発の項目は今回の実装へ追加しないでください。
新しいOpen Questionを探すことを目的とせず、
現在の確定設計を実装へ落とし込む計画を作成してください。
今回はファイルを変更しないでください。
ここで人間が実装順序を確認します。
設計書
↓
Codexが実装単位を整理
↓
★ 人間が確認
↓
問題なし
↓
実装開始
Step 1 Backendの基本構成を実装する
まず、Backendの土台を整えます。 今回のBackendでは、backend/AGENTS.md に従って責務を分離します。
| 層 | 主な責務 |
|---|---|
| handler | HTTPリクエスト・レスポンス |
| service | ビジネスロジック |
| repository | PostgreSQLへのアクセス |
概念的には次の構成です。
HTTP Request
↓
handler
↓
service
↓
repository
↓
PostgreSQL
Codexには、最初から商品・認証・カート・注文を全部作らせず、まずBackendの基本構成だけを依頼します。
一次開発のStep 1として、
Backendの基本構成を実装してください。
実装前に、今回の変更に関係するdocs/と、
ルートAGENTS.md、backend/AGENTS.mdを確認してください。
今回の目的は、今後の商品・認証・カート・注文APIを
追加できるBackendの土台を作ることです。
backend/AGENTS.mdの責務分離に従い、
handler / service / repository を分離してください。
既存ファイルと既存構成を確認し、
必要以上の変更は行わないでください。
まだ商品、認証、カート、注文の
全機能をまとめて実装しないでください。
第2回で設定したDATABASE_URLを使用して、
環境変数からDB接続情報を取得してください。
DBのユーザー名、パスワード、接続URLを
Goのソースコードへ直接記述しないでください。
接続先はDocker Compose内のPostgreSQLなので、
localhost:5432ではなくdb:5432を前提としてください。
TEST_DATABASE_URLはRepository / Integration Test用として
第2回で設定済みの値を利用し、
今回の実装で別の接続方式を追加しないでください。
実装後はbackend-verify Skillに従って検証してください。
最後に、
・実装内容
・変更したファイル
・追加した依存関係
・実行した検証
・検証結果
・未実施事項
・残っている問題
を報告してください。
Codexが変更した内容を確認し、Backendの責務分離が守られているかを人間が確認します。
DB接続については、第2回で設定した環境変数を利用していることも確認します。通常のBackendは DATABASE_URL を参照し、Repository / Integration Testは TEST_DATABASE_URL を参照します。第5回では接続情報そのものを新しく定義するのではなく、第2回の開発環境を実装から利用できるようにします。
Go Backend
↓
DATABASE_URL
↓
db:5432
↓
PostgreSQL
Step 2 PostgreSQLのスキーマと初期データを実装する
次に docs/database-design.mdを基準として、一次開発で必要なテーブルを実装します。 この段階では、設計書に定義されたテーブル、制約、インデックス、外部キーなどをコードへ落とし込みます。 また、一次開発では商品管理画面を作成しないため、商品データは初期データとして用意します。
Codexへの依頼例です。
一次開発のStep 2として、
PostgreSQLのDBスキーマと初期商品データを実装してください。
主に以下を確認してください。
・docs/database-design.md
・docs/requirements.md
・docs/open-questions.md
・docs/test-cases.md
・ルートAGENTS.md
・backend/AGENTS.md
database-design.mdを正として、
一次開発で必要なテーブル、制約、インデックスを実装してください。
商品管理画面は一次開発の対象外なので、
動作確認に使用できる初期商品データも用意してください。
設計書に存在しないカラムやテーブルを
推測で追加しないでください。
設計契約を変更しない実装上の詳細は
合理的に決定して構いません。
DB接続には第2回で設定したDATABASE_URLを使用し、
接続情報をソースコードへ直接記述しないでください。
実装後はbackend-verify Skillに従って検証してください。
最後に変更内容と検証結果を報告してください。
DB実装では、単にテーブルが作成できることだけではなく、設計で決めた一意制約や外部キーなどが反映されていることも確認します。
Step 3 商品一覧・検索・詳細APIを実装する
次に、最初の業務機能として商品参照APIを実装します。 一次開発の商品参照は、
商品一覧
商品名検索
商品詳細
です。
商品参照は認証前でも利用できる公開機能なので、認証や注文処理より比較的切り分けやすく、最初のAPI実装として扱いやすい機能です。
Codexには次のように依頼します。
一次開発のStep 3として、
商品一覧・商品名検索・商品詳細APIを実装してください。
実装前に、今回の変更に関係する以下の設計書を確認してください。
・docs/requirements.md
・docs/use-cases.md
・docs/api-design.md
・docs/database-design.md
・docs/test-cases.md
ルートAGENTS.mdとbackend/AGENTS.mdにも従ってください。
api-design.mdに定義されたRequest、Response、
HTTP Method、Status Codeを変更しないでください。
handler / service / repository の責務を分離してください。
repositoryではパラメータ化SQLを使用し、
ユーザー入力をSQL文字列へ直接連結しないでください。
今回のタスクと無関係な認証、カート、注文機能は
まだ実装しないでください。
今回実装する機能に対応するtest-cases.mdのテストケースを確認し、期待結果を満たすように実装してください。
実装後は、該当するテストケースを基準として検証し、backend-verify Skillに従って検証してください。
最後に、実装内容、変更ファイル、テスト結果、ビルド結果、
残っている問題を報告してください。
このように、今回実装するものだけでなく、今回実装しないものも明示することで変更範囲を限定します。
Backend変更後はSkillで検証する
第4回で作成した backend-verify Skillでは、Backend変更後に次の検証を行います。
変更したGoファイル
↓
gofmt
↓
go test ./...
↓
go build ./...
↓
結果報告
実際のコマンドは、Codex CLIを起動しているDev Containerの app コンテナ内で実行します。第2回・第4回と同様に、GoのテストやビルドのためにWindows PowerShellから docker compose exec で入り直す必要はありません。
Dev Container内のターミナルでBackendへ移動します。
cd /workspaces/shopping-site/backend
そのうえで、Backendのテストを実行します。
go test ./...
今回の実行結果は次のようになりました。
? example.com/shopping-site/backend [no test files]
ok example.com/shopping-site/backend/internal/config (cached)
ok example.com/shopping-site/backend/internal/handler 0.005s
? example.com/shopping-site/backend/internal/product [no test files]
ok example.com/shopping-site/backend/internal/repository 0.004s
? example.com/shopping-site/backend/internal/service [no test files]
ok と表示されたパッケージはテスト成功です。[no test files] は、そのパッケージにテストファイルが存在しないことを示しており、テスト失敗ではありません。今回の結果では config、handler、repository のテストが成功し、go test ./... 全体も正常終了しました。
続いてビルドを確認します。
go build ./...
今回の実行結果は次のとおりでした。
$ go build ./...
$
go build ./... は成功時に何も表示せず、そのままDev Container内のシェルのプロンプトへ戻ることがあります。エラーメッセージがなく終了したため、今回のBackendビルドは成功です。
Backend検証
↓
go test ./...
↓
成功
↓
go build ./...
↓
成功
gofmt はBackend全体へ無条件に実行するのではなく、今回変更したGoファイルを対象にします。 ここで大切なのは、Codexの「実装しました」という報告だけで完了にしないことです。
Codexが実装
↓
Skillで検証
↓
テスト成功
↓
ビルド成功
↓
★ 人間が変更内容を確認
↓
Step完了
Step 4 ユーザー登録・認証を実装する
商品参照APIが動作したら、ユーザー登録と認証へ進みます。 ここでは、設計で決めたパスワードValidation、メールアドレスValidation、セッション、Cookie、Origin、CSRFなどが関係します。 特にQ-32で残したメールアドレスValidatorの具体的なASCII許可文字文法は、確定した入力契約を変更しない範囲で実装時に具体化する項目です。
Q-31
入力契約
↓
確定済み
Q-32
Validatorの具体化
↓
実装時決定
↓
Frontend / Backendで同じ判定
↓
境界値テスト
Codexへの依頼では、Q-32を理由に設計レビューへ戻さないことも明確にします。
一次開発のStep 4として、
ユーザー登録・ログイン・ログアウト・CSRF取得を実装してください。
今回の変更に関係する設計書と`docs/test-cases.md`、
ルートAGENTS.md、backend/AGENTS.mdを確認してください。
特に以下の確定仕様を守ってください。
・登録メールアドレスの入力契約
・パスワードの8〜72 Unicodeコードポイント
・パスワードをtrimしない
・パスワードをUnicode正規化しない
・パスワードを平文保存しない
・サーバー側セッション
・Cookie属性
・Origin検証
・CSRFトークンの取得・再発行・失効
open-questions.mdで「実装時決定」とされた
Q-32のValidator具体化は、
既存の入力契約を変更しない範囲で実装してください。
Q-32だけを理由に設計へ差し戻さないでください。
FrontendとBackendで同じ入力判定になるよう、
境界値をテストしてください。
実装後はbackend-verify Skillに従って検証し、
結果を報告してください。
もし実装中に、既存のAPI契約やDB設計そのものを変更しなければ実装できないことが判明した場合は、そのときだけ人間へ報告させます。
Step 5 カートを実装する
認証が動作したら、認証ユーザーのカートを実装します。 対象は、
カートへ追加
カート表示
数量変更
カートから削除
です。
カートではRequestから userIdを受け取って所有者を決めるのではなく、認証済みセッションのユーザーIDを使用します。 また、数量や在庫の最終判断はBackendで行います。
Frontend
↓
REST API
↓
認証済みセッション
↓
Backend
↓
所有権・数量を検証
↓
PostgreSQL
この段階でも、注文処理まで一緒に実装させず、カート単位で完了させます。 Codexには次のように依頼します。
一次開発のStep 5として、
認証ユーザーのカート機能を実装してください。
実装前に、今回の変更に関係する以下を確認してください。
・docs/requirements.md
・docs/use-cases.md
・docs/api-design.md
・docs/database-design.md
・docs/open-questions.md
・docs/test-cases.md
・ルートAGENTS.md
・backend/AGENTS.md
設計書に定義されたカートAPIの契約を正として、
以下を実装してください。
・カートへの商品追加
・カート表示
・数量変更
・カートからの商品削除
特に以下を守ってください。
・RequestからuserIdを受け取って所有者を決定しない
・認証済みセッションのユーザーIDを使用する
・他ユーザーのカートを参照・変更できないようにする
・数量や在庫の最終判断はBackendで行う
・商品不存在、販売停止、在庫不足などは設計書で定義されたStatus Codeに従う
・注文確定と競合するカート追加・数量変更・削除では、設計で確定した同一ユーザー行のロック規約に従う
・ロック待機後は最新状態を読み直して処理する
・handler / service / repository の責務を分離する
・repositoryではパラメータ化SQLを使用する
・今回のStepでは注文確定処理を追加しない
・ゲストカートなど二次開発の機能を追加しない
今回実装する機能に対応するtest-cases.mdのテストケースを確認し、期待結果を満たすように実装してください。
実装後は、該当するテストケースを基準として検証し、backend-verify Skillに従って検証してください。
正常系だけでなく、
・商品をカートへ追加できること
・自分のカートを表示できること
・数量を変更できること
・商品をカートから削除できること
・他ユーザーのカートを参照・変更できないこと
・未認証の場合に設計どおりのエラーになること
・不正な数量をBackendが拒否すること
・商品不存在、販売停止、在庫不足などが設計どおりに処理されること
を確認してください。
最後に、
・実装内容
・変更したファイル
・追加した依存関係
・実行した検証
・テスト結果
・ビルド結果
・未実施事項
・残っている問題
を報告してください。
Step 6 注文確認・注文確定を実装する
注文処理は一次開発の中でも特に重要な部分です。 設計では、
- 注文時の価格・数量・構成・販売状態・在庫の再検証
- ユーザー→カート→商品ID順のロック
- 注文・明細作成
- 在庫減算
- カート明細削除
- 同一トランザクション
- 失敗時Rollback
Idempotency-Key- 成功済み注文の再送
- 同一キー・異なる内容の409
などを定義しています。
この部分は、Codexへ「注文APIを作って」とだけ依頼するのではなく、設計書を明示して実装させます。
一次開発のStep 6として、
注文内容確認と注文確定を実装してください。
実装前に、今回の変更に関係する以下を確認してください。
・docs/requirements.md
・docs/use-cases.md
・docs/api-design.md
・docs/database-design.md
・docs/open-questions.md
・docs/test-cases.md
・ルートAGENTS.md
・backend/AGENTS.md
特に、
・注文確定時の再検証
・ユーザー、カート、商品のロック順
・注文とカート変更の並行制御
・注文、明細、在庫減算、カート削除のトランザクション
・失敗時Rollback
・負在庫防止
・注文時点の商品名、価格、数量、小計、合計の保存
・Idempotency-Key
・成功済み注文の再送
・同一キーで異なるRequestの場合の409
・404と409の境界
を設計書どおりに実装してください。
Frontendから送られた価格や合計を信用せず、
BackendでDBの情報から検証・計算してください。
今回実装する機能に対応するtest-cases.mdのテストケースを確認し、期待結果を満たすように実装してください。
実装後は、該当するテストケースを基準として検証し、backend-verify Skillに従って検証してください。
docs/test-cases.mdの注文内容確認・注文確定に対応するテストケースも確認してください。
正常系だけでなく、CART_EMPTY、CART_CHANGED、価格変更、在庫変更、在庫競合、冪等再送、Rollback、注文とカート変更の並行処理など、test-cases.mdで定義された期待結果を基準として検証してください。
最後に検証結果を報告してください。
注文処理は「APIが200や201を返した」だけでは十分ではありません。
正常注文
在庫不足
価格変更
カート変更
同一Idempotency-Key再送
同一キー + 異なる内容
途中エラー
並行リクエスト
など、設計で決めた重要な条件を確認します。
Step 7 注文履歴を実装する
注文確定まで実装できたら、自分の注文履歴一覧・詳細を実装します。 注文履歴では、注文時点で保存した商品名、単価、数量、小計、合計を使用します。 現在の商品マスタの値を使って過去の注文を再計算しないことがポイントです。 また、他人の注文を参照できないよう、認証済みユーザーとの所有権確認も行います。 Codexには次のように依頼します。
一次開発のStep 7として、
注文履歴一覧・注文履歴詳細を実装してください。
実装前に、今回の変更に関係する以下を確認してください。
・docs/requirements.md
・docs/use-cases.md
・docs/api-design.md
・docs/database-design.md
・docs/open-questions.md
・docs/test-cases.md
・ルートAGENTS.md
・backend/AGENTS.md
設計書に定義された注文履歴のAPI契約を正として実装してください。
特に以下を守ってください。
・注文履歴一覧は認証済みユーザー自身の注文だけを取得する
・注文履歴詳細は認証済みユーザー自身の注文だけを取得する
・他ユーザーの注文を参照できないよう所有権を確認する
・注文履歴では注文時点で保存した商品名、単価、数量、小計、合計を使用する
・現在の商品マスタの価格や商品名を使って過去の注文内容を再計算しない
・Requestから渡されたuserIdなどを所有者判定に使用せず、認証済みセッションのユーザーIDを使用する
・存在しない注文、または認証ユーザーが所有していない注文については、api-design.mdで確定した404の契約に従う
・handler / service / repository の責務を分離する
・repositoryではパラメータ化SQLを使用する
・今回のタスクと無関係な注文変更、キャンセル、返品、配送状態管理などの二次開発機能は追加しない
今回実装する機能に対応するtest-cases.mdのテストケースを確認し、期待結果を満たすように実装してください。
実装後は、該当するテストケースを基準として検証し、backend-verify Skillに従って検証してください。
正常系だけでなく、
・自分の注文履歴一覧を取得できること
・自分の注文履歴詳細を取得できること
・注文時点の商品名・価格が返されること
・存在しない注文IDで設計どおりの404になること
・他ユーザーの注文を参照できないこと
・未認証の場合に設計どおりのエラーになること
を確認してください。
最後に、
・実装内容
・変更したファイル
・追加した依存関係
・実行した検証
・テスト結果
・ビルド結果
・未実施事項
・残っている問題
を報告してください。
これにより、注文履歴でも単にデータを取得するだけではなく、認証済みユーザーとの所有権確認と、注文時点のスナップショットを使用していることまで検証できます。
Step 8 FrontendをREST APIへ接続する
Backendの主要APIが動作したら、React + TypeScript側を接続します。 Frontendでは frontend/AGENTS.md に従って、関数コンポーネント、TypeScriptによる型定義、API通信処理とcomponentsの分離、Loading / Success / Error / Empty、二重送信防止、フォームValidation、XSSへの配慮、UIの共通化などを守ります。 ここでFrontend全体を一度に実装させると、商品画面、認証、カート、注文、注文履歴まで変更範囲が大きくなります。そのため、Step 8もさらに小さな実装単位へ分割します。
Step 8-1 商品一覧・商品検索・商品詳細
↓
検証・人間が確認
↓
Step 8-2 ユーザー登録・ログイン・ログアウト
↓
検証・人間が確認
↓
Step 8-3 カート
↓
検証・人間が確認
↓
Step 8-4 注文内容確認・注文確定
↓
検証・人間が確認
↓
Step 8-5 注文履歴一覧・注文履歴詳細
↓
検証・人間が確認
↓
Step 8-6 Frontend全体確認
↓
Step 9 Frontend + Backend全体確認
各Stepでは、Backendの既存API契約を変更せず、対象となる画面とAPI通信だけを実装します。
Step 8-1 商品一覧・商品検索・商品詳細
まず、認証を必要としない商品参照画面から実装します。
一次開発のStep 8-1として、
商品一覧・商品検索・商品詳細のFrontendを実装してください。
実装前に、
・docs/requirements.md
・docs/use-cases.md
・docs/screen-design.md
・docs/api-design.md
・docs/test-cases.md
・ルートAGENTS.md
・frontend/AGENTS.md
を確認してください。
既存BackendのAPI契約を変更せず、React + TypeScriptから既存の商品APIを利用してください。
商品一覧画面、商品名検索、商品詳細画面、必要なAPI通信処理、Loading / Error / Empty状態を実装してください。
API通信処理をcomponentsへ直接集中させず、frontend/AGENTS.mdに従って適切に分離してください。
今回は認証、カート、注文、注文履歴のFrontendはまだ実装しないでください。
今回実装する機能に対応するtest-cases.mdのテストケースを確認し、期待結果を満たすように実装してください。
実装後は、該当するテストケースを基準として検証し、frontend-verify Skillに従って検証してください。
最後に、実装内容、変更したファイル、利用したBackend API、検証結果、未実施事項、残っている問題を報告してください。
Step 8-2 ユーザー登録・ログイン・ログアウト
商品参照画面が動作したら、認証関連のFrontendを実装します。
一次開発のStep 8-2として、
ユーザー登録・ログイン・ログアウトのFrontendを実装してください。
実装前に、requirements.md、use-cases.md、screen-design.md、api-design.md、open-questions.md、test-cases.md、ルートAGENTS.md、frontend/AGENTS.mdを確認してください。
既存BackendのAPI契約を変更せず、既存の認証APIを利用してください。
登録メールアドレスのFrontend Validationを確定仕様に合わせ、パスワードは8〜72 Unicodeコードポイントで判定してください。パスワードをtrimまたはUnicode正規化しないでください。
認証状態を画面へ反映し、Cookieベースのセッションを前提としてください。CSRFトークンは設計どおり取得し、永続ストレージへ保存せずメモリで保持してください。認証が必要な変更系RequestではOrigin / CSRFのBackend契約に従ってください。
Loading / Success / Errorを区別し、送信中の二重送信を防止してください。
今回実装する機能に対応するtest-cases.mdのテストケースを確認し、期待結果を満たすように実装してください。
実装後は、該当するテストケースを基準として検証し、frontend-verify Skillに従って検証し、実装内容、変更ファイル、利用したBackend API、Validation、CSRFの扱い、検証結果、未実施事項、残っている問題を報告してください。
Step 8-3 カート
認証画面が動作したら、カート画面を実装します。
一次開発のStep 8-3として、カート機能のFrontendを実装してください。
requirements.md、use-cases.md、screen-design.md、api-design.md、test-cases.md、ルートAGENTS.md、frontend/AGENTS.mdを確認してください。
既存BackendのAPI契約を変更せず、商品追加、カート表示、数量変更、削除、Loading / Success / Error / Empty、必要な二重送信防止を実装してください。
FrontendからuserIdを送信して所有者を決定せず、Backendの認証済みセッションを利用してください。数量や在庫をFrontendだけで最終判断せず、Backendの結果を正として画面へ反映してください。
変更系RequestではStep 8-2で実装したCSRF管理を利用してください。今回は注文確定処理を実装しないでください。
今回実装する機能に対応するtest-cases.mdのテストケースを確認し、期待結果を満たすように実装してください。
実装後は、該当するテストケースを基準として検証し、frontend-verify Skillに従って検証し、結果を報告してください。
Step 8-4 注文内容確認・注文確定
カートが動作したら、注文内容確認と注文確定のFrontendを実装します。
一次開発のStep 8-4として、注文内容確認・注文確定のFrontendを実装してください。
requirements.md、use-cases.md、screen-design.md、api-design.md、open-questions.md、test-cases.md、ルートAGENTS.md、frontend/AGENTS.mdを確認してください。
既存Backendの注文API契約を変更しないでください。
注文内容確認画面を実装し、注文確定中の二重送信を防止してください。価格、合計、在庫の最終判断をFrontendで行わず、Backendの結果を正として表示してください。
注文確定Requestでは設計どおりIdempotency-Keyを扱い、同じ注文確定操作の再試行では必要なIdempotency-KeyとRequest内容を保持してください。
価格変更、在庫不足、カート変更などの409、401、403などを設計に従って画面へ反映してください。403後に注文確定Requestを自動再送せず、必要ならCSRFトークンを再取得し、ユーザーの再操作で再試行できるようにしてください。
今回実装する機能に対応するtest-cases.mdのテストケースを確認し、期待結果を満たすように実装してください。
実装後は、該当するテストケースを基準として検証し、frontend-verify Skillに従って検証し、Idempotency-Key、CSRF再取得、競合時の画面動作を含めて結果を報告してください。
Step 8-5 注文履歴一覧・注文履歴詳細
注文確定まで動作したら、注文履歴画面を実装します。
一次開発のStep 8-5として、注文履歴一覧・注文履歴詳細のFrontendを実装してください。
requirements.md、use-cases.md、screen-design.md、api-design.md、test-cases.md、ルートAGENTS.md、frontend/AGENTS.mdを確認してください。
既存BackendのAPI契約を変更せず、注文履歴一覧画面、注文履歴詳細画面、Loading / Error / Empty状態を実装してください。
Backendから返された注文時点の商品名、単価、数量、小計、合計を表示し、現在の商品情報から過去の注文価格や合計を再計算しないでください。
RequestからuserIdを指定して他ユーザーの注文を取得する実装にはしないでください。
今回実装する機能に対応するtest-cases.mdのテストケースを確認し、期待結果を満たすように実装してください。
実装後は、該当するテストケースを基準として検証し、frontend-verify Skillに従って検証し、結果を報告してください。
Step 8-6 Frontend全体確認
Step 8-1〜8-5が完了したら、Frontendだけを対象に実装漏れと画面間のつながりを確認します。
一次開発のStep 8-6として、Frontend全体を確認してください。
Step 8-1〜8-5で実装した商品一覧、商品検索、商品詳細、ユーザー登録、ログイン、ログアウト、カート、注文内容確認、注文確定、注文履歴一覧、注文履歴詳細について、screen-design.md、api-design.md、test-cases.mdに対応するFrontend実装が存在することを確認してください。
必要な画面と画面遷移、FrontendとBackendのAPI契約、Loading / Success / Error / Empty、フォームValidation、二重送信防止、認証状態、CSRFのメモリ管理、403後の自動再送禁止、注文再試行時のIdempotency-KeyとRequest内容、注文履歴のスナップショット利用を確認してください。
設計契約を変更しない軽微なFrontendの不整合はAGENTS.mdに従って修正して構いません。API契約や確定済み設計そのものの変更が必要な場合は独断で変更せず報告してください。
確認後はfrontend-verify Skillに従って検証してください。
最後に、確認した画面、修正内容、変更ファイル、利用しているBackend API、lint結果、build結果、未実施事項、残っている問題、Step 9へ進めるかを報告してください。
Step 8では、各実装単位が完了するたびに frontend-verify Skillで検証し、人間が結果を確認してから次へ進みます。これにより、FrontendがViteの初期画面のままStep 9へ進むことを防ぎます。
Step 9 全体確認を行う
Step 1〜8までの実装が完了したら、一次開発全体の確認を行います。 ここでは新しい機能を追加するのではなく、確定済み設計に対して実装漏れや明らかな不整合がないかを確認します。 Codexには次のように依頼します。
一次開発のStep 9として、
Step 1〜8で実装したショッピングサイト全体を確認してください。
今回は新しい機能を追加することを目的とせず、
確定済み設計と現在の実装の整合性を確認してください。
以下の設計書を確認してください。
・docs/requirements.md
・docs/use-cases.md
・docs/screen-design.md
・docs/database-design.md
・docs/api-design.md
・docs/open-questions.md
・docs/test-cases.md
ルートAGENTS.md、
backend/AGENTS.md、
frontend/AGENTS.mdにも従ってください。
一次開発の対象である、
・商品一覧
・商品詳細
・商品検索
・ユーザー登録
・ログイン
・ログアウト
・CSRF取得
・カートへの商品追加
・カート表示
・数量変更
・カートからの商品削除
・注文内容確認
・注文確定
・注文履歴一覧
・注文履歴詳細
について、設計書に対応する実装が存在することを確認してください。
特に以下を確認してください。
・FrontendとBackendのAPI契約が一致している
・HTTP MethodとStatus Codeが設計書と一致している
・認証と認可が設計どおりに実装されている
・Origin / CSRFの要件が守られている
・ユーザー登録Validationが確定仕様と一致している
・カートの所有権確認が行われている
・注文処理のトランザクションとロック規約が守られている
・在庫整合性が考慮されている
・注文時点の商品名、価格、数量、小計、合計が保存されている
・Idempotency-Keyの契約が守られている
・注文履歴で現在の商品マスタから過去注文を再計算していない
・二次開発の機能を一次開発へ追加していない
test-cases.mdに定義された一次開発のテストケースについて、対応する実装とテストが存在することを確認してください。
未実施、未自動化、実行不能なテストケースがある場合は、仕様を変更せず、そのテストケースIDと理由を報告してください。
Backendはbackend-verify Skill、
Frontendはfrontend-verify Skillに従って検証してください。
設計契約を変更しない軽微な実装修正で解消できる問題は、
AGENTS.mdのルールに従って修正し、再検証してください。
API契約、DB構造、セキュリティ要件、データ整合性など、
確定済み設計そのものの変更が必要な問題を発見した場合は、
独断で仕様変更せず設計ブロッカーとして報告してください。
新しいOpen Questionを探すことを目的にしないでください。
最後に、
・確認した一次開発機能
・修正した内容
・変更したファイル
・Backendの検証結果
・Frontendの検証結果
・test-cases.mdの確認結果
・未実施、未自動化、実行不能なテストケースIDと理由
・未実施の確認
・設計ブロッカー
・残っている問題
・一次開発の実装完了可否
を報告してください。
Step 9では、実装を広げるのではなく、Step 1〜8で作成した機能を設計書へ照らして確認します。ここで問題がなければ、一次開発の実装フェーズを完了し、第6回の単体テスト・結合テスト・E2Eテストとデバッグへ進みます。
Frontend変更後はSkillで検証する
frontend-verify Skillでは、最初に package.json の scripts を確認します。 現在のプロジェクトでは、
lint
build
が定義されています。 そのため、主に次を実行します。
cd /workspaces/shopping-site/frontend
npm run lint
npm run build
現在の build は、
tsc -b && vite build
なので、TypeScriptのコンパイル確認も含みます。 専用の typecheck や testが定義されていない場合は、存在しないscriptを推測して実行したり、検証のためだけに勝手に追加したりしません。
Codexの実装結果を人間が確認する
Codexが実装と検証を完了したら、そのまま次のStepへ進むのではなく、人間が結果を確認します。
確認するポイントは大きく5つです。
- 今回依頼した範囲だけを変更しているか
- 設計書のAPI・DB・画面仕様を勝手に変更していないか
- 適用される
AGENTS.mdのルールを守っているか - Skillsによる検証が成功しているか
- 対応する
test-cases.mdの期待結果を満たしているか
例えば、商品一覧APIだけを依頼したのに認証方式やDB構造まで大きく変更している場合は、変更範囲が広すぎます。 逆に、内部関数の分割方法など、既存の設計契約を変更しない実装上の判断までWorkへ戻す必要はありません。
Codexの判断
↓
外部仕様を変える?
├─ YES → 人間へ報告
│
└─ NO
↓
実装時決定として進める
実装中に設計上の問題が見つかった場合
第4回で設計レビューの終了条件を決めましたが、実装開始後に設計へ戻ることを完全に禁止したわけではありません。 次のような場合は、実装を止めて人間へ報告します。
API契約を変更しないと実装できない
DB構造を変更しないと実装できない
セキュリティ要件が成立しない
データ整合性を保証できない
設計書同士に直接的な矛盾がある
一方、
Validatorの具体的なコード
内部アルゴリズム
関数の分割
変数名
既存契約内でのライブラリ利用方法
などは、設計契約を変えない限り実装時に決定します。
設計ブロッカー
↓
人間へ報告
↓
必要なら設計へ戻す
実装時決定
↓
Codexが合理的に実装
↓
検証
↓
実装継続
この境界を維持することで、実装開始後に再び「細部を1つ見つけるたびに設計へ戻る」状態になることを防ぎます。
今回の実装サイクル
今回採用する実装サイクルをまとめると、次のようになります。
確定済み設計書
↓
今回の実装範囲を決める
↓
対応するtest-cases.mdを確認
↓
Codexへタスクを依頼
↓
AGENTS.md
↓
ルールに従って実装
↓
test-cases.md
↓
何を確認するか
↓
Skills
↓
どの手順で検証するか
↓
Codexが結果を報告
↓
★ 人間が確認
↓
次の実装タスク
ここで重要なのは、Codexへすべてを任せることではありません。
AI
↓
コードを書く
検証する
結果を整理する
人間
↓
実装範囲を決める
重要な仕様を判断する
変更内容を確認する
次へ進むか判断する
という役割分担にします。
今回の完成構成
一次開発の実装が進むと、プロジェクトは概念的に次の構成になります。
shopping-site
│
├─ docs
│ ├─ requirements.md
│ ├─ use-cases.md
│ ├─ screen-design.md
│ ├─ database-design.md
│ ├─ api-design.md
│ ├─ open-questions.md
│ └─ test-cases.md
│
├─ AGENTS.md
├─ .codex
│ └─ skills
│ ├─ backend-verify
│ │ └─ SKILL.md
│ └─ frontend-verify
│ └─ SKILL.md
│
├─ frontend
│ ├─ AGENTS.md
│ ├─ src
│ │ ├─ components
│ │ ├─ pages
│ │ └─ ...
│ └─ package.json
│
├─ backend
│ ├─ AGENTS.md
│ ├─ handler
│ ├─ service
│ ├─ repository
│ ├─ ...
│ └─ go.mod
│
├─ compose.yml
├─ .env
├─ .env.example
├─ .gitignore
└─ .devcontainer
実際のディレクトリ名や細かな分割は、既存コードと確定設計を確認したうえで決定します。この記事の構成例だけを理由に、設計に存在しない構成を強制するものではありません。
まとめ
今回は、第3回で作成した設計書・test-cases.mdと、第4回で作成した AGENTS.md・Skillsを使い、Codexでショッピングサイトを段階的に実装する流れを整理しました。 重要なのは、Codexへ巨大な1つのタスクとして渡すのではなく、
設計書
↓
test-cases.md
↓
小さな実装タスク
↓
AGENTS.md
↓
Codexが実装
↓
Skillsで検証
↓
人間が確認
↓
次のタスク
というサイクルを繰り返すことです。
今回の役割分担は次のようになります。
設計書 = WHAT
test-cases.md = VERIFY
AGENTS.md = HOW
Skills = PROCEDURE
プロンプト = TASK
Codex = IMPLEMENT
人間 = REVIEW / DECISION
設計時には「何を作るか」を確定し、実装時には「どう作るか」の細部をCodexへ任せます。ただし、API契約、DB構造、セキュリティ、データ整合性など、既存設計の変更が必要になる問題は人間へ戻します。 これにより、AIにすべてを丸投げするのではなく、設計・実装・検証・人間の確認を分離した開発フローにできます。
本連載について
| 回 | タイトル | 対応範囲 | 主な内容 |
|---|---|---|---|
| 第1回 | Docker × VS Code Dev ContainersでGo開発環境を構築する | 🐳 Go開発環境 | Docker Desktop・VS Code・Dev Containersを使ったGo開発環境の構築 |
| 第2回 | React + TypeScript + Go + PostgreSQLのフルスタック開発環境を構築する | 🛠️ フルスタック開発環境 | Docker Desktop・Dev Containers・React・TypeScript・Go・PostgreSQL・Node.js・Vite |
| 第3回 | ChatGPT Workでショッピングサイトを設計してみる | 📐 システム設計 | Project instructions・要件定義・ユースケース・画面設計・ER図・DB設計・REST API設計・テストケース仕様書 |
| 第4回 | Codex × AGENTS.md × Skillsで実装準備を整える | 🤖 AI開発ルール | AGENTS.md・プロジェクトルール・階層化・Skills・実装準備 |
| 第5回 | Codexで設計書からショッピングサイトを実装する | 🛒 ショッピングサイト実装 | 設計書・AGENTS.md・Skillsを活用した段階的なAI開発・実装・検証 |
| 第6回 | Codexで実装したショッピングサイトをテスト・動作確認する | 🧪 テスト・動作確認 | test-cases.md・ユニットテスト・結合テスト・API・ブラウザ・DBによる動作確認 |
| 発展編① | Codexのエージェントハーネスでテスト・デバッグ・再テストを自律化する | 🤖 エージェントハーネス | AGENTS.md・確定仕様・テストケース・停止条件を利用したテスト・デバッグ・修正・再テスト・Regression Testの自律化 |
| 発展編② | Playwrightでブラウザテストを自動化する | 🎭 E2Eテスト自動化 | Playwright・E2Eテスト・ブラウザ操作・Auto-waiting・Trace Viewer・Seleniumとの違い・Codexとの連携 |