# 機能設計書 31-コードレビュー

## 概要

本ドキュメントは、GitLabのマージリクエストにおけるコードレビュー機能の設計仕様を記載する。本機能はマージリクエストの差分に対してコメントやレビューを行う機能を提供する。

### 本機能の処理概要

コードレビュー機能は、マージリクエストで変更されたコードの差分（diff）に対して、レビュアーがコメントを付与し、コードの品質を担保するための機能である。

**業務上の目的・背景**：ソフトウェア開発において、コード変更の品質を担保するためにはチームメンバーによるレビューが不可欠である。コードレビュー機能を提供することで、バグの早期発見、コード品質の向上、チーム内での知識共有を促進する。

**機能の利用シーン**：開発者がブランチで実装した機能をメインブランチにマージする前に、チームメンバーがコード変更内容を確認し、改善点やバグの指摘、承認を行う場面で利用される。

**主要な処理内容**：
1. マージリクエストの差分表示（ファイル単位、行単位での変更表示）
2. 差分の特定行に対するコメントの追加（ドラフトノート、通常ノート）
3. ディスカッションスレッドの管理（解決、未解決の追跡）
4. レビュー状態の管理（未レビュー、レビュー済み、変更要求、承認）
5. ドラフトノートの一括公開

**関連システム・外部連携**：NotificationServiceを通じたメール通知、Webhookによる外部システム連携、GraphQL APIによるリアルタイム更新

**権限による制御**：プロジェクトへのアクセス権限を持つユーザーのみがレビューを実行できる。コメントの編集・削除は作成者またはプロジェクト管理者のみ可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | MR詳細 | 主画面 | マージリクエストの詳細表示、コードレビューコメント |
| 65 | コンフリクト解決 | 参照画面 | マージコンフリクト発生時の参照 |

## 機能種別

コメント・レビュー操作（CRUD操作 + ワークフロー制御）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| merge_request_id | Integer | Yes | 対象マージリクエストのID | 存在チェック |
| note | String | Yes | コメント本文 | 空文字不可、最大長制限 |
| position | JSON | No | 差分内の位置情報 | diff_refs、パス、行番号の整合性 |
| commit_id | String | No | 特定コミットへのコメント時 | 有効なコミットSHA |
| resolve_discussion | Boolean | No | ディスカッション解決フラグ | - |
| line_code | String | No | 行を特定するコード | フォーマット検証 |
| internal | Boolean | No | 内部コメントフラグ | - |

### 入力データソース

- 画面入力（コメントテキスト、位置情報）
- マージリクエストの差分データ（MergeRequestDiff）
- ユーザーセッション情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| draft_note | DraftNote | 作成されたドラフトノート |
| note | Note | 公開されたノート |
| review | Review | レビュー情報 |
| discussions | Array | ディスカッションスレッド一覧 |

### 出力先

- 画面表示（JSON形式でフロントエンドに返却）
- データベース（draft_notes, notes, reviews, merge_request_reviewersテーブル）
- 通知（メール、Web通知）

## 処理フロー

### 処理シーケンス

```
1. ドラフトノート作成
   └─ DraftNotes::CreateServiceを呼び出し、ドラフトノートを保存
2. ドラフトノート更新
   └─ 既存のドラフトノートの内容を編集
3. ドラフトノート公開
   └─ DraftNotes::PublishServiceを呼び出し、ドラフトを通常ノートに変換
4. レビュー状態更新
   └─ UpdateReviewerStateServiceでレビュアーの状態を更新
5. 承認処理
   └─ ApprovalServiceで承認を記録
```

### フローチャート

```mermaid
flowchart TD
    A[レビュー開始] --> B{ドラフトモード?}
    B -->|Yes| C[ドラフトノート作成]
    B -->|No| D[通常ノート作成]
    C --> E[ドラフト編集/追加]
    E --> F{公開?}
    F -->|Yes| G[ドラフト一括公開]
    F -->|No| E
    G --> H{承認?}
    D --> H
    H -->|Yes| I[承認処理]
    H -->|No| J{変更要求?}
    J -->|Yes| K[変更要求記録]
    J -->|No| L[レビュー完了記録]
    I --> M[通知送信]
    K --> M
    L --> M
    M --> N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-31-01 | ドラフト公開制限 | ドラフトノートは作成者のみが公開可能 | ドラフト公開時 |
| BR-31-02 | 承認後の変更要求 | 承認済みレビュアーは変更要求で承認が取り消される | 変更要求時 |
| BR-31-03 | マージ済みMR制限 | マージ済みMRには新規承認不可 | 承認処理時 |
| BR-31-04 | セルフ承認 | 設定により作成者自身の承認を制限可能 | 承認処理時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ドラフト作成 | draft_notes | INSERT | ドラフトノートレコード追加 |
| ドラフト更新 | draft_notes | UPDATE | ドラフトノート内容更新 |
| ドラフト削除 | draft_notes | DELETE | ドラフトノート削除 |
| ノート作成 | notes | INSERT | 公開ノートレコード追加 |
| 承認 | approvals | INSERT | 承認レコード追加 |
| レビュー状態更新 | merge_request_reviewers | UPDATE | state列の更新 |
| レビュー作成 | reviews | INSERT | レビューレコード追加 |

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

#### draft_notes

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | merge_request_id | 対象MRのID | |
| INSERT | author_id | 現在ユーザーのID | |
| INSERT | note | コメント本文 | |
| INSERT | position | 差分位置情報（JSON） | オプション |
| INSERT | commit_id | コミットSHA | オプション |

#### merge_request_reviewers

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | state | 'reviewed', 'approved', 'requested_changes' | 状態値 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | Forbidden | ノート作成権限なし | 権限確認メッセージ表示 |
| 404 | NotFound | 対象MRが存在しない | エラー画面表示 |
| 422 | Unprocessable | バリデーションエラー | エラーメッセージ表示 |
| 500 | InternalError | サーバー内部エラー | エラーログ記録、汎用エラー表示 |

### リトライ仕様

特にリトライ処理は実装されていない。エラー発生時はユーザーに再操作を促す。

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

- ドラフトノートの一括公開時はトランザクション内で処理
- 承認処理時、approvalレコード作成とreviewer状態更新は同一トランザクション

## パフォーマンス要件

- 差分表示: urgency :low指定（低優先度、応答時間制約緩和）
- バッチ表示では1日のキャッシュ有効期限を設定
- ETagによるキャッシュ制御を実施

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

- authorize_create_note!によるノート作成権限チェック
- authorize_admin_draft!によるドラフト管理権限チェック
- プロジェクトアクセス権限の確認
- 内部コメント（internal）フラグによる表示制御

## 備考

- ドラフトノートはレビュアーがコメントを下書きとして保存し、後でまとめて公開できる機能
- PreviewMarkdownServiceによりMarkdownプレビューをサポート

---

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

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

### 推奨読解順序

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

まず、コードレビューに関連するデータモデルを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | draft_note.rb | `app/models/draft_note.rb` | ドラフトノートのデータ構造、バリデーション |
| 1-2 | note.rb | `app/models/note.rb` | 公開ノートのデータ構造 |
| 1-3 | merge_request.rb | `app/models/merge_request.rb` | マージリクエストとノートの関連 |
| 1-4 | merge_request_reviewer.rb | `app/models/merge_request_reviewer.rb` | レビュアー状態の管理 |

**読解のコツ**: Railsのモデルでは`has_many`, `belongs_to`などの関連定義と、`validates`によるバリデーション定義を確認する。

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

コントローラーが処理の起点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | drafts_controller.rb | `app/controllers/projects/merge_requests/drafts_controller.rb` | ドラフトノートのCRUD操作 |
| 2-2 | diffs_controller.rb | `app/controllers/projects/merge_requests/diffs_controller.rb` | 差分表示とコメント位置管理 |

**主要処理フロー**:
1. **24-42行目**: createアクション - DraftNotes::CreateServiceを呼び出してドラフト作成
2. **44-51行目**: updateアクション - ドラフトの更新処理
3. **59-76行目**: publishアクション - ドラフトの一括公開とレビュー状態更新

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

ビジネスロジックはサービスクラスに実装されている。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create_service.rb | `app/services/draft_notes/create_service.rb` | ドラフトノート作成ロジック |
| 3-2 | publish_service.rb | `app/services/draft_notes/publish_service.rb` | ドラフト公開ロジック |
| 3-3 | update_reviewer_state_service.rb | `app/services/merge_requests/update_reviewer_state_service.rb` | レビュアー状態更新 |
| 3-4 | approval_service.rb | `app/services/merge_requests/approval_service.rb` | 承認処理 |

**主要処理フロー**:
- **update_reviewer_state_service.rb 5-33行目**: レビュー状態の更新と関連処理（変更要求、承認取り消し等）
- **approval_service.rb 5-38行目**: 承認処理とイベント発行

#### Step 4: シリアライザーを理解する

APIレスポンスの構造を定義。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | draft_note_serializer.rb | `app/serializers/draft_note_serializer.rb` | ドラフトノートのJSON形式 |
| 4-2 | diffs_serializer.rb | `app/serializers/diffs_serializer.rb` | 差分データのJSON形式 |

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

```
DraftsController
    │
    ├─ create
    │      └─ DraftNotes::CreateService#execute
    │              └─ DraftNote.create
    │
    ├─ update
    │      └─ DraftNote#update
    │
    ├─ publish
    │      ├─ DraftNotes::PublishService#execute
    │      │      └─ Notes::CreateService (for each draft)
    │      │
    │      └─ MergeRequests::UpdateReviewerStateService#execute
    │             ├─ SystemNoteService.requested_changes
    │             └─ MergeRequests::ApprovalService#execute
    │
    └─ discard
           └─ DraftNotes::DestroyService#execute
```

### データフロー図

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

ユーザーコメント ───▶ DraftsController ───▶ DraftNote (DB保存)
                           │
                           ▼
                    DraftNotes::CreateService
                           │
                           ▼
                    DraftNote.create ───▶ draft_notesテーブル
                           │
                    (公開時)
                           ▼
                    DraftNotes::PublishService ───▶ notesテーブル
                           │
                           ▼
                    NotificationService ───▶ メール通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| drafts_controller.rb | `app/controllers/projects/merge_requests/drafts_controller.rb` | コントローラー | ドラフトノートのCRUD操作 |
| diffs_controller.rb | `app/controllers/projects/merge_requests/diffs_controller.rb` | コントローラー | 差分表示とコメント管理 |
| draft_note.rb | `app/models/draft_note.rb` | モデル | ドラフトノートのデータ定義 |
| merge_request.rb | `app/models/merge_request.rb` | モデル | マージリクエストのデータ定義 |
| merge_request_reviewer.rb | `app/models/merge_request_reviewer.rb` | モデル | レビュアー状態管理 |
| create_service.rb | `app/services/draft_notes/create_service.rb` | サービス | ドラフトノート作成ロジック |
| publish_service.rb | `app/services/draft_notes/publish_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` | サービス | 承認処理 |
| draft_note_serializer.rb | `app/serializers/draft_note_serializer.rb` | シリアライザー | JSON出力形式定義 |
