# 画面設計書 120-バッジ一覧

## 概要

本ドキュメントは、GitLabのプロジェクト設定におけるバッジ一覧画面の設計仕様を記載したものである。

### 本画面の処理概要

バッジ一覧画面は、プロジェクトに設定されているバッジの管理を行うための画面である。バッジはプロジェクトの状態（パイプラインステータス、カバレッジ、リリースバージョンなど）を外部に可視化するためのSVG画像である。

**業務上の目的・背景**：プロジェクトのREADMEや外部サイトにバッジを埋め込むことで、プロジェクトの状態を一目で確認できるようにすることが目的である。カスタムバッジを作成することで、プロジェクト固有の情報も表示可能である。

**画面へのアクセス方法**：プロジェクトのサイドバーから「設定」→「一般」を選択し、「バッジ」セクションへスクロールしてアクセスする。または、URL `/:namespace/:project/-/badges` に直接アクセスする。

**主要な操作・処理内容**：
1. プロジェクトバッジの一覧表示
2. 新規バッジの追加
3. 既存バッジの編集
4. バッジの削除
5. バッジのプレビュー表示
6. バッジURLのコピー

**画面遷移**：
- 遷移元：プロジェクト一般設定画面
- 遷移先：なし（同一画面で操作完結）

**権限による表示制御**：
- `admin_project` 権限：バッジ一覧画面へのアクセス、バッジの作成・編集・削除

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 46 | バッジ管理 | 主機能 | バッジの作成・編集・削除 |

## 画面種別

一覧（作成・編集機能付き）

## URL/ルーティング

- **URL**: `/:namespace/:project/-/badges`
- **HTTPメソッド**: GET
- **コントローラー**: `Projects::BadgesController`
- **アクション**: `index`
- **API**: REST API（バッジのCRUD操作）

### バッジ画像URL

| 種別 | URL形式 |
|-----|---------|
| パイプラインバッジ | `/:namespace/:project/badges/:ref/pipeline.svg` |
| カバレッジバッジ | `/:namespace/:project/badges/:ref/coverage.svg` |
| リリースバッジ | `/:namespace/:project/-/badges/release.svg` |
| カスタムバッジ | `/:namespace/:project/-/badges/custom.svg` |

## 入出力項目

### バッジ作成・編集フォーム

| 項目名 | 項目ID | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| 名前 | name | string | はい | バッジの名前（識別用） |
| リンクURL | link_url | string | はい | バッジクリック時の遷移先URL |
| 画像URL | image_url | string | はい | バッジ画像のURL |

### 利用可能なプレースホルダー

| プレースホルダー | 説明 |
|----------------|------|
| %{project_path} | プロジェクトのフルパス |
| %{project_title} | プロジェクトのタイトル |
| %{project_name} | プロジェクト名 |
| %{project_id} | プロジェクトID |
| %{project_namespace} | プロジェクトの名前空間 |
| %{group_name} | グループ名 |
| %{gitlab_server} | GitLabサーバーのホスト |
| %{gitlab_pages_domain} | GitLab Pagesのドメイン |
| %{default_branch} | デフォルトブランチ名 |
| %{commit_sha} | 最新コミットのSHA |
| %{latest_tag} | 最新タグ名 |

## 表示項目

### バッジ一覧

| 項目名 | 説明 |
|--------|------|
| バッジ名 | バッジの識別名 |
| プレビュー | バッジのSVG画像プレビュー |
| リンクURL | バッジクリック時の遷移先 |
| 画像URL | バッジ画像のソースURL |
| アクション | 編集・削除ボタン |

### 組み込みバッジ（システム提供）

| バッジ種別 | 説明 |
|-----------|------|
| パイプラインステータス | CI/CDパイプラインの状態を表示 |
| カバレッジレポート | コードカバレッジの割合を表示 |
| 最新リリース | 最新リリースのバージョンを表示 |

## イベント仕様

### 1-バッジ作成

バッジ作成フォームで「バッジを追加」ボタンを押下すると、新しいバッジが作成される。

- REST API `POST /api/v4/projects/:id/badges` が呼び出される
- 成功時：バッジ一覧に追加される
- 失敗時：エラーメッセージが表示される

### 2-バッジ編集

バッジ一覧の「編集」ボタンを押下すると、編集フォームが表示される。

- REST API `PUT /api/v4/projects/:id/badges/:badge_id` が呼び出される
- 成功時：バッジ情報が更新される
- 失敗時：エラーメッセージが表示される

### 3-バッジ削除

バッジ一覧の「削除」ボタンを押下すると、確認後にバッジが削除される。

- REST API `DELETE /api/v4/projects/:id/badges/:badge_id` が呼び出される
- 成功時：バッジ一覧から削除される
- 失敗時：エラーメッセージが表示される

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| バッジ作成 | badges | INSERT | バッジレコード作成 |
| バッジ編集 | badges | UPDATE | バッジ情報更新 |
| バッジ削除 | badges | DELETE | バッジレコード削除 |

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

#### badges

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | name | フォーム入力値 | バッジ名 |
| INSERT/UPDATE | link_url | フォーム入力値 | リンクURL |
| INSERT/UPDATE | image_url | フォーム入力値 | 画像URL |
| INSERT | project_id | プロジェクトID | プロジェクトバッジの場合 |
| INSERT | type | 'ProjectBadge' | STI型 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| MSG-120-01 | 成功 | Badge has been added. | バッジ作成成功時 |
| MSG-120-02 | 成功 | Badge has been updated. | バッジ更新成功時 |
| MSG-120-03 | 成功 | Badge has been deleted. | バッジ削除成功時 |
| MSG-120-04 | 情報 | No badges to display | バッジが未設定時 |
| MSG-120-05 | エラー | Link url is invalid | リンクURLが不正な場合 |
| MSG-120-06 | エラー | Image url is invalid | 画像URLが不正な場合 |

## 例外処理

| 例外状況 | 対応処理 |
|---------|---------|
| 権限不足 | アクセス拒否画面（403）を表示 |
| プロジェクト未検出 | Not Found画面（404）を表示 |
| バッジ未検出 | Not Found画面（404）を表示 |
| URL形式エラー | バリデーションエラーを表示 |

## 備考

- バッジはプロジェクトレベルとグループレベルで設定可能
- グループレベルのバッジは配下のすべてのプロジェクトに継承される
- プレースホルダーを使用してプロジェクト固有のURLを動的に生成可能
- SVG形式でバッジ画像を提供し、キャッシュ無効化ヘッダーを設定
- Vueコンポーネント（`#badge-settings`）でフロントエンド描画
- REST APIを使用してバッジのCRUD操作を実行
- `custom_project_badges`フィーチャーフラグでカスタムバッジ機能を制御

---

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

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

### 推奨読解順序

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

まず、バッジのデータモデルを理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | badge.rb | `app/models/badge.rb` | バッジの基底モデル、プレースホルダー定義 |
| 1-2 | project_badge.rb | `app/models/badges/project_badge.rb` | プロジェクトバッジのSTIモデル |

**読解のコツ**: `PLACEHOLDERS`定数でURLに埋め込めるプレースホルダーを定義。`rendered_link_url`、`rendered_image_url`でプレースホルダーを展開する。

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

処理の起点となるコントローラーを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | badges_controller.rb | `app/controllers/projects/badges_controller.rb` | 画面表示とバッジ画像生成 |

**主要処理フロー**:
1. **4行目**: `layout 'project_settings'`でプロジェクト設定レイアウト
2. **5行目**: `authorize_admin_project!`で権限確認（indexアクション）
3. **14-23行目**: `pipeline`アクションでパイプラインバッジSVG生成
4. **25-37行目**: `coverage`アクションでカバレッジバッジSVG生成
5. **39-49行目**: `release`アクションでリリースバッジSVG生成
6. **51-65行目**: `custom`アクションでカスタムバッジSVG生成

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

画面の構成要素を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/projects/settings/badges/index.html.haml` | 画面全体の構成 |
| 3-2 | _badge_settings.html.haml | `app/views/shared/badges/_badge_settings.html.haml` | バッジ設定パーシャル |

**主要処理フロー**:
- **index 1-2行目**: パンくずリストとページタイトル
- **index 4行目**: shared/badges/badge_settingsパーシャルをレンダリング
- **_badge_settings 1行目**: `#badge-settings`でVueコンポーネントをマウント、APIエンドポイントをdata属性で渡す

#### Step 4: バッジ画像生成を理解する

バッジSVG画像の生成ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | status.rb | `lib/gitlab/ci/badge/pipeline/status.rb` | パイプラインステータスバッジ |
| 4-2 | report.rb | `lib/gitlab/ci/badge/coverage/report.rb` | カバレッジバッジ |
| 4-3 | latest_release.rb | `lib/gitlab/ci/badge/release/latest_release.rb` | リリースバッジ |

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

```
BadgesController#index (画面表示)
    │
    └─ render 'index'
           └─ render 'shared/badges/badge_settings'
                  └─ #badge-settings (Vue component)
                         │
                         └─ REST API calls
                                ├─ GET /api/v4/projects/:id/badges
                                ├─ POST /api/v4/projects/:id/badges
                                ├─ PUT /api/v4/projects/:id/badges/:badge_id
                                └─ DELETE /api/v4/projects/:id/badges/:badge_id

BadgesController#pipeline (バッジ画像)
    │
    └─ Gitlab::Ci::Badge::Pipeline::Status
           └─ render 'badge' (SVG)

BadgesController#coverage (バッジ画像)
    │
    └─ Gitlab::Ci::Badge::Coverage::Report
           └─ render 'badge' (SVG)
```

### データフロー図

```
[フロントエンド]               [バックエンド]                [データベース]

Vue Component ──────────▶ REST API ────────────────▶ badges テーブル
(#badge-settings)              │
       │                       │
       │                       └─ ProjectBadge model
       │                              │
       ▼                              └─ rendered_link_url
api_endpoint_url                      └─ rendered_image_url
(Vue props)                                 (プレースホルダー展開)

SVGバッジリクエスト
       │
       ▼
BadgesController ──────▶ Gitlab::Ci::Badge::*
       │                       │
       │                       └─ template (SVG生成)
       ▼
    SVG Response
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| badges_controller.rb | `app/controllers/projects/badges_controller.rb` | コントローラー | 画面表示・バッジSVG生成 |
| index.html.haml | `app/views/projects/settings/badges/index.html.haml` | ビュー | 画面テンプレート |
| _badge_settings.html.haml | `app/views/shared/badges/_badge_settings.html.haml` | ビュー | バッジ設定パーシャル |
| badge.rb | `app/models/badge.rb` | モデル | バッジ基底クラス |
| project_badge.rb | `app/models/badges/project_badge.rb` | モデル | プロジェクトバッジ |
| status.rb | `lib/gitlab/ci/badge/pipeline/status.rb` | バッジ | パイプラインステータス |
| report.rb | `lib/gitlab/ci/badge/coverage/report.rb` | バッジ | カバレッジレポート |
| latest_release.rb | `lib/gitlab/ci/badge/release/latest_release.rb` | バッジ | 最新リリース |
| custom_badge.rb | `lib/gitlab/ci/badge/custom/custom_badge.rb` | バッジ | カスタムバッジ |
| project.rb | `config/routes/project.rb` | 設定 | ルーティング定義 |
