# 機能設計書 35-レビュアー・承認者管理

## 概要

本ドキュメントは、GitLabのマージリクエストにおけるレビュアー・承認者管理機能の設計仕様を記載する。本機能はマージリクエストのレビュアーと承認者の設定・管理を提供する。

### 本機能の処理概要

レビュアー・承認者管理機能は、マージリクエストに対してコードレビューを行うレビュアーと、マージを承認する承認者を設定・管理する機能である。

**業務上の目的・背景**：コード品質を担保するためには、適切なレビュアーによるコードレビューと承認プロセスが重要である。本機能により、誰がレビューを担当し、誰が承認したかを明確に追跡でき、チーム内での責任分担を明確化できる。

**機能の利用シーン**：マージリクエスト作成時または作成後に、適切なレビュアーをアサインする。レビュアーはコードを確認し、承認または変更要求を行う。必要な承認が得られた後にマージが可能となる。

**主要な処理内容**：
1. レビュアーの追加・削除
2. レビュアーへのレビュー依頼通知
3. レビュアー状態の管理（未レビュー、レビュー済み、承認、変更要求）
4. 承認の記録
5. 承認の取り消し
6. 必要承認数のチェック

**関連システム・外部連携**：NotificationServiceを通じたレビュー依頼通知、TodoServiceによるTodo追加、Webhookによる外部通知

**権限による制御**：マージリクエストのメタデータ設定権限を持つユーザーがレビュアーを設定可能。承認は対象MRへのアクセス権限を持つユーザーが可能（セルフ承認可否は設定による）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | MR詳細 | 主画面 | レビュアー・承認者の設定、承認操作 |
| 62 | MR新規作成 | 参照画面 | 初期レビュアーの設定 |

## 機能種別

ワークフロー管理（レビュー・承認プロセス）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| merge_request_id | Integer | Yes | 対象マージリクエストのID | 存在チェック |
| reviewer_ids | Array[Integer] | No | レビュアーのユーザーID配列 | 有効なユーザー |
| reviewer_state | String | No | レビュアーの状態 | 'reviewed', 'approved', 'requested_changes' |
| approve | Boolean | No | 承認フラグ | - |

### 入力データソース

- 画面入力（レビュアー選択、承認ボタン）
- API呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| merge_request | MergeRequest | 更新されたマージリクエスト |
| reviewers | Array[User] | レビュアー一覧 |
| approvals | Array[Approval] | 承認一覧 |

### 出力先

- 画面表示（レビュアー・承認者情報）
- データベース（merge_request_reviewers, approvalsテーブル）
- 通知（メール、Todo）

## 処理フロー

### 処理シーケンス

```
1. レビュアー設定
   └─ UpdateReviewersServiceでレビュアー更新
2. レビュー依頼通知
   └─ NotificationServiceで通知送信
3. レビュー状態更新
   └─ UpdateReviewerStateServiceで状態変更
4. 承認処理
   └─ ApprovalServiceで承認記録
5. 承認取り消し
   └─ RemoveApprovalServiceで承認削除
```

### フローチャート

```mermaid
flowchart TD
    A[レビュアー設定] --> B[通知送信]
    B --> C[レビュー開始]
    C --> D{レビュー結果}
    D -->|承認| E[ApprovalService]
    D -->|変更要求| F[UpdateReviewerStateService]
    D -->|レビュー済み| G[レビュー完了記録]
    E --> H[承認記録]
    F --> I[変更要求記録]
    F --> J{既に承認済み?}
    J -->|Yes| K[承認取り消し]
    J -->|No| L[終了]
    H --> L
    I --> L
    G --> L
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-35-01 | 承認後の変更要求 | 承認済みユーザーが変更要求すると承認が取り消される | 変更要求時 |
| BR-35-02 | マージ済み制限 | マージ済みMRには承認不可 | 承認処理時 |
| BR-35-03 | レビュアー上限 | レビュアー数には上限がある（設定による） | レビュアー追加時 |
| BR-35-04 | セルフ承認 | プロジェクト設定により作成者自身の承認を制限可能 | 承認処理時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| レビュアー設定 | merge_request_reviewers | INSERT/DELETE | レビュアー関連付け |
| 状態更新 | merge_request_reviewers | UPDATE | state列更新 |
| 承認 | approvals | INSERT | 承認レコード追加 |
| 承認取り消し | approvals | DELETE | 承認レコード削除 |

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

#### merge_request_reviewers

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | merge_request_id | 対象MRのID | |
| INSERT | user_id | レビュアーのユーザーID | |
| UPDATE | state | 'reviewed', 'approved', 'requested_changes' | 状態値 |

#### approvals

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | merge_request_id | 対象MRのID | |
| INSERT | user_id | 承認者のユーザーID | |
| INSERT | patch_id_sha | 承認時点のパッチID | |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | Forbidden | 権限なし | エラーメッセージ表示 |
| - | :error | レビュアー更新失敗 | エラーメッセージ返却 |
| - | :error | 承認処理失敗 | エラーメッセージ返却 |

### リトライ仕様

特になし

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

- レビュアー更新、承認処理はトランザクション内で実行

## パフォーマンス要件

- レビュアー・承認者情報のプリロード

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

- set_merge_request_metadata権限チェック（レビュアー設定）
- 承認資格チェック（eligible_for_approval_by?）

## 備考

- EE版では必須承認ルール機能が追加
- Suggested reviewers機能（AI推奨）も関連

---

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

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

### 推奨読解順序

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

レビュアー・承認に関連するモデルの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | merge_request.rb | `app/models/merge_request.rb` | has_many :reviewers, has_many :approvals |
| 1-2 | merge_request_reviewer.rb | `app/models/merge_request_reviewer.rb` | レビュアー状態管理 |
| 1-3 | approval.rb | `app/models/approval.rb` | 承認レコード |

**読解のコツ**: merge_request_reviewers中間テーブルとapprovalsテーブルの構造を確認。

#### Step 2: サービス層を理解する

ビジネスロジックはサービスクラスに実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | update_reviewers_service.rb | `app/services/merge_requests/update_reviewers_service.rb` | レビュアー更新 |
| 2-2 | update_reviewer_state_service.rb | `app/services/merge_requests/update_reviewer_state_service.rb` | 状態更新 |
| 2-3 | approval_service.rb | `app/services/merge_requests/approval_service.rb` | 承認処理 |

**主要処理フロー**:
- **update_reviewers_service.rb 5-23行目**: レビュアー更新ロジック
- **update_reviewer_state_service.rb 5-33行目**: 状態更新と関連処理
- **approval_service.rb 5-38行目**: 承認処理とイベント発行

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

```
MergeRequestsController
    │
    ├─ update (reviewer_ids)
    │      └─ UpdateReviewersService#execute
    │              ├─ merge_request.update!(reviewer_ids:)
    │              ├─ handle_reviewers_change
    │              └─ execute_reviewers_hooks
    │
    └─ approve
           └─ ApprovalService#execute
                  ├─ approvals.new
                  ├─ update_reviewer_state('approved')
                  └─ Gitlab::EventStore.publish

DraftsController#publish
    │
    └─ UpdateReviewerStateService#execute
           ├─ create_requested_changes / destroy_requested_changes
           ├─ reviewer.update(state:)
           └─ remove_approval (if requested_changes)
```

### データフロー図

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

レビュアー選択 ───▶ UpdateReviewersService
                         │
                         ▼
                   merge_request_reviewers ───▶ DB保存
                         │
                         ▼
                   NotificationService ───▶ メール通知

承認ボタン ───▶ ApprovalService
                    │
                    ▼
              approvals ───▶ DB保存
                    │
                    ▼
              EventStore ───▶ イベント発行
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| merge_request.rb | `app/models/merge_request.rb` | モデル | MRモデル |
| merge_request_reviewer.rb | `app/models/merge_request_reviewer.rb` | モデル | レビュアー関連 |
| approval.rb | `app/models/approval.rb` | モデル | 承認レコード |
| update_reviewers_service.rb | `app/services/merge_requests/update_reviewers_service.rb` | サービス | レビュアー更新 |
| update_reviewer_state_service.rb | `app/services/merge_requests/update_reviewer_state_service.rb` | サービス | 状態更新 |
| approval_service.rb | `app/services/merge_requests/approval_service.rb` | サービス | 承認処理 |
| remove_approval_service.rb | `app/services/merge_requests/remove_approval_service.rb` | サービス | 承認取り消し |
