# 画面設計書 39-タグ詳細

## 概要

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

### 本画面の処理概要

本画面は、特定のタグの詳細情報を表示し、関連するコミット情報、リリース情報、署名情報などを確認できる画面である。タグの削除やファイルツリーへの遷移などの操作も提供する。

**業務上の目的・背景**：ソフトウェアリリース管理において、タグは特定のバージョンをマーキングする重要な機能である。本画面は、特定のタグの詳細（タグ作成者、メッセージ、対象コミット、関連リリースなど）を確認し、そのバージョンのソースコードへのアクセスやダウンロードを可能にする。

**画面へのアクセス方法**：
- タグ一覧画面でタグ名をクリック
- URL直接入力: `/{namespace}/{project}/-/tags/{tag_name}`

**主要な操作・処理内容**：
1. タグ詳細情報の表示
2. 関連コミット情報の表示
3. リリースへのリンク表示
4. 署名情報の表示
5. ファイルツリーへの遷移
6. コミット履歴への遷移
7. ソースコードのダウンロード
8. タグの削除

**画面遷移**：
- 遷移元: タグ一覧画面
- 遷移先: ファイルツリー画面、コミット一覧画面、リリース詳細画面、タグ一覧画面（削除後）

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 20 | タグ管理 | 主機能 | タグ詳細の表示 |
| 26 | 保護タグ | 補助機能 | 保護タグバッジの表示 |
| 73 | リリース作成 | 遷移先機能 | リリース詳細へのリンク |

## 画面種別

詳細

## URL/ルーティング

```
GET /{namespace}/{project}/-/tags/{tag_name}
```

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

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| namespace | 入力 | String | Yes | プロジェクトの名前空間 |
| project | 入力 | String | Yes | プロジェクト名 |
| id (tag_name) | 入力 | String | Yes | タグ名 |

## 表示項目

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

## イベント仕様

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

タグ詳細情報を取得し表示する。

**処理フロー**:
1. タグをリポジトリから取得（repository.find_tag）
2. タグが存在しない場合は404を返す
3. 関連リリースを取得
4. 対象コミットを取得
5. パイプラインステータスを取得

### 2-Browse filesボタン押下

タグのファイルツリー画面へ遷移する。

**遷移先**: `/{namespace}/{project}/-/tree/{tag_name}?ref_type=tags`

### 3-Browse commitsボタン押下

タグのコミット一覧画面へ遷移する。

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

### 4-Downloadボタン押下

ソースコードをダウンロードする。

**処理**: zip/tar.gz/tar.bz2形式でダウンロード

### 5-Delete tagボタン押下

タグを削除する。

**処理フロー**:
1. 確認モーダル表示
2. Tags::DestroyServiceを実行
3. 成功/エラーメッセージ表示
4. タグ一覧画面へリダイレクト

### 6-Edit releaseボタン押下

リリース編集画面へ遷移する（リリースが存在する場合）。

**遷移先**: リリース編集画面

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

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

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

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

#### events

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|----------|
| M001 | 情報 | "Can't find HEAD commit for this tag" | コミットが見つからない |
| M002 | 成功 | "Tag was deleted." | タグ削除成功 |
| M003 | エラー | "Failed to delete tag '...'" | タグ削除失敗 |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|------|---------|---------|
| 403 Forbidden | 読み取り権限なし | アクセス拒否画面表示 |
| 404 Not Found | タグが存在しない | 404エラー画面表示 |

## 備考

- 注釈付きタグの場合、タグメッセージが`<pre>`タグで表示される
- タグ作成者はメールアドレスからユーザーを検索し、プロファイルへのリンクを表示
- 署名付きタグは署名情報（GPG/SSH）を表示
- 保護タグの場合、タグ名の横に「protected」バッジを表示
- タグ詳細画面から削除した場合は、タグ一覧画面にリダイレクト

---

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

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

### 推奨読解順序

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

タグの詳細情報とリリースとの関連を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | tag.rb | `lib/gitlab/git/tag.rb` | タグオブジェクト |
| 1-2 | release.rb | `app/models/release.rb` | リリースモデル |

**読解のコツ**: タグはGitリポジトリから直接取得され、`user_email`、`message`、`has_signature?`などの属性を持つ。リリースはタグ名をキーにReleaseモデルから取得される。

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

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

**主要処理フロー**:
1. **49行目**: `def show` - メインアクション
2. **50行目**: `repository.find_tag(params[:id])` - タグ取得
3. **52行目**: `render_404 unless @tag` - 存在チェック
4. **54行目**: `@project.releases.find_by(tag: @tag.name)` - リリース取得
5. **55行目**: `repository.commit(@tag.dereferenced_target)` - コミット取得
6. **57-59行目**: パイプラインステータス取得

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/projects/tags/show.html.haml` | メインテンプレート構造 |
| 3-2 | _commit.html.haml | `app/views/projects/branches/_commit.html.haml` | コミット表示パーシャル |
| 3-3 | _release_link.html.haml | `app/views/projects/tags/_release_link.html.haml` | リリースリンクパーシャル |

**主要処理フロー**:
- **1-4行目**: タグ作成者のユーザー情報取得
- **5-7行目**: パンくずとページタイトル
- **9-14行目**: タグ名とアイコンの表示
- **15-16行目**: 保護タグバッジ
- **18-34行目**: タグ作成者の表示
- **35-38行目**: コミット情報の表示
- **40-41行目**: リリースリンクの表示
- **43-59行目**: アクションボタン群（署名、パイプライン、編集、ブラウズ、ダウンロード、削除）
- **61-63行目**: タグメッセージの表示
- **65-66行目**: 削除モーダル

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

```
Projects::TagsController#show
    │
    ├─ repository.find_tag(params[:id])
    │      └─ Gitlab::Git::Repository#find_tag
    │
    ├─ @project.releases.find_by(tag: @tag.name)
    │      └─ Release ActiveRecord query
    │
    ├─ repository.commit(@tag.dereferenced_target)
    │      └─ Gitlab::Git::Repository#commit
    │
    └─ Ci::CommitStatusesFinder#execute
           └─ Pipeline status lookup
```

### データフロー図

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

URL Parameters ───▶ TagsController#show ───▶ HTML Response
  - id (tag_name)    │
                     ├─▶ repository.find_tag ───▶ @tag
                     │      │
                     │      └─▶ Git Repository
                     │
                     ├─▶ releases.find_by ───▶ @release
                     │      │
                     │      └─▶ releases table
                     │
                     ├─▶ repository.commit ───▶ @commit
                     │
                     └─▶ CommitStatusesFinder ───▶ @pipeline_status
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| tags_controller.rb | `app/controllers/projects/tags_controller.rb` | コントローラー | リクエスト処理 |
| show.html.haml | `app/views/projects/tags/show.html.haml` | テンプレート | メインビュー |
| _commit.html.haml | `app/views/projects/branches/_commit.html.haml` | パーシャル | コミット表示 |
| _release_link.html.haml | `app/views/projects/tags/_release_link.html.haml` | パーシャル | リリースリンク |
| _signature.html.haml | `app/views/projects/commit/_signature.html.haml` | パーシャル | 署名表示 |
| _download.html.haml | `app/views/projects/buttons/_download.html.haml` | パーシャル | ダウンロードボタン |
| _remove_tag.html.haml | `app/views/projects/buttons/_remove_tag.html.haml` | パーシャル | 削除ボタン |
| destroy_service.rb | `app/services/tags/destroy_service.rb` | サービス | タグ削除 |
| repository.rb | `config/routes/repository.rb` | ルーティング | URL定義 |
