# 機能設計書 21-リード詳細表示

## 概要

本ドキュメントは、Fat Free CRMシステムにおけるリード詳細表示機能の設計を定義する。この機能は、個別のリード情報を詳細に閲覧し、関連するタイムライン、タスク、バージョン履歴を確認するための画面を提供する。

### 本機能の処理概要

リード詳細表示機能は、CRM（顧客関係管理）システムにおける見込み顧客の詳細情報を一元的に閲覧できる機能である。

**業務上の目的・背景**：営業担当者が見込み顧客（リード）の詳細情報を迅速に把握し、適切なフォローアップアクションを決定するために必要な機能である。リードの属性情報、過去のコミュニケーション履歴、関連タスクを一画面で確認できることで、営業活動の効率化と顧客対応品質の向上を実現する。

**機能の利用シーン**：営業担当者が電話や訪問の前にリードの情報を確認する場合、リードへのフォローアップ状況を確認する場合、リードを連絡先や商談に変換（コンバート）する前の情報確認時に利用される。また、vCard形式でエクスポートしてスマートフォンの連絡先に追加する際にも使用される。

**主要な処理内容**：
1. リードIDに基づくリード情報の取得と表示
2. リードに紐付くコメント・メールのタイムライン表示
3. 関連タスクの一覧表示
4. バージョン履歴（変更履歴）の表示
5. vCard形式でのエクスポート機能

**関連システム・外部連携**：vCard形式でのエクスポートにより、外部の連絡先管理システムやスマートフォンとの連携が可能である。

**権限による制御**：CanCanによる認可制御が行われ、ユーザーは自分が作成したリード、自分に割り当てられたリード、または共有されたリードのみ閲覧可能である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 16 | リード詳細画面 | 主画面 | リード詳細情報、タイムライン表示、vCardエクスポート |
| 16 | リード詳細画面 | 補助機能 | コメント一覧表示（機能No.42） |
| 16 | リード詳細画面 | 補助機能 | コメント作成（機能No.43） |
| 16 | リード詳細画面 | 補助機能 | 購読/購読解除（機能No.86） |
| 16 | リード詳細画面 | 補助機能 | バージョン履歴（機能No.85） |

## 機能種別

データ参照（READ） / エクスポート処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | Integer | Yes | リードID | 数値、存在確認 |

### 入力データソース

- URL: `/leads/:id`
- HTTPメソッド: GET
- データソース: leadsテーブル（主テーブル）、comments/emailsテーブル（タイムライン用）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @lead | Lead | リードオブジェクト |
| @comment | Comment | 新規コメント用の空オブジェクト |
| @timeline | Array | コメントとメールの配列（作成日時降順） |

### 出力先

- HTML形式: 詳細画面表示（show.html.haml）
- JS形式: AJAX更新用（show.js.haml）
- VCF形式: vCardファイルダウンロード

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ GET /leads/:id を受信
2. 認証・認可チェック
   └─ CanCanによる権限確認（load_and_authorize_resource）
3. リードデータ取得
   └─ Leadモデルからリード情報を取得
4. 関連データ取得
   └─ タイムライン（コメント + メール）を取得・ソート
5. 閲覧履歴記録
   └─ バージョン履歴に閲覧イベントを記録
6. レスポンス生成
   └─ フォーマットに応じた出力（HTML/JS/VCF）
```

### フローチャート

```mermaid
flowchart TD
    A[GET /leads/:id] --> B[認証チェック]
    B --> C{認可チェック}
    C -->|許可| D[リードデータ取得]
    C -->|拒否| E[403 Forbidden]
    D --> F[タイムライン取得]
    F --> G[閲覧履歴記録]
    G --> H{フォーマット判定}
    H -->|HTML| I[詳細画面表示]
    H -->|JS| J[AJAX応答]
    H -->|VCF| K[vCardダウンロード]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-21-01 | アクセス権限チェック | ユーザーは自分が作成、割当て、または共有されたリードのみ閲覧可能 | 常時 |
| BR-21-02 | タイムラインソート | コメントとメールは作成日時の降順で表示 | 常時 |
| BR-21-03 | 閲覧履歴記録 | リード詳細を表示した際にバージョン履歴に記録 | 常時 |
| BR-21-04 | vCard出力ファイル名 | ファイル名は「{氏名}.vcf」形式 | VCF出力時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| リード取得 | leads | SELECT | 指定IDのリード情報取得 |
| タイムライン取得 | comments | SELECT | リードに紐付くコメント取得 |
| タイムライン取得 | emails | SELECT | リードに紐付くメール取得 |
| 閲覧履歴記録 | versions | INSERT | 閲覧イベントを記録 |

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

#### leads

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | id = :id | 全カラム取得 |

#### versions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | item_type | 'Lead' | |
| INSERT | item_id | リードID | |
| INSERT | event | 'view' | |
| INSERT | whodunnit | 現在のユーザーID | |
| INSERT | created_at | 現在日時 | |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | Not Found | 指定IDのリードが存在しない | エラーページ表示 |
| 403 | Forbidden | アクセス権限がない | エラーページ表示 |

### リトライ仕様

リトライは実装されていない（参照操作のため不要）

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

閲覧履歴の記録はafter_actionコールバックで実行され、メイン処理とは別トランザクションで処理される。

## パフォーマンス要件

- 詳細画面のレスポンスタイム: 2秒以内
- タイムラインの取得件数: 制限なし（ページネーションなし）

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

- CanCanによる認可制御でアクセス権限をチェック
- XSS対策としてビューでのエスケープ処理
- 閲覧履歴がバージョン履歴として記録される

## 備考

- vCard出力はLeadsHelperのvcard_forメソッドを使用
- タイムラインはコメントとメールをマージして日時降順ソート

---

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

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

### 推奨読解順序

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

リードのデータ構造を理解することが最初のステップである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | lead.rb | `app/models/entities/lead.rb` | リードモデルの属性定義、関連付け、スコープ |

**読解のコツ**:
- **8-37行目**: Schema Informationでテーブル構造を確認
- **40-48行目**: belongs_to/has_many関係でリードの関連エンティティを理解
- **64-74行目**: uses_user_permissions、acts_as_commentable等のmixin定義
- **158-165行目**: full_nameメソッドで氏名の表示形式を確認

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

コントローラーのshowアクションがエントリーポイントである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | leads_controller.rb | `app/controllers/entities/leads_controller.rb` | showアクションの実装 |
| 2-2 | entities_controller.rb | `app/controllers/entities_controller.rb` | 基底クラスの共通処理 |

**主要処理フロー**:
1. **23-31行目** (leads_controller.rb): showアクション - @commentと@timelineを設定
2. **27-30行目**: respond_withでフォーマット別処理、VCF形式はvcard_forヘルパーを使用
3. **17行目** (entities_controller.rb): after_action :update_recently_viewedで閲覧履歴記録
4. **186-188行目** (entities_controller.rb): update_recently_viewedでバージョン履歴にviewイベント記録
5. **215-217行目** (entities_controller.rb): timelineメソッドでコメント+メールをソート

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

画面表示のロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/leads/show.html.haml` | 詳細画面のレイアウト構造 |

**主要処理フロー**:
- **1-2行目**: カスタムビューテンプレートがあれば使用
- **9-12行目**: タイトルバー、サイドバー、コメント入力、タイムライン表示
- **14-20行目**: hookによる拡張ポイント、タスク一覧、バージョン履歴表示

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

```
LeadsController#show
    │
    ├─ load_and_authorize_resource (CanCan)
    │      └─ Lead.find(params[:id])
    │
    ├─ Comment.new (コメント入力用)
    │
    ├─ timeline(@lead)
    │      └─ lead.comments + lead.emails
    │             └─ sort by created_at DESC
    │
    ├─ respond_with(@lead)
    │      ├─ format.html → show.html.haml
    │      ├─ format.js → show.js.haml
    │      └─ format.vcf → vcard_for(@lead)
    │
    └─ update_recently_viewed (after_action)
           └─ entity.versions.create(event: :view)
```

### データフロー図

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

GET /leads/:id ───▶ LeadsController#show ───▶ HTML/JS/VCF
      │                     │
      │                     ├─▶ Lead.find()
      │                     │       └─▶ [leads]テーブル
      │                     │
      │                     ├─▶ timeline()
      │                     │       ├─▶ [comments]テーブル
      │                     │       └─▶ [emails]テーブル
      │                     │
      │                     └─▶ versions.create()
      │                             └─▶ [versions]テーブル
      │
      └─▶ show.html.haml
              ├─▶ _title_bar.html.haml
              ├─▶ _sidebar_show.html.haml
              ├─▶ comments/_new.html.haml
              ├─▶ shared/_timeline.html.haml
              ├─▶ tasks/_tasks.html.haml
              └─▶ versions/_versions.html.haml
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| leads_controller.rb | `app/controllers/entities/leads_controller.rb` | コントローラー | リード操作のエントリーポイント |
| entities_controller.rb | `app/controllers/entities_controller.rb` | コントローラー | エンティティ共通処理の基底クラス |
| lead.rb | `app/models/entities/lead.rb` | モデル | リードのデータモデル定義 |
| leads_helper.rb | `app/helpers/leads_helper.rb` | ヘルパー | リード表示用ヘルパーメソッド |
| show.html.haml | `app/views/leads/show.html.haml` | ビュー | 詳細画面のメインテンプレート |
| show.js.haml | `app/views/leads/show.js.haml` | ビュー | AJAX応答用テンプレート |
| _title_bar.html.haml | `app/views/leads/_title_bar.html.haml` | ビュー | タイトルバーパーシャル |
| _sidebar_show.html.haml | `app/views/leads/_sidebar_show.html.haml` | ビュー | サイドバーパーシャル |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
