# 画面設計書 71-公開ボードクローズド画面

## 概要

本ドキュメントは、Fizzyアプリケーションにおける「公開ボードクローズド画面」の設計仕様を記述したものである。

### 本画面の処理概要

公開ボードクローズド画面は、外部公開されたボードの「クローズ済みカード」を一覧表示するための画面である。認証なしでアクセス可能であり、公開ボードの完了済みタスクを外部ユーザーが閲覧できる。

**業務上の目的・背景**：公開ボードでは、完了したカード（クローズ済みカード）も重要な参考情報となる。外部の利害関係者やパートナーに対して、プロジェクトの完了タスクや過去の作業履歴を共有することで、透明性のあるプロジェクト管理を実現する。未認証ユーザーでもアクセス可能とすることで、組織外への情報共有のハードルを下げている。

**画面へのアクセス方法**：公開ボード詳細画面から「Done」カラムをクリックして遷移する。URL形式は `/public/boards/:published_key/columns/closed` となり、`published_key` はボード公開時に発行される一意のキーである。

**主要な操作・処理内容**：
1. クローズ済みカードの一覧表示（クローズ日時が新しい順）
2. 自動ページネーションによる追加読み込み
3. カードプレビューのクリックによる公開カード詳細画面への遷移

**画面遷移**：
- 遷移元：公開ボード詳細画面
- 遷移先：公開カード詳細画面、公開ボード詳細画面（戻るリンク）

**権限による表示制御**：認証不要。ただし、ボードが公開設定されていること、およびアカウントがキャンセルされていないことが条件となる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 86 | 公開ボード閲覧 | 主機能 | 公開ボードのクローズドカラムを表示 |

## 画面種別

一覧画面

## URL/ルーティング

| パス | HTTPメソッド | コントローラ#アクション |
|------|-------------|----------------------|
| `/public/boards/:board_id/columns/closed` | GET | `Public::Boards::Columns::ClosedsController#show` |

## 入出力項目

本画面は読み取り専用であり、ユーザー入力項目はない。

| 項目 | 入出力 | 説明 |
|------|--------|------|
| board_id | 入力（URL） | 公開キー（published_key） |

## 表示項目

### ヘッダー部

| 項目 | 説明 |
|------|------|
| 戻るリンク | 公開ボード詳細画面へのリンク（ボード名表示） |
| ページタイトル | "Column: Done" |

### カード一覧部

| 項目 | 説明 |
|------|------|
| カード番号 | カードの識別番号 |
| ボード名 | カードが属するボードの名前 |
| タグ | カードに付与されたタグ一覧 |
| カードタイトル | カードのタイトル（最大行数制限あり） |
| カラム表示 | トリアージ済みの場合、所属カラムを表示 |
| スタンプ | カードの状態スタンプ（完了等） |
| メタ情報 | 作成者、日時等のメタ情報 |
| 背景 | カードの色設定による背景表示 |

### フッター部

| 項目 | 説明 |
|------|------|
| コロフォン | アプリケーション情報 |

## イベント仕様

### 1-カードクリック

カードのプレビュー領域をクリックすると、当該カードの公開カード詳細画面に遷移する。

- 遷移先URL: `/public/boards/:board_id/cards/:card_number`
- Turbo Frame: `_top` を指定してフルページ遷移

### 2-戻るリンククリック

ヘッダーの戻るリンク（ボード名）をクリックすると、公開ボード詳細画面に遷移する。

- 遷移先URL: `/public/boards/:board_id`
- ホットキー: 左矢印キー（←）またはEscキーでも同様の遷移

### 3-自動ページネーション

画面スクロールにより、追加のカードデータを自動読み込みする。

- Turbo Frame: `closed_column` フレーム内でコンテンツを更新
- 読み込み条件: `@page.used?` が true の場合

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

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

本画面は読み取り専用であり、データベースの更新は発生しない。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | boards, cards, closures | SELECT | クローズ済みカードの取得 |

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

#### cards（参照のみ）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | 全カラム | board_id = @board.id AND closures.id IS NOT NULL | closed スコープ適用 |

#### closures（参照のみ）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | created_at | ORDER BY created_at DESC | recently_closed_first スコープ |

## メッセージ仕様

| 種別 | 表示条件 | メッセージ |
|------|---------|----------|
| 情報 | カードが0件の場合 | "No cards here" |

## 例外処理

| 条件 | 処理内容 |
|------|---------|
| ボードが存在しない | 404 Not Found |
| ボードが非公開 | 404 Not Found（ensure_board_accessible） |
| アカウントがキャンセル済み | 404 Not Found（ensure_board_accessible） |

## 備考

- 30秒のパブリックキャッシュが設定されており、CDN等でキャッシュ可能
- HTTPキャッシュヘッダー: `public: true, max-age: 30`
- レイアウト: `public`（認証不要レイアウト）

---

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

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

### 推奨読解順序

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

まず、クローズ済みカードの取得に関わるモデルの関連を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | card.rb | `app/models/card.rb` | Cardモデルの定義、Closeableモジュールのinclude確認（2行目） |
| 1-2 | closeable.rb | `app/models/card/closeable.rb` | closed、recently_closed_firstスコープの定義（7-10行目） |
| 1-3 | board.rb | `app/models/board.rb` | Boardモデル、Cardsモジュールのinclude |
| 1-4 | cards.rb | `app/models/board/cards.rb` | has_many :cards関連の定義（5行目） |

**読解のコツ**: RailsのConcernパターンを使用している。`include Closeable` により、Cardモデルにclosedスコープが追加される。

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

処理の起点となるコントローラーを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | closeds_controller.rb | `app/controllers/public/boards/columns/closeds_controller.rb` | showアクションの実装（2-4行目） |
| 2-2 | base_controller.rb | `app/controllers/public/base_controller.rb` | 親クラス、before_action、キャッシュ設定 |

**主要処理フロー**:
1. **3行目**: `set_page_and_extract_portion_from @board.cards.closed.recently_closed_first` - クローズ済みカードを取得しページネーション設定
2. **base_controller 2行目**: `allow_unauthenticated_access` - 認証不要設定
3. **base_controller 4行目**: `before_action :set_board, :set_card, :set_public_cache_expiration` - 各種初期化

#### Step 3: ビューレイヤーを理解する

テンプレートの構造とコンポーネントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.erb | `app/views/public/boards/columns/closeds/show.html.erb` | 全体構造、Turbo Frame、ページネーション |
| 3-2 | _public_previews.html.erb | `app/views/cards/display/_public_previews.html.erb` | カード一覧の部分テンプレート |
| 3-3 | _public_preview.html.erb | `app/views/cards/display/_public_preview.html.erb` | 個別カードプレビューの詳細表示 |
| 3-4 | _footer.html.erb | `app/views/public/_footer.html.erb` | フッター部分 |

**主要処理フロー**:
- **1行目**: `@page_title = "Column: Done"` - ページタイトル設定
- **14-24行目**: Turbo Frame `closed_column` によるページネーション対応
- **17-19行目**: `with_automatic_pagination` ヘルパーによる自動ページネーション

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

```
Public::Boards::Columns::ClosedsController#show
    │
    ├─ Public::BaseController (before_action)
    │      ├─ set_board (published_keyでボード取得)
    │      ├─ set_public_cache_expiration (30秒キャッシュ)
    │      └─ ensure_board_accessible (アクセス可否チェック)
    │
    ├─ @board.cards.closed.recently_closed_first
    │      ├─ Board#cards (has_many関連)
    │      └─ Card::Closeable (closed, recently_closed_first スコープ)
    │
    └─ show.html.erb
           ├─ cards/display/_public_previews.html.erb
           │      └─ cards/display/_public_preview.html.erb (各カード)
           └─ public/_footer.html.erb
```

### データフロー図

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

published_key ───▶ Board.find_by_published_key ───▶ @board
    │
    └──────────▶ @board.cards.closed
                        │
                        └─▶ recently_closed_first ───▶ @page
                                                          │
                                                          └─▶ show.html.erb ───▶ HTML
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| closeds_controller.rb | `app/controllers/public/boards/columns/closeds_controller.rb` | コントローラー | リクエストハンドリング |
| base_controller.rb | `app/controllers/public/base_controller.rb` | コントローラー | 公開画面共通処理 |
| show.html.erb | `app/views/public/boards/columns/closeds/show.html.erb` | テンプレート | メインビュー |
| _public_previews.html.erb | `app/views/cards/display/_public_previews.html.erb` | パーシャル | カード一覧 |
| _public_preview.html.erb | `app/views/cards/display/_public_preview.html.erb` | パーシャル | カードプレビュー |
| card.rb | `app/models/card.rb` | モデル | カードモデル |
| closeable.rb | `app/models/card/closeable.rb` | Concern | クローズ関連機能 |
| board.rb | `app/models/board.rb` | モデル | ボードモデル |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（196-201行目） |
