# 画面設計書 37-タグ一覧

## 概要

本ドキュメントは、GitLabのリポジトリ内のタグを一覧表示する画面（タグ一覧画面）の設計を記述したものである。

### 本画面の処理概要

本画面は、リポジトリ内のすべてのタグを一覧表示し、タグの管理操作を提供する。タグはリリースポイントのマーキングに使用され、バージョン管理やデプロイの重要な参照点となる。RSSフィードによるタグ追加通知機能も提供する。

**業務上の目的・背景**：ソフトウェアリリース管理において、タグは特定のバージョンをマーキングする重要な機能である。本画面は、プロジェクト内のすべてのタグを把握し、リリース履歴の確認、特定バージョンのソースコードへのアクセス、タグの作成・削除などを効率的に行えるようにする。また、リリースとの連携により、変更履歴やアセットの管理も可能にする。

**画面へのアクセス方法**：
- プロジェクトナビゲーションの「Repository > Tags」
- ファイルツリー画面のタグセレクターから
- URL直接入力: `/{namespace}/{project}/-/tags`

**主要な操作・処理内容**：
1. タグ一覧の表示
2. タグの検索
3. タグのソート（名前順、更新日順）
4. 新規タグの作成
5. タグの削除
6. タグ詳細画面への遷移
7. リリース関連情報の表示

**画面遷移**：
- 遷移元: プロジェクト概要画面、リリース一覧画面、ファイルツリー画面
- 遷移先: タグ新規作成画面、タグ詳細画面、ファイルツリー画面、リリース詳細画面

**権限による表示制御**：
- リポジトリ読み取り権限がない場合はアクセス拒否
- タグ管理権限がない場合は作成・削除ボタンが非表示
- 保護タグの削除は権限による制限

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 20 | タグ管理 | 主機能 | リポジトリのタグ一覧表示 |
| 26 | 保護タグ | 補助機能 | 保護タグ設定表示 |
| 73 | リリース作成 | 遷移先機能 | リリース作成画面への遷移 |

## 画面種別

一覧

## URL/ルーティング

```
GET /{namespace}/{project}/-/tags
GET /{namespace}/{project}/-/tags.atom
DELETE /{namespace}/{project}/-/tags/:id
```

**ルート定義**: `config/routes/repository.rb`
```ruby
resources :tags, only: [:index, :show, :new, :create, :destroy]
```

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| namespace | 入力 | String | Yes | プロジェクトの名前空間 |
| project | 入力 | String | Yes | プロジェクト名 |
| search | 入力 | String | No | 検索キーワード |
| sort | 入力 | String | No | ソート順 |
| page | 入力 | Integer | No | ページ番号 |
| format | 入力 | String | No | 出力形式（html/atom） |

## 表示項目

| 項目名 | 説明 | データソース |
|--------|------|-------------|
| タグ名 | タグの名前 | tag.name |
| タグメッセージ | 注釈付きタグのメッセージ | tag.message |
| 作成者 | タグ作成者（注釈付き） | tag.user_email |
| 対象コミット | タグが指すコミット | tag.dereferenced_target |
| コミットメッセージ | コミットのメッセージ | commit.message |
| コミット日時 | コミット作成日時 | commit.committed_date |
| パイプラインステータス | CIパイプラインの状態 | @tag_pipeline_statuses |
| リリースリンク | 関連リリースへのリンク | @releases |
| 保護バッジ | 保護タグかどうか | protected_tag? |
| 署名情報 | タグの署名状態 | tag.has_signature? |

## イベント仕様

### 1-ページ読み込み

タグ一覧を取得し表示する。

**処理フロー**:
1. TagsFinderでタグ一覧を取得
2. ページネーション適用
3. 関連リリース情報の取得
4. パイプラインステータスの取得
5. タグがない場合は空状態を表示

### 2-New tagボタン押下

タグ新規作成画面へ遷移する。

**遷移先**: `/{namespace}/{project}/-/tags/new`

### 3-タグ削除ボタン押下

タグを削除する。

**処理フロー**:
1. 確認モーダル表示
2. Tags::DestroyServiceを実行
3. 成功/エラーメッセージ表示
4. 一覧を再表示

### 4-タグ名クリック

タグ詳細画面へ遷移する。

**遷移先**: `/{namespace}/{project}/-/tags/{tag_name}`

### 5-RSSフィードボタン押下

タグのRSSフィードを表示する。

**遷移先**: `/{namespace}/{project}/-/tags.atom`

### 6-検索実行

タグ名で検索する。

**処理**: `search`パラメータでフィルタリング

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| タグ削除 | events | INSERT | タグ削除イベントの記録 |
| タグ削除 | push_event_payloads | INSERT | 削除イベント詳細 |

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

#### events

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | action | 5 (PUSHED) | プッシュアクション |
| INSERT | author_id | current_user.id | 実行ユーザー |
| INSERT | project_id | @project.id | 対象プロジェクト |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|----------|
| M001 | 成功 | "Tag was deleted." | タグ削除成功 |
| M002 | エラー | "Failed to delete tag '...'" | タグ削除失敗 |
| M003 | エラー | "Cannot delete protected tag '...'" | 保護タグ削除試行 |
| M004 | 情報 | "Repository has no tags yet" | タグがない場合の空状態 |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|------|---------|---------|
| 403 Forbidden | 読み取り権限なし | アクセス拒否画面表示 |
| Gitlab::Git::CommandError | Gitalyエラー | サービス利用不可表示 |

## 備考

- RSSフィードはセッションレス認証に対応
- タグ一覧はデフォルトで更新日順（最新順）でソート
- 署名付きタグは署名情報を表示
- リリースと連携しているタグはリリースへのリンクを表示
- 空状態では`git tag`コマンドの使用方法を案内

---

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

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

### 推奨読解順序

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

タグ取得とリリースとの関連を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | tags_finder.rb | `app/finders/tags_finder.rb` | タグ検索・ソートロジック |
| 1-2 | releases_finder.rb | `app/finders/releases_finder.rb` | リリース取得 |

**読解のコツ**: TagsFinderはGitリポジトリから直接タグを取得し、ソート・フィルタリングを行う。リリース情報はタグ名をキーにReleasesFinder経由で取得される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | tags_controller.rb | `app/controllers/projects/tags_controller.rb` | indexアクション |

**主要処理フロー**:
1. **16-46行目**: `def index` - メインアクション
2. **18-20行目**: パラメータ取得とデフォルト値設定
3. **25行目**: `TagsFinder`でタグ取得（署名バッチロード付き）
4. **27行目**: ページネーション適用
5. **31行目**: `ReleasesFinder`でリリース取得
6. **32-33行目**: パイプラインステータス取得
7. **34-37行目**: エラー時のフォールバック

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/projects/tags/index.html.haml` | メインテンプレート構造 |
| 3-2 | _tag.html.haml | `app/views/projects/tags/_tag.html.haml` | タグ行パーシャル |

**主要処理フロー**:
- **7-21行目**: 空状態の表示（タグがない場合）
- **24-30行目**: ヘッダーとアクションボタン
- **32-33行目**: ソートドロップダウン
- **37-38行目**: Gitalyエラー時の表示
- **40-41行目**: 検索結果なしの表示
- **43-44行目**: タグリストの表示
- **47-48行目**: 削除モーダル

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

```
Projects::TagsController#index
    │
    ├─ tags_params (permit/with_defaults)
    │
    ├─ TagsFinder#execute
    │      └─ Git Repository (tag list)
    │
    ├─ Kaminari.paginate_array
    │
    ├─ ReleasesFinder#execute
    │      └─ releases table (by tag names)
    │
    └─ Ci::CommitStatusesFinder
           └─ Pipeline status for each tag
```

### データフロー図

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

URL Parameters ───▶ TagsController#index ───▶ HTML/ATOM Response
  - search            │
  - sort              ├─▶ TagsFinder ───▶ Tag List
  - page              │      │
  - format            │      └─▶ Git Repository
                      │
                      ├─▶ ReleasesFinder ───▶ Release Info
                      │      │
                      │      └─▶ releases table
                      │
                      └─▶ CommitStatusesFinder ───▶ Pipeline Status
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| tags_controller.rb | `app/controllers/projects/tags_controller.rb` | コントローラー | リクエスト処理 |
| index.html.haml | `app/views/projects/tags/index.html.haml` | テンプレート | メインビュー |
| _tag.html.haml | `app/views/projects/tags/_tag.html.haml` | パーシャル | タグ行表示 |
| tags_finder.rb | `app/finders/tags_finder.rb` | ファインダー | タグ検索 |
| releases_finder.rb | `app/finders/releases_finder.rb` | ファインダー | リリース取得 |
| destroy_service.rb | `app/services/tags/destroy_service.rb` | サービス | タグ削除 |
| repository.rb | `config/routes/repository.rb` | ルーティング | URL定義 |
