# 画面設計書 53-マイルストーン新規作成

## 概要

本ドキュメントは、GitLabにおけるプロジェクトマイルストーン新規作成画面に関する設計書です。新しいマイルストーンを作成するためのフォーム画面の仕様を定義します。

### 本画面の処理概要

**業務上の目的・背景**：マイルストーンは、プロジェクトの開発スケジュールを管理し、特定の期間内に達成すべき目標を設定するための機能です。スプリント計画やリリースマイルストーンを作成することで、課題やマージリクエストを期間ごとにグルーピングし、進捗管理を行います。新規作成画面では、マイルストーンのタイトル、説明、開始日、終了日を設定して新しいマイルストーンを登録します。

**画面へのアクセス方法**：マイルストーン一覧画面の「New milestone」ボタンをクリック、または直接URL `/:namespace/:project/-/milestones/new` にアクセスします。リリース作成画面からのリダイレクトでアクセスすることもあります。

**主要な操作・処理内容**：
1. マイルストーンタイトルの入力（必須）
2. マイルストーン説明の入力（任意、Markdown対応）
3. 開始日の設定（任意）
4. 終了日（期限）の設定（任意）
5. マイルストーンの作成実行
6. キャンセルして一覧画面へ戻る

**画面遷移**：
- 遷移元：マイルストーン一覧画面、リリース新規作成画面
- 遷移先：マイルストーン詳細画面（作成成功時）、マイルストーン一覧画面（キャンセル時）、リリース新規作成画面（redirect_path指定時）

**権限による表示制御**：
- `admin_milestone`権限：マイルストーンの作成が可能。権限がない場合は404エラー

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 41 | マイルストーン管理 | 主機能 | 新規マイルストーンの作成 |
| 73 | リリース作成 | 遷移先機能 | リリース作成画面への遷移（redirect_path指定時） |

## 画面種別

登録画面（フォーム）

## URL/ルーティング

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

コントローラー: `Projects::MilestonesController#new`, `Projects::MilestonesController#create`

## 入出力項目

### 入力項目

| 項目名 | データ型 | 必須 | 最大長 | 説明 |
|--------|---------|------|--------|------|
| title | String | ○ | 255文字 | マイルストーンのタイトル |
| description | Text | - | - | マイルストーンの説明（Markdown対応） |
| start_date | Date | - | - | マイルストーン開始日 |
| due_date | Date | - | - | マイルストーン終了日（期限） |

### 隠し項目

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| redirect_path | String | 作成後のリダイレクト先（new_release等） |

## 表示項目

### フォーム構成

| 項目名 | 入力タイプ | 説明 |
|--------|-----------|------|
| Title | テキストフィールド | マイルストーン名（必須、autofocus） |
| Start date | 日付ピッカー | 開始日 |
| Due date | 日付ピッカー | 終了日 |
| Description | Markdownエディタ | 説明文（プレビュー機能付き） |

### ボタン

| ボタン名 | 説明 |
|---------|------|
| Create milestone | マイルストーンを作成 |
| Cancel | 作成をキャンセルして一覧へ戻る |

## イベント仕様

### 1-Create milestoneボタン押下

フォームに入力された内容でマイルストーンを作成します。

**処理フロー**：
1. フォームデータをPOSTリクエストで送信
2. `Milestones::CreateService`を呼び出してマイルストーンを作成
3. バリデーション成功時：
   - redirect_pathが指定されている場合はリダイレクト先へ遷移
   - 指定がない場合は作成されたマイルストーンの詳細画面へ遷移
4. バリデーション失敗時：エラーメッセージを表示し、フォームを再表示

### 2-Cancelボタン押下

マイルストーン一覧画面へ遷移します。

### 3-Markdownプレビュー

説明フィールドでプレビュータブを選択すると、入力されたMarkdownがレンダリングされて表示されます。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Create milestone押下 | milestones | INSERT | 新規マイルストーン作成 |
| Create milestone押下 | internal_ids | UPDATE | IIDの採番・更新 |
| Create milestone押下 | events | INSERT | 作成イベント記録 |

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

#### milestones

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | project_id | 現在のプロジェクトID | |
| INSERT | title | 入力されたタイトル | 必須 |
| INSERT | description | 入力された説明 | 任意 |
| INSERT | start_date | 入力された開始日 | 任意 |
| INSERT | due_date | 入力された終了日 | 任意 |
| INSERT | state | 'active' | デフォルト値 |
| INSERT | iid | 自動採番 | プロジェクト内で一意 |
| INSERT | created_at | 現在時刻 | |
| INSERT | updated_at | 現在時刻 | |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|---------|
| エラー | Title is too long (maximum is 255 characters) | タイトルが255文字を超える場合 |
| エラー | Title can't be blank | タイトルが空の場合 |
| エラー | already being used for another group or project milestone | 同名のマイルストーンが存在する場合 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| プロジェクトが存在しない | 404ページを表示 |
| 作成権限がない | 404ページを表示 |
| バリデーションエラー | フォームを再表示し、エラーメッセージを表示 |

## 備考

- 同一プロジェクト・グループ内でマイルストーン名は一意である必要があります
- 説明フィールドはMarkdown形式に対応しており、リッチなドキュメントを記述できます
- 日付フィールドはブラウザネイティブの日付ピッカーを使用します
- スパム検出機能が有効な場合、公開プロジェクトではスパムチェックが実行されます

---

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

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

### 推奨読解順序

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

マイルストーンのモデルとバリデーションを理解します。

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

**読解のコツ**: MilestoneモデルはTimeboxをincludeし、start_dateとdue_dateの管理を行います。titleの必須バリデーションとuniqueness_of_titleのカスタムバリデーションに注目。

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

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

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

**主要処理フロー**:
1. **L46-49**: newアクションで新しいMilestoneインスタンスを初期化
2. **L61-73**: createアクションでサービスを呼び出し
3. **L62**: `Milestones::CreateService`を使用してマイルストーンを作成
4. **L64-70**: バリデーション結果に応じてリダイレクト先を決定

#### Step 3: サービスクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create_service.rb | `app/services/milestones/create_service.rb` | マイルストーン作成ロジック |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | new.html.haml | `app/views/projects/milestones/new.html.haml` | 新規作成画面 |
| 4-2 | _form.html.haml | `app/views/projects/milestones/_form.html.haml` | フォームパーシャル |

**主要処理フロー**:
- **new.html.haml L6**: フォームパーシャルをレンダリング
- **_form.html.haml L9-11**: タイトル入力フィールド（必須、255文字制限）
- **_form.html.haml L12**: 日付フィールドのパーシャル呼び出し
- **_form.html.haml L16-24**: Markdownエディタの設定

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

```
Projects::MilestonesController#new
    │
    └─ @milestone = @project.milestones.new
           │
           └─ app/views/projects/milestones/new.html.haml
                  └─ _form.html.haml

Projects::MilestonesController#create
    │
    ├─ Milestones::CreateService.new.execute
    │      ├─ Milestone.create
    │      └─ バリデーション実行
    │
    └─ リダイレクト処理
           ├─ 成功時 → マイルストーン詳細 or リリース新規作成
           └─ 失敗時 → フォーム再表示
```

### データフロー図

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

フォーム入力 ───▶ MilestonesController#create
(title, description,         │
 start_date, due_date)       ▼
                   Milestones::CreateService#execute
                             │
                             ▼
                   Milestone.create (ActiveRecord)
                             │
                   ┌─────────┴─────────┐
                   ▼                   ▼
             バリデーション成功    バリデーション失敗
                   │                   │
                   ▼                   ▼
             リダイレクト        フォーム再表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| milestones_controller.rb | `app/controllers/projects/milestones_controller.rb` | コントローラー | new/createアクション |
| milestone.rb | `app/models/milestone.rb` | モデル | マイルストーンのデータモデル |
| create_service.rb | `app/services/milestones/create_service.rb` | サービス | 作成処理ロジック |
| new.html.haml | `app/views/projects/milestones/new.html.haml` | テンプレート | 新規作成画面 |
| _form.html.haml | `app/views/projects/milestones/_form.html.haml` | 部分テンプレート | フォームパーシャル |
| _form_dates.html.haml | `app/views/shared/milestones/_form_dates.html.haml` | 部分テンプレート | 日付入力パーシャル |
