# 機能設計書 19-カード詳細表示

## 概要

本ドキュメントは、カードの詳細情報（タイトル、説明、コメント等）を表示する機能の設計を記載する。

### 本機能の処理概要

本機能は、特定のカードの詳細情報を表示する機能である。カードのタイトル、説明、添付画像に加えて、コメント、ステップ、タグ、担当者、リアクションなどの関連情報も含めて表示する。

**業務上の目的・背景**：タスクの詳細を確認することは、作業の実行や進捗確認において不可欠である。本機能により、ユーザーはカードに関するすべての情報を一画面で確認でき、必要に応じてコメントの追加やステータスの変更などの操作を行える。

**機能の利用シーン**：カード一覧やボード詳細画面からカードをクリックすると、カード詳細画面に遷移する。リアルタイム更新（Turbo Streams）により、他のユーザーの変更も即座に反映される。

**主要な処理内容**：
1. カード番号（number）からカードを取得
2. 下書きカードの場合は下書き編集画面にリダイレクト
3. 関連データ（コメント、ステップ、タグなど）を含めて表示
4. 既読処理用のbeaconを設定

**関連システム・外部連携**：Turbo Streamsによるリアルタイム更新。Action Cableによるブロードキャスト。既読トラッキング用のbeacon。

**権限による制御**：ユーザーがアクセス可能なカード（accessible_cards）のみ表示可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | カード詳細画面 | 主画面 | カードの詳細情報を表示 |
| 21 | カード下書き画面 | リダイレクト先 | 下書きカードの場合の遷移先 |

## 機能種別

CRUD操作（Read） / データ取得処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | BigInt/String | Yes | カード番号（number） | 存在するカードであること、ユーザーがアクセス可能であること |

### 入力データソース

- URLパラメータ: id（カード番号）
- セッション: 認証済みユーザー情報（Current.user）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| card | Card | カードオブジェクト |
| card.title | String | カードタイトル |
| card.description | ActionText::RichText | カード説明（リッチテキスト） |
| card.image | ActiveStorage::Attachment | 添付画像 |
| card.comments | Array[Comment] | コメント一覧 |
| card.steps | Array[Step] | ステップ（チェックリスト）一覧 |
| card.tags | Array[Tag] | タグ一覧 |
| card.assignees | Array[User] | 担当者一覧 |
| card.reactions | Array[Reaction] | リアクション一覧 |

### 出力先

- 画面表示: HTML
- Turbo Streamsサブスクリプション: リアルタイム更新用

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信（GET /cards/:id）
   └─ set_cardによりnumberからカードを取得

2. 下書きチェック（redirect_if_drafted）
   └─ 下書きの場合は card_draft_path へリダイレクト

3. ビューレンダリング
   └─ ページタイトル設定
   └─ ソーシャルタグ設定（OGP）
   └─ Turbo Streamsサブスクリプション設定
   └─ beaconコントローラー設定（既読用）
```

### フローチャート

```mermaid
flowchart TD
    A[リクエスト受信] --> B[set_card: カード取得]
    B --> C[accessible_cards.find_by!]
    C --> D{カード存在?}
    D -->|No| E[404 Not Found]
    D -->|Yes| F{下書き?}
    F -->|Yes| G[redirect_to card_draft_path]
    F -->|No| H[ビューレンダリング]
    H --> I[ページタイトル設定]
    I --> J[ソーシャルタグ設定]
    J --> K[Turbo Streamsサブスクリプション]
    K --> L[beacon設定]
    L --> M[終了]
    G --> M
    E --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 下書きリダイレクト | 下書き状態のカードは編集画面にリダイレクト | カードがdrafted状態の場合 |
| BR-02 | 既読トラッキング | beaconを使用して閲覧を記録 | 常時 |
| BR-03 | リアルタイム更新 | Turbo Streamsで変更をリアルタイム反映 | 常時 |
| BR-04 | 番号でのルーティング | カードはIDではなくnumber（連番）で識別 | URLパラメータ |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| カード取得 | cards | SELECT | numberでカード1件取得 |
| 関連データ取得 | 複数テーブル | SELECT | コメント、ステップ、タグ等 |

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

#### cards

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | number = params[:id] | accessible_cards経由 |
| JOIN | accesses | ユーザーアクセス権の確認 | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | Not Found | 存在しないnumberが指定 | RecordNotFound例外 |
| 401 | Unauthorized | 未認証ユーザー | ログイン画面へリダイレクト |

### リトライ仕様

該当なし（読み取り専用操作）

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

該当なし（SELECT文のみ）

## パフォーマンス要件

- レスポンス時間: 300ms以内
- 関連データはビューでの遅延読み込み（一部）

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

- 認証: ログイン済みユーザーのみアクセス可能
- 認可: accessible_cardsによりアクセス可能なカードのみ表示
- OGP: ソーシャルシェア用のメタタグを生成

## 備考

- to_paramメソッドでnumberを返すため、URLはcard.idではなくcard.numberを使用
- lightboxコントローラーで画像の拡大表示に対応

---

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

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

### 推奨読解順序

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

カードの関連データ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | card.rb | `app/models/card.rb` | カードモデル、to_paramでnumberを返す |

**読解のコツ**: to_paramメソッドによりRailsのルーティングヘルパー（card_path等）がnumberを使用する。

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

リクエストを受け付けるコントローラーを確認する。

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

**主要処理フロー**:
1. **5行目**: before_action :set_cardでカードを取得
2. **6行目**: before_action :redirect_if_draftedで下書きチェック
3. **27-28行目**: showアクション（空実装、ビューに委譲）
4. **56-58行目**: set_cardでaccessible_cards.find_by!を使用
5. **60-62行目**: redirect_if_draftedで下書き時リダイレクト

#### Step 3: ビュー表示を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.erb | `app/views/cards/show.html.erb` | カード詳細の表示構造 |

**主要処理フロー**:
- **1行目**: @page_titleにカードタイトルを設定
- **4-6行目**: ソーシャルタグ（OGP）を設定
- **15-16行目**: Turbo Streamsサブスクリプション（@card, @card:activity）
- **18行目**: beaconコントローラーで既読処理を設定
- **19-20行目**: cards/containerとcards/messagesパーシャルを表示

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

```
CardsController#show
    │
    ├─ set_card
    │      └─ Current.user.accessible_cards.find_by!(number: params[:id])
    │
    ├─ redirect_if_drafted
    │      └─ @card.drafted? → redirect_to card_draft_path
    │
    └─ show.html.erb
           ├─ card_social_tags(@card)
           ├─ turbo_stream_from @card
           ├─ turbo_stream_from @card, :activity
           ├─ cards/container
           └─ cards/messages
```

### データフロー図

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

GET /cards/:number
         │
         ▼
┌─────────────────┐
│ accessible_cards │ ───▶ find_by!(number: params[:id])
└─────────────────┘
         │
         ▼
┌─────────────────┐
│ drafted?チェック │ ───▶ リダイレクト or 続行
└─────────────────┘
         │
         ▼
┌─────────────────┐
│ ビューレンダリング│ ───▶ show.html.erb
└─────────────────┘
         │
         ▼
┌─────────────────┐
│ Turbo Streams   │ ───▶ サブスクリプション設定
└─────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cards_controller.rb | `app/controllers/cards_controller.rb` | コントローラー | カード詳細リクエストの処理 |
| card.rb | `app/models/card.rb` | モデル | カードモデル、to_param |
| show.html.erb | `app/views/cards/show.html.erb` | ビュー | カード詳細表示 |
| _container.html.erb | `app/views/cards/_container.html.erb` | パーシャル | カード本体の表示 |
| _messages.html.erb | `app/views/cards/_messages.html.erb` | パーシャル | コメント一覧の表示 |
| schema.rb | `db/schema.rb` | スキーマ | cardsテーブル定義（202-217行目） |
