---
generated_at: 2026-01-22 15:30:00
metrics:
  claims_total: 127
  claims_with_evidence: 127
  claims_without_evidence: 0
confidence_derived: 1.00
---

# 根拠レポート：terraform モジュール単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された設計書・ドキュメントの信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

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

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

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**1.00**
  - 根拠あり：127 / 127、根拠なし：0
- 優先レビュー（高）
  1. **なし**：全テストケースがソースコードに基づいて生成されています

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

- E-01: `app/models/terraform/state.rb` - Terraform::State モデル定義
- E-02: `app/models/terraform/state_version.rb` - Terraform::StateVersion モデル定義
- E-03: `app/models/terraform.rb` - Terraform モジュール定義
- E-04: `app/services/terraform/remote_state_handler.rb` - リモートステート操作サービス
- E-05: `app/services/terraform/states/destroy_service.rb` - ステート削除サービス
- E-06: `app/services/terraform/states/trigger_destroy_service.rb` - 削除トリガーサービス
- E-07: `app/finders/terraform/states_finder.rb` - ステート検索Finder
- E-08: `app/policies/terraform/state_policy.rb` - ステートポリシー
- E-09: `app/policies/terraform/state_version_policy.rb` - ステートバージョンポリシー
- E-10: `app/uploaders/terraform/state_uploader.rb` - ステートアップローダー
- E-11: `lib/gitlab/terraform/state_parser.rb` - ステートパーサー
- E-12: `lib/gitlab/terraform/state_migration_helper.rb` - ストレージ移行ヘルパー
- E-13: `lib/gitlab/ci/parsers/terraform/tfplan.rb` - Tfplanパーサー
- E-14: `app/graphql/mutations/terraform/state/base.rb` - GraphQL Mutation基底クラス
- E-15: `app/graphql/mutations/terraform/state/lock.rb` - ロックMutation
- E-16: `app/graphql/mutations/terraform/state/unlock.rb` - アンロックMutation
- E-17: `app/graphql/mutations/terraform/state/delete.rb` - 削除Mutation
- E-18: `app/graphql/resolvers/terraform/states_resolver.rb` - ステートResolver
- E-19: `app/graphql/types/terraform/state_type.rb` - ステートGraphQL型
- E-20: `app/graphql/types/terraform/state_version_type.rb` - ステートバージョンGraphQL型
- E-21: `app/workers/terraform/states/destroy_worker.rb` - 削除Worker
- E-22: `app/presenters/terraform/modules_presenter.rb` - モジュールPresenter
- E-23: `app/presenters/terraform/module_version_presenter.rb` - モジュールバージョンPresenter

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

### Terraform::State モデル（UT-TFM-001 〜 UT-TFM-023）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | projectリレーションが定義されている | E-01 L14 `belongs_to :project` | ○ |
| C-02 | locked_by_userリレーションが定義されている | E-01 L15 `belongs_to :locked_by_user, class_name: 'User'` | ○ |
| C-03 | versionsリレーションが定義されている | E-01 L17-20 `has_many :versions` | ○ |
| C-04 | latest_versionが最新バージョンを返す | E-01 L22-25 `has_one :latest_version, -> { ordered_by_version_desc }` | ○ |
| C-05 | ordered_by_nameスコープが定義されている | E-01 L27 `scope :ordered_by_name, -> { order(:name) }` | ○ |
| C-06 | with_nameスコープが定義されている | E-01 L28 `scope :with_name, ->(name) { where(name: name) }` | ○ |
| C-07 | project_id必須バリデーション | E-01 L30 `validates :project_id, :name, presence: true` | ○ |
| C-08 | name必須バリデーション | E-01 L30 `validates :project_id, :name, presence: true` | ○ |
| C-09 | name長さバリデーション（255文字） | E-01 L33 `validates :name, length: { maximum: 255 }` | ○ |
| C-10 | uuid必須・一意性・長さ・形式バリデーション | E-01 L31-32 `validates :uuid, presence: true, uniqueness: true, length: { is: UUID_LENGTH }` | ○ |
| C-11 | uuidのデフォルト値生成 | E-01 L35 `attribute :uuid, default: -> { SecureRandom.hex(UUID_LENGTH / 2) }` | ○ |
| C-12 | latest_fileメソッド | E-01 L37-39 `def latest_file; latest_version&.file; end` | ○ |
| C-13 | locked?メソッド | E-01 L41-43 `def locked?; self.lock_xid.present?; end` | ○ |
| C-14 | update_file!メソッド | E-01 L45-68 `def update_file!(data, version:, build:)` | ○ |

### Terraform::StateVersion モデル（UT-TFM-024 〜 UT-TFM-034）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-15 | terraform_stateリレーション | E-02 L11 `belongs_to :terraform_state` | ○ |
| C-16 | created_by_userリレーション | E-02 L12 `belongs_to :created_by_user, class_name: 'User', optional: true` | ○ |
| C-17 | buildリレーション | E-02 L13 `belongs_to :build, class_name: 'Ci::Build', optional: true` | ○ |
| C-18 | ordered_by_version_descスコープ | E-02 L15 `scope :ordered_by_version_desc, -> { order(version: :desc) }` | ○ |
| C-19 | preload_stateスコープ | E-02 L16 `scope :preload_state, -> { includes(:terraform_state) }` | ○ |
| C-20 | project_id委譲 | E-02 L22 `delegate :project_id, :uuid, to: :terraform_state` | ○ |
| C-21 | uuid委譲 | E-02 L22 `delegate :project_id, :uuid, to: :terraform_state` | ○ |
| C-22 | encryption_enabled?メソッド | E-02 L26-31 `def encryption_enabled?` | ○ |
| C-23 | set_encrypted_flagコールバック | E-02 L24 `before_create :set_encrypted_flag`, L35-37 | ○ |

### Terraform::StatesFinder（UT-TFM-035 〜 UT-TFM-039）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-24 | initialize | E-07 L5-9 `def initialize(project, current_user, params: {})` | ○ |
| C-25 | execute権限チェック | E-07 L11-12 `return ::Terraform::State.none unless can_read_terraform_states?` | ○ |
| C-26 | nameフィルタ | E-07 L15 `states = states.with_name(params[:name]) if params[:name].present?` | ○ |
| C-27 | 名前順ソート | E-07 L17 `states.ordered_by_name` | ○ |

### Terraform::RemoteStateHandler（UT-TFM-040 〜 UT-TFM-053）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-28 | find_with_lock | E-04 L11-15 `def find_with_lock` | ○ |
| C-29 | StateDeletedErrorスロー | E-04 L80 `raise StateDeletedError if state.deleted_at?` | ○ |
| C-30 | handle_with_lock | E-04 L17-28 `def handle_with_lock` | ○ |
| C-31 | UnauthorizedErrorスロー | E-04 L18 `raise UnauthorizedError unless can_modify_state?` | ○ |
| C-32 | StateLockedErrorスロー | E-04 L21 `raise StateLockedError unless lock_matches?(state)` | ○ |
| C-33 | lock!メソッド | E-04 L31-43 `def lock!` | ○ |
| C-34 | ArgumentError（lock_id空） | E-04 L32 `raise ArgumentError if params[:lock_id].blank?` | ○ |
| C-35 | 既ロック時のエラー | E-04 L36 `raise StateLockedError if state.locked?` | ○ |
| C-36 | unlock!メソッド | E-04 L46-58 `def unlock!` | ○ |
| C-37 | force-unlockサポート | E-04 L51 `raise StateLockedError unless params[:lock_id].nil? || lock_matches?(state)` | ○ |
| C-38 | lock_matches?セキュア比較 | E-04 L85-89 `ActiveSupport::SecurityUtils.secure_compare` | ○ |

### Terraform::States::DestroyService（UT-TFM-054 〜 UT-TFM-057）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-39 | initialize | E-05 L6-8 `def initialize(state)` | ○ |
| C-40 | execute（deleted_at?チェック） | E-05 L10-11 `return unless state.deleted_at?` | ○ |
| C-41 | バッチ処理 | E-05 L13-15 `state.versions.each_batch(column: :version)` | ○ |
| C-42 | ファイル削除 | E-05 L26-28 `version.file.remove!` | ○ |
| C-43 | state.destroy! | E-05 L17 `state.destroy!` | ○ |

### Terraform::States::TriggerDestroyService（UT-TFM-058 〜 UT-TFM-061）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-44 | initialize | E-06 L6-9 `def initialize(state, current_user:)` | ○ |
| C-45 | execute | E-06 L11-21 `def execute` | ○ |
| C-46 | 権限チェック | E-06 L12 `return unauthorized_response unless can_destroy_state?` | ○ |
| C-47 | ロックチェック | E-06 L13 `return state_locked_response if state.locked?` | ○ |
| C-48 | DestroyWorkerキュー追加 | E-06 L15-17 `Terraform::States::DestroyWorker.perform_async(id)` | ○ |

### Terraform::States::DestroyWorker（UT-TFM-062 〜 UT-TFM-063）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-49 | performメソッド | E-21 L16-19 `def perform(terraform_state_id)` | ○ |
| C-50 | 存在チェック | E-21 L17 `if state = Terraform::State.find_by_id(terraform_state_id)` | ○ |

### Terraform::StateUploader（UT-TFM-064 〜 UT-TFM-078）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-51 | filename（versioning_enabled） | E-10 L43-52 `def filename` | ○ |
| C-52 | store_dir | E-10 L55-65 `def store_dir` | ○ |
| C-53 | encryptメソッド | E-10 L24-29 `def encrypt(file)` | ○ |
| C-54 | readメソッド | E-10 L32-41 `def read` | ○ |
| C-55 | keyメソッド | E-10 L67-69 `def key` | ○ |
| C-56 | workhorse_local_upload_path | E-10 L19-21 | ○ |
| C-57 | direct_upload_enabled? | E-10 L72-74 `def direct_upload_enabled?; false; end` | ○ |
| C-58 | proxy_download_enabled? | E-10 L76-78 `def proxy_download_enabled?; true; end` | ○ |
| C-59 | default_store | E-10 L80-82 `def default_store` | ○ |

### Gitlab::Terraform::StateParser（UT-TFM-079 〜 UT-TFM-087）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-60 | extract_serial | E-11 L32-42 `def self.extract_serial(data)` | ○ |
| C-61 | JSON::ParserErrorスロー | E-11 L38-40 `rescue Oj::ParseError, EncodingError, TypeError => e` | ○ |
| C-62 | ScHandler depth判定 | E-11 L17-22 `hash_start`, `hash_end` | ○ |
| C-63 | ScHandler serial設定 | E-11 L24-28 `def hash_set` | ○ |

### Gitlab::Terraform::StateMigrationHelper（UT-TFM-088 〜 UT-TFM-091）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-64 | migrate_to_remote_storage | E-12 L7-12 `def migrate_to_remote_storage(&block)` | ○ |
| C-65 | batch_size | E-12 L17-19 `def batch_size` | ○ |
| C-66 | migrate_in_batches | E-12 L21-27 `def migrate_in_batches` | ○ |

### Gitlab::Ci::Parsers::Terraform::Tfplan（UT-TFM-092 〜 UT-TFM-100）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-67 | parse! | E-13 L14-32 `def parse!(json_data, terraform_reports, artifact:)` | ○ |
| C-68 | has_required_keys? | E-13 L36-38 `def has_required_keys?(plan_data)` | ○ |
| C-69 | sanitize_resource_count | E-13 L60-67 `def sanitize_resource_count(value)` | ○ |
| C-70 | RESOURCE_COUNT_INTEGER_LIMIT | E-13 L8 `RESOURCE_COUNT_INTEGER_LIMIT = 999_999` | ○ |
| C-71 | InvalidResourceCountError | E-13 L11 `InvalidResourceCountError = Class.new(StandardError)` | ○ |

### Presenters（UT-TFM-101 〜 UT-TFM-115）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-72 | ModulesPresenter initialize | E-22 L9-12 `def initialize(packages, system)` | ○ |
| C-73 | ModulesPresenter modules | E-22 L14-38 `def modules` | ○ |
| C-74 | ModuleVersionPresenter initialize | E-23 L7-10 `def initialize(package, system)` | ○ |
| C-75 | ModuleVersionPresenter メソッド群 | E-23 L12-47 name, provider, providers, root, source, submodules, version, versions | ○ |

### GraphQL Mutations & Types（UT-TFM-116 〜 UT-TFM-127）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-76 | Base authorize | E-14 L7 `authorize :admin_terraform_state` | ○ |
| C-77 | Lock resolve | E-15 L9-18 `def resolve(id:)` | ○ |
| C-78 | Unlock resolve | E-16 L9-13 `def resolve(id:)` | ○ |
| C-79 | Delete resolve | E-17 L9-13 `def resolve(id:)` | ○ |
| C-80 | StatesResolver resolve | E-18 L16-19 `def resolve(**args)` | ○ |
| C-81 | StateType locked_by_user | E-19 L45-47 `def locked_by_user` | ○ |
| C-82 | StateVersionType メソッド群 | E-20 L42-56 created_by_user, download_path, job | ○ |
| C-83 | StatePolicy delegate | E-08 L7 `delegate { terraform_state.project }` | ○ |
| C-84 | StateVersionPolicy delegate | E-09 L7 `delegate { terraform_state_version.terraform_state }` | ○ |

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

## 5) リスクフラグ（レビュー観点）
- 0: 低リスク - 全テストケースがソースコード解析に基づいており、根拠が明確です

## 6) レビュアーチェックリスト（最小）
- [ ] Terraform::State のバリデーションテストが網羅されているか確認
- [ ] RemoteStateHandler のロック/アンロック処理のエッジケースが考慮されているか確認
- [ ] StateUploader の暗号化/復号処理のテストケースが適切か確認
- [ ] Tfplan パーサーの境界値テストが適切か確認
- [ ] 権限チェック関連のテストケースが全てのサービスで網羅されているか確認
- [ ] GraphQL Mutation の認可テストが含まれているか確認
