# 通知設計書 119-export_work_items_csv_email

## 概要

本ドキュメントは、GitLabにおけるWork Item CSVエクスポート完了通知（export_work_items_csv_email）の設計仕様を記述する。

### 本通知の処理概要

Work Item CSVエクスポート完了通知は、プロジェクトのWork ItemをCSVファイルにエクスポートした結果を、エクスポートをリクエストしたユーザーに対して通知するメールを送信する。エクスポートされたCSVファイルはメールに添付される。

**業務上の目的・背景**：Work Item（Issue、Task、Epicなど）のデータをCSV形式でエクスポートすることで、外部ツールでの分析やバックアップ、他システムへの移行が可能になる。エクスポートは時間がかかる可能性があるため、バックグラウンドで処理され、完了時にメールでユーザーに通知される。

**通知の送信タイミング**：ExportCsvServiceでのエクスポート処理が完了した時点で、同期的に送信される（deliver_now）。

**通知の受信者**：エクスポートをリクエストしたユーザーに送信される。

**通知内容の概要**：エクスポートされたWork Itemの件数、プロジェクト情報、およびCSVファイル添付を通知する。サイズ制限により切り詰められた場合はその旨も通知される。

**期待されるアクション**：受信者は添付されたCSVファイルをダウンロードして利用する。切り詰められた場合は、フィルタ条件を調整して再エクスポートを検討する。

## 通知種別

メール

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（deliver_now） |
| 優先度 | 高（即時送信） |
| リトライ | なし（同期送信のため） |

### 送信先決定ロジック

エクスポートをリクエストしたユーザー（mail_to_user）の通知用メールアドレスに送信される。

## 通知テンプレート

### メール通知の場合

| 項目 | 内容 |
|-----|------|
| 送信元アドレス | GitLabインスタンス設定に従う |
| 送信元名称 | GitLab |
| 件名 | 共通のCSVエクスポート件名形式 |
| 形式 | テキスト |

### 本文テンプレート

```
Your CSV export of {count} work item(s) from project {project_name} ({project_url}) has been added to this email as an attachment.

(切り詰められた場合)
This attachment has been truncated to avoid exceeding the maximum allowed attachment size of {size_limit}. {written_count} of {total_count} work items have been included. Consider re-exporting with a narrower selection of work items.
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| {project_name}_work_items_{timestamp}.csv | CSV | 常に添付 | エクスポートされたWork Itemデータ |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| @project | 対象プロジェクト | サービスから渡される | Yes |
| @written_count | 書き込まれた件数 | csv_builder.rows_written | Yes |
| @count | 総件数 | csv_builder.rows_expected | Yes |
| @truncated | 切り詰めフラグ | export_status[:truncated] | Yes |
| @size_limit | サイズ制限値 | export_status[:size_limit] | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| サービス呼び出し | ExportCsvService#email | 常に送信 | エクスポート完了後に送信 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | エクスポート結果に関わらず常に通知が送信される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[エクスポートリクエスト] --> B[ExportCsvService実行]
    B --> C[Work Itemデータ取得]
    C --> D[CSV生成]
    D --> E{サイズ制限超過?}
    E -->|Yes| F[切り詰め処理]
    E -->|No| G[emailメソッド呼び出し]
    F --> G
    G --> H[Notify.export_work_items_csv_email.deliver_now]
    H --> I[終了]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| projects | 対象プロジェクト情報取得 | |
| issues/work_items | エクスポート対象データ | |
| work_item_types | ワークアイテムタイプ情報 | |
| users | 作成者・担当者情報 | |
| milestones | マイルストーン情報 | |
| labels | ラベル情報 | |
| timelogs | 時間追跡情報 | |

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

#### work_items（エクスポート対象項目）

| 参照項目（カラム名） | 用途 | エクスポート列名 |
|-------------------|------|-----------------|
| id | ID | ID |
| iid | 内部ID | IID |
| title | タイトル | Title |
| description | 説明 | Description |
| state | 状態 | State |
| confidential | 機密フラグ | Confidential |
| created_at | 作成日時 | Created At (UTC) |
| updated_at | 更新日時 | Updated At (UTC) |
| closed_at | クローズ日時 | Closed At (UTC) |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | 本通知処理ではDB更新は行わない |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| メール送信失敗 | SMTPエラー等 | 例外が発生（同期送信のため） |
| 添付サイズ超過 | CSV生成結果が大きすぎる | 自動切り詰めが行われる |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（同期送信） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | システム設定に従う |
| 1日あたり上限 | システム設定に従う |

### 配信時間帯

制限なし（24時間送信可能）

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

- エクスポートは適切な権限を持つユーザーのみ実行可能
- 機密のWork Itemも含まれる可能性があるため、送信先は実行者に限定
- 添付ファイルはメール経由で送信されるため、メールセキュリティポリシーに注意

## 備考

- csv_emailメソッドは共通実装で、type引数により対象（work_items）を指定
- エクスポート列はheader_to_value_hashで定義される
- widget_value_forメソッドでWork Itemのウィジェットから値を取得

---

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

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

### 推奨読解順序

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

エクスポート処理のサービスとメール送信の流れを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | export_csv_service.rb | `app/services/work_items/export_csv_service.rb` | emailメソッド、header_to_value_hash |

**読解のコツ**: 基底クラスExportCsv::BaseServiceの継承関係に注目

**主要処理フロー**:
1. **10-12行目**: emailメソッドでNotify.export_work_items_csv_email呼び出し
2. **24-42行目**: header_to_value_hashでエクスポート列定義

#### Step 2: メーラー実装を理解する

メール本文生成ロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | work_items.rb | `app/mailers/emails/work_items.rb` | export_work_items_csv_emailメソッド |

**主要処理フロー**:
- **15-17行目**: csv_emailメソッド呼び出しで共通処理に委譲

#### Step 3: テンプレートを理解する

メール本文テンプレートを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | export_work_items_csv_email.text.erb | `app/views/notify/export_work_items_csv_email.text.erb` | 共通テンプレートのrender |
| 3-2 | _issuable_csv_export.text.erb | `app/views/notify/_issuable_csv_export.text.erb` | 共通エクスポートテンプレート |

**主要処理フロー**:
- **1行目**: render 'issuable_csv_export'で共通テンプレート呼び出し
- **共通テンプレート3行目**: エクスポート結果メッセージ
- **共通テンプレート5-7行目**: 切り詰め時のメッセージ

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

```
WorkItems::ExportCsvService#execute
    │
    ├─ csv_builder
    │      ├─ header_to_value_hash
    │      └─ CSV生成
    │
    └─ email(mail_to_user)
           │
           └─ Notify.export_work_items_csv_email.deliver_now
                  │
                  ├─ csv_email (共通メソッド)
                  │      ├─ 添付ファイル追加
                  │      └─ email_with_layout
                  │
                  └─ render 'issuable_csv_export'
```

### データフロー図

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

エクスポートリクエスト ──────▶ ExportCsvService
                                      │
Work Items ────────────────────────▶ CSV生成
    │                                 │
    ├─ id, iid, title ────────────────┤
    ├─ description ───────────────────┤
    ├─ state, confidential ───────────┤
    ├─ author, assignees ─────────────┤
    ├─ milestone, labels ─────────────┤
    ├─ dates ─────────────────────────┤
    ├─ parent item ───────────────────┤
    └─ time tracking ─────────────────┤
                                      │
mail_to_user ──────────────────┬──────▼
project ───────────────────────┤ Notify.export_work_items_csv_email ──▶ メール送信
csv_data ──────────────────────┤                                       │
export_status ─────────────────┤                                       ├─ 添付CSV
    ├─ :truncated ─────────────┤                                       │
    └─ :size_limit ────────────┘                                       │
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| export_csv_service.rb | `app/services/work_items/export_csv_service.rb` | ソース | CSVエクスポートサービス |
| work_items.rb | `app/mailers/emails/work_items.rb` | ソース | メーラーメソッド定義 |
| export_work_items_csv_email.text.erb | `app/views/notify/export_work_items_csv_email.text.erb` | テンプレート | メール本文テンプレート |
| _issuable_csv_export.text.erb | `app/views/notify/_issuable_csv_export.text.erb` | テンプレート | 共通エクスポートテンプレート |
| base_service.rb | `app/services/export_csv/base_service.rb` | ソース | CSVエクスポートの基底クラス |
