# 帳票設計書 9-Terraform Reports

## 概要

本ドキュメントは、GitLabのCIパイプラインにおけるTerraformプラン実行結果レポートを生成する機能の帳票設計書である。

### 本帳票の処理概要

本帳票は、CIパイプラインで実行されたTerraform Planの結果を取得し、マージリクエストのウィジェットに表示するためのレポートデータを生成する。リアクティブキャッシングを活用して効率的にデータを提供する。

**業務上の目的・背景**：Infrastructure as Code（IaC）の実践において、Terraformによるインフラストラクチャ変更の影響を事前に確認することは重要である。この帳票により、開発者とインフラエンジニアはマージリクエスト画面上でTerraformプランの結果を確認でき、意図しないインフラ変更を防ぐことができる。

**帳票の利用シーン**：マージリクエストのレビュー時にインフラ変更の影響を確認する際、CI/CDパイプラインでのインフラ変更のプレビュー時、Terraformによるインフラ変更の承認プロセスなどに利用される。

**主要な出力内容**：
1. Terraformプランの実行結果
2. 作成/更新/削除されるリソースの情報
3. 変更の詳細

**帳票の出力タイミング**：マージリクエストのTerraformウィジェットが表示される際にリアクティブキャッシング経由でデータが取得される。

**帳票の利用者**：開発者、インフラエンジニア、DevOpsエンジニア

## 帳票種別

インフラレポート（JSON出力）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | Merge Request Widget | `/:namespace/:project/-/merge_requests/:id` | 自動表示（Terraformウィジェット） |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | JSON |
| 用紙サイズ | - |
| 向き | - |
| ファイル名 | - |
| 出力方法 | リアクティブキャッシング |
| 文字コード | UTF-8 |

### レスポンス構造

```json
{
  "status": "parsed",
  "key": [base_pipeline_id, base_updated_at, head_pipeline_id, head_updated_at],
  "data": {
    "plan_name": {
      "create": 2,
      "update": 1,
      "delete": 0,
      "job_name": "terraform plan",
      "job_path": "/path/to/job"
    }
  }
}
```

| フィールド | 説明 |
|-----------|------|
| status | 処理状態（parsed/error） |
| key | キャッシュキー（パイプラインID+更新日時） |
| data | Terraformプラン情報 |

## 帳票レイアウト

### レイアウト概要

JSONレスポンスはstatus、key、dataの3つの主要フィールドで構成される。

```
{
  "status": "処理状態",
  "key": [キャッシュキー配列],
  "data": {
    "プラン名": {
      "create": 作成リソース数,
      "update": 更新リソース数,
      "delete": 削除リソース数,
      "job_name": "ジョブ名",
      "job_path": "ジョブパス"
    }
  }
}
```

### データ項目

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | status | 処理状態 | サービス処理結果 | 文字列（parsed/error） |
| 2 | key | キャッシュキー | パイプライン情報 | 配列 |
| 3 | data | プラン情報 | terraform_reports.plans | オブジェクト |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| base_pipeline | ベースパイプライン | No（比較用、未使用） |
| head_pipeline | ヘッドパイプライン | Yes |

### ソート順

該当なし（プラン名がキー）

### 改ページ条件

JSON形式のため該当なし

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| ci_pipelines | パイプライン情報 | 主テーブル |
| ci_builds | ジョブ情報 | ci_pipelines.id = ci_builds.commit_id |
| ci_job_artifacts | Terraformアーティファクト | ci_builds.id = ci_job_artifacts.job_id |

### テーブル別参照項目詳細

#### ci_pipelines

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| id | key[0], key[2] | - | キャッシュキー |
| updated_at | key[1], key[3] | - | キャッシュキー |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| key | [base_pipeline.id, base_pipeline.updated_at, head_pipeline.id, head_pipeline.updated_at] | - | キャッシュ有効性確認用 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[MRウィジェット表示] --> B[GenerateTerraformReportsService.execute]
    B --> C[head_pipeline.terraform_reports取得]
    C --> D[terraform_reports.plans取得]
    D --> E{正常完了?}
    E -->|Yes| F[status: parsed返却]
    E -->|No| G[StandardError発生]
    G --> H[Gitlab::ErrorTracking.track_exception]
    H --> I[status: error返却]
    F --> J[keyを付与して返却]
    I --> J
    J --> K[latest?でキャッシュ有効性確認]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 取得エラー | StandardError発生 | "An error occurred while fetching terraform reports." | エラーログ確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | プラン数に依存（通常1-10件程度） |
| 目標出力時間 | リアクティブキャッシング使用 |
| 同時出力数上限 | リクエスト単位 |

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

- パイプラインへのアクセス権限が必要
- Terraformプランにはインフラ設定情報が含まれる可能性があるため適切なアクセス制御が必要
- エラー時はGitlab::ErrorTrackingを使用してログに記録

## 備考

- CompareReportsBaseServiceを継承しているが、実際にはレポート比較は行わない
- base_pipelineは未使用（TODOコメントに記載あり）
- feature_categoryはinfrastructure_as_code
- issue: https://gitlab.com/gitlab-org/gitlab/issues/34224 で設計の見直しが予定されている

---

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

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

### 推奨読解順序

#### Step 1: サービスクラスを理解する

レポート生成サービスの実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | generate_terraform_reports_service.rb | `app/services/ci/generate_terraform_reports_service.rb` | executeメソッド（10-22行目） |

**読解のコツ**: TODOコメントに設計意図が記載されている。CompareReportsBaseServiceを継承しているが比較機能は使用していない。

#### Step 2: 基底クラスを理解する

CompareReportsBaseServiceの構造を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | compare_reports_base_service.rb | `app/services/ci/compare_reports_base_service.rb` | keyメソッド（54-59行目） |
| 2-2 | compare_reports_base_service.rb | `app/services/ci/compare_reports_base_service.rb` | latest?メソッド（35-37行目） |

**主要処理フロー**:
1. **54-59行目**: キャッシュキーの生成（base/headパイプラインのID+更新日時）
2. **35-37行目**: キャッシュの有効性確認

#### Step 3: エラーハンドリングを理解する

エラー発生時の処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | generate_terraform_reports_service.rb | `app/services/ci/generate_terraform_reports_service.rb` | rescueブロック（16-22行目） |

**主要処理フロー**:
- **16行目**: StandardErrorをキャッチ
- **17行目**: Gitlab::ErrorTracking.track_exceptionでログ記録
- **18-22行目**: エラーレスポンス返却

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

```
Ci::GenerateTerraformReportsService
    │
    ├─ CompareReportsBaseService (継承)
    │      │
    │      ├─ key(base_pipeline, head_pipeline)
    │      │      └─ [base.id, base.updated_at, head.id, head.updated_at]
    │      │
    │      └─ latest?(base_pipeline, head_pipeline, data)
    │             └─ data[:key] == key(...)
    │
    ├─ execute(base_pipeline, head_pipeline)
    │      │
    │      ├─ head_pipeline.terraform_reports
    │      │      └─ .plans
    │      │
    │      └─ rescue StandardError
    │             └─ Gitlab::ErrorTracking.track_exception
    │
    └─ latest?(base_pipeline, head_pipeline, data)
           └─ キャッシュ有効性確認
```

### データフロー図

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

MRウィジェット ───▶ GenerateTerraformReportsService
    │                      │
    │                      ▼
head_pipeline ───▶ terraform_reports.plans ───▶ status: parsed
    │                      │                        │
    │                      ▼                        ▼
    │               エラー発生時 ───▶ status: error
    │                                               │
    └───────────────────────────────────────▶ JSON返却
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| generate_terraform_reports_service.rb | `app/services/ci/generate_terraform_reports_service.rb` | ソース | レポート生成サービス |
| compare_reports_base_service.rb | `app/services/ci/compare_reports_base_service.rb` | ソース | 基底クラス |
| terraform_reports.rb | `lib/gitlab/ci/reports/terraform_reports.rb` | ソース | レポートモデル |
