# 画面設計書 57-ラベル新規作成

## 概要

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

### 本画面の処理概要

**業務上の目的・背景**：ラベルは課題やマージリクエストを分類・フィルタリングするためのタグです。「バグ」「機能追加」「優先度：高」などのラベルを作成することで、チームはワークフローを整理し、課題の管理を効率化できます。新規作成画面では、ラベルの名前、説明、色を設定して新しいラベルを登録します。

**画面へのアクセス方法**：ラベル一覧画面の「New label」ボタンをクリック、または直接URL `/:namespace/:project/-/labels/new` にアクセスします。

**主要な操作・処理内容**：
1. ラベル名の入力（必須）
2. ラベル説明の入力（任意）
3. 背景色の選択（カラーピッカーまたはプリセットから）
4. ラベルの作成実行
5. キャンセルして一覧画面へ戻る

**画面遷移**：
- 遷移元：ラベル一覧画面
- 遷移先：ラベル一覧画面（作成成功時）、ラベル一覧画面（キャンセル時）

**権限による表示制御**：
- `admin_label`権限：ラベルの作成が可能。権限がない場合は404エラー

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 40 | ラベル管理 | 主機能 | 新規ラベルの作成 |

## 画面種別

登録画面（フォーム）

## URL/ルーティング

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

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

## 入出力項目

### 入力項目

| 項目名 | データ型 | 必須 | 最大長 | 説明 |
|--------|---------|------|--------|------|
| title | String | ○ | - | ラベルの名前 |
| description | Text | - | 512KB | ラベルの説明 |
| color | String | ○ | 7文字 | 背景色（HEX形式 例: #FF0000） |

## 表示項目

### フォーム構成

| 項目名 | 入力タイプ | 説明 |
|--------|-----------|------|
| Title | テキストフィールド | ラベル名（必須、autofocus） |
| Description (optional) | テキストエリア | 説明文 |
| Background color | カラーピッカー + テキストフィールド | 背景色 |
| プリセットカラー | ボタン群 | 推奨色の選択 |

### ボタン

| ボタン名 | 説明 |
|---------|------|
| Create label | ラベルを作成 |
| Cancel | 作成をキャンセルして一覧へ戻る |

## イベント仕様

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

フォームに入力された内容でラベルを作成します。

**処理フロー**：
1. フォームデータをPOSTリクエストで送信
2. `Labels::CreateService`を呼び出してラベルを作成
3. バリデーション成功時：ラベル一覧画面へリダイレクト
4. バリデーション失敗時：エラーメッセージを表示し、フォームを再表示

### 2-Cancelボタン押下

ラベル一覧画面へ遷移します。

### 3-カラーピッカー操作

カラーピッカーで色を選択すると、テキストフィールドにHEX値が反映されます。

### 4-プリセットカラー選択

推奨色ボタンをクリックすると、その色がカラーピッカーとテキストフィールドに反映されます。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Create label押下 | labels | INSERT | 新規ラベル作成 |

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

#### labels

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | project_id | 現在のプロジェクトID | |
| INSERT | title | 入力されたラベル名 | 必須 |
| INSERT | description | 入力された説明 | 任意 |
| INSERT | color | 入力された背景色 | HEX形式 |
| INSERT | type | 'ProjectLabel' | ラベル種別 |
| INSERT | created_at | 現在時刻 | |
| INSERT | updated_at | 現在時刻 | |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|---------|
| エラー | Title has already been taken | 同名のラベルが存在する場合 |
| エラー | Title can't be blank | タイトルが空の場合 |
| エラー | Color is invalid | 色形式が不正な場合 |

## 例外処理

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

## 備考

- 同一プロジェクト内でラベル名は一意である必要があります（group_id, project_idスコープ）
- 色はHEX形式（#で始まる6桁の16進数）で指定します
- プリセットカラーはGitLabのデザインガイドラインに基づいた推奨色です
- JSON形式でのレスポンスにも対応しており、APIからの作成も可能です

---

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

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

### 推奨読解順序

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

ラベルのモデルとバリデーションを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | label.rb | `app/models/label.rb` | validates、uniqueness制約 |
| 1-2 | base_label.rb | `app/models/concerns/base_label.rb` | 共通バリデーション |

**読解のコツ**: Labelモデルはtitleのuniquenessバリデーション（group_id, project_idスコープ）を持ちます。colorはHEX形式である必要があります。

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

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

**主要処理フロー**:
1. **L44-46**: newアクションで新しいLabelインスタンスを初期化
2. **L48-62**: createアクションでサービスを呼び出し
3. **L49**: `Labels::CreateService`を使用してラベルを作成
4. **L166-173**: label_paramsでパラメータをpermit

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

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

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

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

**主要処理フロー**:
- **new.html.haml L6**: フォームパーシャルをレンダリング
- **_form.html.haml L18-20**: タイトル入力フィールド
- **_form.html.haml L23-26**: 説明テキストエリア
- **_form.html.haml L28-36**: カラーピッカーとプリセット色

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

```
Projects::LabelsController#new
    │
    └─ @label = @project.labels.new
           │
           └─ app/views/projects/labels/new.html.haml
                  └─ shared/labels/_form.html.haml
                         └─ render_suggested_colors

Projects::LabelsController#create
    │
    ├─ Labels::CreateService.new(label_params).execute(project: @project)
    │      ├─ Label.create
    │      └─ バリデーション実行
    │
    └─ リダイレクト処理
           ├─ 成功時 → ラベル一覧
           └─ 失敗時 → フォーム再表示
```

### データフロー図

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

フォーム入力 ───▶ LabelsController#create
(title, description,         │
 color)                      ▼
                   Labels::CreateService#execute
                             │
                             ▼
                   Label.create (ActiveRecord)
                             │
                   ┌─────────┴─────────┐
                   ▼                   ▼
             バリデーション成功    バリデーション失敗
                   │                   │
                   ▼                   ▼
             リダイレクト        フォーム再表示
             (一覧画面)          (エラー表示)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| labels_controller.rb | `app/controllers/projects/labels_controller.rb` | コントローラー | new/createアクション |
| label.rb | `app/models/label.rb` | モデル | ラベルのデータモデル |
| create_service.rb | `app/services/labels/create_service.rb` | サービス | 作成処理ロジック |
| new.html.haml | `app/views/projects/labels/new.html.haml` | テンプレート | 新規作成画面 |
| _form.html.haml | `app/views/shared/labels/_form.html.haml` | 部分テンプレート | フォームパーシャル |
| labels_helper.rb | `app/helpers/labels_helper.rb` | ヘルパー | render_suggested_colors等 |
