# 機能設計書 6-ボード一覧表示

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるボード一覧表示機能の設計書である。ユーザーがアクセス可能なカンバンボードの一覧を表示し、ボードへのナビゲーションを提供する。

### 本機能の処理概要

**業務上の目的・背景**：チームやプロジェクトごとにボードを分けて管理することで、タスクの整理と可視化を実現する。ユーザーは自分がアクセス権を持つボードのみを一覧で確認でき、効率的にボード間を移動できる。

**機能の利用シーン**：ユーザーがFizzyにログイン後、マイメニューやダッシュボードからボード一覧を確認する。最近アクセスしたボードが上位に表示されるため、頻繁に使用するボードにすばやくアクセスできる。

**主要な処理内容**：
1. ユーザーがアクセス可能なボードを取得
2. HTML形式: ボードをそのまま一覧表示
3. JSON形式: 最近アクセス順でソートしてページング付きで取得
4. ページングとETag対応による効率的なデータ取得

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

**権限による制御**：all_access（全員アクセス可能）なボード、または個別にアクセス権を付与されたボードのみ表示される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 48 | マイメニュー画面 | 主画面 | マイページのメニューとボード一覧を表示 |

## 機能種別

データ取得 / 一覧表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| page | Integer | No | ページ番号（ページング用） | 正の整数 |
| format | String | No | レスポンス形式（html/json） | - |

### 入力データソース

- Cookie（セッショントークン）- 現在のユーザーを特定
- URLパラメータ（ページ番号）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @page | Page | ページングされたボード一覧 |
| boards | Array<Board> | ボードレコードの配列 |

### 出力先

- 画面表示（ボード一覧）
- JSON API（ページング付きボード一覧）

## 処理フロー

### 処理シーケンス

```
1. ボード一覧リクエスト受信（BoardsController#index）
   └─ request.formatで形式判定
2. ボード取得
   └─ JSON: Current.user.boards.ordered_by_recently_accessed
   └─ HTML: Current.user.boards
3. ページング処理
   └─ set_page_and_extract_portion_from
4. ETagキャッシュ処理（JSON）
   └─ fresh_when etag: @page.records
5. レスポンス返却
```

### フローチャート

```mermaid
flowchart TD
    A[ボード一覧リクエスト] --> B{レスポンス形式}
    B -->|JSON| C[最近アクセス順でソート]
    B -->|HTML| D[デフォルト順で取得]
    C --> E[ページング処理]
    D --> E
    E --> F[ETagキャッシュ判定]
    F -->|変更なし| G[304 Not Modified]
    F -->|変更あり| H[ボード一覧返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | アクセス権フィルタ | ユーザーがアクセス可能なボードのみ表示 | 全リクエスト |
| BR-002 | 最近アクセス順 | JSON形式では最近アクセスしたボードが上位 | JSON形式リクエスト |
| BR-003 | ETagキャッシュ | ボード内容に変更がない場合は304返却 | JSON形式リクエスト |

### 計算ロジック

- アクセス可能ボード: User.boardsでAccessテーブル経由で取得
- 最近アクセス順: Access.ordered_by_recently_accessed（accessed_at DESC）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ボード取得 | boards, accesses | SELECT | user_idでアクセス可能なボードを取得 |

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

#### boards（accessesを経由）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | - | accesses.user_id = Current.user.id | JOINで取得 |
| ORDER | accessed_at | DESC（JSON形式） | 最近アクセス順 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | 認証エラー | 未認証状態でアクセス | ログイン画面へリダイレクト |

### リトライ仕様

該当なし

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

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

## パフォーマンス要件

- ETagキャッシュ: 変更がない場合は304レスポンスで帯域削減
- ページング: 大量のボードがある場合も効率的に取得

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

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

## 備考

- User#boardsはAccessテーブルを経由してボードを取得
- all_access=trueのボードは全ユーザーに自動的にAccess付与

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | board.rb | `app/models/board.rb` | Boardモデルの構造、includeされるモジュール |
| 1-2 | accessible.rb | `app/models/board/accessible.rb` | アクセス権管理、has_many :users through: :accesses |
| 1-3 | access.rb | `app/models/access.rb` | Accessモデル、ordered_by_recently_accessedスコープ |

**読解のコツ**: BoardモデルはAccessibleモジュールをincludeしており、アクセス権管理はAccessテーブルを介して行われる。

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

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

**主要処理フロー**:
1. **7-13行目**: indexアクションの実装
2. **8-10行目**: JSON形式の場合、ordered_by_recently_accessedとETag設定
3. **12行目**: HTML形式の場合、シンプルな一覧取得

#### Step 3: ユーザーとボードの関連を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | user.rb | `app/models/user.rb` | Accessorモジュールのinclude |

**主要処理フロー**:
- User#boardsはAccessorモジュールで定義されている

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

```
BoardsController#index
    │
    ├─ [JSON] Current.user.boards.ordered_by_recently_accessed
    │      └─ merge(Access.ordered_by_recently_accessed)
    │             └─ order(accessed_at: :desc)
    │
    ├─ [HTML] Current.user.boards
    │      └─ has_many :boards, through: :accesses
    │
    └─ set_page_and_extract_portion_from
           └─ ページング処理
```

### データフロー図

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

Current.user ─────────▶ BoardsController#index
                              │
                              ├──▶ boards.ordered_by_... ───▶ @page（ボード一覧）
                              │
                              └──▶ fresh_when ───────────────▶ ETag/304
```

### 関連ファイル一覧

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