# 画面設計書 51-ボード表示

## 概要

本ドキュメントは、GitLabにおける課題ボード（Issue Board）の表示画面に関する設計書です。カンバン形式で課題を視覚的に管理・操作するための画面仕様を定義します。

### 本画面の処理概要

**業務上の目的・背景**：課題ボードは、プロジェクト内の課題（Issue）をカンバン形式で視覚的に管理するための画面です。アジャイル開発やスクラム手法において、タスクの進捗状況を一目で把握し、ドラッグ＆ドロップで状態を変更できる機能を提供します。開発チームがスプリント内のタスク管理や優先順位付けを効率的に行うことを目的としています。

**画面へのアクセス方法**：プロジェクトのサイドナビゲーションから「Plan」→「Issue boards」を選択、または直接URL `/:namespace/:project/-/boards/:board_id` にアクセスします。ボード一覧画面からボードを選択して遷移することもできます。

**主要な操作・処理内容**：
1. ボード上の課題カードの表示と一覧閲覧
2. 課題カードのドラッグ＆ドロップによるリスト間の移動（ステータス変更）
3. リストの追加・削除・並び替え
4. 課題のフィルタリング（ラベル、担当者、マイルストーンなど）
5. 課題カードのクイック編集（担当者、ラベルの変更）
6. 新規課題の作成（リスト内から直接作成）
7. ボードの切り替え（複数ボードが利用可能な場合）

**画面遷移**：
- 遷移元：ボード一覧画面、プロジェクトトップページ、課題一覧画面
- 遷移先：課題詳細画面（カードクリック時）、ラベル管理画面、マイルストーン管理画面

**権限による表示制御**：
- `read_issue_board`権限：ボードの閲覧が可能
- `admin_issue`権限：課題の移動・編集が可能
- `admin_issue_board_list`権限：リストの追加・削除が可能
- `admin_issue_board`権限：ボード設定の変更が可能

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 39 | イシューボード | 主機能 | カンバン形式での課題管理 |
| 36 | イシュー作成 | 補助機能 | ボード上での新規課題作成 |
| 37 | イシュー編集 | 補助機能 | 課題カードの編集操作 |
| 40 | ラベル管理 | 補助機能 | ラベルによるリスト作成・フィルタリング |
| 41 | マイルストーン管理 | 補助機能 | マイルストーンによるフィルタリング |

## 画面種別

一覧・操作画面（カンバンボード形式）

## URL/ルーティング

```
GET /:namespace/:project/-/boards/:id
```

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

## 入出力項目

### フィルター項目

| 項目名 | データ型 | 必須 | 説明 |
|--------|---------|------|------|
| assignee_username | String | - | 担当者によるフィルタ |
| label_name | Array[String] | - | ラベルによるフィルタ |
| milestone_title | String | - | マイルストーンによるフィルタ |
| search | String | - | キーワード検索 |
| author_username | String | - | 作成者によるフィルタ |

## 表示項目

### ボードヘッダー

| 項目名 | 説明 |
|--------|------|
| ボード名 | 現在表示中のボード名 |
| ボード切り替えドロップダウン | 他のボードへの切り替え |
| フィルターバー | 課題のフィルタリング条件 |

### リスト（列）

| 項目名 | 説明 |
|--------|------|
| リスト名 | ラベル名またはリスト種別名 |
| 課題数 | リスト内の課題件数 |
| 課題カード一覧 | リスト内の課題カード |
| 新規課題追加ボタン | リスト内に課題を追加 |

### 課題カード

| 項目名 | 説明 |
|--------|------|
| 課題番号 | #IID形式 |
| タイトル | 課題のタイトル |
| ラベル | 付与されているラベル（色付き） |
| 担当者アバター | 担当者のアバター画像 |
| マイルストーン | 関連付けられたマイルストーン |
| 期日 | 期限日（設定されている場合） |
| 重み | 課題の重み（設定されている場合） |

## イベント仕様

### 1-課題カードドラッグ＆ドロップ

課題カードを別のリストにドラッグ＆ドロップすると、課題のラベルが自動的に更新されます。移動元リストのラベルが削除され、移動先リストのラベルが付与されます。

**処理フロー**：
1. フロントエンドでドラッグ操作を検知
2. GraphQL API経由でボードリスト内の課題位置を更新
3. 課題のラベルを更新
4. UIを更新して新しい位置を反映

### 2-リスト追加

新規リストを追加します。ラベルベースのリストまたは担当者ベースのリストを作成できます。

### 3-課題クイック作成

リスト内の「新規課題」ボタンから、タイトルのみを入力して課題を素早く作成します。

### 4-フィルタリング

フィルターバーで条件を指定すると、該当する課題のみがボード上に表示されます。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| カード移動 | label_links | INSERT/DELETE | ラベルの付け替え |
| カード位置変更 | issues | UPDATE | relative_position更新 |
| リスト追加 | lists | INSERT | 新規リスト作成 |
| リスト削除 | lists | DELETE | リスト削除 |
| 課題クイック作成 | issues | INSERT | 新規課題作成 |
| 課題クイック作成 | label_links | INSERT | ラベル関連付け |

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

#### lists

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | board_id | 現在のボードID | |
| INSERT | label_id | 選択されたラベルID | ラベルリストの場合 |
| INSERT | list_type | リスト種別 | label, closed, backlog等 |
| INSERT | position | リスト位置 | |

#### label_links

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | target_id | 課題ID | |
| INSERT | target_type | 'Issue' | |
| INSERT | label_id | 移動先リストのラベルID | |
| DELETE | label_id | 移動元リストのラベルID | |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|---------|
| 成功 | Issue moved successfully | 課題移動成功時 |
| 警告 | Positioning is disabled | リポジトリで位置付けが無効な場合 |
| エラー | Unable to move issue | 課題移動失敗時 |
| エラー | Unable to create issue | 課題作成失敗時 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| ボードが存在しない | 404ページを表示 |
| 閲覧権限がない | 403エラーを返却 |
| ボードが無効化されている | 「Positioning is disabled」アラートを表示 |
| API通信エラー | エラーメッセージを表示し、操作を元に戻す |

## 備考

- ボード機能はVue.jsベースのSPAとして実装されており、GraphQL APIを通じてデータを取得・更新します
- 複数ボード機能は有料プランで利用可能な場合があります
- Work Itemsへの移行に伴い、将来的にはWork Itemsベースのボードに統合される予定です

---

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

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

### 推奨読解順序

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

ボード機能の中核となるモデルとその関連を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | board.rb | `app/models/board.rb` | Boardモデルの定義、lists関連付け |
| 1-2 | list.rb | `app/models/list.rb` | Listモデルの定義、リスト種別 |
| 1-3 | label.rb | `app/models/label.rb` | Labelモデルとリストの関連 |

**読解のコツ**: BoardはProjectまたはGroupに属し、複数のListを持ちます。ListはLabelに関連付けられています。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | boards_controller.rb | `app/controllers/projects/boards_controller.rb` | showアクションのルーティング |
| 2-2 | boards_actions.rb | `app/controllers/concerns/boards_actions.rb` | 共通ロジック |

**主要処理フロー**:
1. **L7-13**: before_actionでフラグを設定
2. **L20-24**: board_finderでボードを取得
3. **L32-34**: 権限チェック

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/projects/boards/show.html.haml` | 共有テンプレートの呼び出し |
| 3-2 | _show.html.haml | `app/views/shared/boards/_show.html.haml` | Vue.jsアプリのマウントポイント |

**主要処理フロー**:
- **L22**: `#js-issuable-board-app`がVue.jsアプリケーションのマウントポイント
- **L10**: `board_data`ヘルパーでフロントエンドに必要なデータを渡す

#### Step 4: ヘルパーとフロントエンドデータを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | boards_helper.rb | `app/helpers/boards_helper.rb` | board_dataの構築 |

**主要処理フロー**:
- **L8-29**: `board_data`メソッドでVue.jsに渡すデータを構築
- **L107-117**: 権限チェックメソッド群

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

```
Projects::BoardsController#show
    │
    ├─ BoardsActions (concern)
    │      ├─ board_finder (Boards::BoardsFinder)
    │      └─ authorize_read_board!
    │
    ├─ app/views/projects/boards/show.html.haml
    │      └─ shared/boards/_show.html.haml
    │             └─ board_data (BoardsHelper)
    │
    └─ #js-issuable-board-app (Vue.js Application)
           ├─ GraphQL API calls
           └─ Vuex Store
```

### データフロー図

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

URLパラメータ ───▶ BoardsController ───▶ @board取得
                        │
                        ▼
              BoardsHelper#board_data ───▶ JSON形式でVue.jsに渡す
                        │
                        ▼
              Vue.js Application ───▶ GraphQL API呼び出し
                        │
                        ▼
              ボード表示・操作 ───▶ 画面レンダリング
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| boards_controller.rb | `app/controllers/projects/boards_controller.rb` | コントローラー | ボード画面のエントリーポイント |
| boards_actions.rb | `app/controllers/concerns/boards_actions.rb` | Concern | 共通ボードアクション |
| board.rb | `app/models/board.rb` | モデル | ボードのデータモデル |
| list.rb | `app/models/list.rb` | モデル | リストのデータモデル |
| boards_helper.rb | `app/helpers/boards_helper.rb` | ヘルパー | ビューヘルパー |
| show.html.haml | `app/views/projects/boards/show.html.haml` | テンプレート | ビューテンプレート |
| _show.html.haml | `app/views/shared/boards/_show.html.haml` | 部分テンプレート | 共有テンプレート |
| boards_finder.rb | `app/finders/boards/boards_finder.rb` | Finder | ボード検索ロジック |
