# 画面設計書 60-作業アイテム詳細

## 概要

本ドキュメントは、GitLabにおけるプロジェクト作業アイテム（Work Items）詳細画面に関する設計書です。Epics、Tasks、Objectives、Key Results、Incidentsなど様々なタイプの作業アイテムの詳細情報を表示し、編集するための画面仕様を定義します。

### 本画面の処理概要

**業務上の目的・背景**：Work Items（作業アイテム）は、従来のIssueを発展させた新しいワークアイテム管理システムです。詳細画面では、作業アイテムの全情報（タイトル、説明、担当者、ラベル、マイルストーンなど）を表示し、ウィジェットベースの柔軟なUIで各種情報の閲覧・編集が可能です。作業アイテムタイプごとに表示されるウィジェットが異なり、タイプに応じた最適な情報管理を実現します。

**画面へのアクセス方法**：作業アイテム一覧画面から該当アイテムをクリック、または直接URL `/:namespace/:project/-/work_items/:iid` にアクセスします。

**主要な操作・処理内容**：
1. 作業アイテムの詳細情報表示
2. タイトル・説明の編集
3. 担当者・ラベル・マイルストーンの設定
4. 親子関係の管理（階層構造）
5. 関連アイテムのリンク管理
6. コメント・ディスカッションの追加
7. 作業アイテムタイプの変換
8. 時間トラッキングの管理
9. デザイン管理（対応タイプの場合）

**画面遷移**：
- 遷移元：作業アイテム一覧画面、課題一覧画面、ボード画面
- 遷移先：親作業アイテム詳細画面、子作業アイテム詳細画面、関連アイテム詳細画面

**権限による表示制御**：
- プロジェクトメンバー：作業アイテムの閲覧が可能
- `update_work_item`権限：作業アイテムの編集が可能
- `admin_work_item`権限：作業アイテムの削除・タイプ変換が可能

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 46 | ワークアイテム管理 | 主機能 | 作業アイテムの詳細表示・編集 |
| 36 | イシュー作成 | 補助機能 | 作業アイテムとしてのIssue管理 |

## 画面種別

詳細画面（Vue.js SPA）

## URL/ルーティング

```
GET /:namespace/:project/-/work_items/:iid
GET /:namespace/:project/-/work_items/new
```

コントローラー: `Projects::WorkItemsController#show`

## 入出力項目

### URLパラメータ

| 項目名 | データ型 | 必須 | 説明 |
|--------|---------|------|------|
| namespace | String | ○ | ネームスペース（グループまたはユーザー名） |
| project | String | ○ | プロジェクト名 |
| iid | Integer/String | ○ | 作業アイテムのIID、または 'new' |

### クエリパラメータ

| 項目名 | データ型 | 必須 | 説明 |
|--------|---------|------|------|
| edit | String | - | 'true'の場合、編集モードで開く |

## 表示項目

### ヘッダー部

| 項目名 | 説明 |
|--------|------|
| タイプアイコン | 作業アイテムタイプのアイコン |
| タイトル | 作業アイテムのタイトル（編集可能） |
| IID | 作業アイテムの識別番号 |
| 状態バッジ | Open/Closed状態の表示 |
| アクションボタン | 編集、クローズ、削除など |

### ウィジェット（作業アイテムタイプにより表示が異なる）

| ウィジェット名 | 説明 |
|---------------|------|
| Description | 説明文（Markdown対応） |
| Assignees | 担当者の設定 |
| Labels | ラベルの設定 |
| Milestone | マイルストーンの設定 |
| Start and Due Date | 開始日・期日の設定 |
| Time Tracking | 時間トラッキング |
| Hierarchy | 親子関係の表示・管理 |
| Linked Items | 関連アイテムのリンク |
| Notes | コメント・ディスカッション |
| Participants | 参加者一覧 |
| Notifications | 通知設定 |
| Current User Todos | 現在のユーザーのToDo |
| Award Emoji | 絵文字リアクション |
| Designs | デザイン管理（対応タイプのみ） |
| Development | 開発情報（MR、ブランチ） |
| CRM Contacts | CRM連絡先 |

### サイドバー

| 項目名 | 説明 |
|--------|------|
| 担当者 | 担当者の選択・表示 |
| ラベル | ラベルの選択・表示 |
| マイルストーン | マイルストーンの選択・表示 |
| 期日 | 期日の設定・表示 |
| 時間トラッキング | 見積もり時間・実績時間 |
| 機密性 | 機密アイテムの設定 |
| ロック | ディスカッションのロック |

## イベント仕様

### 1-タイトル編集

タイトルをクリックして編集モードに入り、変更を保存します。GraphQL APIを通じて非同期で更新されます。

### 2-説明編集

説明セクションの編集ボタンをクリックし、Markdownエディタで編集します。プレビュー機能あり。

### 3-担当者変更

サイドバーの担当者セクションから担当者を追加・削除します。複数担当者の設定が可能です。

### 4-ラベル変更

サイドバーのラベルセクションからラベルを追加・削除します。ラベル検索・作成も可能です。

### 5-状態変更

「Close」または「Reopen」ボタンをクリックして状態を変更します。

### 6-子アイテム追加

Hierarchyウィジェットから子アイテムを追加します。既存アイテムのリンクまたは新規作成が可能です。

### 7-関連アイテム追加

Linked Itemsウィジェットから関連アイテムをリンクします。「relates to」「blocks」「is blocked by」の関係タイプを選択できます。

### 8-コメント追加

Notesウィジェットでコメントを追加します。Markdown対応、メンション機能あり。

### 9-タイプ変換

アクションメニューから作業アイテムタイプを変換します。変換可能なタイプは現在のタイプと階層制約により制限されます。

### 10-削除

アクションメニューから作業アイテムを削除します。確認モーダルが表示されます。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 詳細表示 | issues | SELECT | 作業アイテム取得 |
| タイトル編集 | issues | UPDATE | タイトル更新 |
| 説明編集 | issues | UPDATE | 説明更新 |
| 担当者変更 | issue_assignees | INSERT/DELETE | 担当者関連付け |
| ラベル変更 | label_links | INSERT/DELETE | ラベル関連付け |
| 状態変更 | issues | UPDATE | state_id更新 |
| 子アイテム追加 | work_item_parent_links | INSERT | 親子関係作成 |
| 関連アイテム追加 | issue_links | INSERT | リンク作成 |
| コメント追加 | notes | INSERT | ノート作成 |
| 削除 | issues | DELETE | 作業アイテム削除 |

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

#### issues

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | title | 入力されたタイトル | 必須 |
| UPDATE | description | 入力された説明 | Markdown |
| UPDATE | state_id | 1(open)/2(closed) | 状態変更時 |
| UPDATE | milestone_id | 選択されたマイルストーン | |
| UPDATE | confidential | true/false | 機密設定 |
| UPDATE | discussion_locked | true/false | ロック設定 |
| UPDATE | updated_at | 現在時刻 | |

#### work_item_parent_links

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | work_item_id | 子アイテムID | |
| INSERT | work_item_parent_id | 親アイテムID | |
| INSERT | relative_position | 相対位置 | 並び順用 |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|---------|
| 成功 | Work item updated | 更新成功時 |
| 成功 | Work item closed | クローズ成功時 |
| 成功 | Work item reopened | リオープン成功時 |
| 成功 | Work item deleted | 削除成功時 |
| エラー | Something went wrong | API呼び出し失敗時 |
| エラー | A non-confidential work item cannot have a confidential parent | 機密設定エラー時 |
| 警告 | All child items must be confidential | 機密化時に子アイテムが非機密の場合 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| 作業アイテムが存在しない | 404ページを表示 |
| 閲覧権限がない | 404ページを表示 |
| 編集権限がない | 編集機能を非表示 |
| 親子関係の制約違反 | エラーメッセージを表示 |
| 最大深度超過 | エラーメッセージを表示 |

## 備考

- Work Items機能はVue.jsベースのSPAとして実装されており、GraphQL APIを通じてデータを取得・更新します
- WorkItemはIssueモデルを継承しており、内部的には同じテーブル（issues）を使用します
- 表示されるウィジェットは作業アイテムタイプごとにWidgetDefinitionで定義されています
- 親子関係にはHierarchyRestrictionによる制約があり、許可されたタイプの組み合わせのみリンク可能です
- 階層には最大深度制限があり、same_type_descendants_depthで管理されています
- 機密アイテムは親子関係に制約があります（親が機密の場合、子も機密である必要あり）

---

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

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

### 推奨読解順序

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

Work Itemのモデルとウィジェットシステムを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | work_item.rb | `app/models/work_item.rb` | WorkItemモデル、Issueからの継承、widgets メソッド |
| 1-2 | type.rb | `app/models/work_items/type.rb` | 作業アイテムタイプの定義、BASE_TYPES |
| 1-3 | widget_definition.rb | `app/models/work_items/widget_definition.rb` | ウィジェット定義 |
| 1-4 | parent_link.rb | `app/models/work_items/parent_link.rb` | 親子関係モデル |

**読解のコツ**: WorkItemはIssueを継承しており、table_nameは'issues'です。widgets メソッドでタイプに応じたウィジェットを取得できます。get_widget(type)で個別ウィジェットにアクセスします。

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

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

**主要処理フロー**:
1. **L45-49**: showアクションで@work_itemを設定
2. **L46**: iidが'new'の場合は早期リターン（新規作成モード）
3. **L121-125**: issuableメソッドでWorkItemsFinderを使用して取得

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/projects/work_items/show.html.haml` | 詳細画面テンプレート |
| 3-2 | _work_item_metadata.html.haml | `app/views/shared/_work_item_metadata.html.haml` | メタデータパーシャル |

**主要処理フロー**:
- **show.html.haml L1-2**: @work_itemが存在する場合、メタデータをレンダリング
- **show.html.haml L11**: `#js-work-items`がVue.jsアプリケーションのマウントポイント
- **show.html.haml L11**: `work_item_views_only_data`ヘルパーでフロントエンドにデータを渡す

#### Step 4: ウィジェットシステムを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | base.rb | `app/models/work_items/widgets/base.rb` | ウィジェット基底クラス |
| 4-2 | description.rb | `app/models/work_items/widgets/description.rb` | 説明ウィジェット |
| 4-3 | hierarchy.rb | `app/models/work_items/widgets/hierarchy.rb` | 階層ウィジェット |
| 4-4 | assignees.rb | `app/models/work_items/widgets/assignees.rb` | 担当者ウィジェット |

#### Step 5: Finderを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | work_items_finder.rb | `app/finders/work_items/work_items_finder.rb` | 作業アイテム検索ロジック |

**主要処理フロー**:
- **L23-25**: klassメソッドでWorkItemクラスを返す
- **L38-48**: filter_itemsでウィジェットベースのフィルタリングを実行
- **L68-78**: by_widgetsで各ウィジェットのフィルタを適用

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

```
Projects::WorkItemsController#show
    │
    ├─ issuable (L121-125)
    │      └─ WorkItems::WorkItemsFinder
    │             └─ find_by_iid(show_params[:iid])
    │
    └─ app/views/projects/work_items/show.html.haml
           │
           ├─ shared/_work_item_metadata.html.haml
           │      └─ ページタイトル・メタ情報設定
           │
           └─ #js-work-items (Vue.js Application)
                  │
                  ├─ GraphQL API呼び出し
                  │      ├─ workItem query
                  │      └─ workItemUpdate mutation
                  │
                  ├─ ウィジェットコンポーネント群
                  │      ├─ DescriptionWidget
                  │      ├─ AssigneesWidget
                  │      ├─ LabelsWidget
                  │      ├─ MilestoneWidget
                  │      ├─ HierarchyWidget
                  │      ├─ LinkedItemsWidget
                  │      ├─ NotesWidget
                  │      └─ ... (タイプに応じて動的)
                  │
                  └─ Apollo Client / Vuex Store
```

### データフロー図

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

URLアクセス ───▶ WorkItemsController#show
(/:iid)                │
                       ▼
             WorkItemsFinder.find_by_iid
                       │
                       ▼
             @work_item 取得
                       │
                       ▼
             Vue.js Application マウント
                       │
                       ▼
             GraphQL workItem クエリ
                       │
                       ▼
             ウィジェット別データ取得 ───▶ 画面レンダリング


[更新操作]

ウィジェット操作 ───▶ GraphQL workItemUpdate ミューテーション
                              │
                              ▼
                    WorkItems::UpdateService
                              │
                              ▼
                    WorkItem.update / 関連テーブル更新
                              │
                              ▼
                    Apollo キャッシュ更新 ───▶ UI再レンダリング
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| work_items_controller.rb | `app/controllers/projects/work_items_controller.rb` | コントローラー | 詳細画面のエントリーポイント |
| work_item.rb | `app/models/work_item.rb` | モデル | 作業アイテムのデータモデル |
| type.rb | `app/models/work_items/type.rb` | モデル | 作業アイテムタイプ定義 |
| parent_link.rb | `app/models/work_items/parent_link.rb` | モデル | 親子関係モデル |
| work_items_finder.rb | `app/finders/work_items/work_items_finder.rb` | Finder | 検索ロジック |
| show.html.haml | `app/views/projects/work_items/show.html.haml` | テンプレート | 詳細画面 |
| _work_item_metadata.html.haml | `app/views/shared/_work_item_metadata.html.haml` | 部分テンプレート | メタデータ設定 |
| work_items_helper.rb | `app/helpers/work_items_helper.rb` | ヘルパー | work_item_views_only_data等 |
| widgets/base.rb | `app/models/work_items/widgets/base.rb` | モデル | ウィジェット基底クラス |
| widgets/description.rb | `app/models/work_items/widgets/description.rb` | モデル | 説明ウィジェット |
| widgets/hierarchy.rb | `app/models/work_items/widgets/hierarchy.rb` | モデル | 階層ウィジェット |
| widgets/assignees.rb | `app/models/work_items/widgets/assignees.rb` | モデル | 担当者ウィジェット |
| widgets/labels.rb | `app/models/work_items/widgets/labels.rb` | モデル | ラベルウィジェット |
| widgets/milestone.rb | `app/models/work_items/widgets/milestone.rb` | モデル | マイルストーンウィジェット |
| widgets/notes.rb | `app/models/work_items/widgets/notes.rb` | モデル | ノートウィジェット |
| widgets/linked_items.rb | `app/models/work_items/widgets/linked_items.rb` | モデル | 関連アイテムウィジェット |
