# 機能設計書 132-エラートラッキング

## 概要

本ドキュメントは、GitLabにおけるエラートラッキング機能の設計について記述する。アプリケーションで発生したエラーを収集・追跡し、問題の特定と解決を支援する機能を定義する。

### 本機能の処理概要

**業務上の目的・背景**：本番環境で稼働するアプリケーションで発生するランタイムエラーや例外を収集・集約し、開発者がエラーの傾向を把握して迅速に問題を修正できるようにする。従来はSentryなどの外部エラートラッキングサービスに依存していたが、GitLab内蔵のエラートラッキング機能により、コード管理とエラー管理を一元化し、DevOpsサイクルを効率化する。

**機能の利用シーン**：
- 本番環境でアプリケーション例外が発生した際に自動でエラー情報を収集
- 類似エラーのグルーピングによる発生頻度・影響範囲の可視化
- エラーからイシューを作成して修正タスクを管理
- 解決済みエラーのステータス管理とトレンド分析
- Sentryなど外部エラートラッキングサービスとの連携

**主要な処理内容**：
1. エラーイベントの受信と保存
2. エラーの一覧表示（ステータス、検索、ソート、ページネーション）
3. エラー詳細情報の表示（スタックトレース、発生回数、最終発生日時）
4. エラーのステータス更新（resolved/unresolved/ignored）
5. エラー解決時の関連イシュー自動クローズ
6. 外部Sentryプロジェクトとの連携

**関連システム・外部連携**：
- Sentry（外部エラートラッキングサービス）
- GitLab内蔵エラートラッキング（統合モード）
- GitLab Issue（関連イシューとの連携）

**権限による制御**：
- `read_sentry_issue`: エラー一覧・詳細の閲覧
- `update_sentry_issue`: エラーステータスの更新

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 101 | エラートラッキング | 主機能 | エラートラッキングの一覧表示 |
| 114 | 運用設定 | 補助機能 | エラートラッキング設定 |
| 171 | Observability | 補助機能 | Observability画面の表示 |
| 172 | Observabilityセットアップ | 補助機能 | Observabilityセットアップ |

## 機能種別

CRUD操作 / データ連携 / ステータス管理 / 外部API連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| issue_status | String | No | エラーステータスフィルタ | resolved/unresolved/ignored |
| search_term | String | No | 検索キーワード | - |
| sort | String | No | ソート順 | デフォルト: last_seen |
| cursor | String | No | ページネーションカーソル | - |
| limit | Integer | No | 取得件数 | デフォルト: 20 |
| issue_id | String | Yes (更新時) | エラーID | - |
| status | String | Yes (更新時) | 更新後ステータス | resolved/unresolved/ignored |

### 入力データソース

- GitLab UI上でのユーザー操作
- REST API / GraphQL API経由のリクエスト
- 外部Sentryサービスからのデータ取得
- GitLab内蔵エラートラッキングからのデータ取得

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | String | エラーID |
| title | String | エラータイトル |
| type | String | エラータイプ |
| status | String | エラーステータス |
| count | Integer | 発生回数 |
| first_seen | DateTime | 初回発生日時 |
| last_seen | DateTime | 最終発生日時 |
| message | String | エラーメッセージ |
| culprit | String | エラー発生箇所 |
| external_url | String | 外部Sentryへのリンク |
| pagination | Object | ページネーション情報 |

### 出力先

- GitLab UIでのエラー一覧・詳細表示
- REST API / GraphQL APIレスポンス

## 処理フロー

### 処理シーケンス

```
1. エラー一覧取得リクエスト受信
   └─ 検索条件、ステータスフィルタ、ソート順、ページネーションを受け取る
2. データソース判定
   └─ 統合エラートラッキング有効か外部Sentry連携かを判定
3. エラーデータ取得
   └─ 内部DBまたは外部Sentry APIからエラーデータを取得
4. レスポンス整形
   └─ 統一フォーマットでエラー一覧とページネーション情報を返却
5. UI表示
   └─ エラー一覧画面でデータを表示
```

### フローチャート

```mermaid
flowchart TD
    A[エラー一覧リクエスト] --> B{ステータス検証}
    B -->|有効| C{統合モード?}
    B -->|無効| X[Bad Request]
    C -->|Yes| D[内部DB検索]
    C -->|No| E[Sentry API呼び出し]
    D --> F[レスポンス整形]
    E --> F
    F --> G[エラー一覧返却]

    H[エラー更新リクエスト] --> I{権限チェック}
    I -->|OK| J{統合モード?}
    I -->|NG| Y[Unauthorized]
    J -->|Yes| K[内部DB更新]
    J -->|No| L[Sentry API更新]
    K --> M{resolved?}
    L --> M
    M -->|Yes| N[関連イシュークローズ]
    M -->|No| O[キャッシュクリア]
    N --> O
    O --> P[更新結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-132-01 | ステータス値制限 | resolved/unresolved/ignoredのみ許可 | エラー一覧取得時 |
| BR-132-02 | デフォルトステータス | ステータス未指定時はunresolved | エラー一覧取得時 |
| BR-132-03 | デフォルト件数 | 件数未指定時は20件 | エラー一覧取得時 |
| BR-132-04 | デフォルトソート | ソート未指定時はlast_seen | エラー一覧取得時 |
| BR-132-05 | 関連イシュー自動クローズ | エラーをresolvedにすると関連イシューを自動クローズ | エラー更新時 |

### 計算ロジック

- **ページネーション**: カーソルベースのページネーションを使用
- **エラーグルーピング**: フィンガープリントによる類似エラーの自動グルーピング

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| エラー一覧取得 | error_tracking_errors | SELECT | エラー一覧取得 |
| エラー詳細取得 | error_tracking_errors | SELECT | エラー詳細取得 |
| エラー更新 | error_tracking_errors | UPDATE | ステータス更新 |
| イシュークローズ | issues | UPDATE | 関連イシューのクローズ |
| システムノート追加 | notes | INSERT | クローズ時のシステムノート |

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

#### error_tracking_errors

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | status, project_id | ステータスフィルタ、プロジェクトID | 一覧取得 |
| UPDATE | status | resolved/unresolved/ignored | ステータス更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 400 | Bad Request | 無効なステータス値 | resolved/unresolved/ignoredを指定 |
| 401 | Unauthorized | エラートラッキング無効または権限なし | 設定を有効化、権限を付与 |
| 503 | Service Unavailable | 外部Sentry接続失敗 | 接続設定を確認 |

### リトライ仕様

外部Sentry API呼び出し失敗時は、クライアント側でリトライを実施

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

- エラー更新と関連イシュークローズは同一トランザクション内で実行しない
- イシュークローズ失敗時もエラーステータス更新は成功として扱う

## パフォーマンス要件

- エラー一覧取得は20件以下で500ms以内
- ポーリング間隔の設定によりサーバー負荷を制御

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

- エラー詳細にはスタックトレースが含まれるため、適切な権限チェックを実施
- 外部Sentryのトークンは暗号化して保存
- スタックトレース内の機密情報（パスワード等）はマスキング推奨

## 備考

- 統合エラートラッキング（内蔵モード）はプロジェクト設定で有効化
- 外部Sentry連携は非推奨化の方向

---

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

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

### 推奨読解順序

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

エラートラッキングのデータモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | error_tracking.rb | `app/models/error_tracking.rb` | モジュール定義、テーブル名プレフィックス |
| 1-2 | error_tracking_type.rb | `app/graphql/types/work_items/widgets/error_tracking_type.rb` | GraphQL型定義 |

**読解のコツ**: ErrorTrackingモジュールはテーブル名プレフィックスを`error_tracking_`に設定している。実際のデータモデルはEE版に含まれている可能性がある。

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

エラートラッキング機能のUIエントリーポイント。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | error_tracking_controller.rb | `app/controllers/projects/error_tracking_controller.rb` | 画面表示とAPI処理 |
| 2-2 | error_tracking_helper.rb | `app/helpers/projects/error_tracking_helper.rb` | ビューヘルパー |

**主要処理フロー**:
1. **6行目**: `authorize_read_sentry_issue!`で閲覧権限チェック
2. **7行目**: `authorize_update_sentry_issue!`で更新権限チェック（更新時のみ）
3. **15-23行目**: `index`アクションでHTML/JSON両対応
4. **25-33行目**: `details`アクションでエラー詳細表示
5. **35-44行目**: `update`アクションでステータス更新

#### Step 3: エラー一覧取得サービスを理解する

エラー一覧取得のビジネスロジック。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | list_issues_service.rb | `app/services/error_tracking/list_issues_service.rb` | エラー一覧取得ロジック |

**主要処理フロー**:
- **5-7行目**: デフォルト値定義（status: unresolved, limit: 20, sort: last_seen）
- **10-14行目**: 有効なステータス値（resolved/unresolved/ignored）
- **22-36行目**: `perform`メソッドでステータス検証とデータ取得
- **62-99行目**: `list_issues`で統合モード/Sentryモードを判定してデータ取得

#### Step 4: エラー更新サービスを理解する

エラーステータス更新のビジネスロジック。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | issue_update_service.rb | `app/services/error_tracking/issue_update_service.rb` | エラー更新ロジック |

**主要処理フロー**:
- **7-19行目**: `perform`メソッドで更新実行と後処理
- **21-26行目**: `update_related_issue`で関連イシュー取得
- **28-36行目**: `close_and_create_note`でイシュークローズとシステムノート作成
- **76-98行目**: `update_issue`で統合モード/Sentryモードを判定して更新

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

```
ErrorTrackingController
    │
    ├─ index (エラー一覧)
    │      ├─ ListIssuesService#execute
    │      │      ├─ valid_status? (ステータス検証)
    │      │      └─ list_issues
    │      │             ├─ [統合モード] error_repository.list_errors
    │      │             └─ [Sentryモード] project_error_tracking_setting.list_sentry_issues
    │      │
    │      └─ ErrorSerializer#represent (レスポンス整形)
    │
    ├─ details (エラー詳細)
    │      ├─ IssueDetailsService#execute
    │      └─ DetailedErrorSerializer#represent
    │
    └─ update (エラー更新)
           └─ IssueUpdateService#execute
                  ├─ update_issue
                  │      ├─ [統合モード] error_repository.update_error
                  │      └─ [Sentryモード] project_error_tracking_setting.update_issue
                  │
                  └─ update_related_issue
                         ├─ SentryIssueFinder#execute
                         ├─ Issues::CloseService#execute
                         └─ SystemNoteService#close_after_error_tracking_resolve
```

### データフロー図

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

ユーザーリクエスト ───────▶ ErrorTrackingController ───────▶ エラー一覧画面
      │                           │                              │
      ▼                           ▼                              ▼
検索条件/フィルタ          ListIssuesService              エラー詳細画面
      │                           │                              │
      ▼                           ▼                              ▼
                      ┌─────────────────────┐
                      │   データソース判定    │
                      └─────────────────────┘
                              │
              ┌───────────────┼───────────────┐
              ▼                               ▼
    [統合モード]                      [Sentryモード]
    error_repository             project_error_tracking_setting
              │                               │
              └───────────────┬───────────────┘
                              ▼
                       レスポンス整形
                              │
                              ▼
                       JSON/HTML出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| error_tracking.rb | `app/models/error_tracking.rb` | モデル | モジュール定義 |
| error_tracking_controller.rb | `app/controllers/projects/error_tracking_controller.rb` | コントローラー | UI/API処理 |
| list_issues_service.rb | `app/services/error_tracking/list_issues_service.rb` | サービス | エラー一覧取得 |
| issue_update_service.rb | `app/services/error_tracking/issue_update_service.rb` | サービス | エラー更新 |
| issue_details_service.rb | `app/services/error_tracking/issue_details_service.rb` | サービス | エラー詳細取得 |
| base_service.rb | `app/services/error_tracking/base_service.rb` | サービス | 基底クラス |
| error_tracking_helper.rb | `app/helpers/projects/error_tracking_helper.rb` | ヘルパー | ビューヘルパー |
| error_tracking_list.vue | `app/assets/javascripts/error_tracking/components/error_tracking_list.vue` | Vue | 一覧表示コンポーネント |
| error_tracking_actions.vue | `app/assets/javascripts/error_tracking/components/error_tracking_actions.vue` | Vue | アクションコンポーネント |
| error_tracking_form.vue | `app/assets/javascripts/error_tracking_settings/components/error_tracking_form.vue` | Vue | 設定フォーム |
