# 画面設計書 204-通知設定

## 概要

本ドキュメントは、GitLabの通知設定画面について定義する。グローバル通知レベル、グループ別通知設定、プロジェクト別通知設定など、メール通知の受信設定を管理する。

### 本画面の処理概要

本画面は、GitLabからのメール通知の受信設定を一元管理する画面である。グローバル通知レベルの設定、自分のアクティビティに対する通知の有無、グループ単位・プロジェクト単位での詳細な通知レベル設定を提供する。

**業務上の目的・背景**：開発チームでは、Issue、マージリクエスト、パイプライン結果など多様なイベントに関する通知が発生する。すべての通知を受け取ると情報過多になり、重要な通知を見逃す可能性がある。本画面では、通知レベル（Watch/Participating/Mention/Disabled/Custom）をグローバル、グループ、プロジェクト単位で設定し、必要な情報のみを受け取れるようにする。

**画面へのアクセス方法**：
1. 右上のユーザーアバターをクリック → 「Preferences」を選択 → 「Notifications」を選択
2. または「Edit profile」→ 左側メニューから「Notifications」を選択
3. 直接URL: `/-/profile/notifications`

**主要な操作・処理内容**：
1. グローバル通知レベルの設定（Watch/Participating/Mention/Disabled/Custom）
2. 自分のアクティビティに対する通知の有無設定
3. グループ別通知レベルの設定
4. プロジェクト別通知レベルの設定
5. EE版：通知メールアドレスの設定

**画面遷移**：
- 遷移元：プロフィール編集画面、ヘッダーメニュー、プロジェクト/グループ設定
- 遷移先：各グループ詳細画面、各プロジェクト詳細画面

**権限による表示制御**：
- ログインユーザーのみアクセス可能
- グループ/プロジェクトの通知設定はメンバーとして参加しているものみ表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 83 | 通知設定 | 主機能 | 通知設定の管理 |
| 137 | メール通知 | 補助機能 | 通知メールの送信制御 |

## 画面種別

設定（一覧・編集複合）

## URL/ルーティング

- **URL**: `/-/profile/notifications`
- **HTTPメソッド**: GET（表示）、PUT（更新）
- **ルーティング**: `profiles/notifications#show`、`profiles/notifications#update`

## 入出力項目

| 項目名 | 項目種別 | データ型 | 必須 | 説明 |
|--------|----------|----------|------|------|
| notification_email | フォーム | String | - | 通知用メールアドレス（EE版） |
| notified_of_own_activity | フォーム | Boolean | - | 自分のアクティビティ通知 |
| level | フォーム | String | - | グローバル通知レベル |

## 表示項目

| 項目名 | 表示内容 | データソース |
|--------|----------|--------------|
| エラーメッセージ | バリデーションエラー | @user.errors |
| グローバル通知レベル | 現在の通知レベル | @global_notification_setting.level |
| 通知レベル選択肢 | Watch/Participating/Mention/Disabled/Custom | notification_dropdown_items |
| グループ一覧 | 参加グループと通知設定 | @group_notifications |
| グループ総数 | 参加グループ数 | @user_groups.total_count |
| プロジェクト一覧 | 参加プロジェクトと通知設定 | @project_notifications |
| プロジェクト数 | 通知設定されたプロジェクト数 | @project_notifications.size |

## イベント仕様

### 1-グローバル通知レベル変更

**処理内容**：
1. Vue.jsコンポーネント（.js-vue-notification-dropdown）で通知レベルを選択
2. 選択後、通知設定APIを呼び出し
3. グローバル通知レベルを更新

### 2-自分のアクティビティ通知設定変更

**処理内容**：
1. チェックボックスの変更でフォーム送信
2. PUTリクエストを`/-/profile/notifications`に送信
3. `Users::UpdateService`で設定を保存
4. 成功時：「Notification settings saved」メッセージ
5. 失敗時：「Failed to save new settings」メッセージ
6. 画面にリダイレクト

### 3-グループ通知設定変更

**処理内容**：
1. 各グループ行の通知レベルドロップダウンで変更
2. グループ単位のNotificationSettingを更新
3. パーシャル（_group_settings）で表示

### 4-プロジェクト通知設定変更

**処理内容**：
1. 各プロジェクト行の通知レベルドロップダウンで変更
2. プロジェクト単位のNotificationSettingを更新
3. パーシャル（_project_settings）で表示

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| グローバル通知レベル変更 | notification_settings | UPDATE | グローバル設定更新 |
| 自分のアクティビティ通知変更 | users | UPDATE | notified_of_own_activity更新 |
| グループ通知設定変更 | notification_settings | UPDATE/INSERT | グループ別設定更新 |
| プロジェクト通知設定変更 | notification_settings | UPDATE/INSERT | プロジェクト別設定更新 |

### テーブル別更新項目詳細

#### notification_settings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | level | 選択された通知レベル | global/watch/participating/mention/disabled/custom |
| UPDATE | notification_email | 選択されたメールアドレス | EE版のみ |
| UPDATE | 各イベントフラグ | true/false | customレベル時の個別設定 |

#### users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | notified_of_own_activity | true/false | チェックボックスの値 |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|----------|----------|
| 成功 | Notification settings saved | 設定保存成功時 |
| エラー | Failed to save new settings | 設定保存失敗時 |
| 情報 | You do not belong to any groups yet. | グループ未参加時 |
| 情報 | You do not belong to any projects yet. | プロジェクト未参加時 |
| 情報 | To specify the notification level per project of a group you belong to, visit the project page and change the notification level there. | プロジェクト設定の補足説明 |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| バリデーションエラー | エラーメッセージをアラートで表示 |
| 権限不足（グループ/プロジェクト） | 通知設定から除外（表示しない） |

## 備考

- グローバル設定が適用されるのは、グループ/プロジェクト単位で設定されていない場合
- グループは名前順でソート、ページネーション対応
- プロジェクト通知設定は最大500件まで表示
- 通知レベル「Custom」では個別イベントごとの通知設定が可能
- EE版ではグループ別の通知メールアドレス設定が可能

---

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

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

### 推奨読解順序

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

通知設定の構造とユーザーとの関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | notification_setting.rb | `app/models/notification_setting.rb` | NotificationSettingモデル、levelのenum定義、EMAIL_EVENTS |
| 1-2 | user.rb | `app/models/user.rb` | global_notification_setting、notified_of_own_activity |

**読解のコツ**: NotificationSettingはpolymorphic association（source）を使い、グローバル/グループ/プロジェクト設定を同一テーブルで管理。

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

コントローラーの処理フローを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | notifications_controller.rb | `app/controllers/profiles/notifications_controller.rb` | show、updateアクション |

**主要処理フロー**:
1. **7-13行目**: show - 各種通知設定の取得
2. **8-9行目**: user_groups、group_notifications取得
3. **10-11行目**: project_notifications取得
4. **12行目**: グローバル通知設定取得
5. **15-25行目**: update - 設定更新処理

#### Step 3: ビューレイヤーを理解する

画面の構成を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/profiles/notifications/show.html.haml` | 各セクションの構成 |
| 3-2 | _group_settings.html.haml | `app/views/profiles/notifications/_group_settings.html.haml` | グループ設定パーシャル |
| 3-3 | _project_settings.html.haml | `app/views/profiles/notifications/_project_settings.html.haml` | プロジェクト設定パーシャル |

**主要処理フロー**:
- **1-9行目**: エラー表示
- **11行目**: hidden_field（notification_type: global）
- **19-20行目**: EE版メール設定
- **22-28行目**: グローバル通知レベル設定
- **30-32行目**: 自分のアクティビティ通知設定
- **34-47行目**: グループ通知設定一覧
- **49-61行目**: プロジェクト通知設定一覧

#### Step 4: 通知レベル選択コンポーネントを理解する

Vue.jsコンポーネントの動作を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | notification_dropdown.vue | `app/assets/javascripts/notifications/components/` | 通知レベルドロップダウン |

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

```
NotificationsController#show
    │
    ├─ user_groups（GroupsFinder）
    │      └─ order_name_asc.page
    │
    ├─ UserGroupNotificationSettingsFinder#execute
    │      └─ @group_notifications
    │
    ├─ project_notifications_with_preloaded_associations
    │      ├─ notification_settings.for_projects
    │      ├─ preload_source_route
    │      └─ UserMaxAccessLevelInProjectsPreloader
    │
    └─ global_notification_setting
           └─ NotificationSetting（source: nil）

NotificationsController#update
    │
    ├─ user_params（notification_email, notified_of_own_activity）
    │
    └─ Users::UpdateService#execute
           └─ User#update
```

### データフロー図

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

GET /profile/notifications
         │
         ▼
  NotificationsController#show
         │
         ├─ GroupsFinder ─────────▶ @user_groups
         │
         ├─ UserGroupNotificationSettingsFinder ──▶ @group_notifications
         │
         ├─ notification_settings.for_projects ──▶ @project_notifications
         │
         └─ global_notification_setting ──▶ @global_notification_setting
                                                      │
                                                      ▼
                                              show.html.haml
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| notifications_controller.rb | `app/controllers/profiles/notifications_controller.rb` | コントローラー | 通知設定の処理制御 |
| show.html.haml | `app/views/profiles/notifications/show.html.haml` | ビュー | 通知設定画面のレンダリング |
| _group_settings.html.haml | `app/views/profiles/notifications/_group_settings.html.haml` | パーシャル | グループ通知設定行 |
| _project_settings.html.haml | `app/views/profiles/notifications/_project_settings.html.haml` | パーシャル | プロジェクト通知設定行 |
| notification_setting.rb | `app/models/notification_setting.rb` | モデル | 通知設定データの永続化 |
| user_group_notification_settings_finder.rb | `app/finders/user_group_notification_settings_finder.rb` | ファインダー | グループ通知設定検索 |
| profile.rb | `config/routes/profile.rb` | ルーティング | URLルーティング定義 |
