# 通知設計書 103-service_desk_verification_triggered_email

## 概要

本ドキュメントは、GitLabのService Deskカスタムメール機能において、カスタムメールの検証プロセスが開始されたことをプロジェクトオーナーおよびトリガーユーザーに通知するメールの設計を記載するものです。

### 本通知の処理概要

本通知は、Service Deskのカスタムメールアドレス検証が開始されたことを、プロジェクトオーナーと検証を開始したユーザーに知らせるための通知です。

**業務上の目的・背景**：Service Deskのカスタムメール設定は、プロジェクトのセキュリティに関わる重要な設定変更です。この設定変更が行われたことをプロジェクトオーナーに通知することで、不正な設定変更を早期に検知し、必要に応じて対応できるようにします。また、設定変更を行ったユーザー自身にも確認のために通知されます。

**通知の送信タイミング**：`ServiceDesk::CustomEmailVerifications::CreateService`において、検証状態が`started`に更新された直後、検証メールを送信する前に非同期で送信されます（47-51行目: `notify_project_owners_and_user_about_verification_start`）。

**通知の受信者**：プロジェクトのオーナー全員と、検証を開始した現在のユーザーです。メールアドレスが重複する場合は1通のみ送信されます。

**通知内容の概要**：誰がカスタムメール設定を更新し検証プロセスをトリガーしたか、設定されたカスタムメールアドレス、使用するSMTPホストの情報が含まれます。

**期待されるアクション**：受信者は通知内容を確認し、自分または権限のあるユーザーが正当に行った操作であることを確認します。心当たりがない場合は、設定を変更または無効化することが推奨されます。

## 通知種別

メール通知

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（deliver_later） |
| 優先度 | 高（セキュリティ関連通知） |
| リトライ | Sidekiqのデフォルト設定に準拠 |

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

1. `project.owners.map(&:email)`でプロジェクトオーナー全員のメールアドレスを取得
2. `current_user.email`を追加（検証をトリガーしたユーザー）
3. `uniq(&:downcase)`で重複を除去
4. 各メールアドレスに対して通知を送信

## 通知テンプレート

### メール通知の場合

| 項目 | 内容 |
|-----|------|
| 送信元アドレス | GitLabのデフォルトメールアドレス |
| 送信元名称 | GitLab |
| 件名 | `Verification for custom email {email} for {project_name} triggered` |
| 形式 | HTML/テキスト（マルチパート） |

### 本文テンプレート

#### HTML版（service_desk_verification_triggered_email.html.haml）
```
@{username} updated the custom email address credentials for the Service Desk of {project_name} and triggered the verification process.

The provided custom email address is {email_address} and uses the SMTP host {smtp_host}.

If this was a mistake you can change these settings or deactivate the custom email address in the project settings.
```

#### テキスト版（service_desk_verification_triggered_email.text.erb）
```
@{username} updated the custom email address credentials for the Service Desk of {project_name} and triggered the verification process.

The provided custom email address is {email_address} and uses the SMTP host {smtp_host}.

If this was a mistake you can change these settings or deactivate the custom email address in the project settings.
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | 本通知には添付ファイルはありません |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| @service_desk_setting | Service Desk設定 | 引数として渡される | Yes |
| @triggerer | 検証をトリガーしたユーザー | @service_desk_setting.custom_email_verification.triggerer | Yes |
| @smtp_address | SMTPサーバーアドレス | @service_desk_setting.custom_email_credential.smtp_address | Yes |
| user_name | トリガーユーザーのusername | '@' + @triggerer.username | Yes |
| project_link | プロジェクトURL | @service_desk_setting.project.web_url | Yes |
| project_name | プロジェクト名 | @service_desk_setting.project.human_name | Yes |
| email_address | カスタムメールアドレス | @service_desk_setting.custom_email | Yes |
| smtp_host | SMTPホスト | @smtp_address | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作/API | ServiceDesk::CustomEmailVerifications::CreateService.execute | 検証状態がstartedに更新された後 | カスタムメール検証開始時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | 検証開始が成功した場合は必ず送信される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[CreateService.execute] --> B[update_settings]
    B --> C[verification.mark_as_started!]
    C --> D[notify_project_owners_and_user_about_verification_start]
    D --> E[BaseService#notify_project_owners_and_user_with_email]
    E --> F[project.owners.map&:email 取得]
    F --> G[current_user.email 追加]
    G --> H[重複除去 uniq&:downcase]
    H --> I{各メールアドレスに対して}
    I --> J[Notify.service_desk_verification_triggered_email]
    J --> K[deliver_later]
    K --> I
    I --> L[検証メール送信処理へ]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| service_desk_settings | カスタムメール設定の取得 | |
| service_desk_custom_email_verifications | 検証情報の取得（triggerer） | |
| service_desk_custom_email_credentials | SMTP設定の取得 | |
| projects | プロジェクト情報の取得 | |
| users | オーナーユーザー情報の取得 | |
| members | プロジェクトオーナーの特定 | |

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

#### service_desk_settings

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| custom_email | カスタムメールアドレス | |
| project_id | プロジェクトID | |

#### service_desk_custom_email_verifications

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| triggerer_id | トリガーユーザーID | |

#### service_desk_custom_email_credentials

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| smtp_address | SMTPサーバーアドレス | |

#### users（オーナー・トリガーユーザー）

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| email | 通知送信先 | |
| username | 本文表示用 | |

### 更新テーブル一覧

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

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 送信失敗 | SMTP接続エラー等 | Sidekiqによるリトライ |
| テンプレートエラー | ビューのレンダリングエラー | エラーログ出力 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Sidekiqデフォルト（25回） |
| リトライ間隔 | 指数バックオフ |
| リトライ対象エラー | 一時的なネットワークエラー、SMTP接続エラー等 |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | GitLab全体のメール送信レート制限に準拠 |
| 1日あたり上限 | GitLab全体のメール送信レート制限に準拠 |

### 配信時間帯

特に制限なし（イベント発生時に即時送信）

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

- プロジェクトオーナーへの通知により、不正な設定変更を検知可能
- SMTPホスト情報を通知に含めることで、意図しない外部サーバーへの転送を確認可能
- 通知にはSMTP認証情報（パスワード等）は含まれない

## 備考

- 本通知は検証メール送信の前に送信される
- 検証プロセス全体の成否に関わらず、開始時点で必ず送信される
- プロジェクト設定ページへのリンクは含まれていないが、本文で設定変更を案内している

---

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

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

### 推奨読解順序

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

通知に必要なデータモデルの関連を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | service_desk_setting.rb | `app/models/service_desk_setting.rb` | custom_email_verification、custom_email_credentialとの関連 |
| 1-2 | custom_email_verification.rb | `app/models/service_desk/custom_email_verification.rb` | triggererアソシエーション |

**読解のコツ**: belongs_to/has_oneのアソシエーションを追跡し、データの取得パスを理解する。

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

通知送信のトリガーとなるサービスを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | create_service.rb | `app/services/service_desk/custom_email_verifications/create_service.rb` | notify_project_owners_and_user_about_verification_startの呼び出し |
| 2-2 | base_service.rb | `app/services/service_desk/custom_email_verifications/base_service.rb` | notify_project_owners_and_user_with_emailの実装 |

**主要処理フロー**:
1. **21行目**: notify_project_owners_and_user_about_verification_start呼び出し
2. **47-51行目**: notify_project_owners_and_user_about_verification_startの実装
3. **18-26行目（base_service.rb）**: notify_project_owners_and_user_with_emailの実装

#### Step 3: メーラーを理解する

通知メールの生成処理を確認します。

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

**主要処理フロー**:
- **119-130行目**: service_desk_verification_triggered_email
- **120行目**: @triggererの取得
- **122行目**: @smtp_addressの取得
- **124-127行目**: 件名の生成
- **129行目**: email_with_layout呼び出し

#### Step 4: ビューテンプレートを理解する

メール本文のテンプレートを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | service_desk_verification_triggered_email.html.haml | `app/views/notify/service_desk_verification_triggered_email.html.haml` | HTML形式の本文テンプレート |
| 4-2 | service_desk_verification_triggered_email.text.erb | `app/views/notify/service_desk_verification_triggered_email.text.erb` | テキスト形式の本文テンプレート |

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

```
ServiceDesk::CustomEmailVerifications::CreateService#execute
    │
    ├─ update_settings
    │      └─ verification.mark_as_started!(current_user)
    │
    └─ notify_project_owners_and_user_about_verification_start
           │
           └─ BaseService#notify_project_owners_and_user_with_email
                  │
                  ├─ project.owners.map(&:email)
                  │
                  ├─ user.email（current_user）
                  │
                  ├─ uniq(&:downcase)
                  │
                  └─ Notify.service_desk_verification_triggered_email(settings, email_address)
                         │
                         ├─ @service_desk_setting設定
                         │
                         ├─ @triggerer取得
                         │
                         ├─ @smtp_address取得
                         │
                         └─ email_with_layout
                                └─ deliver_later
```

### データフロー図

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

service_desk_setting    BaseService#notify_project          通知メール送信
（カスタムメール設定）───▶ _owners_and_user_with_email  ───▶ （各オーナー・トリガーユーザーへ）
                                   │
current_user                 ───▶  │
（トリガーユーザー）                │
                                   │
project.owners              ───▶   │
（プロジェクトオーナー）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| create_service.rb | `app/services/service_desk/custom_email_verifications/create_service.rb` | ソース | 検証開始サービス（通知トリガー） |
| base_service.rb | `app/services/service_desk/custom_email_verifications/base_service.rb` | ソース | 通知送信の共通処理 |
| service_desk.rb | `app/mailers/emails/service_desk.rb` | ソース | Service Deskメーラー |
| service_desk_verification_triggered_email.html.haml | `app/views/notify/service_desk_verification_triggered_email.html.haml` | テンプレート | HTML本文テンプレート |
| service_desk_verification_triggered_email.text.erb | `app/views/notify/service_desk_verification_triggered_email.text.erb` | テンプレート | テキスト本文テンプレート |
| service_desk_setting.rb | `app/models/service_desk_setting.rb` | ソース | Service Desk設定モデル |
| custom_email_verification.rb | `app/models/service_desk/custom_email_verification.rb` | ソース | 検証状態モデル |
