# 帳票設計書 2-Merge Request CSV Export

## 概要

本ドキュメントは、GitLabのプロジェクトにおけるMerge Request一覧をCSV形式でエクスポートする機能の帳票設計書である。

### 本帳票の処理概要

本帳票は、プロジェクト内のMerge Request情報を一括でCSVファイルとして出力し、コードレビュープロセスの分析、進捗管理、監査目的でのデータ保存に活用するための機能を提供する。

**業務上の目的・背景**：開発チームがMerge Requestの進捗状況を外部ツールで分析したい場合や、コードレビュープロセスの改善のためのメトリクス収集、監査目的でのMR履歴保存が必要な場合に、この機能が活用される。また、プロジェクト間でのMR状況比較やレポート作成にも使用される。

**帳票の利用シーン**：エンジニアリングマネージャーがチームのMR処理速度を分析する際、品質管理担当者がコードレビューの傾向を把握する際、プロジェクトマネージャーがリリース準備状況を確認する際などに利用される。

**主要な出力内容**：
1. MR基本情報（Title、Description、MR IID、URL、State）
2. ブランチ情報（Source Branch、Target Branch、Source Project ID、Target Project ID）
3. 担当者情報（Author、Assignees、Approvers、Merged User）
4. メタデータ（Milestone ID、Created At、Updated At）

**帳票の出力タイミング**：ユーザーがプロジェクトのMerge Request一覧画面から「Export as CSV」操作を行った際に非同期で処理が開始され、完了後にメールで送信される。

**帳票の利用者**：開発者、エンジニアリングマネージャー、プロジェクトマネージャー、品質管理担当者

## 帳票種別

一覧表（CSVエクスポート）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | Project Merge Requests | `/:namespace/:project/-/merge_requests` | "Export as CSV"操作 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | CSV |
| 用紙サイズ | - |
| 向き | - |
| ファイル名 | merge_requests_export.csv |
| 出力方法 | メール送付 |
| 文字コード | UTF-8 |

### CSV固有設定

| 項目 | 内容 |
|-----|------|
| ヘッダー行 | あり |
| 区切り文字 | カンマ |
| 囲み文字 | ダブルクォート |
| 最大ファイルサイズ | 15MB（Base64エンコード前） |

## 帳票レイアウト

### レイアウト概要

CSVファイルはヘッダー行と明細行で構成される。各行は17項目のカラムを持つ。

```
┌─────────────────────────────────────┐
│         ヘッダー行（1行目）           │
├─────────────────────────────────────┤
│         明細行（2行目以降）           │
│         （MR毎に1行）                │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Title | MRのタイトル | merge_requests.title | 文字列 |
| 2 | Description | MRの説明 | merge_requests.description | 文字列 |
| 3 | MR IID | MR IID | merge_requests.iid | 数値 |
| 4 | URL | MRのURL | GitlabRoutingHelper | URL文字列 |
| 5 | State | MRの状態 | merge_requests.state | 文字列（opened/merged/closed） |
| 6 | Source Branch | ソースブランチ名 | merge_requests.source_branch | 文字列 |
| 7 | Target Branch | ターゲットブランチ名 | merge_requests.target_branch | 文字列 |
| 8 | Source Project ID | ソースプロジェクトID | merge_requests.source_project_id | 数値 |
| 9 | Target Project ID | ターゲットプロジェクトID | merge_requests.target_project_id | 数値 |
| 10 | Author | 作成者名 | users.name | 文字列 |
| 11 | Author Username | 作成者ユーザー名 | users.username | 文字列 |
| 12 | Assignees | 担当者名 | assignees.name | カンマ区切り文字列 |
| 13 | Assignee Usernames | 担当者ユーザー名 | assignees.username | カンマ区切り文字列 |
| 14 | Approvers | 承認者名 | approved_by_users.name | カンマ区切り文字列 |
| 15 | Approver Usernames | 承認者ユーザー名 | approved_by_users.username | カンマ区切り文字列 |
| 16 | Merged User | マージ実行者名 | metrics.merged_by.name | 文字列 |
| 17 | Merged Username | マージ実行者ユーザー名 | metrics.merged_by.username | 文字列 |
| 18 | Milestone ID | マイルストーンID | milestones.id | 数値 |
| 19 | Created At (UTC) | 作成日時 | merge_requests.created_at | 日時（UTC） |
| 20 | Updated At (UTC) | 更新日時 | merge_requests.updated_at | 日時（UTC） |

### 明細部

各Merge Requestごとに1行を出力。出力順はリクエスト時のフィルタ条件に基づく。

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| プロジェクト | 対象プロジェクト | Yes |
| フィルタ条件 | MR一覧画面のフィルタ条件を継承 | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | リクエスト時の指定 | 画面のソート順を継承 |

### 改ページ条件

CSVのため改ページなし

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| merge_requests | MR基本情報 | 主テーブル |
| users (author) | 作成者情報 | merge_requests.author_id = users.id |
| merge_request_assignees | 担当者関連 | merge_requests.id = merge_request_assignees.merge_request_id |
| users (assignees) | 担当者情報 | merge_request_assignees.user_id = users.id |
| approvals | 承認情報 | merge_requests.id = approvals.merge_request_id |
| users (approved_by) | 承認者情報 | approvals.user_id = users.id |
| merge_request_metrics | MRメトリクス | merge_requests.id = merge_request_metrics.merge_request_id |
| users (merged_by) | マージ実行者 | merge_request_metrics.merged_by_id = users.id |
| milestones | マイルストーン | merge_requests.milestone_id = milestones.id |

### テーブル別参照項目詳細

#### merge_requests

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| title | Title | - | - |
| description | Description | - | - |
| iid | MR IID | - | プロジェクト内の連番 |
| state | State | - | opened/merged/closed |
| source_branch | Source Branch | - | - |
| target_branch | Target Branch | - | - |
| source_project_id | Source Project ID | - | フォークからのMR対応 |
| target_project_id | Target Project ID | - | - |
| created_at | Created At (UTC) | - | UTC形式 |
| updated_at | Updated At (UTC) | - | UTC形式 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| Assignees | assignees.map(&:name).join(', ') | - | カンマ区切り結合 |
| Approvers | approved_by_users.map(&:name).join(', ') | - | カンマ区切り結合 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[Export as CSV操作] --> B[export_csvアクション呼び出し]
    B --> C[IssuableExportCsvWorker.perform_async]
    C --> D[非同期ワーカー起動]
    D --> E[MergeRequests::ExportCsvService.new]
    E --> F[MergeRequestsFinder で対象MR取得]
    F --> G[csv_builder.render でCSV生成]
    G --> H[CsvBuilder バッチ処理]
    H --> I{ファイルサイズ確認}
    I -->|15MB以下| J[Notify.merge_requests_csv_email]
    I -->|15MB超過| K[処理中断]
    J --> L[メール送信]
    L --> M[終了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| データなし | 対象MRが0件 | - | 空のCSVが送信される |
| ファイルサイズ超過 | 15MB超過 | 処理が途中で打ち切られる | フィルタ条件を絞る |
| 権限エラー | プロジェクトへのアクセス権がない | 認証エラー画面 | 権限を確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数百〜数千件 |
| 目標出力時間 | 非同期処理のため制限なし |
| 同時出力数上限 | Sidekiqワーカーの並列数に依存 |

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

- 認証済みユーザーのみがエクスポート可能
- プロジェクトへの読み取り権限が必要
- メールは登録済みメールアドレスにのみ送信
- 承認者情報など機密性の高い情報も含まれるため注意

## 備考

- Merge Request固有のフォーク元プロジェクト情報（Source Project ID）を含む
- Approvers情報はEE機能の一部として拡張される可能性がある

---

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

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

### 推奨読解順序

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

CSV出力のカラム定義とデータ取得方法を理解することが最初のステップ。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | export_csv_service.rb | `app/services/merge_requests/export_csv_service.rb` | header_to_value_hashでCSVカラム定義を確認（14-36行目） |

**読解のコツ**: IssueのCSVエクスポートと比較して、Merge Request固有のSource/Target Branch、Approvers等のカラムに注目。

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

ユーザー操作からの処理開始点を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | merge_requests_controller.rb | `app/controllers/projects/merge_requests_controller.rb` | export_csvアクション |

**主要処理フロー**:
1. コントローラーでIssuableExportCsvWorkerを非同期実行
2. リダイレクトとフラッシュメッセージ表示

#### Step 3: CSV生成サービスを理解する

CSVデータ生成の詳細ロジックを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | base_service.rb | `app/services/export_csv/base_service.rb` | csv_builderの生成とrender呼び出し |
| 3-2 | export_csv_service.rb | `app/services/merge_requests/export_csv_service.rb` | MR固有のカラム定義 |

**主要処理フロー**:
- **8-9行目**: `email`メソッドでNotify.merge_requests_csv_emailを呼び出し
- **14-36行目**: `header_to_value_hash`でカラム定義

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

```
Projects::MergeRequestsController#export_csv
    │
    ├─ IssuableExportCsvWorker.perform_async
    │      │
    │      └─ MergeRequests::ExportCsvService.new
    │             │
    │             ├─ ExportCsv::BaseService (継承)
    │             │      └─ CsvBuilder.new
    │             │             └─ render (CSV生成)
    │             │
    │             └─ email
    │                    └─ Notify.merge_requests_csv_email
```

### データフロー図

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

MR一覧画面 ───▶ MergeRequestsController ───▶ IssuableExportCsvWorker
    │                                              │
    │                                              ▼
    │                                    MergeRequests::ExportCsvService
    │                                              │
    │                                              ▼
    │                                        CsvBuilder.render
    │                                              │
    │                                              ▼
    └──────────────────────────────────▶ Notify.merge_requests_csv_email
                                                   │
                                                   ▼
                                              ユーザーメール
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| export_csv_service.rb | `app/services/merge_requests/export_csv_service.rb` | ソース | MR CSV生成サービス |
| base_service.rb | `app/services/export_csv/base_service.rb` | ソース | CSV生成基底クラス |
| merge_requests_controller.rb | `app/controllers/projects/merge_requests_controller.rb` | ソース | コントローラー |
| issuable_export_csv_worker.rb | `app/workers/issuable_export_csv_worker.rb` | ソース | 非同期ワーカー |
| csv_builder.rb | `lib/csv_builder.rb` | ソース | CSV構築ユーティリティ |
| notify.rb | `app/mailers/notify.rb` | ソース | メール送信 |
