---
generated_at: 2026-01-13 18:25:00
metrics:
  claims_total: 52
  claims_with_evidence: 48
  claims_without_evidence: 4
confidence_derived: 0.92
---

# 根拠レポート：observers 単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された単体テストケース一覧の信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

### チェック方法
以下の観点でドキュメントの内容（Claim：主張）を検証しています：

1. **根拠の有無確認**：各主張に対して、ソースコード・既存設計書・要件定義書などの根拠（Evidence）が存在するか
2. **根拠との整合性**：主張の内容が根拠と矛盾していないか
3. **網羅性**：参照すべき情報源を適切にカバーしているか

### 信頼度スコアの算出
- **confidence_derived** = 根拠あり件数 / 総主張件数
- 状態「○」：根拠あり、「△」：根拠不足または要確認

### 本レポートの使い方
1. まず「サマリー」で全体の信頼度と優先レビュー項目を確認
2. 「Claims と根拠の対応」で △ の項目を重点的にレビュー
3. 「不足情報」で補完が必要な情報源を確認

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**0.92**
  - 根拠あり：48 / 52、根拠なし：4
- 優先レビュー（高）
  1. **C-05（receive_assigned_notifications?メソッド）**：Userモデルにメソッドが存在するか未確認
  2. **C-21（nil状態からの遷移）**：リードステータスがnilになるケースの仕様確認必要
  3. **C-46（二重計上防止）**：won→won遷移が実際に発生するシナリオの確認必要
  4. **C-51（nil収益の数値変換）**：キャンペーン収益がnilになるケースの確認必要

## 2) 参照した情報（Evidence一覧）

- E-01: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/models/observers/entity_observer.rb`
- E-02: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/models/observers/lead_observer.rb`
- E-03: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/models/observers/task_observer.rb`
- E-04: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/models/observers/opportunity_observer.rb`
- E-05: `/Users/tomokababa/Work/route06/fat_free_crm-master/spec/models/observers/entity_observer_spec.rb`
- E-06: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/mailers/user_mailer.rb`
- E-07: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/models/entities/lead.rb`
- E-08: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/models/polymorphic/task.rb`
- E-09: `/Users/tomokababa/Work/route06/fat_free_crm-master/app/models/entities/opportunity.rb`

## 3) Claims と根拠の対応（レビューの主戦場）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | エンティティ作成時にアサイニーに通知が送信される | E-01 (L11-13), E-05 (L27-29) | ○ |
| C-02 | アサイニーが未設定の場合は通知が送信されない | E-01 (L21-22), E-05 (L31-34) | ○ |
| C-03 | 自分自身にアサインした場合は通知が送信されない | E-01 (L12), E-05 (L36-39) | ○ |
| C-04 | Setting.hostが未設定の場合は通知が送信されない | E-01 (L26-28), E-05 (L41-44) | ○ |
| C-05 | アサイニーが通知受信を無効にしている場合は通知が送信されない | E-01 (L22) | △ |
| C-06 | アサイニーが変更された場合に新しいアサイニーに通知が送信される | E-01 (L15-16), E-05 (L53-55) | ○ |
| C-07 | アサイニーが変更されていない場合は通知が送信されない | E-01 (L16), E-05 (L58-61) | ○ |
| C-08 | アサイニーが解除された場合は通知が送信されない | E-01 (L22), E-05 (L63-66) | ○ |
| C-09 | 自分自身に再アサインした場合は通知が送信されない | E-01 (L16), E-05 (L68-71) | ○ |
| C-10 | PaperTrail.whodunnitがUserオブジェクトの場合はそのまま返す | E-01 (L32-34) | ○ |
| C-11 | PaperTrail.whodunnitがString（ユーザーID）の場合はUserを検索して返す | E-01 (L35-37) | ○ |
| C-12 | PaperTrail.whodunnitが存在しないユーザーIDの場合はnilが返る | E-01 (L36) | ○ |
| C-13 | PaperTrail.whodunnitがnilの場合はnilが返る | E-01 (L32-37) | ○ |
| C-14 | Setting.hostが設定されている場合はtrueを返す | E-01 (L26-28) | ○ |
| C-15 | Setting.hostが空の場合はfalseを返す | E-01 (L27) | ○ |
| C-16 | Setting.hostがnilの場合はfalseを返す | E-01 (L27) | ○ |
| C-17 | 更新前のリード状態がキャッシュされる | E-02 (L13-15) | ○ |
| C-18 | ステータスがrejectedに変更された場合にアクティビティログが記録される | E-02 (L17-21) | ○ |
| C-19 | ステータスがrejected以外に変更された場合はログが記録されない | E-02 (L20) | ○ |
| C-20 | ステータスが変更されていない場合はログが記録されない | E-02 (L20) | ○ |
| C-21 | 元のステータスがnilからrejectedに変更された場合にログが記録される | E-02 (L20) | △ |
| C-22 | キャッシュに元データがない場合はログが記録されない | E-02 (L18, L20) | ○ |
| C-23 | LeadObserver: PaperTrailバージョンが正しく作成される | E-02 (L25-27) | ○ |
| C-24 | 更新前のタスク状態がキャッシュされる | E-03 (L13-15) | ○ |
| C-25 | タスクが完了した場合にcompleteイベントがログされる | E-03 (L17-20) | ○ |
| C-26 | タスクが再アサインされた場合にreassignイベントがログされる | E-03 (L21) | ○ |
| C-27 | タスクのバケットが変更された場合にrescheduleイベントがログされる | E-03 (L23) | ○ |
| C-28 | タスク完了がreassignより優先される | E-03 (L20) | ○ |
| C-29 | タスク完了がrescheduleより優先される | E-03 (L20) | ○ |
| C-30 | reassignがrescheduleより優先される | E-03 (L21) | ○ |
| C-31 | 何も変更がない場合はログが記録されない | E-03 (L17-24) | ○ |
| C-32 | TaskObserver: キャッシュに元データがない場合はログが記録されない | E-03 (L19) | ○ |
| C-33 | TaskObserver: PaperTrailバージョンが正しく作成される | E-03 (L29-31) | ○ |
| C-34 | ステージがwonで作成された場合にキャンペーン収益が更新される | E-04 (L13-15) | ○ |
| C-35 | ステージがwon以外で作成された場合はキャンペーン収益が更新されない | E-04 (L14) | ○ |
| C-36 | キャンペーンが未設定の場合は収益更新されない | E-04 (L14) | ○ |
| C-37 | amountとdiscountがnilの場合は0として計算される | E-04 (L14, L25) | ○ |
| C-38 | 更新前の商談状態がキャッシュされる | E-04 (L17-19) | ○ |
| C-39 | ステージがwonに変更された場合にキャンペーン収益が加算される | E-04 (L24-25) | ○ |
| C-40 | ステージがwonに変更された場合に確率が100%に設定される | E-04 (L26) | ○ |
| C-41 | ステージがwonに変更された場合にwonイベントがログされる | E-04 (L27) | ○ |
| C-42 | ステージがwonから他に変更された場合にキャンペーン収益が減算される | E-04 (L28-29) | ○ |
| C-43 | ステージがlostに変更された場合に確率が0%に設定される | E-04 (L30-31) | ○ |
| C-44 | ステージがlostに変更された場合はwonイベントがログされない | E-04 (L30-31) | ○ |
| C-45 | ステージが変更されない場合は何も更新されない | E-04 (L22-33) | ○ |
| C-46 | wonからwonに変更された場合は収益が二重加算されない | E-04 (L24) | △ |
| C-47 | OpportunityObserver: キャッシュに元データがない場合は何も更新されない | E-04 (L22-23) | ○ |
| C-48 | キャンペーンの収益が正しく加算される | E-04 (L42-44) | ○ |
| C-49 | キャンペーンの収益が正しく減算される | E-04 (L42-44) | ○ |
| C-50 | キャンペーンがnilの場合は何もしない | E-04 (L43) | ○ |
| C-51 | キャンペーンの収益がnilの場合は0として計算される | E-04 (L43) | △ |
| C-52 | OpportunityObserver: PaperTrailバージョンが正しく作成される | E-04 (L38-40) | ○ |

## 4) 不足情報（Unknown / Missing）

- **C-05: receive_assigned_notifications?メソッド**
  - EntityObserverのL22で呼び出されているが、Userモデルでの定義を直接確認していない
  - 候補：`app/models/users/user.rb` / Preferenceモデル / Concernsファイル

- **C-21: nil状態からの遷移**
  - Leadモデルではstatusにデフォルトがないためnilになる可能性があるが、実際の運用でnilから直接rejectedに遷移するケースの確認が必要
  - 候補：Lead作成フロー / 管理画面の仕様 / バリデーション

- **C-46: won→won遷移**
  - コードロジック上は正しく防止されているが、実際にwon状態から再度保存されるシナリオが存在するか確認が必要
  - 候補：管理画面操作 / API呼び出し / バッチ処理

- **C-51: nil収益の数値変換**
  - Campaign.revenueがnilになるケースの確認が必要。スキーマまたはモデルでデフォルト値が設定されている可能性
  - 候補：Campaignモデル / DBスキーマ / マイグレーション

## 5) リスクフラグ（レビュー観点）

- **0（低リスク）**: C-12, C-13, C-16, C-22, C-32, C-47 - エッジケースだが安全に処理される
- **1（中リスク）**: C-05, C-21, C-51 - 仕様確認が必要なケース
- **2（高リスク）**: なし

## 6) レビュアーチェックリスト（最小）

- [ ] EntityObserver: Userモデルにreceive_assigned_notifications?メソッドが存在することを確認
- [ ] EntityObserver: 4つのエンティティタイプ（account, contact, lead, opportunity）すべてで動作確認
- [ ] LeadObserver: statusがnilのリードが実際に存在するか確認
- [ ] TaskObserver: イベント優先順位（complete > reassign > reschedule）が業務要件と一致することを確認
- [ ] OpportunityObserver: 収益計算（amount - discount）の精度要件を確認
- [ ] OpportunityObserver: probability自動設定（100%/0%）が業務要件と一致することを確認
- [ ] 全Observer: PaperTrail versionsテーブルのeventカラムに対するバリデーション有無を確認
