# 機能設計書 8-ボード詳細表示

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるボードの詳細（カラムとカード）を表示する機能の設計書である。カンバンボードの全体像を表示し、カードのトリアージやカラムへの振り分けを行う基盤となる画面を提供する。

### 本機能の処理概要

**業務上の目的・背景**：カンバン方式のタスク管理において、ボード全体を俯瞰し、タスク（カード）の状態を把握することが重要である。本機能はボードの詳細表示を通じて、トリアージ待ちカードの確認やカラムごとのカード配置を可視化する。

**機能の利用シーン**：ユーザーがボードを選択して詳細を確認する際に使用する。フィルター条件が設定されている場合はフィルター結果のカード一覧、設定されていない場合はトリアージ待ちカードとカラム一覧を表示する。

**主要な処理内容**：
1. ボードの取得とアクセス権確認
2. フィルター条件の判定
3. フィルターありの場合: フィルター結果のカード一覧表示
4. フィルターなしの場合: トリアージ待ちカード一覧とカラム表示
5. ETagキャッシュによる効率的な更新チェック

**関連システム・外部連携**：なし

**権限による制御**：ユーザーがアクセス権を持つボードのみ表示可能。Current.user.boards.findでアクセス権チェック。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | ボード詳細画面 | 主画面 | ボードの詳細（カラムとカード）を表示 |

## 機能種別

データ取得 / 詳細表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | String | Yes | ボードID | UUID形式 |
| filter params | Hash | No | フィルター条件（クエリパラメータ） | - |
| page | Integer | No | ページ番号 | 正の整数 |

### 入力データソース

- URLパラメータ（ボードID）
- クエリパラメータ（フィルター条件、ページ番号）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @board | Board | ボードレコード |
| @page | Page | ページングされたカード一覧 |
| @filter | Filter | フィルター条件オブジェクト |

### 出力先

- 画面表示（ボード詳細、カード一覧）

## 処理フロー

### 処理シーケンス

```
1. ボード取得（set_board）
   └─ Current.user.boards.find(params[:id])
2. フィルター条件判定（showアクション）
   └─ @filter.used?(ignore_boards: true)で判定
3. フィルターありの場合（show_filtered_cards）
   └─ @filter.board_ids = [@board.id]で絞り込み
   └─ @filter.cardsでフィルター適用
4. フィルターなしの場合（show_columns）
   └─ @board.cards.awaiting_triage.latest.with_golden_first
   └─ preloadedで関連データ取得
5. ページング処理
   └─ set_page_and_extract_portion_from
6. ETagキャッシュ
   └─ fresh_when etag: [@board, @page.records, ...]
```

### フローチャート

```mermaid
flowchart TD
    A[ボード詳細リクエスト] --> B[set_board]
    B --> C{アクセス権あり?}
    C -->|No| D[404 Not Found]
    C -->|Yes| E{フィルター使用?}
    E -->|Yes| F[show_filtered_cards]
    E -->|No| G[show_columns]
    F --> H[ページング処理]
    G --> I[トリアージ待ちカード取得]
    I --> H
    H --> J[ETagキャッシュ判定]
    J -->|変更なし| K[304 Not Modified]
    J -->|変更あり| L[ボード詳細表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | アクセス権チェック | ユーザーがアクセス権を持つボードのみ表示 | 全リクエスト |
| BR-002 | フィルター分岐 | フィルター条件がある場合はフィルター結果を表示 | フィルターパラメータあり |
| BR-003 | ゴールデン優先 | ゴールデンマーク付きカードを上位に表示 | トリアージ待ち一覧 |
| BR-004 | 最新順 | カードは作成日時の新しい順に表示 | トリアージ待ち一覧 |

### 計算ロジック

- トリアージ待ち: cards.awaiting_triageスコープ
- ゴールデン優先: with_golden_firstスコープ
- 最新順: latestスコープ

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ボード取得 | boards, accesses | SELECT | アクセス権チェック付きでボード取得 |
| カード取得 | cards | SELECT | トリアージ待ちまたはフィルター結果 |
| 関連データ取得 | 複数テーブル | SELECT | preloadedで関連データ一括取得 |

### テーブル別操作詳細

#### boards

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id | params[:id] | accessesとJOINしてアクセス権チェック |

#### cards

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | board_id, column_id | board_id = @board.id, column_id = NULL | awaiting_triage |
| ORDER | golden, created_at | golden DESC, created_at DESC | 優先順位 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | Not Found | ボードが存在しないまたはアクセス権なし | 404画面表示 |
| 401 | 認証エラー | 未認証状態でアクセス | ログイン画面へリダイレクト |

### リトライ仕様

該当なし

## トランザクション仕様

- 読み取り専用操作のためトランザクション不要

## パフォーマンス要件

- ETagキャッシュ: 変更がない場合は304レスポンスで帯域削減
- preloaded: N+1問題回避のための一括プリロード
- ページング: 大量のカードがある場合も効率的に取得

## セキュリティ考慮事項

- アクセス権チェック: Current.user.boards.findでアクセス可能なボードのみ取得
- 認証必須: 認証済みユーザーのみアクセス可能

## 備考

- FilterScopedモジュールでフィルター機能を提供
- fresh_whenのetagに[@board, @page.records, @user_filtering, Current.account]を含め、変更検知を最適化

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | board.rb | `app/models/board.rb` | Boardモデルの構造、includeされるモジュール |
| 1-2 | cards.rb | `app/models/board/cards.rb`（推測） | has_many :cards、カード関連スコープ |

**読解のコツ**: BoardモデルはCardsモジュールをincludeしており、カード関連のスコープ（awaiting_triage等）が定義されている。

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

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

**主要処理フロー**:
1. **4行目**: before_action :set_boardでボード取得
2. **16-22行目**: showアクションの実装
3. **17-21行目**: フィルター使用の判定と処理分岐
4. **83-86行目**: show_filtered_cardsの実装
5. **88-92行目**: show_columnsの実装

#### Step 3: フィルター機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | filter_scoped.rb | `app/controllers/concerns/filter_scoped.rb`（推測） | FilterScopedモジュール |

**主要処理フロー**:
- @filter.used?でフィルター使用判定
- @filter.cardsでフィルター適用されたカード取得

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

```
BoardsController#show
    │
    ├─ set_board
    │      └─ Current.user.boards.find(params[:id])
    │
    ├─ @filter.used?(ignore_boards: true)
    │      │
    │      ├─ [true] show_filtered_cards
    │      │      ├─ @filter.board_ids = [@board.id]
    │      │      └─ set_page_and_extract_portion_from @filter.cards
    │      │
    │      └─ [false] show_columns
    │             ├─ @board.cards.awaiting_triage.latest.with_golden_first.preloaded
    │             ├─ set_page_and_extract_portion_from cards
    │             └─ fresh_when etag: [...]
    │
    └─ レスポンス返却
```

### データフロー図

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

id (ボードID) ─────────▶ BoardsController#show
filter params                 │
                              ├──▶ set_board ───────────────▶ @board
                              │
                              ├──▶ [フィルターあり]
                              │      └──▶ @filter.cards ───▶ @page（カード一覧）
                              │
                              └──▶ [フィルターなし]
                                     └──▶ awaiting_triage ──▶ @page（トリアージ待ち）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| boards_controller.rb | `app/controllers/boards_controller.rb` | コントローラー | ボード詳細取得 |
| board.rb | `app/models/board.rb` | モデル | ボードモデル |
| accessible.rb | `app/models/board/accessible.rb` | コンサーン | アクセス権管理 |
| filter_scoped.rb | `app/controllers/concerns/filter_scoped.rb` | コンサーン | フィルター機能 |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
