# 画面設計書 150-マイルストーン詳細

## 概要

本ドキュメントは、GitLabにおけるグループマイルストーン詳細画面の設計仕様を定義するものである。グループマイルストーンの詳細情報と関連する課題・マージリクエストの進捗状況を表示する画面を提供する。

### 本画面の処理概要

グループマイルストーン詳細画面は、特定のグループマイルストーンの詳細情報を表示する画面である。マイルストーンに関連する課題・マージリクエストの一覧、参加者、使用ラベルなどをタブ形式で表示し、進捗状況を可視化する。

**業務上の目的・背景**：スプリントやリリースの進捗を確認するため、マイルストーンに紐づくすべての作業項目を一元的に把握する必要がある。この画面では、課題の完了状況、マージリクエストのステータス、関与するメンバーを確認でき、プロジェクトマネジメントの意思決定に活用される。

**画面へのアクセス方法**：以下のいずれかの方法でアクセス可能である。
- グループマイルストーン一覧画面のマイルストーン名をクリック
- URL直接アクセス: `/groups/{group_path}/-/milestones/{iid}`

**主要な操作・処理内容**：
1. マイルストーン基本情報の表示（タイトル、期間、説明）
2. 課題一覧の表示（Work items タブ）
3. マージリクエスト一覧の表示（Merge requests タブ）
4. 参加者一覧の表示（Participants タブ）
5. ラベル一覧の表示（Labels タブ）
6. マイルストーン状態の変更（Close/Reopen）
7. マイルストーン編集画面への遷移

**画面遷移**：
- 遷移元：グループマイルストーン一覧画面、課題詳細画面
- 遷移先：マイルストーン編集画面、課題詳細画面、マージリクエスト詳細画面

**権限による表示制御**：
- Guest：マイルストーン詳細の閲覧
- Reporter以上：課題・MR詳細の閲覧
- Maintainer以上：マイルストーン編集・削除、状態変更（admin_milestone権限）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 42 | マイルストーン管理 | 主機能 | グループマイルストーンの詳細表示 |

## 画面種別

詳細

## URL/ルーティング

- パス: `/groups/{group_path}/-/milestones/{iid}`
- ルーティング: `groups/milestones#show`
- HTTPメソッド: GET
- 追加エンドポイント:
  - `/groups/{group_path}/-/milestones/{iid}/issues` - 課題タブ（Ajax）
  - `/groups/{group_path}/-/milestones/{iid}/merge_requests` - MRタブ（Ajax）
  - `/groups/{group_path}/-/milestones/{iid}/participants` - 参加者タブ（Ajax）
  - `/groups/{group_path}/-/milestones/{iid}/labels` - ラベルタブ（Ajax）

## 入出力項目

| 項目名 | 種別 | 必須 | データ型 | 説明 |
|--------|------|------|----------|------|
| iid | パスパラメータ | 必須 | Integer | マイルストーンIID |

## 表示項目

| 項目名 | データ型 | 説明 | 表示条件 |
|--------|----------|------|----------|
| マイルストーンタイトル | h1 | マイルストーン名 | 常時 |
| 完了アラート | Alert | 全課題完了の通知 | 全課題完了時 |
| ステータスバッジ | Badge | Active/Closed | 常時 |
| 期間情報 | Text | 開始日〜期限日 | 日付設定時 |
| 説明 | Markdown | マイルストーン説明 | 設定時 |
| バーンダウンチャート | Chart | 進捗グラフ | EE機能 |
| 課題タブ | Tab | Work items一覧 | 常時 |
| MRタブ | Tab | Merge requests一覧 | MR有効時 |
| 参加者タブ | Tab | 参加者一覧 | 常時 |
| ラベルタブ | Tab | 使用ラベル一覧 | 常時 |
| サイドバー | Sidebar | 進捗・アクション | 常時 |
| 編集ボタン | Button | 編集画面へ遷移 | admin_milestone権限 |
| Close/Reopenボタン | Button | 状態変更 | admin_milestone権限 |
| 削除ボタン | Button | マイルストーン削除 | admin_milestone権限 |

## イベント仕様

### 1-マイルストーン詳細表示（GET show）

1. `milestone`メソッドで対象マイルストーン取得（113-117行目）
2. `group.milestones.find_by_iid(params[:id])`でIIDで検索
3. `@noteable = @milestone`でノータブル設定
4. 共有パーシャル（`shared/milestones/_top`、`_tabs`、`_sidebar`）をレンダリング

### 2-タブデータ取得（Ajax）

1. MilestoneActions concernで各タブアクションを提供
2. `issues`アクション：マイルストーンに紐づく課題を取得
3. `merge_requests`アクション：マイルストーンに紐づくMRを取得
4. `participants`アクション：課題の参加者を取得
5. `labels`アクション：使用されているラベルを取得

### 3-状態変更（PATCH update）

1. `authorize_admin_milestones!`による権限チェック
2. `Milestones::UpdateService`による更新処理
3. `state_event`パラメータで`close`または`activate`を実行
4. 楽観的ロック（lock_version）でコンフリクト検出

### 4-マイルストーン削除（DELETE destroy）

1. `authorize_admin_milestones!`による権限チェック
2. `Milestones::DestroyService`による削除処理
3. マイルストーン一覧へリダイレクト

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 詳細表示 | milestones | SELECT | マイルストーン取得 |
| 詳細表示 | issues | SELECT | 関連課題取得 |
| 詳細表示 | merge_requests | SELECT | 関連MR取得 |
| 詳細表示 | users | SELECT | 参加者取得 |
| 状態変更 | milestones | UPDATE | state更新 |
| 削除 | milestones | DELETE | マイルストーン削除 |

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

#### milestones

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | group_id, iid | マイルストーン取得 |
| UPDATE | state | 'active' or 'closed' | 状態変更時 |
| UPDATE | updated_at | 現在時刻 | 状態変更時 |
| DELETE | - | milestone_id | 削除時 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | 情報 | All issues for this milestone are closed. | 全課題完了時 |
| MSG-002 | 情報 | You may close the milestone now. | グループマイルストーン全課題完了時 |
| MSG-003 | エラー | Someone edited this milestone at the same time you did. | コンフリクト発生時 |

## 例外処理

| 例外条件 | 処理内容 | 遷移先 |
|----------|----------|--------|
| マイルストーン不存在 | 404エラー | エラーページ |
| 閲覧権限なし | 404エラー | エラーページ |
| 楽観的ロックエラー | コンフリクトメッセージ表示 | 編集画面 |

## 備考

- タブのコンテンツはAjaxで遅延読み込み（パフォーマンス最適化）
- 課題数・MR数はタブにカウントバッジで表示
- バーンダウンチャートはEE機能（render_if_exists）
- `merge_requests_enabled?`でMRタブの表示を制御
- 参加者は課題に関与したユーザーを集計（issue_participants_visible_by_user）
- ラベルは課題に付与されているラベルを集計（issue_labels_visible_by_user）
- サイドバーには進捗バーと主要アクションを表示
- プロジェクトマイルストーンとグループマイルストーンで一部表示が異なる

---

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

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

### 推奨読解順序

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

マイルストーンモデルと関連エンティティを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | milestone.rb | `app/models/milestone.rb` | マイルストーンモデル、関連 |
| 1-2 | milestoneish.rb | `app/models/concerns/milestoneish.rb` | 課題・MR関連メソッド |

**読解のコツ**: `has_many :merge_requests`（27行目）で関連を確認。Milestoneish concernで`milestone_issues`、`merge_requests_visible_to_user`などのヘルパーメソッドを提供。

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

コントローラーの`show`アクションと、タブ用の各アクションがエントリーポイント。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | milestones_controller.rb | `app/controllers/groups/milestones_controller.rb` | showアクション |
| 2-2 | milestone_actions.rb | `app/controllers/concerns/milestone_actions.rb` | タブアクション |

**主要処理フロー**:
1. **38行目**: showアクションは空（milestoneメソッドが事前実行）
2. **113-117行目**: `milestone`メソッドでIIDで検索、404ハンドリング
3. MilestoneActions concernで`issues`、`merge_requests`、`participants`、`labels`アクション

#### Step 3: ビューレイヤーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/groups/milestones/show.html.haml` | メインテンプレート |
| 3-2 | _top.html.haml | `app/views/shared/milestones/_top.html.haml` | ヘッダー部分 |
| 3-3 | _tabs.html.haml | `app/views/shared/milestones/_tabs.html.haml` | タブUI |
| 3-4 | _sidebar.html.haml | `app/views/shared/milestones/_sidebar.html.haml` | サイドバー |

**主要処理フロー**:
- show.html.haml **3行目**: `_top`パーシャルでヘッダー表示
- show.html.haml **4行目**: `_tabs`パーシャルでタブ表示
- show.html.haml **5行目**: `_sidebar`パーシャルでサイドバー表示
- _tabs.html.haml **9-11行目**: Work itemsタブ（課題数バッジ付き）
- _tabs.html.haml **12-15行目**: MRタブ（merge_requests_enabled?で表示制御）
- _tabs.html.haml **16-18行目**: Participantsタブ
- _tabs.html.haml **19-21行目**: Labelsタブ

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

```
Groups::MilestonesController#show
    │
    ├─ milestone (before_action)
    │      └─ group.milestones.find_by_iid(params[:id])
    │             └─ render_404 unless @milestone
    │
    └─ render 'show'
           │
           ├─ shared/milestones/_top
           │      ├─ milestone_complete_alert
           │      ├─ _header (ステータス、編集ボタン)
           │      └─ _description (Markdown)
           │
           ├─ shared/milestones/_tabs
           │      ├─ #tab-issues (Work items)
           │      │      └─ milestone_tab_path(milestone, 'issues')
           │      ├─ #tab-merge-requests
           │      │      └─ milestone_tab_path(milestone, 'merge_requests')
           │      ├─ #tab-participants
           │      │      └─ milestone_tab_path(milestone, 'participants')
           │      └─ #tab-labels
           │             └─ milestone_tab_path(milestone, 'labels')
           │
           └─ shared/milestones/_sidebar
                  ├─ 進捗バー
                  ├─ Close/Reopen ボタン
                  └─ Delete ボタン

MilestoneActions#issues (Ajax)
    └─ @milestone.milestone_issues(current_user)

MilestoneActions#merge_requests (Ajax)
    └─ @milestone.merge_requests_visible_to_user(current_user)

MilestoneActions#participants (Ajax)
    └─ @milestone.issue_participants_visible_by_user(current_user)

MilestoneActions#labels (Ajax)
    └─ @milestone.issue_labels_visible_by_user(current_user)
```

### データフロー図

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

URL (iid) ───────────────▶ MilestonesController#show ───▶ HTML Response
                                  │
                                  ├── milestone取得
                                  │    (find_by_iid)
                                  │
                                  └── render partials
                                          │
                                          ├── _top (header, description)
                                          ├── _tabs (lazy load placeholders)
                                          └── _sidebar (actions)

Ajax request ────────────▶ MilestoneActions#issues ─────▶ HTML partial
(tab endpoint)                    │
                                  └── milestone.milestone_issues
                                          │
                                          └── issues table (SELECT)

Ajax request ────────────▶ MilestoneActions#merge_requests ─▶ HTML partial
                                  │
                                  └── milestone.merge_requests_visible_to_user
                                          │
                                          └── merge_requests table (SELECT)

Ajax request ────────────▶ MilestoneActions#participants ───▶ HTML partial
                                  │
                                  └── milestone.issue_participants_visible_by_user
                                          │
                                          └── users table (SELECT via issues)

Ajax request ────────────▶ MilestoneActions#labels ─────────▶ HTML partial
                                  │
                                  └── milestone.issue_labels_visible_by_user
                                          │
                                          └── labels table (SELECT via issues)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| milestones_controller.rb | `app/controllers/groups/milestones_controller.rb` | コントローラー | showアクション定義 |
| milestone_actions.rb | `app/controllers/concerns/milestone_actions.rb` | Concern | タブアクション |
| milestone.rb | `app/models/milestone.rb` | モデル | マイルストーンモデル |
| milestoneish.rb | `app/models/concerns/milestoneish.rb` | Concern | 関連データ取得 |
| show.html.haml | `app/views/groups/milestones/show.html.haml` | ビュー | メインテンプレート |
| _header_title.html.haml | `app/views/groups/milestones/_header_title.html.haml` | ビュー | ヘッダータイトル |
| _top.html.haml | `app/views/shared/milestones/_top.html.haml` | ビュー | ヘッダー部分 |
| _tabs.html.haml | `app/views/shared/milestones/_tabs.html.haml` | ビュー | タブUI |
| _sidebar.html.haml | `app/views/shared/milestones/_sidebar.html.haml` | ビュー | サイドバー |
| _header.html.haml | `app/views/shared/milestones/_header.html.haml` | ビュー | ステータス表示 |
| _description.html.haml | `app/views/shared/milestones/_description.html.haml` | ビュー | 説明表示 |
