私とClaude Code
こんにちは。
プロダクト開発本部の伊藤です。
早くも2回目のブログ投稿です。
ジンジャーではAI導入積極推進中で、プロダクト開発部のメンバーにもCopilotやCline、Amazon Q Developerなど、さまざまなAIの利用を推奨しています。
その中で、私はClaude Codeを利用しています。
そこまでいろいろ試して比較したわけではないのですが、CopilotとClineを利用してきた中で、Claude Codeの方が精度が高いなと感じたためです。(Copilotはちょっとしたエラーの解決など比較的ライトなタスクで使用しています)
まだまだ性能を引き出せていない部分もありますが、私が業務内でClaude Codeをどのように使用しているかを紹介します。
テストコードの生成
私の担当プロダクトはジンジャー人事労務で、長く続いているプロダクトですが、一部テストコードの整備がされていない箇所がありました。
私自身もテストコードを書くのは好きですし、開発していく上で欠かせないと考えていますが、何せ既存のコードで仕様を把握できていないものに対してテストを書くのはなかなかに骨が折れる作業です。
そこでClaude Codeにテストを書いてもらうことにしました。
テストコード生成のルール
テストコード生成に関してのルールを記載したマークダウンファイルを用意して、CLAUDE.mdに読み込ませています。
基本ルール・設計ルール・実装ルールの3つを作成しました。
以下引用したものです。
# テスト作成ルール
## 基本ルール
- アウトプットは日本語で行なってください。
- 技術スタックは以下です。
- フレームワーク: {フレームワーク名}
- テストフレームワーク: {テストフレームワーク名}
- 品質管理: {ライブラリ名}
- データベース: {データベース種類名}
- ディレクトリ構造は以下です。
- .claude/test-architect/: テスト設計資料の集約場所
- .claude/test-architect/api/: apiごとのテスト設計資料の集約場所
- .claude/test-architect/service/: サービスクラスごとのテスト設計資料の集約場所
- .claude/test-architect/test-design-format-rules.md: テスト設計書のフォーマットルール
- 実行可能コマンドは以下です。
- テスト実行: {実行コマンド}
- 禁止事項は以下です。
- 実装詳細記述(モック設定等)
- 推奨事項は以下です。
- モックオブジェクト(外部インフラ依存コンポーネント)
- パブリックメソッド単位整理(構造明確化)
# テスト作成ルール
## 設計ルール
- パブリックメソッド単位でテストを設計してください。
- テスト設計の際はパブリックメソッド1つで1タスクとして考えてください。時間がかかっても構わないので丁寧に設計しましょう。
- カバレッジとしてC0で80%, C1で70%を超えるように設計してください。
- {リクエストのバリデーション設定を記載しているファイル}の内容に準じて、テストケースを設計してください。
- メソッド内で使用しているクラスで、DBへの変更とDBからの取得を行うクラスはモックせず、実際にDBとの疎通を行う形にしてください。
- 管理下にない依存(メール、Slack、S3へのファイル操作など)は、モック化してください。
- CSVの出力を伴うテストについては、モック等を用いて可能な限り出力されたCSVの内容を検証してください。
- DBの値の取得が必要な場合は、テストデータをDBに挿入して取得してください。
- テストデータを挿入したテーブルはテスト実行毎に初期化してください。
- 実行結果としてDBの値に変更がある場合は、DBの保存値が正しいことも検証してください。
- 設計結果は.claude/test-architect/{テスト対象メソッド}/ディレクトリに格納してください。
- テスト設計技法を積極的に使ってください。
- 同値分析
- 境界値分析
- デシジョンテーブル
- 例
| 条件1 | 条件2 | バリデーション対象 | 期待結果 |
|-------|-------|-------------------|----------|
| true | true | フィールドA | 必須 |
| true | false | フィールドB | 任意 |
| false | true | フィールドC | 必須 |
- 状態遷移図
- 設計書のフォーマットはテスト設計書のフォーマットルールで統一してください。
- 更新履歴には日本時間の正しい日付を入れてください。
# テスト作成ルール
## 実装ルール
- 設計ドキュメントをもとにテストケースを実装してください。
- テスト実装の際はパブリックメソッド1つで1タスクとして考えてください。時間がかかっても構わないので丁寧に実装しましょう。
- テスト実装前に、テスト用DBにマイグレーションを実行してDBを最新の状態にしましょう。
- テスト用DBマイグレーション実行: {マイグレーション用コマンド}
- カバレッジの確認は以下のように行ってください。
- 1. テストの実装前に、{カバレッジ記載ファイル}読み込み → 対象メソッドの行番号とカバレッジ状況を記録して、実装前のカバレッジを把握
- 2. テストを実装
- 3. テストの実装後、{カバレッジ記載ファイル}読み込み → 対象メソッドの行番号とカバレッジ状況を確認し、1の結果と比較します。これにより、2の実装がカバレッジの向上に寄与したか、カバーできていない実行パスがないかを理解
- Line, Branchどちらのカバレッジも確認するようにしましょう。
- テストケースを実装するたびに、デバッグをこまめに行いましょう。実行コマンドは基本ルールに記載されたコマンドを使用してください。
- 実装した全てのテストケースのデバッグを行い、実行を確認してください。
- 全工程完了したら、実装内容と設計書を確認し、要件と品質についてレビューしてください。
- レビューに問題がなければ、実装内容と設計書を確認し、差分があれば設計書を更新してください。
まずは計画せよ
テストを作成する際はすぐ実装には入らず、まずは設計・計画から始めます。
shift+tabで、plan moodeに変更できます。
このモードで最初に計画をおこない、Claude Codeが思わぬ方向に進んだり勝手に編集したりするのを防ぎます。

@の後にファイルパスを記載することで、指定したファイルを確実に読み込ませることができます。
テストを書きたいファイルを指定してプロンプトを投げましょう。
この際、先述したCLAUDE.mdにインポートさせたテストコード生成に関してのルールをClaude Codeが読み込んでいるので、自動的にルールに従って設計してくれます。
今回はサンプルコードとして以下のクラスのテストを生成させます。
class GetEmployeesByCompanyId
{
/**
* Get employees by company ID
*
* @param integer $companyId
* @return array
*/
public function handle(int $companyId): array
{
return Employee::where('company_id', $companyId)
->select(['id', 'code', 'first_name', 'last_name', 'first_name_kana', 'last_name_kana', 'email'])
->get()
->toArray();
}
}
細かくタスクを実行させる
テストの設計が完了し、そのままテスト設計書の作成を実行させ、test-design.mdを作成しました。

以下test-design.mdの抜粋です。
# GetEmployeesByCompanyId::handle() テスト設計書
## 1. メソッド概要
- **対象メソッド**: `GetEmployeesByCompanyId.php:handle()` (16-22行)
- **機能**: 指定された会社IDに所属する従業員の基本情報を取得する
- **戻り値**: `array` - 従業員情報の配列 [id, code, first_name, last_name, first_name_kana, last_name_kana, email]
## 2. メソッド処理フロー分析
### 2.1 主要な処理ステップ
1. **Eloquentクエリ実行** (18行): Employeeモデルでcompany_idによるWHERE条件設定
2. **カラム選択** (19行): 必要なカラムのみをselect句で指定
3. **データ取得** (20行): get()メソッドでコレクション取得
4. **配列変換** (21行): toArray()メソッドで配列形式に変換
### 2.2 条件分岐
- **分岐なし**: 単純な条件クエリのみで分岐処理は存在しない
### 2.3 外部依存
- **Employeeモデル**: Eloquent ORMによるデータベースアクセス
## 3. バリデーションルール分析
**入力パラメータ**:
- **company_id**: `int` 型、必須パラメータ
- **バリデーション**: メソッド内では実施されていない(呼び出し元で保証される想定)
**想定されるエラーパターン**:
- 存在しないcompany_id指定時: 空配列を返却(エラーではない)
- null値指定: PHP Type Error発生の可能性
- 不正な型指定: PHP Type Error発生の可能性
## 4. テスト設計技法適用
### 4.1 同値分析
#### 4.1.1 company_id値による分類
| 分類 | 値の範囲 | 説明 | 代表値 |
|------|---------|------|--------|
| 有効な会社ID(データあり) | 1以上の整数 | DBに存在し従業員データがある | 1 |
| 有効な会社ID(データなし) | 1以上の整数 | DBに存在するが従業員データがない | 999 |
| 無効な会社ID | 0以下の整数 | DBに存在しない | 0, -1 |
| null値 | null | 不正な入力 | null |
### 4.2 境界値分析
#### 4.2.1 company_id境界値
| 境界値 | 説明 | 期待結果 |
|--------|------|----------|
| 0 | 最小境界値 | 空配列 |
| 1 | 最小有効値 | データに応じた結果 |
| -1 | 負の値 | 空配列 |
### 4.3 デシジョンテーブル
| company_id有効性 | 従業員データ存在 | 期待結果 | テストケース |
|-----------------|----------------|----------|-------------|
| 有効 | あり(複数) | 従業員配列(複数件) | TC-N01 |
| 有効 | あり(1件) | 従業員配列(1件) | TC-N02 |
| 有効 | なし | 空配列 | TC-N03 |
| 無効 | - | 空配列 | TC-E01 |
## 5. テストケース設計
### 5.1 正常系テストケース
#### TC-N01: 有効なcompany_idで従業員データが複数存在
- **テスト名**: `test_handle_会社IDに対応する従業員データ複数件取得成功`
- **前提条件**: company_id=1に複数の従業員データが存在
- **入力データ**: `company_id = 1`
- **期待結果**:
- 配列形式で複数件の従業員データが返却される
- 各レコードに[id, code, first_name, last_name, first_name_kana, last_name_kana, email]が含まれる
#### TC-N02: 有効なcompany_idで従業員データが1件存在
- **テスト名**: `test_handle_会社IDに対応する従業員データ1件取得成功`
- **前提条件**: company_id=2に1件の従業員データが存在
- **入力データ**: `company_id = 2`
- **期待結果**:
- 配列形式で1件の従業員データが返却される
- レコードに指定した全カラムが含まれる
#### TC-N03: 有効なcompany_idで従業員データが0件
- **テスト名**: `test_handle_従業員データが存在しない会社ID指定`
- **前提条件**: company_id=3に従業員データが存在しない
- **入力データ**: `company_id = 3`
- **期待結果**: 空配列`[]`が返却される
### 5.2 異常系テストケース
#### TC-E01: 存在しない大きなcompany_id指定
- **テスト名**: `test_handle_存在しない会社ID指定`
- **前提条件**: データベースにcompany_id=999999は存在しない
- **入力データ**: `company_id = 999999`
- **期待結果**: 空配列`[]`が返却される
### 5.3 境界値テストケース
#### TC-B01: company_id = 0
- **テスト名**: `test_handle_会社ID境界値0指定`
- **前提条件**: company_id=0の従業員データは存在しない
- **入力データ**: `company_id = 0`
- **期待結果**: 空配列`[]`が返却される
#### TC-B02: company_id = -1(負の値)
- **テスト名**: `test_handle_会社ID負の値指定`
- **前提条件**: 負のcompany_idは存在しない
- **入力データ**: `company_id = -1`
- **期待結果**: 空配列`[]`が返却される
## 6. モック設計
### 6.1 必要なモック
- **モック不要**: Employeeモデルは実際のDBとの疎通を行うためモック化しない
### 6.2 テストデータ設計
#### 6.2.1 employeesテーブル挿入データ
{テストケースによるテストデータ}
## 7. カバレッジ目標
- **C0 (Line Coverage)**: 100% - 全6行(16-21行)をカバー
- **C1 (Branch Coverage)**: N/A - 分岐処理が存在しないため該当なし
### 7.1 重要な実行パス
- **18-21行**: Eloquentクエリ実行からtoArray()までの連続処理
- **全テストケース**: 各パターンでこの実行パスが通る
## 8. 実装時の注意点
{各注意点}
### 8.1 使用するテスト技法
- **データプロバイダー**: 使用しない(各テストケースで明確にテストデータを設定)
- **setUp/tearDown**: employeesテーブルのクリーンアップを実施
### 8.2 実装順序
1. **正常系テスト**: TC-N01 → TC-N02 → TC-N03の順序で実装
2. **異常系・境界値テスト**: TC-E01 → TC-B01 → TC-B02の順序で実装
## 9. 実行コマンド
{テスト実行コマンド}
## 10. 期待されるテストメソッド構成
- `test_handle_会社IDに対応する従業員データ複数件取得成功()`
- `test_handle_会社IDに対応する従業員データ1件取得成功()`
- `test_handle_従業員データが存在しない会社ID指定()`
- `test_handle_存在しない会社ID指定()`
- `test_handle_会社ID境界値0指定()`
- `test_handle_会社ID負の値指定()`
## 更新履歴
- 2025-10-01: 初版作成
ここから設計書をもとに実装に入りますが、一気におこなわず、細かく実行していきます。

まずは小さく実行させ、精度を確認しながら進めていきます。
念のため再度plan modeで、正常系の1つ目のテストケースだけ計画・実装させます。
生成されたテストファイルの内容も確認し、1つのテストケースのみまずはデバッグして実行し、成功を確認します。
以下生成されたテストコードの抜粋です。
場合によってこのタイミングで適宜コードを修正しながら進めていきます。
/**
* TC-N01: 有効なcompany_idで従業員データが複数存在
*/
public function test_handle_会社IDに対応する従業員データ複数件取得成功()
{
// Given: company_id=1に複数の従業員データが存在
$company_id = 1;
// When: handleメソッドを実行
$result = $this->task->handle($company_id);
// Then: 期待される結果が返される
$this->assertIsArray($result, 'レスポンスが配列形式であること');
$this->assertCount(2, $result, '2件の従業員データが返されること');
// 戻り値をidでソートして検証順序を安定化
usort($result, function($a, $b) {
return $a['id'] <=> $b['id'];
});
// 1つ目の従業員データの構造検証
$employee1 = $result[0];
$this->assertArrayHasKey('id', $employee1, '1人目の従業員データにidキーが存在すること');
$this->assertArrayHasKey('code', $employee1, '1人目の従業員データにcodeキーが存在すること');
$this->assertArrayHasKey('first_name', $employee1, '1人目の従業員データにfirst_nameキーが存在すること');
$this->assertArrayHasKey('last_name', $employee1, '1人目の従業員データにlast_nameキーが存在すること');
$this->assertArrayHasKey('first_name_kana', $employee1, '1人目の従業員データにfirst_name_kanaキーが存在すること');
$this->assertArrayHasKey('last_name_kana', $employee1, '1人目の従業員データにlast_name_kanaキーが存在すること');
$this->assertArrayHasKey('email', $employee1, '1人目の従業員データにemailキーが存在すること');
// 1つ目の従業員データの内容検証
$this->assertEquals(1, $employee1['id'], '1人目の従業員のIDが正しいこと');
$this->assertEquals('EMP001', $employee1['code'], '1人目の従業員のcodeが正しいこと');
$this->assertEquals('太郎', $employee1['first_name'], '1人目の従業員のfirst_nameが正しいこと');
$this->assertEquals('田中', $employee1['last_name'], '1人目の従業員のlast_nameが正しいこと');
$this->assertEquals('タロウ', $employee1['first_name_kana'], '1人目の従業員のfirst_name_kanaが正しいこと');
$this->assertEquals('タナカ', $employee1['last_name_kana'], '1人目の従業員のlast_name_kanaが正しいこと');
$this->assertEquals('taro@example.com', $employee1['email'], '1人目の従業員のemailが正しいこと');
// 2つ目の従業員データの構造検証
$employee2 = $result[1];
$this->assertArrayHasKey('id', $employee2, '2人目の従業員データにidキーが存在すること');
$this->assertArrayHasKey('code', $employee2, '2人目の従業員データにcodeキーが存在すること');
$this->assertArrayHasKey('first_name', $employee2, '2人目の従業員データにfirst_nameキーが存在すること');
$this->assertArrayHasKey('last_name', $employee2, '2人目の従業員データにlast_nameキーが存在すること');
$this->assertArrayHasKey('first_name_kana', $employee2, '2人目の従業員データにfirst_name_kanaキーが存在すること');
$this->assertArrayHasKey('last_name_kana', $employee2, '2人目の従業員データにlast_name_kanaキーが存在すること');
$this->assertArrayHasKey('email', $employee2, '2人目の従業員データにemailキーが存在すること');
// 2つ目の従業員データの内容検証
$this->assertEquals(2, $employee2['id'], '2人目の従業員のIDが正しいこと');
$this->assertEquals('EMP002', $employee2['code'], '2人目の従業員のcodeが正しいこと');
$this->assertEquals('花子', $employee2['first_name'], '2人目の従業員のfirst_nameが正しいこと');
$this->assertEquals('佐藤', $employee2['last_name'], '2人目の従業員のlast_nameが正しいこと');
$this->assertEquals('ハナコ', $employee2['first_name_kana'], '2人目の従業員のfirst_name_kanaが正しいこと');
$this->assertEquals('サトウ', $employee2['last_name_kana'], '2人目の従業員のlast_name_kanaが正しいこと');
$this->assertEquals('hanako@example.com', $employee2['email'], '2人目の従業員のemailが正しいこと');
}


次の作業内容について確認せよ
1つのテストケース実装完了後は、続けてテストケースの実装を進めていきます。
細かい単位で実行していった方が、少しずつ精度が上がっていき、確認しながら安全に実行できます。
ここでそのまま続行させることもできますが、作業が思わぬ方向に向かわないよう、私はClaude Codeに次の作業を確認させることにしています。
そのまま続行していい内容であれば続行させ、想定と違う内容であれば改めて命令をします。
毎回作業確認のプロンプトを打つのも面倒だったので、/confirm-next-actionというカスタムスラッシュコマンドを作成して使用しています。
---
description: "次の作業を実行する前に内容の確認を行います."
---
# 絶対に守るべき事
- 次の作業を実行する前に**必ず内容の確認をしてください。**
- **確認せず、また指示を待たずに次の作業を実行することは禁止です。**
確認した結果、2つ目の正常系のテストケースから順次実装していく流れで想定しているようだったので、そのまま次の作業をおこなってもらうよう命令します。

このような流れで、想定外の実装や方針にならないように細かく確認しながら進めていきます。
テスト設計書の更新
テスト実装後は、生成したテストコードとテスト設計書に整合性があるかを確認します。

実装していく中で設計通りで成功しなかった箇所や、自らで修正した箇所なども発生するので、テスト設計書とコードとの間で差分がないかを確認し、差分がある場合は設計書を更新し、整合性を保たせます。

今回は重要な差分はないとのことなので、設計書の更新はスキップします。
ドキュメントの生成・蓄積
テストの生成が一通り完了したら、生成したテストコードをもとに、対象のプロダクションコードの詳細設計書・API仕様書などのドキュメントを生成させます。

ジンジャー人事労務には開発用のドキュメントもあまり整備されていなかったので、テスト生成のついでにドキュメントをマークダウンで生成させることで、蓄積させて今後のナレッジとさせるとともに、コンテキストとしても使用することができるのでは?と考え、毎回ドキュメントの生成もあわせておこなっています。

以下生成した詳細設計書の抜粋です。
# GetEmployeesByCompanyId::handle メソッド詳細設計書
## 1. メソッド概要
- **対象メソッド**: GetEmployeesByCompanyId.php:handle() (16-22行)
- **機能**: 指定された会社IDに所属する従業員の基本情報を取得する
- **分類**: CRUD操作(データ取得処理)
- **複雑度**: 低 - 単純なSELECTクエリのみ
- **重要度**: 中 - 従業員一覧取得の基盤機能
- **テスト設計書**: `.claude/test-architect/service/GetEmployeesByCompanyId/handle/test_design.md`
## 2. インターフェース仕様
### 2.1 メソッドシグネチャ
public function handle(int $companyId): array
### 2.2 パラメータ仕様
| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 | 制約・形式 |
|------------|----|----|------------|-----|----------|
| $companyId | int | ○ | - | 会社の一意識別子 | 整数値(負の値も許可) |
### 2.3 戻り値仕様
| 型 | 構造 | 説明 |
|----|------|------|
| array | 従業員レコード配列 | 指定会社IDに所属する従業員の基本情報配列 |
| array | [] | 該当する従業員が存在しない場合は空配列 |
### 2.4 例外仕様
| 例外クラス | 発生条件 | メッセージ例 |
|-----------|----------|------------|
| PHP TypeError | null値や非int型の引数 | "Argument 1 passed to handle() must be of the type int" |
| Eloquent例外 | DB接続エラー、テーブル不存在 | "SQLSTATE[42S02]: Base table or view not found" |
## 3. 処理フロー詳細
### 3.1 全体フロー
1. **WHERE条件設定** (行番号: 18) - Employeeモデルでcompany_idによる絞り込み
2. **カラム選択** (行番号: 19) - 必要な7つのカラムのみをselect句で指定
3. **データ取得実行** (行番号: 20) - get()メソッドでEloquentコレクション取得
4. **配列変換・戻り値生成** (行番号: 21) - toArray()メソッドで連想配列に変換
### 3.2 条件分岐詳細
| 条件 | 分岐先 | 処理内容 | 行番号 |
|------|--------|----------|--------|
| 条件分岐なし | - | 直線的な処理フロー | 18-21 |
### 3.3 重要な処理ロジック
- **効率的カラム選択**: 必要最小限のカラムのみを取得してメモリ使用量を最適化
- **Eloquentチェーン**: メソッドチェーンによる可読性の高いクエリ構築
- **型安全性**: int型制約による入力値の型安全性保証
## 4. データ構造設計
### 4.1 入力データ構造
// パラメータは単純なint型
$companyId = 1; // 正の整数、負の整数、0も許可
### 4.2 内部データ構造
// Eloquentクエリビルダーによる内部処理
// 1. WHERE句: company_id = $companyId
// 2. SELECT句: ['id', 'code', 'first_name', 'last_name', 'first_name_kana', 'last_name_kana', 'email']
// 3. Eloquentコレクション(Illuminate\Database\Eloquent\Collection)
### 4.3 出力データ構造
// 複数従業員の場合
{複数従業員の場合の出力データ構造}
// 該当データなしの場合
{該当データなしの場合の出力データ構造}
## 5. バリデーション仕様
### 5.1 基本バリデーションルール
| フィールド | ルール | エラーメッセージ | 実装箇所 |
|-----------|--------|-----------------|----------|
| $companyId | int型 | PHP型エラー | メソッドシグネチャ |
### 5.2 カスタムバリデーション
- **バリデーション処理なし**: メソッド内では独自のバリデーション処理を実装していない
- **型制約のみ**: PHP 7+の型宣言によるint型制約のみ
### 5.3 依存バリデーション
- **外部キー制約**: employeesテーブルのcompany_idが存在しない場合は結果0件(エラーではない)
## 6. データベース操作仕様
### 6.1 関連テーブル
| テーブル名 | 操作種別 | 説明 | 実装箇所 |
|-----------|----------|------|----------|
| employees | SELECT | 会社IDによる従業員一覧取得 | 18-21行 |
### 6.2 SQL詳細
-- EloquentORMによって生成されるSQL(推定)
SELECT `id`, `code`, `first_name`, `last_name`, `first_name_kana`, `last_name_kana`, `email`
FROM `employees`
WHERE `company_id` = ?
AND `employees`.`deleted_at` IS NULL;
### 6.3 トランザクション制御
- **開始**: 該当なし(単一SELECT文のため)
- **コミット**: 該当なし
- **ロールバック**: 該当なし
### 6.4 外部キー制約
| 制約名 | 親テーブル | 子テーブル | 説明 |
|--------|-----------|-----------|------|
| employees_company_id_foreign | companies | employees | 会社IDの整合性制約(想定) |
## 7. エラーハンドリング仕様
### 7.1 エラー分類
| エラー分類 | 対応方法 | 通知先 | 実装箇所 |
|-----------|----------|--------|----------|
| 型エラー | PHP例外で中断 | なし | メソッドシグネチャ |
| DB接続エラー | Eloquent例外で中断 | なし | Eloquent内部 |
| クエリエラー | Eloquent例外で中断 | なし | Eloquent内部 |
### 7.2 エラーメッセージ体系
// 現在の実装では独自のエラーハンドリングなし
// PHPおよびEloquentの標準例外処理に依存
### 7.3 言語ファイル対応
現在の実装では独自のエラーメッセージ処理なし
## 8. セキュリティ仕様
### 8.1 入力値検証
- **SQLインジェクション対策**: EloquentORMのプリペアドステートメント使用(18行)
- **XSS対策**: 該当なし(データ取得のみ、HTML出力なし)
- **認証・認可**: メソッド内では実装なし(呼び出し元で制御想定)
### 8.2 データ保護
- **機密データ**: 従業員の個人情報(氏名、メールアドレス)を含むため適切な権限制御が必要
- **ログ出力**: 現在の実装では特別なログ出力なし
- **権限チェック**: 呼び出し元での会社IDアクセス権限確認が必要
## 9. パフォーマンス仕様
### 9.1 処理時間目標
| データ量 | 目標処理時間 | 実測値 |
|----------|-------------|-------|
| 100名以下 | 50ms以内 | 測定必要 |
| 1000名程度 | 200ms以内 | 測定必要 |
| 10000名程度 | 1秒以内 | 測定必要 |
### 9.2 メモリ使用量
- **最大使用量**: 従業員データ量に比例(1名あたり約1KB想定)
- **最適化箇所**: select句による必要カラムのみ取得(19行)
### 9.3 データベースパフォーマンス
- **インデックス**: company_idにインデックス必須
- **クエリ最適化**: 単一テーブルSELECTのため最適化余地は限定的
## 10. 外部依存関係
### 10.1 依存サービス
| サービス名 | バージョン | 用途 | 実装箇所 |
|-----------|-----------|------|----------|
| 該当なし | - | - | - |
### 10.2 依存モデル
| モデル名 | メソッド | 用途 | 実装箇所 |
|---------|---------|------|----------|
| Employee | where, select, get, toArray | 従業員データ取得 | 18-21行 |
### 10.3 ヘルパー関数
| 関数名 | 場所 | 用途 | 実装箇所 |
|-------|------|------|----------|
| 該当なし | - | - | - |
## 11. 統合仕様
### 11.1 API連携
外部API連携なし
### 11.2 イベント処理
システム内イベントの発火なし
### 11.3 設定依存
- **データベース接続設定**: config/database.php
- **Eloquent設定**: EloquentORMの標準設定に依存
## 12. 実装ガイダンス
### 12.1 コーディング規約
- **命名規則**: キャメルケース($companyId)
- **コメント**: PHPDocによるメソッド仕様記述(10-15行)
- **例外処理**: 現在は実装なし(必要に応じて呼び出し元で実装)
### 12.2 実装時の注意点
1. **Eloquentモデル依存**: Employeeモデルの存在と正常動作が前提
2. **型安全性**: int型宣言による入力値制約
### 12.3 コードレビューポイント
- **確認項目**: Eloquentクエリの正確性、戻り値の型一貫性
- **品質基準**: 全テストケース通過、100%コードカバレッジ
## 13. テスト連携
### 13.1 対応テストケース
| テストケース | テストメソッド | 検証内容 |
|------------|--------------|----------|
| TC-N01 | test_handle_会社IDに対応する従業員データ複数件取得成功 | 複数従業員データの正常取得 |
| TC-N02 | test_handle_会社IDに対応する従業員データ1件取得成功 | 単一従業員データの正常取得 |
| TC-N03 | test_handle_従業員データが存在しない会社ID指定 | データ0件時の空配列返却 |
| TC-E01 | test_handle_存在しない会社ID指定 | 存在しない会社ID指定時の処理 |
| TC-B01 | test_handle_会社ID境界値0指定 | 境界値0指定時の処理 |
| TC-B02 | test_handle_会社ID負の値指定 | 負の値指定時の処理 |
### 13.2 モック仕様
実際のDBとの疎通を行う実装のためモック不要
### 13.3 テストデータ
- **company_id=1**: 2名の従業員データ(太郎 田中、花子 佐藤)
- **company_id=2**: 1名の従業員データ(次郎 山田)
- **company_id=3**: 従業員データなし
## 14. 運用・保守仕様
### 14.1 ログ仕様
- **ログレベル**: 現在の実装ではログ出力なし
- **ログ形式**: 該当なし
- **ログローテーション**: 該当なし
### 14.2 監視ポイント
- **監視項目**: 処理時間、エラー発生率、メモリ使用量
- **アラート条件**: 処理時間1秒超過、エラー率1%超過
### 14.3 バックアップ・リカバリ
employeesテーブルのバックアップが必要
## 15. 参考情報・関連資料
### 15.1 関連ドキュメント
- **テスト設計書**: `.claude/test-architect/service/GetEmployeesByCompanyId/handle/test_design.md`
- **テスト実装**: `application/tests/Services/Employee/GetEmployeesByCompanyIdTest.php`
- **カバレッジレポート**: `application/tests/build/coverage/html/services/Employee/GetEmployeesByCompanyId.php.html`
### 15.2 実装参考
- **実装コード**: `application/services/Employee/GetEmployeesByCompanyId.php`
- **ライブラリ**: Laravel Eloquent ORM
### 15.3 変更履歴
| 日付 | バージョン | 変更者 | 変更内容 |
|------|-----------|-------|----------|
| 2025-10-07 | v1.0 | Claude | 初版作成 - テストコードベースの詳細設計書作成 |
今後の課題
コードレビューや成果物のレビューに関しては、いまだにベストなやり方が見出せていないので、課題として残っています。
コードに関しては、細かくタスクを実行して確認していけばまだ可能ではありますが、ドキュメントなどの成果物へのレビューをどうするべきか、いまだに模索中です。
テストから生成したドキュメントについては、念のため最終的に対象のプロダクションコードとの整合性を確認させてはいますが、信憑性があるかどうかは保証できないかと思います。

どういった観点でレビューしていくのかといったルールなど策定しながら、ほかの情報も調べて、少しずつレビューを試していければと思っています。
最後に
AIはまさしく日進月歩で、日々更新され、性能の高いものが次々に現れます。
私自身、正直最初はAIに対して懐疑的な部分もありましたが、さまざまなAIの進歩を見聞きするうちに、「これは避けては通れない」と感じるようになり、今ではAIをいかに使いこなすかを考えています。
私はまだまだですが、ほかのメンバーのAIに関する過去の記事もあるので、ぜひ読んでみてほしいです。
- 【AWS Summit Japan 2025】激動のAI時代にエンジニアが今すぐ習慣化すべきこと
- AI活用の効果を高めるために、コンテキストの理解を整理する
- AI開発ツールで変わる開発者の働き方:現場で見えたリアルな変化と可能性
- ModelContextProtocol tools入門
さまざまなAIの導入を積極的に推進・推奨しているジンジャーは、今の時代のエンジニアにとっては非常に恵まれた環境ではないかと感じます。
こういったスピード感も、日本一の開発組織を目指す上で欠かせない要素だと思います。
うまくAIを使いこなす方法を探りながら、日々の開発をより効率的に、バクソクでより良いプロダクトを届けられるよう、そしてジンジャーのプロダクト開発部が日本一になれるよう、精進していきたいと思います。
私たちプロダクト開発部は仲間を探しています。
ご興味ある方はお気軽にご応募ください!
積極的にAIを使える環境で、一緒に日本一を目指しましょう!
Discussion