# 機能設計書 103-プロジェクト内検索

## 概要

本ドキュメントは、GitLabのプロジェクト内検索機能についての機能設計書である。

### 本機能の処理概要

プロジェクト内検索は、特定のプロジェクト内でファイル、コード、イシュー、マージリクエスト、コミットなどを検索する機能である。プロジェクトコンテキスト内で効率的に情報を見つけることができる。

**業務上の目的・背景**：開発者がプロジェクト内のコードやドキュメント、イシュー、マージリクエストを迅速に検索するための機能を提供する。特にコード検索は、関連するコードの調査やリファクタリング時に重要な役割を果たす。

**機能の利用シーン**：
- プロジェクト内のファイル名やコード片を検索
- 特定のイシューやマージリクエストを検索
- コミットメッセージやコミットSHAで履歴を検索
- Wikiページの内容を検索
- マイルストーンやユーザーを検索

**主要な処理内容**：
1. 検索クエリの受付とバリデーション
2. プロジェクトコンテキストの特定
3. 検索スコープの決定
4. リポジトリブランチ/タグの指定（コード検索時）
5. 検索エンジンへのクエリ実行
6. 結果のフィルタリング・ソート
7. シンタックスハイライト付きコード表示

**関連システム・外部連携**：
- Gitaly（リポジトリコード検索）
- Elasticsearch/OpenSearch（高度な検索機能有効時）
- PostgreSQL全文検索（基本検索）

**権限による制御**：
- プロジェクトへの読み取り権限が必要
- コード検索は`read_code`権限が必要
- 機密イシューは権限に応じてフィルタリング

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 284 | 検索結果 | 主画面 | 検索結果表示 |
| 46 | ファイル検索 | 主画面 | リポジトリ内ファイル検索 |

## 機能種別

データ検索 / 全文検索 / コード検索

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| search | String | Yes | 検索キーワード | 最大256文字、最大64語 |
| scope | String | No | 検索スコープ | blobs/issues/merge_requests/milestones/wiki_blobs/commits/notes/users |
| project_id | Integer | Yes | プロジェクトID | 有効なプロジェクトID |
| repository_ref | String | No | ブランチ/タグ名 | コード検索時に指定可能 |
| sort | String | No | ソート順 | created_desc/created_asc等 |
| state | String | No | 状態フィルタ | opened/closed/merged等 |
| confidential | Boolean | No | 機密フラグ | true/false |
| language | Array | No | プログラミング言語フィルタ | コード検索時 |

### 入力データソース

- プロジェクト内検索ボックス
- ファイル検索UI（Ctrl+P / Cmd+P）
- 検索結果ページのフィルタUI

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| search_results | Array | 検索結果オブジェクト配列 |
| blobs | Array | コードブロブ検索結果 |
| wiki_blobs | Array | Wikiページ検索結果 |
| commits | Array | コミット検索結果 |
| issues | Array | イシュー検索結果 |
| merge_requests | Array | マージリクエスト検索結果 |

### 出力先

- 検索結果画面（HTML）
- JSON API（オートコンプリート）

## 処理フロー

### 処理シーケンス

```
1. 検索リクエスト受付
   └─ SearchController#show がプロジェクトコンテキストで受付
2. プロジェクト取得
   └─ project_id からプロジェクトを取得
3. 権限チェック
   └─ プロジェクトへのアクセス権限確認
4. スコープ決定
   └─ 有効なスコープを決定（プロジェクト設定に依存）
5. 検索実行
   └─ Search::ProjectService 経由で検索
6. 結果整形
   └─ シンタックスハイライト、ページネーション
7. レスポンス返却
   └─ HTML/JSON形式で結果返却
```

### フローチャート

```mermaid
flowchart TD
    A[検索リクエスト] --> B{プロジェクト存在?}
    B -->|No| C[404 Not Found]
    B -->|Yes| D{アクセス権限?}
    D -->|No| E[403 Forbidden]
    D -->|Yes| F{スコープ有効?}
    F -->|No| G[デフォルトスコープ使用]
    F -->|Yes| H[指定スコープ使用]
    G --> I{コード検索?}
    H --> I
    I -->|Yes| J{read_code権限?}
    I -->|No| K[DB検索実行]
    J -->|No| L[コード結果なし]
    J -->|Yes| M[Gitaly/検索エンジン検索]
    K --> N[結果表示]
    L --> N
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-103-01 | スコープ有効性チェック | プロジェクト設定で無効化されたスコープは使用不可 | 全検索 |
| BR-103-02 | コード検索権限 | read_code権限がない場合、コード検索結果を表示しない | blobsスコープ |
| BR-103-03 | repository_ref指定 | ブランチ/タグ指定時はそのrefでコード検索 | コード検索 |
| BR-103-04 | 機密イシューフィルタ | 機密イシューは権限に応じて表示/非表示 | イシュー検索 |

### 計算ロジック

有効スコープの決定:
1. リクエストされたスコープが許可スコープに含まれるかチェック
2. Search::Navigation でタブが有効かチェック
3. カスタムデフォルトスコープ設定があれば優先
4. なければ最初の有効スコープを使用

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| イシュー検索 | issues | SELECT | プロジェクト内イシュー検索 |
| マージリクエスト検索 | merge_requests | SELECT | プロジェクト内MR検索 |
| マイルストーン検索 | milestones | SELECT | プロジェクト内マイルストーン検索 |
| コミット検索 | - | - | Gitaly経由 |
| コード検索 | - | - | Gitaly/検索エンジン経由 |

### テーブル別操作詳細

#### issues テーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | title, description | プロジェクトIDと検索キーワードでフィルタ | 全文検索インデックス使用 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | Not Found | プロジェクトが存在しない | 正しいプロジェクトパスを確認 |
| 403 | Forbidden | プロジェクトへのアクセス権限なし | 権限をリクエスト |
| 408 | Request Timeout | 検索タイムアウト | 検索条件を絞る |

### リトライ仕様

- タイムアウト時: エラー画面表示、条件を絞って再検索

## トランザクション仕様

- 検索は読み取り専用操作のため、トランザクション制御不要

## パフォーマンス要件

- プロジェクト内検索はグローバル検索より高速（スコープが限定されるため）
- コード検索はGitaly呼び出しのため、リポジトリサイズに依存
- 大規模リポジトリでは検索エンジン（Elasticsearch/Zoekt）推奨

## セキュリティ考慮事項

- プロジェクトアクセス権限チェック
- コード読み取り権限チェック
- 機密イシューのアクセス制御

## 備考

- スコープの有効/無効はプロジェクト設定で制御可能
- EEではElasticsearch/Zoektによる高速コード検索が利用可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

検索結果の構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | project_search_results.rb | `lib/gitlab/project_search_results.rb` | プロジェクト内検索結果クラス |

**読解のコツ**: `Gitlab::ProjectSearchResults`は`Gitlab::SearchResults`を継承し、プロジェクト固有の検索ロジックを追加している。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | search_controller.rb | `app/controllers/search_controller.rb` | プロジェクトコンテキスト検索 |

**主要処理フロー**:
- **49行目**: `@project = search_service.project` でプロジェクト取得
- **56-58行目**: スコープと検索タイプの検証

#### Step 3: プロジェクト検索サービスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | project_service.rb | `app/services/search/project_service.rb` | プロジェクト内検索サービス |

**主要処理フロー**:
- **16-25行目**: `execute`メソッドで`Gitlab::ProjectSearchResults`生成
- **27-33行目**: `allowed_scopes`で許可スコープ取得
- **35-49行目**: `scope`メソッドで有効スコープ決定

### プログラム呼び出し階層図

```
SearchController#show
    │
    ├─ search_service.project
    │
    └─ Search::ProjectService
           │
           ├─ allowed_scopes
           │      └─ Search::Scopes.available_for_context
           │
           ├─ scope
           │      └─ Search::Navigation#tab_enabled_for_project?
           │
           └─ execute
                  └─ Gitlab::ProjectSearchResults
                         │
                         ├─ issues (DBクエリ)
                         ├─ merge_requests (DBクエリ)
                         ├─ blobs (Gitaly/検索エンジン)
                         ├─ commits (Gitaly)
                         └─ wiki_blobs (Gitaly)
```

### データフロー図

```
[入力]                        [処理]                           [出力]

検索クエリ (search) ────▶ Search::ProjectService ────────▶ 検索結果
プロジェクトID                  │
スコープ (scope)                ├─ Gitlab::ProjectSearchResults
リポジトリ参照                  │      │
                               │      ├─ DB検索 (issues/MRs)
                               │      └─ Gitaly検索 (blobs/commits)
                               │
                               └─ 検索結果表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| search_controller.rb | `app/controllers/search_controller.rb` | ソース | HTTPエンドポイント |
| project_service.rb | `app/services/search/project_service.rb` | ソース | プロジェクト検索サービス |
| project_search_results.rb | `lib/gitlab/project_search_results.rb` | ソース | プロジェクト検索結果 |
| navigation.rb | `app/services/search/navigation.rb` | ソース | 検索ナビゲーション |
| scopes.rb | `app/services/search/scopes.rb` | ソース | スコープ管理 |
