---
generated_at: 2026-02-25 03:00:00
metrics:
  claims_total: 61
  claims_with_evidence: 61
  claims_without_evidence: 0
confidence_derived: 1.00
---

# 根拠レポート：lib-rails_ext単体テストケース一覧

## 本レポートについて

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

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

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

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**1.00**
  - 根拠あり：61 / 61、根拠なし：0
- 優先レビュー（高）
  1. **UUID型のシリアライズ/デシリアライズ処理**：データ整合性に関わる重要機能
  2. **ActiveStorage認可処理**：セキュリティに関わる重要機能
  3. **レプリカDB接続設定**：インフラ構成に関わる重要機能

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。抽出フェーズで付けたIDをそのまま出す。

- E-01: `lib/rails_ext/string.rb` - Stringクラスへのall_emoji?メソッド追加
- E-02: `lib/rails_ext/active_support_array_conversions.rb` - Arrayクラスへのto_choice_sentenceメソッド追加
- E-03: `lib/rails_ext/active_record_uuid_type.rb` - UUID型の定義（generate, hex_to_base36, base36_to_hex, serialize, deserialize, cast）
- E-04: `lib/rails_ext/active_record_date_arithmetic.rb` - MySQL/SQLite用日付演算メソッド
- E-05: `lib/rails_ext/prepend_order.rb` - ActiveRecord::Relationへのprepend_orderメソッド追加
- E-06: `lib/rails_ext/active_record_replica_support.rb` - レプリカDB接続サポート（configure_replica_connections, replica_configured?, with_reading_role）
- E-07: `lib/rails_ext/active_storage_blob_service_url_for_direct_upload_expiry.rb` - ダイレクトアップロードURL有効期限設定
- E-08: `lib/rails_ext/active_storage_analyze_job_suppress_broadcasts.rb` - AnalyzeJob実行時のブロードキャスト抑制
- E-09: `lib/rails_ext/active_storage_authorization.rb` - ActiveStorage認可機能（Blob, Attachment, Authorizeモジュール）
- E-10: `lib/rails_ext/action_mailer_mail_delivery_job.rb` - MailDeliveryJobへのエラーハンドリング追加

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

### String拡張（E-01）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | all_emoji?メソッドが絵文字のみの文字列でtrueを返す | E-01: `self.match?(/\A(\p{Emoji_Presentation}|\p{Extended_Pictographic}|\uFE0F)+\z/u)` | ○ |
| C-02 | 複数種類の絵文字でtrueを返す | E-01: 正規表現がEmoji_Presentation, Extended_Pictographicをカバー | ○ |
| C-03 | 絵文字バリアント付きでtrueを返す | E-01: `\uFE0F`（バリアントセレクタ）が正規表現に含まれる | ○ |
| C-04 | 通常文字列でfalseを返す | E-01: `\A...\z`のアンカーで全体マッチを要求 | ○ |
| C-05 | 絵文字と文字の混在でfalseを返す | E-01: 正規表現が絵文字のみにマッチ | ○ |
| C-06 | 空文字列でfalseを返す | E-01: `+`量指定子により1文字以上を要求 | ○ |
| C-07 | 単一絵文字でtrueを返す | E-01: `+`量指定子により1文字以上でマッチ | ○ |
| C-08 | 数字のみでfalseを返す | E-01: 正規表現が数字にマッチしない | ○ |
| C-09 | スペースを含む文字列でfalseを返す | E-01: 正規表現がスペースにマッチしない | ○ |

### Array拡張（E-02）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-10 | 3要素以上で", or "区切りの文が生成される | E-02: `last_word_connector: ", or "` | ○ |
| C-11 | 2要素で" or "区切りの文が生成される | E-02: `two_words_connector: " or "` | ○ |
| C-12 | 1要素でその要素が返る | E-02: to_sentenceの既存動作 | ○ |
| C-13 | 空配列で空文字列が返る | E-02: to_sentenceの既存動作 | ○ |

### UUID型（E-03）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-14 | generateでbase36文字列が生成される | E-03: `SecureRandom.uuid_v7`からhex_to_base36変換 | ○ |
| C-15 | 生成されるIDが一意 | E-03: `SecureRandom.uuid_v7`使用 | ○ |
| C-16 | hex_to_base36でゼロ値が正しく変換される | E-03: `hex.to_i(16).to_s(36).rjust(BASE36_LENGTH, "0")` | ○ |
| C-17 | hex_to_base36で最大値が正しく変換される | E-03: 同上 | ○ |
| C-18 | base36_to_hexでゼロ値が正しく逆変換される | E-03: `base36.to_s.to_i(36).to_s(16).rjust(32, "0")` | ○ |
| C-19 | hex_to_base36とbase36_to_hexが逆変換として機能する | E-03: 両メソッドの実装から導出可能 | ○ |
| C-20 | serializeでバイナリに変換される | E-03: `base36_to_hex(value).scan(/../).map(&:hex).pack("C*")` | ○ |
| C-21 | serializeでnilがnilを返す | E-03: `return unless value` | ○ |
| C-22 | deserializeでbase36に変換される | E-03: `value.to_s.unpack1("H*")`からhex_to_base36 | ○ |
| C-23 | deserializeでnilがnilを返す | E-03: `return unless value` | ○ |
| C-24 | serialize/deserializeのラウンドトリップが一致 | E-03: 両メソッドの実装から導出可能 | ○ |
| C-25 | castで値がそのまま返る | E-03: `def cast(value) value end` | ○ |

### 日付演算（E-04）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-26 | MySQLでDATE_SUB式が生成される | E-04: `"DATE_SUB(#{date_column}, INTERVAL #{seconds_expression} SECOND)"` | ○ |
| C-27 | MySQLで複雑な式が正しく生成される | E-04: 同上、文字列補間で任意の式を受け入れ | ○ |
| C-28 | SQLiteでdatetime式が生成される | E-04: `"datetime(#{date_column}, '-' || (#{seconds_expression}) || ' seconds')"` | ○ |
| C-29 | SQLiteで複雑な式が正しく生成される | E-04: 同上 | ○ |

### prepend_order（E-05）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-30 | 新しい順序が先頭に追加される | E-05: `relation.order_values = new_orders + order_values` | ○ |
| C-31 | 複数の順序条件が追加される | E-05: `args.flatten.map` | ○ |
| C-32 | Arelオブジェクトがto_sqlで変換される | E-05: `arg.is_a?(String) ? arg : arg.to_sql` | ○ |
| C-33 | 元のリレーションが変更されない | E-05: `spawn.tap` でコピーを作成 | ○ |
| C-34 | 空配列で元の順序が維持される | E-05: `new_orders + order_values`で空配列は影響なし | ○ |

### レプリカサポート（E-06）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-35 | レプリカ設定時にconnects_toが呼ばれる | E-06: `if replica_configured? connects_to database: { writing: :primary, reading: :replica }` | ○ |
| C-36 | レプリカ未設定時は何もしない | E-06: `if replica_configured?`の条件分岐 | ○ |
| C-37 | replica_configured?でレプリカ設定を検出 | E-06: `configurations.find_db_config("replica").present?` | ○ |
| C-38 | replica_configured?でレプリカ未設定を検出 | E-06: 同上 | ○ |
| C-39 | with_reading_roleでreadingロールに切り替え | E-06: `connected_to(role: :reading, &block)` | ○ |
| C-40 | レプリカ未設定時はブロックをそのまま実行 | E-06: `else yield end` | ○ |

### ダイレクトアップロード有効期限（E-07）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-41 | デフォルトで48時間の有効期限 | E-07: `expires_in: ActiveStorage.service_urls_for_direct_uploads_expire_in`、デフォルト`48.hours` | ○ |
| C-42 | カスタム有効期限が指定可能 | E-07: `expires_in:`引数で上書き可能 | ○ |
| C-43 | デフォルト値が48時間 | E-07: `mattr_accessor :service_urls_for_direct_uploads_expire_in, default: 48.hours` | ○ |
| C-44 | 値が変更可能 | E-07: `mattr_accessor`によりsetter生成 | ○ |

### AnalyzeJobブロードキャスト抑制（E-08）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-45 | Board.suppressing_turbo_broadcasts内でsuper実行 | E-08: ネストされた`Board.suppressing_turbo_broadcasts do ... super ... end` | ○ |
| C-46 | Card.suppressing_turbo_broadcasts内でsuper実行 | E-08: ネストされた`Card.suppressing_turbo_broadcasts do ... super ... end` | ○ |

### ActiveStorage認可（E-09）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-47 | Blob.accessible_to?でattachmentがアクセス可能な場合true | E-09: `attachments.includes(:record).any? { |attachment| attachment.accessible_to?(user) }` | ○ |
| C-48 | Blob.accessible_to?でattachmentがアクセス不可の場合false | E-09: 同上 | ○ |
| C-49 | Blob.accessible_to?でattachmentがない場合true | E-09: `|| attachments.none?` | ○ |
| C-50 | Blob.publicly_accessible?で公開アクセス可能な場合true | E-09: `attachments.includes(:record).any? { |attachment| attachment.publicly_accessible? }` | ○ |
| C-51 | Blob.publicly_accessible?で非公開の場合false | E-09: 同上 | ○ |
| C-52 | Attachment.accessible_to?でrecordがアクセス可能な場合true | E-09: `record.try(:accessible_to?, user)` | ○ |
| C-53 | Attachment.accessible_to?でrecordがアクセス不可の場合false | E-09: 同上 | ○ |
| C-54 | Attachment.accessible_to?でrecordがnilの場合nil | E-09: `record.try`によりnilを返す | ○ |
| C-55 | Attachment.publicly_accessible?でrecordが公開の場合true | E-09: `record.try(:publicly_accessible?)` | ○ |
| C-56 | Attachment.publicly_accessible?でrecordが非公開の場合false | E-09: 同上 | ○ |
| C-57 | Authorize.publicly_accessible_blob?でblobが公開の場合true | E-09: `@blob.publicly_accessible?` | ○ |
| C-58 | Authorize.publicly_accessible_blob?でblobが非公開の場合false | E-09: 同上 | ○ |
| C-59 | ensure_accessibleでアクセス可能な場合何もしない | E-09: `unless @blob.accessible_to?(Current.user)`の条件分岐 | ○ |
| C-60 | ensure_accessibleでアクセス不可の場合forbiddenを返す | E-09: `head :forbidden` | ○ |

### MailDeliveryJob（E-10）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-61 | SmtpDeliveryErrorHandlingがincludeされる | E-10: `ActionMailer::MailDeliveryJob.include SmtpDeliveryErrorHandling` | ○ |

## 4) 不足情報（Unknown / Missing）
- なし
  - すべてのテストケースはソースコードに基づいて生成されている

## 5) リスクフラグ（レビュー観点）
- 0: 低リスク - すべてのテストケースに根拠あり
- 注意点：
  - UUID型のテストは実際のDBアダプタ（Trilogy, SQLite3）での動作確認が推奨される
  - ActiveStorage認可のテストは統合テストでの検証も推奨される
  - レプリカ接続のテストはインフラ環境に依存するため、モック/スタブを使用した単体テストと実環境での結合テストの両方が推奨される

## 6) レビュアーチェックリスト（最小）
- [ ] UUID型のserialize/deserializeがバイナリストレージで正しく動作するか確認
- [ ] ActiveStorage認可がすべてのコントローラ（RedirectController, ProxyController）に適用されているか確認
- [ ] レプリカDB接続設定がdatabase.ymlの構成と整合しているか確認
- [ ] 日付演算のSQL式が対象DBで正しく実行されるか確認
- [ ] prepend_orderがActiveRecord::RelationとAssociationRelationの両方で動作するか確認
- [ ] ブロードキャスト抑制がBoard, Cardの両モデルで有効になるか確認
