# 機能設計書 38-イシュークローズ/再オープン

## 概要

本ドキュメントは、GitLabのイシュークローズ/再オープン機能の設計仕様を記載する。本機能はイシューの完了状態の管理を提供する。

### 本機能の処理概要

イシュークローズ/再オープン機能は、イシューの状態を「Open（オープン）」から「Closed（クローズ）」へ、またはその逆に変更する機能である。

**業務上の目的・背景**：タスクや課題が完了した際に、それを明示的にクローズすることで、プロジェクトの進捗状況を可視化する。また、誤ってクローズした場合や、再度対応が必要になった場合は再オープンできる。

**機能の利用シーン**：バグ修正が完了した際のクローズ、要望が実装された際のクローズ、マージリクエストのマージによる自動クローズ、誤クローズの再オープン、仕様変更により対応が再開される場合の再オープン。

**主要な処理内容**：
1. イシューのクローズ（状態をclosedに変更）
2. イシューの再オープン（状態をopenedに変更）
3. クローズ/再オープンのシステムノート作成
4. 関連通知の送信
5. アラート/インシデントの連動処理
6. MRマージによる自動クローズ

**関連システム・外部連携**：NotificationServiceを通じた状態変更通知、Webhookによる外部システム連携、AlertManagementとの連動

**権限による制御**：update_issue権限を持つユーザーがクローズ可能。reopen_issue権限を持つユーザーが再オープン可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 49 | 課題詳細 | 主画面 | 課題のクローズ・再オープン |
| 47 | 課題一覧 | 参照画面 | クローズ/オープン状態でのフィルタ |

## 機能種別

状態管理（ワークフロー）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | Integer | Yes | イシューID（iid） | 存在チェック |
| state_event | String | Yes | 状態イベント | 'close' or 'reopen' |

### 入力データソース

- 画面入力（クローズ/再オープンボタン）
- API呼び出し
- MRマージによる自動クローズ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| issue | Issue | 更新されたイシュー |
| state | String | 新しい状態（opened/closed） |

### 出力先

- 画面表示（状態更新の反映）
- データベース（issuesテーブルのstate_id更新）
- 通知（メール、Webhook）

## 処理フロー

### 処理シーケンス

```
1. 権限チェック
   └─ クローズ/再オープン権限の確認
2. 状態変更
   └─ issue.close / issue.reopen
3. イベント記録
   └─ EventService.close_issue / reopen_issue
4. システムノート作成
   └─ SystemNoteService.change_status
5. 通知送信
   └─ NotificationService.close_issue / reopen_issue
6. 関連処理
   └─ Todo更新、アラート解決等
7. Webhook実行
   └─ execute_hooks
```

### フローチャート

```mermaid
flowchart TD
    A[クローズ/再オープン要求] --> B{権限チェック}
    B -->|No| C[403エラー]
    B -->|Yes| D{クローズ?}
    D -->|Yes| E[CloseService#execute]
    D -->|No| F[ReopenService#execute]
    E --> G[issue.close]
    F --> H[issue.reopen]
    G --> I[システムノート作成]
    H --> I
    I --> J[通知送信]
    J --> K{インシデント?}
    K -->|Yes| L[インシデント連動処理]
    K -->|No| M[Webhook実行]
    L --> M
    M --> N[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-38-01 | 既クローズ制限 | 既にクローズ済みの場合はクローズ不可 | クローズ時 |
| BR-38-02 | 既オープン制限 | 既にオープン済みの場合は再オープン不可 | 再オープン時 |
| BR-38-03 | アラート連動 | インシデントクローズ時は関連アラートも解決 | クローズ時 |
| BR-38-04 | マイルストーン更新 | クローズ/再オープン時にマイルストーンの完了数を更新 | 状態変更時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 状態更新 | issues | UPDATE | state_id更新 |
| イベント記録 | events | INSERT | close/reopenイベント |
| ノート作成 | notes | INSERT | システムノート |
| Todo更新 | todos | UPDATE | 完了状態に更新 |
| アラート更新 | alert_management_alerts | UPDATE | 解決状態に更新 |

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

#### issues

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | state_id | 2 (closed) / 1 (opened) | 状態値 |
| UPDATE | closed_at | 現在時刻 / null | クローズ時刻 |
| UPDATE | closed_by_id | ユーザーID / null | クローズした人 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | Forbidden | 権限なし | エラーメッセージ表示 |
| - | 処理失敗 | 既に同じ状態 | 何もせず現在の状態を返す |

### リトライ仕様

特になし

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

状態更新と関連レコード更新は同一トランザクション内で実行。

## パフォーマンス要件

特になし

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

- update_issue権限チェック（クローズ）
- reopen_issue権限チェック（再オープン）

## 備考

- MRマージによる自動クローズは別途クローズリンク機能で管理
- 外部イシュートラッカー連携時は外部システムのクローズも実行

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | close_service.rb | `app/services/issues/close_service.rb` | クローズ処理 |
| 1-2 | reopen_service.rb | `app/services/issues/reopen_service.rb` | 再オープン処理 |

**主要処理フロー（close_service.rb）**:
- **8-15行目**: executeメソッド - 権限チェックとクローズ実行
- **22-32行目**: close_issueメソッド - 実際のクローズ処理
- **54-87行目**: after_closeメソッド - 後処理（通知、Todo、Hook等）

**主要処理フロー（reopen_service.rb）**:
- **5-11行目**: executeメソッド - 権限チェックと再オープン実行
- **16-35行目**: after_reopenメソッド - 後処理

#### Step 2: モデル層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | issue.rb | `app/models/issue.rb` | close, reopenメソッド |

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

```
IssuesController#update (state_event: 'close')
    │
    └─ Issues::CloseService#execute
           │
           ├─ can_close? (権限チェック)
           ├─ close_issue
           │      └─ issue.close
           │
           └─ after_close
                  ├─ EventService.close_issue
                  ├─ SystemNoteService.change_status
                  ├─ NotificationService.close_issue
                  ├─ TodoService.close_issue
                  ├─ resolve_alerts
                  └─ execute_hooks

IssuesController#update (state_event: 'reopen')
    │
    └─ Issues::ReopenService#execute
           │
           ├─ can_reopen? (権限チェック)
           ├─ reopen_issue
           │      └─ issue.reopen
           │
           └─ after_reopen
                  ├─ EventService.reopen_issue
                  ├─ SystemNoteService.change_status
                  ├─ NotificationService.reopen_issue
                  └─ execute_hooks
```

### データフロー図

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

クローズ要求 ───▶ CloseService#execute
                       │
                       ▼
                 issue.close ───▶ state_id = 2
                       │
                       ▼
                 after_close
                       │
                       ├─▶ SystemNoteService (ノート作成)
                       ├─▶ NotificationService (通知送信)
                       ├─▶ TodoService (Todo完了)
                       └─▶ execute_hooks (Webhook)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| close_service.rb | `app/services/issues/close_service.rb` | サービス | クローズ処理 |
| reopen_service.rb | `app/services/issues/reopen_service.rb` | サービス | 再オープン処理 |
| issue.rb | `app/models/issue.rb` | モデル | イシューモデル |
| event_service.rb | `app/services/event_service.rb` | サービス | イベント記録 |
| system_note_service.rb | `app/services/system_note_service.rb` | サービス | システムノート |
| notification_service.rb | `app/services/notification_service.rb` | サービス | 通知送信 |
| todo_service.rb | `app/services/todo_service.rb` | サービス | Todo管理 |
