# 画面設計書 250-ブロードキャストメッセージ一覧

## 概要

本ドキュメントは、GitLab管理者がシステム全体に表示するブロードキャストメッセージを管理する画面の設計書です。

### 本画面の処理概要

ブロードキャストメッセージ一覧画面は、GitLabインスタンス全体に表示するバナーや通知メッセージを作成・管理するための管理者専用画面です。

**業務上の目的・背景**：GitLab管理者は、計画メンテナンス、システムアップグレード、重要な通知などをユーザーに周知する必要があります。ブロードキャストメッセージ機能を使用することで、すべてのユーザーまたは特定の条件を満たすユーザーに対してバナー（画面上部）または通知（サイドバー）形式でメッセージを表示できます。

**画面へのアクセス方法**：
1. 管理者としてGitLabにログイン
2. 左サイドメニューから「Admin Area」をクリック
3. 「Messages」をクリック

**主要な操作・処理内容**：
1. 既存ブロードキャストメッセージの一覧表示
2. 新規メッセージの作成
3. メッセージの編集
4. メッセージの削除
5. メッセージのプレビュー

**画面遷移**：
- 遷移元：管理者ダッシュボード
- 遷移先：ブロードキャストメッセージ編集画面

**権限による表示制御**：管理者権限を持つユーザーのみがこの画面にアクセス可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 118 | ブロードキャストメッセージ | 主機能 | メッセージ一覧表示・管理 |

## 画面種別

一覧（作成機能も同一画面に含む）

## URL/ルーティング

- URL: `/admin/broadcast_messages`
- HTTP メソッド: GET（一覧表示）/ POST（作成）
- ルート名: `admin_broadcast_messages`

## 入出力項目

### 新規作成フォーム

| 項目名 | 項目ID | 型 | 必須 | バリデーション | 備考 |
|--------|--------|-----|------|----------------|------|
| メッセージ | message | Text | ○ | - | Markdown対応 |
| タイプ | broadcast_type | Enum | ○ | banner/notification | 表示形式 |
| テーマ | theme | Enum | ○ | 10種類 | バナーの色テーマ |
| 開始日時 | starts_at | DateTime | ○ | - | 表示開始日時 |
| 終了日時 | ends_at | DateTime | ○ | - | 表示終了日時 |
| ターゲットパス | target_path | String | - | - | 表示対象パス（ワイルドカード可） |
| ターゲットロール | target_access_levels | Array | - | ALLOWED_TARGET_ACCESS_LEVELS | 表示対象ロール |
| 閉じることを許可 | dismissable | Boolean | - | - | ユーザーが閉じられるか |
| CLIに表示 | show_in_cli | Boolean | - | - | Git CLIに表示するか |

## 表示項目

| 項目名 | 表示形式 | 備考 |
|--------|----------|------|
| ページタイトル | テキスト | "Broadcast Messages" |
| ページ説明 | テキスト | 説明文 |
| 新規作成フォーム | フォーム | Vue.jsコンポーネント |
| メッセージ一覧 | テーブル/カード | Vue.jsコンポーネント |
| ステータス | バッジ | Active/Expired/Pending |
| タイプ | バッジ | Banner/Notification |
| プレビュー | パネル | メッセージプレビュー |

### 一覧表示項目

| 項目名 | 説明 |
|--------|------|
| ステータス | Active/Expired/Pending |
| メッセージ | メッセージ本文 |
| テーマ | 色テーマ |
| タイプ | Banner/Notification |
| 対象ロール | 対象アクセスレベル |
| 対象パス | 表示対象パス |
| 開始日時 | 表示開始日時 |
| 終了日時 | 表示終了日時 |
| Actions | 編集・削除 |

## イベント仕様

### 1-メッセージ作成

**トリガー**: 「Add message」ボタンクリック

**処理フロー**:
1. フォームバリデーション
2. POSTリクエスト送信（JSON形式も対応）
3. `Admin::BroadcastMessagesController#create`呼び出し
4. `System::BroadcastMessage.new(broadcast_message_params)`
5. 保存
6. 成功: 一覧に追加、成功メッセージ
7. 失敗: エラーメッセージ表示

### 2-メッセージ編集

**トリガー**: 編集リンククリック

**処理フロー**: ブロードキャストメッセージ編集画面へ遷移

### 3-メッセージ削除

**トリガー**: 削除アイコンクリック

**処理フロー**:
1. DELETEリクエスト送信（JS形式）
2. `Admin::BroadcastMessagesController#destroy`呼び出し
3. メッセージ削除
4. 一覧から削除

### 4-プレビュー

**トリガー**: プレビューボタンクリック

**処理フロー**:
1. POSTリクエスト送信（`/admin/broadcast_messages/preview`）
2. `Admin::BroadcastMessagesController#preview`呼び出し
3. Banzaiでメッセージレンダリング
4. プレビューパネルに表示

### 5-ページネーション

**トリガー**: ページリンククリック

**処理フロー**:
1. pageパラメータを設定してGETリクエスト
2. 該当ページのメッセージ取得
3. 一覧再表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Add message | broadcast_messages | INSERT | メッセージ作成 |
| 編集保存 | broadcast_messages | UPDATE | メッセージ更新 |
| 削除 | broadcast_messages | DELETE | メッセージ削除 |

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

#### broadcast_messages (system_broadcast_messages)

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | message | フォーム入力値 | メッセージ本文 |
| INSERT | broadcast_type | フォーム選択値 | banner/notification |
| INSERT | theme | フォーム選択値 | 色テーマ |
| INSERT | starts_at | フォーム入力値 | 開始日時 |
| INSERT | ends_at | フォーム入力値 | 終了日時 |
| INSERT | target_path | フォーム入力値 | 対象パス |
| INSERT | target_access_levels | フォーム選択値 | 対象ロール配列 |
| INSERT | dismissable | フォームチェック状態 | 閉じ可否 |
| INSERT | show_in_cli | フォームチェック状態 | CLI表示 |
| INSERT | color | デフォルト値(#E75E40) | 背景色 |
| INSERT | font | デフォルト値(#FFFFFF) | 文字色 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 成功 | Broadcast Message was successfully created. | 作成成功時 |
| MSG002 | 成功 | Broadcast Message was successfully updated. | 更新成功時 |
| MSG003 | エラー | バリデーションエラーメッセージ | バリデーション失敗時 |

## 例外処理

| 例外条件 | 処理内容 | 表示メッセージ |
|----------|----------|---------------|
| 権限不足 | 403エラー画面へリダイレクト | アクセスが拒否されました |
| バリデーションエラー | エラーメッセージ表示 | 各フィールドのエラー |

## 備考

- Vue.jsコンポーネント（`#js-broadcast-messages`）でレンダリング
- メッセージはMarkdown形式をサポート
- テーマ: indigo, light-indigo, blue, light-blue, green, light-green, red, light-red, dark, light
- ターゲットパスはワイルドカード（`*`）使用可能
- ターゲットロール: Guest, Planner, Reporter, Developer, Maintainer, Owner
- 閉じられたメッセージはCookieで管理
- キャッシュはRedisで管理され、2週間保持
- 作成・更新時にキャッシュがフラッシュされる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | broadcast_message.rb | `app/models/system/broadcast_message.rb` | モデル定義、バリデーション、キャッシュ |

**読解のコツ**:
- `enum :theme`でテーマ定義確認
- `enum :broadcast_type`でタイプ定義確認
- `ALLOWED_TARGET_ACCESS_LEVELS`で対象ロール確認
- `current_banner_messages`/`current_notification_messages`でキャッシュ取得
- `flush_redis_cache`でキャッシュ無効化

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | broadcast_messages_controller.rb | `app/controllers/admin/broadcast_messages_controller.rb` | CRUD操作 |

**主要処理フロー**:
1. **7-8行目**: before_actionでメッセージロード
2. **13-15行目**: `index`アクション - 新規インスタンスとページング
3. **19-39行目**: `create`アクション - JSON/HTML対応
4. **41-59行目**: `update`アクション
5. **62-69行目**: `destroy`アクション
6. **71-74行目**: `preview`アクション

#### Step 3: ヘルパーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | broadcast_messages_helper.rb | `app/helpers/admin/broadcast_messages_helper.rb` | データシリアライズ |

**主要処理フロー**:
- **66-84行目**: `admin_broadcast_messages_data` - 一覧用データ生成
- **86-102行目**: `broadcast_message_data` - 編集用データ生成

#### Step 4: ビュー層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.html.haml | `app/views/admin/broadcast_messages/index.html.haml` | 一覧画面レイアウト |

**主要処理フロー**:
- **5行目**: ページ説明
- **7-13行目**: Vue.jsコンポーネントマウント（大量のdata属性）

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

```
ブラウザ (GET /admin/broadcast_messages)
    │
    ├─ before_action :find_broadcast_messages
    │      └─ System::BroadcastMessage.order(ends_at: :desc).page
    │
    └─ Admin::BroadcastMessagesController#index
           ├─ @broadcast_message = System::BroadcastMessage.new
           │
           └─ View: admin/broadcast_messages/index.html.haml
                  └─ Vue.js Component: #js-broadcast-messages
                         ├─ 新規作成フォーム
                         └─ メッセージ一覧

ブラウザ (POST /admin/broadcast_messages)
    │
    └─ Admin::BroadcastMessagesController#create
           ├─ System::BroadcastMessage.new(broadcast_message_params)
           ├─ @broadcast_message.save
           │      └─ after_commit :flush_redis_cache
           └─ JSON or HTML response
```

### データフロー図

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

フォームデータ ───────▶ BroadcastMessagesController ──▶ JSON/HTML応答
  - message                   #create
  - broadcast_type            │
  - theme                     ├─ BroadcastMessage.new
  - starts_at                 ├─ save
  - ends_at                   │     └─ flush_redis_cache
  - target_path               │
  - target_access_levels      └─ 成功/失敗レスポンス
  - dismissable
  - show_in_cli
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| broadcast_messages_controller.rb | `app/controllers/admin/broadcast_messages_controller.rb` | コントローラ | リクエスト処理 |
| broadcast_message.rb | `app/models/system/broadcast_message.rb` | モデル | データ定義、キャッシュ |
| broadcast_messages_helper.rb | `app/helpers/admin/broadcast_messages_helper.rb` | ヘルパー | データシリアライズ |
| index.html.haml | `app/views/admin/broadcast_messages/index.html.haml` | ビュー | 一覧画面 |
| edit.html.haml | `app/views/admin/broadcast_messages/edit.html.haml` | ビュー | 編集画面 |
| admin.rb | `config/routes/admin.rb` | 設定 | ルーティング |
| _broadcast_message.html.haml | `app/views/shared/_broadcast_message.html.haml` | パーシャル | メッセージ表示 |
