---
name: where
description: >
  特定の処理を行っているコードの箇所を特定し、エントリポイントから対象処理までの呼び出し経路を網羅的に調査するスキル。
  「〇〇の処理をしている箇所を調査してください」「どこで〇〇を呼んでいますか？」「〇〇に関するコードを探してください」
  「〇〇の実装箇所を特定してください」といった依頼のときに使用する。
  リポジトリ全体を見落としなく調査し、エントリポイント（HTTPエンドポイント・バッチ・CLIコマンド等）から
  対象処理までの呼び出し経路をファイルパス・関数名・行番号付きで返す。
  コード調査、コードリーディング、実装箇所特定、呼び出し経路追跡の依頼があれば積極的に使うこと。
---

# コード調査スキル

リポジトリ全体を網羅的に調査し、特定の処理を行っているコードの箇所とそこへの**エントリポイントからのフルの呼び出し経路**を特定する。

## 出力の完成イメージ（最重要）

**最終的な出力は必ずこの形式**にする。テーブル・箇条書き・まとめは使わない。

フォーマットの構造:
```
## 調査結果: {何についての調査かを簡潔に説明}

### {番号}. {この処理の呼び出しルートの特徴を簡潔に説明}

{エントリポイントの説明。HTTPエンドポイントならHTTPメソッドとパス、Cloud Schedulerからの起動ならTerraformで記述されているリソース名+"スケジューラ"など}
{次の呼び出し部分を呼び出している箇所のファイルパスと行番号。スケジューラで呼び出しが直接記述されていない場合は、Terraformのスケジューラ定義箇所のファイルパスと行番号}
  └─ {1行で呼び出し部分を説明}
     {パッケージ名.関数名}
     {次の呼び出し部分を呼び出している箇所のファイルパスと行番号}
       └─ {1行で呼び出し部分を説明}
          {パッケージ名.関数名}
          {次の呼び出し部分を呼び出している箇所のファイルパスと行番号}
            └─ { 調査対象なら"⭐️"をつける} {1行で呼び出し部分を説明}
               {パッケージ名.関数名}
               {調査対象の処理を行っている箇所のファイルパスと行番号}
```

具体的な例:
```
## 調査結果: 会員ランク計算の処理を行っている箇所

### 1. HTTPエンドポイントからの呼び出し

POST /api/customer/{id}/rank
./src/router.go:120
  └─ 会員ランク計算のハンドラ関数
     handler.CustomerRank()
     ./src/handler/customer.go:45
       └─ 会員ランク計算のユースケース関数
          usecase.CustomerRank()
          ./src/usecase/customer.go:80
            └─ 会員ランク計算のドメイン関数
               domain.CalcCustomerRank()
               ./src/domain/customer.go:120
                  └─ ⭐️ 会員ランクの算出
                     ./src/domain/customer.go:135

### 2. バッチ処理からの呼び出し

calculate-rank スケジューラ 毎日0時に起動
./terraform/scheduler.go:45
  └─ Cloud Run jobs起動
     calculate-rank-job.main()
     ./jobs/calculate-rank-job/main.go:52
       └─ 会員ランク計算のユースケース関数
          usecase.CustomerRankJob()
          ./src/usecase/customer_rank_job.go:80
            └─ 会員ランク計算のドメイン関数
               domain.CalcCustomerRank()
               ./src/domain/customer.go:120
                  └─ ⭐️ 会員ランクの算出
                     ./src/domain/customer.go:135
```

- **エントリポイントが起点**: HTTPルート、バッチスケジューラ、CLIコマンド等が最上位
- **対象処理が末端**: ユーザーが指定した処理が末端ノード（`[対象処理: ...]` と明記）
- **経路はフル**: エントリポイントから対象処理まで途中の関数呼び出しをすべて記載する
- **ファイルパスと行番号を必ず付ける**: `./パス/to/ファイル.go:行番号`
- **ファイルパスと行番号が指す位置は次の処理の呼び出し箇所**: 次のステップに繋がる呼び出しが書いてある行を指す
- **ルートの数だけ `###` セクションを作る**: ルートが5個あれば5つのセクション

## 調査手順

### Step 1: 対象処理を特定する（ボトムアップ）

ユーザーが指定した処理に関連するキーワードで `Grep` を使ってリポジトリ全体を検索し、実装箇所を特定する。

- 処理名・関数名・定数名・設定キー・ライブラリ名など複数のキーワードで検索する
- **【重要】クエリに含まれるビジネス用語を日本語そのままでもGrepする**
  - 例: "仮受注確定" → コメント・定数定義・文字列リテラルをGrep
  - 例: "確定" "連携" などの部分キーワードも試す
  - コードエンティティ名の検索結果と日本語ビジネス用語の検索結果を突き合わせて候補を絞る
- **【重要】クエリに具体的な値・定数が含まれる場合、その定数値そのものをGrepして全使用箇所を列挙する**
  - 例: "ChumonKbnを1または2で送る" → `ChumonKbn1` と `ChumonKbn2` をそれぞれGrepして全使用箇所を先に列挙する
  - 関数名・型名だけで検索すると、同じ値を返す別の関数が見落とされる
- **【重要】1箇所見つかった時点で検索を止めない。すべての候補箇所を列挙してからStep 1.5に進む**
- 見つかった候補箇所のコードを `Read` で読み、対象処理かどうか確認する
- 対象処理の**関数名**を控える（次のステップで使う）

#### クエリが「設定値・環境値」を含む場合

バケット名、接続先URL、環境変数の値など、**実行時に注入される設定値**がクエリに含まれる場合は以下の手順で探す。

1. Goコード等から環境変数名を特定する
   - 例: `GOOGLE_CLOUD_STORAGE_BUCKET_NAME`

2. その環境変数名で以下のファイルを Grep する
   - デプロイ設定ファイル: `**/deploy/**/*.yaml`, `**/*service.yaml`
   - Kubernetes マニフェスト: `**/k8s/**/*.yaml`
   - 環境変数ファイル: `**/.env*`, `**/env/**`
   - CI/CD 設定: `**/.github/**/*.yaml`, `**/cloudbuild.yaml`

3. 見つかった設定ファイルから実際の値を確認する

コードベースに値が存在しない場合は「コードベースには存在しない」と判断する前に、上記のファイル群を必ず確認すること。

### Step 2: 候補コードの要件適合確認（必須）

Step 1で候補が見つかった後、**「クエリの要件を満たしているか」を必ず確認する**。

- クエリに含まれるビジネス的な条件（例: "仮受注確定", "chumonKbn=5"）が実際にそのコードで実現されているかをコードを読んで確認する
- 条件が満たされていない場合は、その候補を棄却して検索を継続する
- **「エンティティ名が一致する」「それらしい名前のコードが見つかった」だけでは要件適合とみなさない**
- 要件適合が確認できた箇所のみを調査対象として次のステップに進む

### Step 3: 呼び出し元を逆に辿る（エントリポイントまで）

Step 2 で要件適合が確認できた処理の関数名で `Grep` を使い、その関数を呼んでいる箇所を探す。見つかったら、その呼び出し元をさらに `Grep` で探す。これをエントリポイントに到達するまで繰り返す。

エントリポイントの例:
- **Go**: `router.go`, `main.go`, `cmd/` 配下、ハンドラ関数
- **Node.js/TypeScript**: `routes/`, `app.ts`, `index.ts`
- **Python**: `views.py`, `urls.py`, `tasks.py`（Celery）, `main.py`
- **バッチ・ジョブ**: `jobs/`, `cron/`, `scheduler/` 配下、スケジューラ設定ファイル

辿った経路を「関数名 ファイルパス:行番号」の形式で記録しながら進む。

### Step 4: 非同期メカニズム経由の全呼び出し元を横断検索する（**常に実行する**）

非同期メカニズム（Cloud Tasks、Pub/Sub等）を使うプロジェクトでは、同期的なルート（HTTPエンドポイント等）しか見つからなくても、**必ず非同期ルートの存在を確認する**。呼び出し経路に非同期メカニズムが現れることを待ってからチェックするのではなく、Step 3の完了後に常に実行すること。

呼び出し経路に**非同期メカニズム**（タスクキュー、メッセージブローカー、イベントバス等）が含まれる場合、そのメカニズムを通じた**他の呼び出し経路が存在しないか**を必ず確認する。1つのDispatchルートを見つけただけで調査完了と判断しないこと。

**タスクキュー（Cloud Tasks、Celery、Sidekiq等）の場合**
タスクを生成・エンキューする関数（コンストラクタ、エンキュー関数）の名前で `Grep` し、その関数を呼んでいる全箇所を列挙する。異なるDispatch関数が同じタスクを生成するケースを見逃さないために行う。

**メッセージブローカー（PubSub、Kafka、SQS等）の場合**
Subscriber（またはConsumer）の登録箇所を `Grep` で確認する。また、同じドメインに関するトピック・キューの定義ファイルを確認し、対象処理に関係する他のトピックが漏れていないか確認する。

**イベントシステム（イベントバス、Webhook等）の場合**
イベント名・トピック名・ハンドラ名で `Grep` し、同じイベントを発行している箇所や、関連するイベントを処理しているハンドラを漏れなく確認する。

### Step 5: 別のルートがないか確認する

Step 3 で一つのルートが見つかっても、他のルートがないか必ず以下を確認する。

**1. 姉妹関数の存在確認**
見つかった関数が属するファイル内に、同じプレフィックスまたはサフィックスを持つ関連関数が存在しないか確認する。例えば `DeleteByOrderCancel` という関数を見つけたら、同ファイルで `^func.*Delete` のような正規表現で検索し、`DeleteByOrderDelete` や `DeleteTask` といった姉妹関数が存在しないか確認する。姉妹関数が存在する場合、それぞれについて Step 3 を実行する。

**2. Dispatch/Publishパターンの網羅確認**
`DispatchTask`、`PublishMessage`、`Enqueue` のような「処理をキューや別サービスに渡す」命名の関数が登場したら、同じドメインに関する他の同種関数（Create/Update/Cancel/Delete など操作の種類違い）も確認し、調査対象の処理に繋がる別ルートがないか確認する。

**3. 複数候補の網羅**
Step 1 で複数の候補が見つかった場合、それぞれについて Step 3 を実行する。対象処理の関数名を呼んでいる箇所が複数あれば、それぞれのルートを辿る。

### Step 6: 見落としチェック

- 動的呼び出し（インターフェース、リフレクション、イベントバス等）がないか確認する
- 設定ファイル（YAML, JSON）でトリガーや設定値が定義されていないか確認する
  - 「トリガー」だけでなく、バケット名・URL・環境変数の値なども対象
  - 特にデプロイ設定 YAML（`*service.yaml` など）は見落としやすい
- テストファイルが手がかりになる場合は参照する

## 出力フォーマットの詳細ルール

### ルール1: エントリポイントが最上位

エントリポイントは HTTPメソッド+パス、スケジュール設定名など、**コード外の起点**を最上位に書く。

```
  POST /api/order          ← HTTPエンドポイントの場合
  Cloud Scheduler 毎日0時  ← バッチの場合
  CLI: go run main.go sync ← CLIの場合
```

### ルール2: 中間の呼び出しをすべて記載する

エントリポイントから対象処理までの**すべての関数呼び出し**を `└─` で繋ぐ。途中を省略しない。

```
  POST /api/order
     └─ handler.OrderCreate ./src/handler/order.go:45
        └─ usecase.OrderCreate ./src/usecase/order.go:80     ← 中間の呼び出しも必ず記載
           └─ domain.CalcPrice ./src/domain/order.go:120
              └─ [対象処理: 購入金額の算出] ./src/domain/order.go:135
```

### ルール3: 対象処理は末端に `[対象処理: ...]` と明記する

対象処理を行っている行は末端ノードとし、`[対象処理: 処理の説明]` と明記する。

### ルール4: テーブル・まとめ・要約を使わない

- 表（markdown table）は使わない
- 「まとめ」「要約」「中心となる関数」のようなセクションは作らない
- ツリー形式のセクションのみで結果を表現する

### ルール5: ルートが見つからない場合

```
## 調査結果: 〇〇の処理

調査した結果、対象処理へのルートが見つかりませんでした。

調査したキーワード: [キーワード一覧]
調査したファイル: [ファイル一覧]
考えられる理由: [推測]
```

### ルール6: 要件適合確認を末尾に必ず記載する

各ルートの末尾に、要件適合を確認したコード箇所を明記する。

```
**要件適合確認**:
- クエリのビジネス要件: 〇〇（例: chumonKbn=5 で送る）
- 確認したコード箇所: {ファイルパス:行番号}
- 確認内容: {実際に該当処理をしていることを裏付けるコードの抜粋}
```
