# 機能設計書 54-トリガー管理

## 概要

本ドキュメントは、GitLabの外部からパイプラインをトリガーするためのトリガートークンの設定・管理機能について記述した機能設計書である。

### 本機能の処理概要

トリガー管理機能は、外部システムやスクリプトからCI/CDパイプラインを起動するためのトリガートークンを作成・管理する機能である。

**業務上の目的・背景**：外部システム（GitHub、Jenkins、Webhook等）からGitLabのパイプラインを起動したい場合や、スケジューリングツールから定期的にパイプラインを実行したい場合に、認証済みのトリガートークンが必要となる。本機能により、セキュアかつ管理しやすい形で外部連携を実現できる。

**機能の利用シーン**：
- 外部CIシステムからGitLabパイプラインを連携起動する場合
- Webhookでパイプラインを自動起動する場合
- cron等のスケジューラーから定期パイプラインを実行する場合
- マイクロサービス間でパイプラインを連携する場合
- ChatOpsでパイプラインを起動する場合

**主要な処理内容**：
1. トリガートークンの作成
2. トリガートークンの説明編集
3. トリガートークンの削除
4. トリガートークン一覧の表示
5. トリガートークンの有効期限設定

**関連システム・外部連携**：
- 外部CIシステム（Jenkins等）
- Webhookサービス
- スケジューリングツール（cron等）
- REST API（トリガーエンドポイント）

**権限による制御**：
- トリガー管理: `manage_trigger`権限が必要
- トリガー管理（管理者操作）: `admin_trigger`権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 112 | CI/CD設定 | 主画面 | トリガー設定の管理 |

## 機能種別

CRUD操作 / トークン管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| description | String | Yes | トリガーの説明 | - |
| expires_at | Date | No | 有効期限 | 最大有効期限チェック |

### 入力データソース

- 画面入力（トリガー設定フォーム）
- API リクエスト（REST）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | トリガーID |
| token | String | トリガートークン（作成時のみ完全表示） |
| short_token | String | トークンの先頭4文字 |
| description | String | 説明 |
| owner | Object | 所有者情報 |
| last_used | DateTime | 最終使用日時 |
| expires_at | Date | 有効期限 |

### 出力先

- 画面表示（トリガー一覧）
- リダイレクト（CI/CD設定画面）
- フラッシュメッセージ（操作結果）

## 処理フロー

### 処理シーケンス

```
1. 権限チェック
   └─ manage_trigger 権限の確認

2. 操作種別の判定
   └─ 作成/更新/削除の判定

3. サービス呼び出し
   └─ 該当するServiceクラスを実行

4. 結果処理
   └─ 成功/失敗に応じたレスポンス生成

5. リダイレクト
   └─ CI/CD設定画面へ遷移
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{manage_trigger権限?}
    B -->|No| C[アクセス拒否]
    B -->|Yes| D{操作種別}
    D -->|作成| E[CreateService実行]
    D -->|更新| F{admin_trigger権限?}
    D -->|削除| G[DestroyService実行]
    F -->|No| C
    F -->|Yes| H[UpdateService実行]
    E --> I{成功?}
    H --> I
    G --> I
    I -->|Yes| J[成功メッセージ]
    I -->|No| K[エラーメッセージ]
    J --> L[CI/CD設定へリダイレクト]
    K --> L
    L --> M[終了]
    C --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-54-01 | 有効期限上限 | トークンの有効期限は最大でPersonalAccessToken::MAX_PERSONAL_ACCESS_TOKEN_LIFETIME_IN_DAYS日間 | 作成時 |
| BR-54-02 | 所有者設定 | トリガー作成者が自動的に所有者となる | 作成時 |
| BR-54-03 | プロジェクトスコープ | トリガーはプロジェクト単位で管理される | 全操作時 |
| BR-54-04 | トークンプレフィックス | トークンにはglptt-プレフィックスが付与される | 作成時 |
| BR-54-05 | 期限切れトークン保持 | 期限切れトークンは30日間保持後に削除可能 | 自動クリーンアップ時 |

### 計算ロジック

- short_token: トークンからプレフィックスを除いた先頭4文字
- 最大有効期限: `Date.current + MAX_PERSONAL_ACCESS_TOKEN_LIFETIME_IN_DAYS`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| トリガー作成 | ci_triggers | INSERT | 新規トリガーレコード作成 |
| トリガー更新 | ci_triggers | UPDATE | description等の更新 |
| トリガー削除 | ci_triggers | DELETE | トリガーレコード削除 |
| 最終使用日時取得 | ci_pipelines | SELECT | 最後に使用されたパイプラインの日時取得 |

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

#### ci_triggers

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | token_encrypted | 暗号化されたトークン | 自動生成 |
| INSERT | owner_id | 作成者のユーザーID | - |
| INSERT | project_id | 対象プロジェクトID | - |
| INSERT | description | ユーザー入力値 | - |
| INSERT | expires_at | 指定された有効期限 | オプション |
| UPDATE | description | 新しい説明文 | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | Forbidden | manage_trigger権限なし | プロジェクトへのMaintainer以上の権限を取得 |
| 403 | Forbidden | admin_trigger権限なし（更新時） | トークン所有者または管理者権限を取得 |
| 404 | Not Found | トリガー未検出 | 正しいトリガーIDを確認 |
| 422 | Validation Error | 有効期限が上限を超過 | 有効期限を調整 |

### リトライ仕様

- 作成/更新/削除失敗時は自動リトライなし
- ユーザーによる再操作が必要

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

- 個別のCRUD操作は単一トランザクション内で実行
- パイプライン起動との連携は別トランザクション

## パフォーマンス要件

- トリガー一覧取得: 1秒以内
- トリガー作成/更新/削除: 1秒以内

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

- トークンは暗号化して保存（token_encrypted）
- 完全なトークンは作成時のみ表示
- 短縮トークン（short_token）で識別表示
- プロジェクト単位でのアクセス制御
- 有効期限によるトークンの自動無効化

## 備考

- トークンプレフィックス（glptt-）はインスタンスプレフィックスと組み合わせ可能
- EXPIRED_TOKEN_RETENTIONは30日間

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | trigger.rb | `app/models/ci/trigger.rb` | トリガーの属性、バリデーション、スコープを理解する |

**読解のコツ**:
- **11行目**: `TRIGGER_TOKEN_PREFIX = 'glptt-'` でトークンプレフィックスを確認
- **13行目**: `EXPIRED_TOKEN_RETENTION = 30.days` で期限切れトークン保持期間を確認
- **27行目**: `validate :expires_at_before_instance_max_expiry_date` で有効期限バリデーションを確認
- **66-70行目**: `last_used`メソッドで最終使用日時の取得ロジックを確認
- **72-78行目**: `short_token`メソッドで短縮トークン生成ロジックを確認
- **80-82行目**: `can_access_project?`でプロジェクトアクセス権チェックを確認

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | triggers_controller.rb | `app/controllers/projects/triggers_controller.rb` | 各アクションの処理フローを確認 |

**主要処理フロー**:
- **4-5行目**: 権限チェックのbefore_action
- **15-16行目**: indexはCI/CD設定画面へリダイレクト
- **19-35行目**: createアクションでCreateServiceを呼び出し
- **38-47行目**: updateアクションでUpdateServiceを呼び出し
- **50-59行目**: destroyアクションでDestroyServiceを呼び出し
- **81-82行目**: trigger_paramsでdescriptionとexpires_atを許可

#### Step 3: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create_service.rb | `app/services/ci/pipeline_triggers/create_service.rb` | トリガー作成のビジネスロジック |

**主要処理フロー**:
- **17-38行目**: executeメソッドで権限チェックと作成処理を実行
- **44-47行目**: create_paramsでパラメータ組み立て

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

```
Projects::TriggersController
    │
    ├─ #create
    │      └─ Ci::PipelineTriggers::CreateService#execute
    │             └─ project.triggers.create
    │
    ├─ #update
    │      └─ Ci::PipelineTriggers::UpdateService#execute
    │             └─ trigger.update
    │
    └─ #destroy
           └─ Ci::PipelineTriggers::DestroyService#execute
                  └─ trigger.destroy
```

### データフロー図

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

トリガー設定
フォーム    ───▶ TriggersController ───▶ CI/CD設定画面
                      │
                      ▼
              PipelineTriggers::*Service
                      │
                      ▼
              Ci::Trigger (Model)
                      │
                      ▼
              ci_triggers テーブル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| trigger.rb | `app/models/ci/trigger.rb` | モデル | トリガーのデータモデル |
| triggers_controller.rb | `app/controllers/projects/triggers_controller.rb` | コントローラー | トリガー操作のエンドポイント |
| create_service.rb | `app/services/ci/pipeline_triggers/create_service.rb` | サービス | トリガー作成ロジック |
| update_service.rb | `app/services/ci/pipeline_triggers/update_service.rb` | サービス | トリガー更新ロジック |
| destroy_service.rb | `app/services/ci/pipeline_triggers/destroy_service.rb` | サービス | トリガー削除ロジック |
