# 機能設計書 148-バッジ管理

## 概要

本ドキュメントは、GitLabのバッジ管理機能に関する設計書である。バッジ管理機能はプロジェクトやグループのステータスバッジ（パイプライン状態、カバレッジ、リリース情報等）をSVG形式で生成・表示する。

### 本機能の処理概要

バッジ管理機能は、プロジェクトの状態を視覚的に表示するためのステータスバッジを生成する。パイプラインの実行状態、テストカバレッジ率、最新リリース情報などをSVG形式の画像として動的に生成し、READMEファイルやプロジェクトページに埋め込むことができる。

**業務上の目的・背景**：プロジェクトの品質や状態を一目で把握できるようにするため、ステータスバッジを提供する。外部サービス（GitHub等）で一般的に使われているバッジ形式を採用し、READMEファイルに埋め込むことでプロジェクトの信頼性や品質を可視化する。

**機能の利用シーン**：
- READMEファイルへのCI/CDパイプラインステータスバッジ埋め込み
- プロジェクトのテストカバレッジ率の表示
- 最新リリースバージョンの表示
- 外部ドキュメントやウェブサイトでのプロジェクト状態表示
- カスタムバッジによる任意情報の表示

**主要な処理内容**：
1. パイプラインステータスバッジの生成
2. カバレッジバッジの生成
3. リリースバッジの生成
4. カスタムバッジの生成
5. SVG形式でのレンダリング

**関連システム・外部連携**：
- CI/CDパイプラインシステム
- カバレッジレポート
- リリース管理システム

**権限による制御**：
- パイプライン/カバレッジバッジ: read_build権限が必要
- 設定画面（index）: admin_project権限が必要
- リリースバッジ: プロジェクトへの読み取り権限

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 120 | バッジ一覧 | 主機能 | プロジェクトバッジの設定 |
| 178 | バッジ一覧 | 主機能 | グループバッジの設定 |

## 機能種別

画像生成 / APIエンドポイント

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ref | String | No | ブランチ/タグ参照 | 有効な参照名 |
| job | String | No | ジョブ名（カバレッジ用） | ジョブ名文字列 |
| style | String | No | バッジスタイル（flat, flat-square） | 許可値のみ |
| key_text | String | No | キー部分のカスタムテキスト | 文字列 |
| key_width | Integer | No | キー部分の幅 | 正の整数 |
| key_color | String | No | キー部分の色（カスタムバッジ） | 色コード |
| value_text | String | No | 値部分のカスタムテキスト | 文字列 |
| value_width | Integer | No | 値部分の幅 | 正の整数 |
| value_color | String | No | 値部分の色（カスタムバッジ） | 色コード |
| ignore_skipped | Boolean | No | スキップされたパイプラインを無視 | true/false |
| min_good | Integer | No | 良好判定の最小値（カバレッジ） | 0-100 |
| min_acceptable | Integer | No | 許容判定の最小値（カバレッジ） | 0-100 |
| min_medium | Integer | No | 中間判定の最小値（カバレッジ） | 0-100 |
| order_by | String | No | リリースの並び順 | released_at等 |

### 入力データソース

- URLパラメータ
- CI/CDパイプラインステータス
- カバレッジレポート
- リリース情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| SVGバッジ | XML/SVG | ステータスバッジ画像 |

### 出力先

- HTTPレスポンス（image/svg+xml）

## 処理フロー

### 処理シーケンス

```
1. バッジリクエスト受信
   └─ /badges/:ref/pipeline.svg 等

2. キャッシュヘッダ設定
   └─ no_cache_headers

3. 権限確認（必要な場合）
   └─ authorize_read_build! または authorize_admin_project!

4. バッジオブジェクト生成
   └─ Gitlab::Ci::Badge::Pipeline::Status 等

5. SVGテンプレートレンダリング
   └─ badge または badge_flat-square レイアウト

6. レスポンス返却
   └─ format.svg でSVG出力
```

### フローチャート

```mermaid
flowchart TD
    A[バッジリクエスト] --> B{バッジ種別}

    B -->|pipeline| C[パイプラインステータス取得]
    B -->|coverage| D[カバレッジ情報取得]
    B -->|release| E[リリース情報取得]
    B -->|custom| F[カスタムパラメータ取得]

    C --> G{権限確認}
    D --> G
    E --> H[バッジ生成]
    F --> I{Feature Flag確認}

    G -->|OK| H
    G -->|NG| J[404エラー]

    I -->|有効| H
    I -->|無効| J

    H --> K{スタイル判定}
    K -->|flat| L[badge テンプレート]
    K -->|flat-square| M[badge_flat-square テンプレート]

    L --> N[SVGレスポンス]
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-148-01 | パイプライン権限 | pipeline/coverageバッジにはread_build権限が必要 | pipeline, coverageアクション |
| BR-148-02 | 設定画面権限 | バッジ設定画面にはadmin_project権限が必要 | indexアクション |
| BR-148-03 | スタイル選択 | flat または flat-square スタイルを選択可能 | 全バッジ |
| BR-148-04 | カスタムバッジ制限 | カスタムバッジはFeature Flagで制御 | customアクション |
| BR-148-05 | キャッシュ無効 | バッジは常に最新状態を表示（キャッシュなし） | 全バッジ |

### 計算ロジック

**パイプラインステータス取得**:
```ruby
pipelines = project.ci_pipelines.for_ref(ref).order_id_desc
pipelines = pipelines.without_statuses([:skipped]) if ignore_skipped
status = pipelines.pick(:status) || 'unknown'
```

**カバレッジ色判定**:
- カバレッジ率に応じて色が変化
- min_good以上: 緑
- min_acceptable以上: 黄
- min_medium以上: オレンジ
- それ以下: 赤

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| パイプライン取得 | ci_pipelines | SELECT | 最新パイプラインステータス取得 |
| カバレッジ取得 | ci_builds | SELECT | カバレッジ率取得 |
| リリース取得 | releases | SELECT | 最新リリース情報取得 |

### テーブル別操作詳細

#### ci_pipelines

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | status | ref = :ref ORDER BY id DESC | パイプラインステータス取得 |

#### releases

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | tag | ORDER BY released_at DESC | 最新リリース取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | Not Found | HTML形式でアクセス | render_404 |
| 404 | Not Found | カスタムバッジのFeature Flag無効 | render_404 |

### リトライ仕様

特になし

## トランザクション仕様

読み取り専用のためトランザクション管理不要

## パフォーマンス要件

- no_cache_headers によりキャッシュ無効（常に最新表示）
- feature_category: continuous_integration, groups_and_projects, code_testing, release_orchestration

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

- read_build権限によるパイプライン/カバレッジ情報保護
- admin_project権限による設定画面保護
- Feature Flagによるカスタムバッジ制御

## 備考

- SVG形式で動的にバッジを生成
- 2種類のスタイル（flat, flat-square）をサポート
- カスタムバッジは実験的機能（Feature Flag: custom_project_badges）

---

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

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

### 推奨読解順序

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

メインコントローラの処理フローを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | badges_controller.rb | `app/controllers/projects/badges_controller.rb` | バッジ生成のエントリーポイント |

**主要処理フロー**:
1. **5行目**: authorize_admin_project! - 設定画面の権限確認
2. **6行目**: no_cache_headers - キャッシュ無効化
3. **7行目**: authorize_read_build! - ビルド読み取り権限
4. **14-23行目**: pipeline アクション - パイプラインバッジ生成
5. **25-37行目**: coverage アクション - カバレッジバッジ生成
6. **39-49行目**: release アクション - リリースバッジ生成
7. **51-65行目**: custom アクション - カスタムバッジ生成
8. **69-78行目**: badge_layout - スタイル判定
9. **80-87行目**: render_badge - SVGレンダリング

**読解のコツ**:
- 各アクションでBadgeクラスを生成し、render_badgeに渡す
- format.svgでSVG出力、format.htmlで404を返す

#### Step 2: バッジクラスを理解する

パイプラインバッジの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | status.rb | `lib/gitlab/ci/badge/pipeline/status.rb` | パイプラインステータスバッジ |

**主要処理フロー**:
1. **12-19行目**: initialize - オプション処理
2. **26-29行目**: status - ステータス取得

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

バッジのSVGテンプレートを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | badge.svg.erb | `app/views/projects/badges/badge.svg.erb` | flat スタイルテンプレート |
| 3-2 | badge_flat-square.svg.erb | `app/views/projects/badges/badge_flat-square.svg.erb` | flat-square スタイルテンプレート |

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

```
Projects::BadgesController
    │
    ├─ pipeline
    │      └─ Gitlab::Ci::Badge::Pipeline::Status.new(project, ref, opts)
    │             ├─ status (パイプラインステータス取得)
    │             ├─ metadata
    │             └─ template
    │
    ├─ coverage
    │      └─ Gitlab::Ci::Badge::Coverage::Report.new(project, ref, opts)
    │
    ├─ release
    │      └─ Gitlab::Ci::Badge::Release::LatestRelease.new(project, current_user, opts)
    │
    ├─ custom
    │      └─ Gitlab::Ci::Badge::Custom::CustomBadge.new(project, opts)
    │
    └─ render_badge(badge)
           └─ render badge_layout, locals: { badge: badge.template }
```

### データフロー図

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

GET /badges/:ref/       ───▶  BadgesController          ───▶  SVG画像
pipeline.svg                  ├─ Badge生成
                              ├─ ステータス取得
                              └─ SVGレンダリング

GET /badges/:ref/       ───▶  BadgesController          ───▶  SVG画像
coverage.svg                  ├─ Badge生成
                              ├─ カバレッジ取得
                              └─ SVGレンダリング
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| badges_controller.rb | `app/controllers/projects/badges_controller.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` | ライブラリ | カスタムバッジ |
| base.rb | `lib/gitlab/ci/badge/base.rb` | ライブラリ | バッジ基底クラス |
| badge.svg.erb | `app/views/projects/badges/badge.svg.erb` | ビュー | flat スタイルテンプレート |
| badge_flat-square.svg.erb | `app/views/projects/badges/badge_flat-square.svg.erb` | ビュー | flat-square スタイルテンプレート |
