# 画面設計書 58-ラベル編集

## 概要

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

### 本画面の処理概要

**業務上の目的・背景**：プロジェクトの進行に伴い、ラベルの名前や色、説明を変更する必要が生じることがあります。編集画面では、ラベルの属性を変更し、ワークフローの見直しを反映できます。また、不要になったラベルの削除やアーカイブもこの画面から行えます。

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

**主要な操作・処理内容**：
1. ラベル名の編集（必須）
2. ラベル説明の編集（任意）
3. 背景色の変更（カラーピッカーまたはプリセットから）
4. マージ時ロック設定の変更（対応プロジェクトのみ）
5. 変更内容の保存
6. ラベルの削除
7. ラベルのアーカイブ解除（アーカイブ済みラベルの場合）
8. キャンセルして一覧画面へ戻る

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

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

## 関連機能

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

## 画面種別

編集画面（フォーム）

## URL/ルーティング

```
GET   /:namespace/:project/-/labels/:id/edit
PATCH /:namespace/:project/-/labels/:id
PUT   /:namespace/:project/-/labels/:id
```

コントローラー: `Projects::LabelsController#edit`, `Projects::LabelsController#update`

## 入出力項目

### 入力項目

| 項目名 | データ型 | 必須 | 最大長 | 説明 |
|--------|---------|------|--------|------|
| title | String | ○ | - | ラベルの名前 |
| description | Text | - | 512KB | ラベルの説明 |
| color | String | ○ | 7文字 | 背景色（HEX形式 例: #FF0000） |
| lock_on_merge | Boolean | - | - | マージ時ロック設定 |
| archived | Boolean | - | - | アーカイブ状態 |

## 表示項目

### アーカイブアラート（アーカイブ済みの場合）

| 項目名 | 説明 |
|--------|------|
| 警告メッセージ | 「This label is archived and not available for use.」 |
| Unarchive labelボタン | アーカイブ解除 |

### フォーム構成

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

### ボタン

| ボタン名 | 説明 |
|---------|------|
| Save changes | 変更を保存 |
| Cancel | 編集をキャンセルして一覧へ戻る |
| Delete | ラベルを削除（赤色、右寄せ） |

## イベント仕様

### 1-Save changesボタン押下

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

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

### 2-Cancelボタン押下

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

### 3-Deleteボタン押下

確認モーダルを表示後、ラベルを削除します。ロックされたラベル（lock_on_merge=true）は削除できません。

### 4-Unarchive labelボタン押下

アーカイブ済みラベルをアーカイブ解除し、再び使用可能な状態にします。

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

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

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Save changes押下 | labels | UPDATE | ラベル更新 |
| Delete押下 | labels | DELETE | ラベル削除 |
| Delete押下 | label_links | DELETE | ラベルリンク削除 |
| Delete押下 | label_priorities | DELETE | 優先順位削除 |
| Unarchive押下 | labels | UPDATE | archived=false |

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

#### labels

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | title | 入力されたラベル名 | 必須 |
| UPDATE | description | 入力された説明 | 任意 |
| UPDATE | color | 入力された背景色 | HEX形式 |
| UPDATE | lock_on_merge | チェック状態 | 対応プロジェクトのみ |
| UPDATE | archived | チェック状態 | フィーチャーフラグ有効時 |
| UPDATE | updated_at | 現在時刻 | |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|---------|
| 成功 | {label_name} was removed | 削除成功時 |
| 警告 | This label is archived and not available for use. Unarchive to use it again. | アーカイブ済みラベル表示時 |
| エラー | Title has already been taken | 同名のラベルが存在する場合 |
| エラー | {label_name} is locked and was not removed | ロックされたラベルの削除試行時 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| ラベルが存在しない | 404ページを表示 |
| 編集権限がない | 404ページを表示 |
| バリデーションエラー | フォームを再表示し、エラーメッセージを表示 |
| ロックされたラベルの削除 | エラーメッセージを表示し、一覧画面へリダイレクト |

## 備考

- lock_on_merge属性が設定されたラベルは削除できません
- アーカイブ機能はフィーチャーフラグ（labels_archive）で制御されます
- テンプレートラベルにはlock_on_mergeを設定できません
- 同一プロジェクト内でラベル名は一意である必要があります
- lock_on_mergeが既に設定されている場合、チェックボックスは無効化されます

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | label.rb | `app/models/label.rb` | validates、lock_on_merge、archived |

**読解のコツ**: Labelモデルはlock_on_mergeとarchivedの属性を持ち、それぞれ削除防止とアーカイブ状態を管理します。

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

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

**主要処理フロー**:
1. **L64**: editアクションは空（ビューレンダリングのみ）
2. **L66-74**: updateアクションでサービスを呼び出し
3. **L67**: `Labels::UpdateService`を使用してラベルを更新
4. **L89-97**: destroyアクションでラベルを削除

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

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

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

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

**主要処理フロー**:
- **edit.html.haml L5**: show_lock_on_mergeフラグの設定
- **edit.html.haml L9**: フォームパーシャルをレンダリング
- **_form.html.haml L5-13**: アーカイブ済みラベルのアラート表示
- **_form.html.haml L37-43**: lock_on_mergeチェックボックス
- **_form.html.haml L53-56**: 削除ボタン

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

```
Projects::LabelsController#edit
    │
    └─ app/views/projects/labels/edit.html.haml
           └─ shared/labels/_form.html.haml
                  ├─ アーカイブアラート（条件付き）
                  ├─ フォームフィールド
                  ├─ lock_on_mergeチェックボックス（条件付き）
                  └─ 削除ボタン

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

Projects::LabelsController#destroy
    │
    ├─ @label.destroy
    │      └─ prevent_locked_label_destroy コールバック
    │
    └─ リダイレクト（一覧画面）
```

### データフロー図

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

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

### 関連ファイル一覧

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