# 機能設計書 5-取引先詳細表示

## 概要

本ドキュメントは、Fat Free CRMシステムにおける取引先詳細表示機能の設計を定義する。この機能は、取引先の詳細情報、関連する商談、タイムラインを表示する。

### 本機能の処理概要

取引先詳細表示機能は、特定の取引先に関する全ての情報を一画面で確認できる機能である。基本情報に加え、関連する連絡先、商談、タスク、コメント履歴などを統合的に表示する。

**業務上の目的・背景**：営業担当者が顧客との商談前に、取引先の詳細情報や過去のやり取りを確認する必要がある。本機能により、取引先に関する全ての情報を一元的に把握でき、効果的な営業活動を支援する。また、複数の関連エンティティ（連絡先、商談など）との紐付けを確認することで、顧客との関係性を深く理解できる。

**機能の利用シーン**：
- 営業担当者が顧客訪問前に取引先情報を確認する場面
- マネージャーが特定取引先の商談進捗を確認する場面
- 過去のコメントやメールのやり取りを振り返る場面
- 取引先に新しいコメントを追加する場面

**主要な処理内容**：
1. 取引先データの取得と認可確認
2. 商談ステージ設定の取得
3. コメント入力フォームの準備
4. タイムライン（コメント・メール）の取得
5. 関連データ（タスク、連絡先、商談、バージョン履歴）の表示
6. 閲覧履歴の記録

**関連システム・外部連携**：本機能は外部システムとの連携はなく、内部データベースからのデータ取得のみで構成される。

**権限による制御**：`load_and_authorize_resource`により、ユーザーがアクセス権限を持つ取引先のみ閲覧可能。アクセス権限がない場合は403エラーが返される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | 取引先詳細画面 | 主画面 | 取引先詳細情報、関連商談、タイムライン表示 |

## 機能種別

データ表示（READ操作）+ 履歴記録（CREATE操作）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | Integer | Yes | 取引先ID | 存在する取引先IDであること |

### 入力データソース

- URLパラメータ（:id）
- セッション情報（current_user）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @account | Account | 取引先データ |
| @stage | Array | 商談ステージ設定 |
| @comment | Comment | 新規コメント用オブジェクト |
| @timeline | Array | コメントとメールの配列（時系列ソート済み） |

### 出力先

- HTML画面表示（デフォルト）
- AJAX部分更新（format: js）

## 処理フロー

### 処理シーケンス

```
1. before_action実行
   ├─ set_current_tab: タブ状態設定
   ├─ set_view: 表示形式設定
   └─ load_and_authorize_resource: リソースロード・認可
2. showアクション実行
   ├─ Setting.unroll(:opportunity_stage): 商談ステージ取得
   ├─ Comment.new: 新規コメントオブジェクト作成
   └─ timeline(@account): タイムライン取得
3. after_action実行
   └─ update_recently_viewed: 閲覧履歴記録
4. respond_with(@account)
   └─ show.html.hamlレンダリング
```

### フローチャート

```mermaid
flowchart TD
    A[リクエスト受信] --> B[認証チェック]
    B --> C[リソースロード]
    C --> D{認可チェック}
    D -->|NG| E[403エラー]
    D -->|OK| F[商談ステージ取得]
    F --> G[コメントオブジェクト作成]
    G --> H[タイムライン取得]
    H --> I[respond_with]
    I --> J[閲覧履歴記録]
    J --> K[画面レンダリング]
    K --> L[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 閲覧履歴記録 | 詳細画面を表示するたびにVersionテーブルに記録 | 常時 |
| BR-002 | タイムライン順序 | コメントとメールを作成日時の降順でソート | 常時 |
| BR-003 | アクセス権限 | 所有・割当・共有された取引先のみ閲覧可能 | 常時 |

### 計算ロジック

**タイムライン生成ロジック**：
```ruby
def timeline(asset)
  (asset.comments + asset.emails).sort { |x, y| y.created_at <=> x.created_at }
end
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 取引先取得 | accounts | SELECT | 指定IDの取引先を取得 |
| コメント取得 | comments | SELECT | 取引先に紐づくコメントを取得 |
| メール取得 | emails | SELECT | 取引先に紐づくメールを取得 |
| 閲覧履歴記録 | versions | INSERT | 閲覧イベントを記録 |

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

#### accounts

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

#### comments

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | commentable_type = 'Account', commentable_id = @account.id | ポリモーフィック関連 |

#### emails

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | mediator_type = 'Account', mediator_id = @account.id | ポリモーフィック関連 |

#### versions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | event, whodunnit, item_type, item_id | event: :view, whodunnit: current_user.id | 閲覧履歴 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | 認証エラー | 未ログイン状態でアクセス | ログイン画面へリダイレクト |
| 403 | 認可エラー | アクセス権限がない | エラーメッセージ表示 |
| 404 | 未検出 | 指定IDの取引先が存在しない | 一覧画面へリダイレクト |

### リトライ仕様

本機能ではリトライ処理は実装されていない。

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

閲覧履歴の記録（versions INSERT）は独立した操作であり、明示的なトランザクション制御は不要。

## パフォーマンス要件

- 画面表示時間: 3秒以内を目標
- 関連データ（タスク、連絡先、商談）は遅延ロード可能

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

- 認証: Deviseによるユーザー認証が必須
- 認可: CanCanによるアクセス権限制御
- 閲覧履歴: PaperTrailによる監査ログ

## 備考

- 詳細画面の表示形式はカスタマイズ可能（template_for_current_view）
- 関連エンティティ（タスク、連絡先、商談）はパーシャルで表示

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | account.rb | `app/models/entities/account.rb` | Accountモデルの関連定義 |
| 1-2 | comment.rb | `app/models/polymorphic/comment.rb` | コメントモデル |
| 1-3 | email.rb | `app/models/polymorphic/email.rb` | メールモデル |

**読解のコツ**: Accountモデルの`has_many`関連（contacts, opportunities, tasks, emails）に注目する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | routes.rb | `config/routes.rb` | GET /accounts/:id ルート |
| 2-2 | accounts_controller.rb | `app/controllers/entities/accounts_controller.rb` | showアクション |

**主要処理フロー**:
1. **25-30行目**: showアクション
2. **26行目**: Setting.unroll(:opportunity_stage) - ステージ設定取得
3. **27行目**: Comment.new - 新規コメント準備
4. **28行目**: timeline(@account) - タイムライン取得

#### Step 3: 基底クラスのロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | entities_controller.rb | `app/controllers/entities_controller.rb` | timelineメソッド、update_recently_viewedメソッド |

**主要処理フロー**:
- **215-217行目**: timeline - コメント+メールを時系列ソート
- **186-188行目**: update_recently_viewed - 閲覧履歴記録

#### Step 4: ビュー層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | show.html.haml | `app/views/accounts/show.html.haml` | 詳細画面レイアウト |
| 4-2 | _title_bar.html.haml | `app/views/accounts/_title_bar.html.haml` | タイトルバー |
| 4-3 | _sidebar_show.html.haml | `app/views/accounts/_sidebar_show.html.haml` | サイドバー |
| 4-4 | _timeline.html.haml | `app/views/shared/_timeline.html.haml` | タイムライン表示 |

**主要処理フロー**:
- **1-2行目**: template_for_current_viewによるカスタムテンプレート対応
- **14行目**: コメント入力フォーム
- **15行目**: タイムライン表示
- **19行目**: タスク一覧
- **21行目**: 連絡先一覧
- **23行目**: 商談一覧
- **25行目**: バージョン履歴

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

```
AccountsController#show
    │
    ├─ before_action
    │   ├─ set_current_tab (ApplicationController)
    │   ├─ set_view (EntitiesController)
    │   └─ load_and_authorize_resource (CanCan)
    │
    ├─ Setting.unroll(:opportunity_stage)
    ├─ Comment.new
    ├─ timeline(@account)
    │   └─ (asset.comments + asset.emails).sort
    │
    ├─ respond_with(@account)
    │   └─ show.html.haml
    │       ├─ _title_bar.html.haml
    │       ├─ _sidebar_show.html.haml
    │       ├─ comments/_new.html.haml
    │       ├─ shared/_timeline.html.haml
    │       ├─ tasks/_tasks.html.haml
    │       ├─ contacts/_contacts.html.haml
    │       ├─ opportunities/_opportunities.html.haml
    │       └─ versions/_versions.html.haml
    │
    └─ after_action
        └─ update_recently_viewed
            └─ entity.versions.create(event: :view)
```

### データフロー図

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

URLパラメータ ───▶ AccountsController#show ───▶ @account
(id)                   │                        @stage
                       │                        @comment
                       │                        @timeline
                       │                            │
                       ├─ Account.find             │
                       ├─ Setting.unroll           │
                       ├─ Comment.new              │
                       └─ timeline()               │
                       │                           ▼
                       ▼                    show.html.haml
                データベース                       │
                (accounts,                        │
                 comments,                        ▼
                 emails,                    ブラウザ表示
                 versions)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| accounts_controller.rb | `app/controllers/entities/accounts_controller.rb` | ソース | メインコントローラー |
| entities_controller.rb | `app/controllers/entities_controller.rb` | ソース | 基底コントローラー |
| account.rb | `app/models/entities/account.rb` | ソース | 取引先モデル |
| comment.rb | `app/models/polymorphic/comment.rb` | ソース | コメントモデル |
| email.rb | `app/models/polymorphic/email.rb` | ソース | メールモデル |
| show.html.haml | `app/views/accounts/show.html.haml` | テンプレート | 詳細画面 |
| _title_bar.html.haml | `app/views/accounts/_title_bar.html.haml` | テンプレート | タイトルバー |
| _sidebar_show.html.haml | `app/views/accounts/_sidebar_show.html.haml` | テンプレート | サイドバー |
| _timeline.html.haml | `app/views/shared/_timeline.html.haml` | テンプレート | タイムライン |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
