# 通知設計書 125-notify (AbuseReportMailer)

## 概要

本ドキュメントは、GitLabにおける「不正利用報告通知」メールの設計を記載します。ユーザーが他のユーザーを不正利用として報告した際に、管理者に通知されるメールです。

### 本通知の処理概要

本通知は、GitLabユーザーが別のユーザーを「スパム」「攻撃的」「フィッシング」などの理由で不正利用として報告した際に、設定された管理者メールアドレスに通知を送信する機能です。

**業務上の目的・背景**：GitLabはコミュニティプラットフォームとして、利用規約に違反する行為（スパム投稿、攻撃的なコンテンツ、フィッシング、暗号通貨マイニング、認証情報の漏洩、著作権侵害、マルウェア配布など）を行うユーザーへの対処が必要です。本通知は、一般ユーザーからの報告を管理者に迅速に伝え、適切な対応（警告、アカウント停止など）を可能にします。

**通知の送信タイミング**：AbuseReportモデルが保存された後、`notify`メソッドが呼び出された際に非同期で送信されます。

**通知の受信者**：GitLabインスタンスの`abuse_notification_email`に設定されたメールアドレスに送信されます。これは通常、管理者またはセキュリティチームのメールアドレスです。

**通知内容の概要**：報告対象のユーザー情報、報告者情報、報告理由（カテゴリとメッセージ）、管理画面へのリンクが含まれます。

**期待されるアクション**：管理者は、報告内容を確認し、必要に応じて報告対象ユーザーに対して警告、アカウント停止、削除などの対応を行います。

## 通知種別

メール（Email）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（`deliver_later`） |
| 優先度 | 中 |
| リトライ | Sidekiqのデフォルトリトライに依存 |

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

`Gitlab::CurrentSettings.abuse_notification_email`に設定されたメールアドレスに送信されます。この設定が空の場合、メールは送信されません。

## 通知テンプレート

### メール通知の場合

| 項目 | 内容 |
|-----|------|
| 送信元アドレス | `Gitlab.config.gitlab.email_from` |
| 送信元名称 | `Gitlab.config.gitlab.email_display_name` |
| 件名 | `{報告対象ユーザー名} ({報告対象ユーザー名}) was reported for abuse` |
| 形式 | HTML/テキスト（マルチパート） |

### 本文テンプレート

**HTML版:**
```html
<p>
  <a href="{報告対象ユーザーURL}">{報告対象ユーザー名}</a>
  (@{報告対象ユーザーID}) was reported for abuse by
  <a href="{報告者URL}">{報告者名}</a>
  (@{報告者ID}).
</p>
<div class="blockquote">
  {報告メッセージ}
</div>
<p>
  <a href="{管理画面URL}">View details</a>
</p>
```

**テキスト版:**
```
{報告対象ユーザー名} (@{報告対象ユーザーID}) was reported for abuse by {報告者名} (@{報告者ID}).

> {報告メッセージ}

View details: {管理画面URL}
```

### 添付ファイル

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

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| @abuse_report | 不正利用報告 | AbuseReportモデル | Yes |
| @abuse_report.user | 報告対象ユーザー | users（関連） | Yes |
| @abuse_report.user.name | 報告対象ユーザー名 | users.name | Yes |
| @abuse_report.user.username | 報告対象ユーザーID | users.username | Yes |
| @abuse_report.reporter | 報告者 | users（関連） | Yes |
| @abuse_report.reporter.name | 報告者名 | users.name | Yes |
| @abuse_report.reporter.username | 報告者ID | users.username | Yes |
| @abuse_report.message | 報告メッセージ | abuse_reports.message | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| モデルメソッド | AbuseReport#notify | abuse_notification_emailが設定されており、レコードが永続化済み | 不正利用報告が作成された後 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `abuse_notification_email`が未設定 | インスタンス設定で通知先メールアドレスが空の場合 |
| レコードが未永続化 | `persisted?`がfalseの場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ユーザーが不正利用報告を送信] --> B[AbuseReport.create]
    B --> C[AbuseReport#notify 呼び出し]
    C --> D{persisted?}
    D -->|No| E[処理終了]
    D -->|Yes| F{abuse_notification_email設定あり?}
    F -->|No| G[処理終了（return）]
    F -->|Yes| H[AbuseReportMailer.notify.deliver_later]
    H --> I[メール送信]
    I --> J[終了]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| abuse_reports | 報告情報の取得 | message |
| users | 報告対象・報告者情報 | name, username |
| application_settings | 通知先メールアドレス | abuse_notification_email |

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

#### abuse_reports

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | レコード識別 | find(abuse_report_id) |
| message | 報告メッセージ | 本文に表示 |
| user_id | 報告対象ユーザー | belongs_to :user |
| reporter_id | 報告者 | belongs_to :reporter |

#### users

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| name | ユーザー表示名 | 件名・本文に表示 |
| username | ユーザーID | 件名・本文に表示 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | メール送信のみで、DB更新は行わない |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| レコード未存在 | 無効なabuse_report_idが渡された | ActiveRecord::RecordNotFoundが発生 |
| 送信失敗 | SMTPサーバー接続エラー | Sidekiqリトライに依存 |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（報告作成時に即座にキューイング）

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

- 報告者と報告対象者の情報が含まれるため、管理者以外には送信しない
- `abuse_notification_email`の設定は管理者権限が必要
- 報告メッセージにはユーザー入力が含まれるため、XSS対策が必要（テンプレートでエスケープ済み）

## 備考

- 報告カテゴリ（spam, offensive, phishing, crypto, credentials, copyright, malware, other）は件名やメール本文には含まれない
- 詳細な報告内容は管理画面で確認する必要がある
- スクリーンショットが添付されている場合も、メールには含まれない（管理画面で確認）

---

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

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

### 推奨読解順序

#### Step 1: モデルのトリガーを理解する

通知のトリガーとなるAbuseReportモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | abuse_report.rb | `app/models/abuse_report.rb` | `notify`メソッドの定義、`deliver_later`の呼び出し |

**主要処理フロー**:
1. **行117-121**: `notify`メソッドの定義
2. **行118**: `persisted?`チェックで未保存レコードをスキップ
3. **行120**: `AbuseReportMailer.notify(id).deliver_later`で非同期送信

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | abuse_report_mailer.rb | `app/mailers/abuse_report_mailer.rb` | `notify`メソッド、`deliverable?`条件 |

**主要処理フロー**:
1. **行8-17**: `notify`メソッドの定義
2. **行9**: `deliverable?`で送信可能かチェック
3. **行11**: `AbuseReport.find(abuse_report_id)`でレポート取得
4. **行13-16**: `mail_with_locale`でメール送信

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | notify.html.haml | `app/views/abuse_report_mailer/notify.html.haml` | HTML版メールテンプレート |
| 3-2 | notify.text.haml | `app/views/abuse_report_mailer/notify.text.haml` | テキスト版メールテンプレート |

**主要処理フロー（HTML版）**:
- **行1-5**: 報告対象ユーザーと報告者の情報、リンク
- **行7-8**: 報告メッセージのブロック引用
- **行10-11**: 管理画面へのリンク

#### Step 4: テストから仕様を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | abuse_report_mailer_spec.rb | `spec/mailers/abuse_report_mailer_spec.rb` | テストケース |

**主要処理フロー**:
- **行26-29**: `abuse_notification_email`設定時の送信先検証
- **行31-32**: 件名のフォーマット検証
- **行36-43**: `abuse_notification_email`未設定時の送信スキップ検証

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

```
Controller (不正利用報告フォーム)
    │
    └─ AbuseReport.create
           │
           └─ AbuseReport#notify (コールバックまたは明示的呼び出し)
                  │
                  ├─ persisted? チェック
                  │
                  └─ AbuseReportMailer.notify(id).deliver_later
                         │
                         ├─ deliverable? チェック
                         │      └─ abuse_notification_email.present?
                         │
                         └─ mail_with_locale
                                └─ テンプレートレンダリング
                                       ├─ notify.html.haml
                                       └─ notify.text.haml
```

### データフロー図

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

ユーザー操作
(不正利用報告)   ───▶  AbuseReportsController
                              │
                              ▼
                        AbuseReport.create
                              │
                              ▼
                        AbuseReport#notify
                              │
                              ▼
                        AbuseReportMailer
                        .notify(id)
                        .deliver_later    ───▶  Sidekiqキュー
                                                    │
                                                    ▼
                                               メール送信
                                               (abuse_notification_email)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| abuse_report.rb | `app/models/abuse_report.rb` | ソース | AbuseReportモデル（通知トリガー） |
| abuse_report_mailer.rb | `app/mailers/abuse_report_mailer.rb` | ソース | AbuseReportメーラー |
| notify.html.haml | `app/views/abuse_report_mailer/notify.html.haml` | テンプレート | HTML版メールテンプレート |
| notify.text.haml | `app/views/abuse_report_mailer/notify.text.haml` | テンプレート | テキスト版メールテンプレート |
| abuse_report_mailer_spec.rb | `spec/mailers/abuse_report_mailer_spec.rb` | テスト | メーラーのテスト |
| abuse_report_spec.rb | `spec/models/abuse_report_spec.rb` | テスト | モデルのテスト |
