# 画面設計書 52-マイルストーン一覧

## 概要

本ドキュメントは、GitLabにおけるプロジェクトマイルストーン一覧画面に関する設計書です。プロジェクト内のマイルストーンを一覧表示し、進捗状況を確認・管理するための画面仕様を定義します。

### 本画面の処理概要

**業務上の目的・背景**：マイルストーンは、プロジェクトの開発期間を区切り、特定の期間内に達成すべき目標を設定するための機能です。スプリントやリリースサイクルの管理に活用され、課題やマージリクエストを特定のマイルストーンにグルーピングすることで、進捗状況を可視化します。一覧画面では、すべてのマイルストーンの状態を俯瞰し、必要に応じて新規作成・編集・削除を行います。

**画面へのアクセス方法**：プロジェクトのサイドナビゲーションから「Plan」→「Milestones」を選択、または直接URL `/:namespace/:project/-/milestones` にアクセスします。

**主要な操作・処理内容**：
1. マイルストーン一覧の表示（アクティブ/クローズド状態でのフィルタリング）
2. マイルストーンの検索（タイトルによる検索）
3. マイルストーンの並び替え（期日、名前など）
4. 新規マイルストーンの作成（作成画面への遷移）
5. マイルストーン詳細の閲覧（詳細画面への遷移）
6. マイルストーンのグループマイルストーンへの昇格（権限がある場合）
7. マイルストーンの削除

**画面遷移**：
- 遷移元：プロジェクトトップページ、課題一覧画面、ダッシュボード
- 遷移先：マイルストーン詳細画面、マイルストーン新規作成画面、マイルストーン編集画面

**権限による表示制御**：
- `read_milestone`権限：マイルストーンの閲覧が可能
- `admin_milestone`権限：マイルストーンの作成・編集・削除が可能
- グループへの`admin_milestone`権限：グループマイルストーンへの昇格が可能

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 41 | マイルストーン管理 | 主機能 | マイルストーンの一覧表示 |
| 36 | イシュー作成 | 遷移先機能 | マイルストーン詳細画面への遷移 |
| 28 | マージリクエスト作成 | 遷移先機能 | マイルストーン詳細画面への遷移 |

## 画面種別

一覧画面

## URL/ルーティング

```
GET /:namespace/:project/-/milestones
```

コントローラー: `Projects::MilestonesController#index`

## 入出力項目

### フィルター項目

| 項目名 | データ型 | 必須 | 説明 |
|--------|---------|------|------|
| state | String | - | 状態フィルタ（active/closed/all） |
| search_title | String | - | タイトルによる検索 |
| sort | String | - | 並び順（due_date_asc, due_date_desc, name_asc, name_desc等） |

### ページネーション

| 項目名 | データ型 | 必須 | 説明 |
|--------|---------|------|------|
| page | Integer | - | ページ番号 |

## 表示項目

### ヘッダー部

| 項目名 | 説明 |
|--------|------|
| 状態タブ | Active / Closed / All の切り替え |
| 検索フォーム | タイトル検索入力欄 |
| 並び替えドロップダウン | 並び順の選択 |
| 新規作成ボタン | 新規マイルストーン作成画面への遷移（権限がある場合） |

### マイルストーン一覧

| 項目名 | 説明 |
|--------|------|
| マイルストーン名 | マイルストーンのタイトル（リンク） |
| 期間 | 開始日〜終了日 |
| 進捗バー | 完了課題の割合を視覚化 |
| 課題統計 | Open / Closed の課題数 |
| マージリクエスト統計 | Open / Merged / Closed のMR数 |
| アクションボタン | 編集・削除・昇格など |

## イベント仕様

### 1-状態フィルター変更

状態タブ（Active/Closed/All）をクリックすると、該当する状態のマイルストーンのみが表示されます。

### 2-検索実行

検索フォームにタイトルを入力して検索すると、部分一致するマイルストーンが表示されます。

### 3-並び替え変更

並び替えドロップダウンで選択すると、指定した順序でマイルストーンが再表示されます。

### 4-新規作成ボタン押下

新規マイルストーン作成画面（`/:namespace/:project/-/milestones/new`）に遷移します。

### 5-マイルストーン名クリック

該当マイルストーンの詳細画面（`/:namespace/:project/-/milestones/:id`）に遷移します。

### 6-削除ボタン押下

確認モーダルを表示後、マイルストーンを削除します。削除は非同期で実行されます。

### 7-グループへ昇格

プロジェクトマイルストーンをグループマイルストーンに昇格させます。グループへのadmin_milestone権限が必要です。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 一覧表示 | milestones | SELECT | マイルストーン取得 |
| 削除ボタン押下 | milestones | DELETE | マイルストーン削除 |
| 削除ボタン押下 | events | DELETE | 関連イベント削除 |

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

#### milestones（削除時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | id | 指定されたマイルストーンID | |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|---------|
| 成功 | Milestone was successfully deleted | 削除成功時 |
| 成功 | {title} promoted to group milestone | 昇格成功時 |
| 情報 | No milestones to show | マイルストーンが存在しない場合 |
| エラー | Failed to promote milestone | 昇格失敗時 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| プロジェクトが存在しない | 404ページを表示 |
| 閲覧権限がない | 403エラーを返却 |
| 削除権限がない | 404エラーを返却 |

## 備考

- マイルストーン一覧では、プロジェクト固有のマイルストーンのみが表示されます
- グループマイルストーンは、グループのマイルストーン一覧で確認できます
- JSON形式でのレスポンスにも対応しており、APIからの取得も可能です

---

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

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

### 推奨読解順序

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

マイルストーンのモデルと関連を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | milestone.rb | `app/models/milestone.rb` | Milestoneモデルの定義、スコープ、状態遷移 |
| 1-2 | timebox.rb | `app/models/concerns/timebox.rb` | 期間管理の共通ロジック |

**読解のコツ**: MilestoneはTimeboxモジュールを含み、期間（start_date, due_date）と状態（active/closed）を管理します。ProjectまたはGroupに属します。

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

リクエストの受け口となるコントローラーを確認します。

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

**主要処理フロー**:
1. **L27-44**: indexアクションでマイルストーン一覧を取得
2. **L28**: ソート順の設定（デフォルト: due_date_asc）
3. **L33**: @milestone_statesで状態ごとの件数を取得
4. **L37-38**: プロジェクトマイルストーンのみをフィルタ、ページネーション

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/projects/milestones/index.html.haml` | 一覧画面のテンプレート |
| 3-2 | milestones_filter | `app/views/shared/_milestones_filter.html.haml` | 状態フィルタータブ |

**主要処理フロー**:
- **L6-8**: マイルストーンが存在する場合のみフィルターエリアを表示
- **L13-15**: admin_milestone権限がある場合のみ新規作成ボタンを表示
- **L28-29**: @milestonesをレンダリング
- **L31**: ページネーション

#### Step 4: 検索・フィルタリングロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | milestones_finder.rb | `app/finders/milestones_finder.rb` | マイルストーン検索ロジック |

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

```
Projects::MilestonesController#index
    │
    ├─ MilestonesFinder#execute
    │      ├─ 状態フィルタリング
    │      ├─ タイトル検索
    │      └─ プロジェクト/グループスコープ
    │
    ├─ Milestone.sort_by_attribute
    │      └─ ソート処理
    │
    ├─ Milestone.states_count
    │      └─ 状態別件数カウント
    │
    └─ app/views/projects/milestones/index.html.haml
           ├─ shared/milestones_filter
           ├─ shared/milestones/search_form
           ├─ shared/milestones_sort_dropdown
           └─ @milestones パーシャルレンダリング
```

### データフロー図

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

URLパラメータ ───▶ MilestonesController#index
(state, search_title, sort)          │
                                     ▼
                          MilestonesFinder#execute ───▶ @milestones取得
                                     │
                                     ▼
                          Milestone.states_count ───▶ @milestone_states
                                     │
                                     ▼
                          index.html.haml ───▶ HTML応答
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| milestones_controller.rb | `app/controllers/projects/milestones_controller.rb` | コントローラー | マイルストーン画面のエントリーポイント |
| milestone.rb | `app/models/milestone.rb` | モデル | マイルストーンのデータモデル |
| milestones_finder.rb | `app/finders/milestones_finder.rb` | Finder | 検索ロジック |
| index.html.haml | `app/views/projects/milestones/index.html.haml` | テンプレート | 一覧画面テンプレート |
| _milestone.html.haml | `app/views/shared/milestones/_milestone.html.haml` | 部分テンプレート | 個別マイルストーン表示 |
| milestones_filter | `app/views/shared/_milestones_filter.html.haml` | 部分テンプレート | フィルタータブ |
| destroy_service.rb | `app/services/milestones/destroy_service.rb` | サービス | 削除処理 |
| promote_service.rb | `app/services/milestones/promote_service.rb` | サービス | 昇格処理 |
