# 機能設計書 18-ファイル削除

## 概要

本ドキュメントは、GitLabにおけるファイル削除機能の設計仕様を定義する。Web UIからリポジトリ内のファイルを削除する機能について、処理フロー、入出力仕様、ビジネスルールを記載する。

### 本機能の処理概要

ファイル削除機能は、GitリポジトリのファイルをWeb UI上で削除し、コミットする機能である。開発者はローカル環境を使わずに、不要なファイルの削除を行うことができる。

**業務上の目的・背景**：ローカル環境のセットアップなしに、ブラウザから直接ファイルを削除できる利便性を提供。不要なファイルの整理、設定ファイルの削除などに活用される。

**機能の利用シーン**：
- 不要になった設定ファイルを削除する場合
- 誤って追加されたファイルを削除する場合
- リポジトリの整理を行う場合
- 古いドキュメントを削除する場合

**主要な処理内容**：
1. 削除権限の確認
2. ファイル存在確認
3. コンフリクト検出（last_commit_shaによる）
4. 削除コミットの作成

**関連システム・外部連携**：
- Gitalyサーバーとの連携（コミット作成）

**権限による制御**：
- プロジェクトへの書き込み権限（push_code）が必要
- 保護ブランチの場合は追加の権限チェック

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 33 | ファイル編集 | 主画面 | ファイル削除オプション |
| 31 | ファイル表示 | 遷移元画面 | 削除操作への遷移 |

## 機能種別

CRUD操作（Delete）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| namespace_id | String | Yes | 名前空間パス | 存在する名前空間 |
| project_id | String | Yes | プロジェクトパス | 存在するプロジェクト |
| id | String | Yes | ref/ファイルパス | 有効なref、存在するファイル |
| commit_message | String | Yes | コミットメッセージ | 空でないこと |
| branch_name | String | Yes | コミット先ブランチ | 有効なブランチ名 |
| last_commit_sha | String | No | 最終コミットSHA | コンフリクト検出用 |

### 入力データソース

- 画面入力：コミットメッセージ
- URLパラメータ：プロジェクト識別子、ref、ファイルパス

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| success | Boolean | 削除成功/失敗 |
| commit | Gitlab::Git::Commit | 作成されたコミット情報 |

### 出力先

- 画面表示：削除完了後、ツリー表示画面にリダイレクト
- Gitリポジトリ：新しいコミットの作成

## 処理フロー

### 処理シーケンス

```
1. 削除リクエスト
   └─ BlobController#destroyが呼び出される

2. 権限チェック
   └─ authorize_edit_tree!で編集権限を確認

3. 変更検出
   └─ file_has_changed?で他のユーザーによる変更を検出

4. コミット作成
   └─ Files::DeleteService#execute
      └─ repository.delete_file

5. 結果処理
   ├─ 成功: ツリー表示画面にリダイレクト
   └─ 失敗: エラー表示
```

### フローチャート

```mermaid
flowchart TD
    A[ファイル削除リクエスト] --> B{削除権限?}
    B -->|No| C[403エラー]
    B -->|Yes| D{コンフリクト検出?}
    D -->|Yes| E[コンフリクトエラー表示]
    D -->|No| F[削除コミット作成]
    F --> G{成功?}
    G -->|Yes| H[ツリー表示へリダイレクト]
    G -->|No| I[エラー表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 削除権限 | push_code権限が必要 | 常時 |
| BR-02 | コンフリクト検出 | 編集開始時と異なるコミットがある場合はエラー | 削除時 |
| BR-03 | コミットメッセージ必須 | コミットメッセージは必須 | 常時 |
| BR-04 | ブランチ指定必須 | コミット先ブランチは必須 | 常時 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 該当なし | - | - | Gitリポジトリへの直接操作 |

### Gitalyへのリクエスト

| 操作 | 内容 | 備考 |
|-----|------|------|
| UserCommitFiles | ファイル削除コミット | 削除時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | Forbidden | 削除権限がない | 権限を確認 |
| - | コンフリクト | 他ユーザーが編集 | 最新内容を確認して再試行 |
| - | バリデーションエラー | コミットメッセージ空 | メッセージを入力 |

### リトライ仕様

- コンフリクト時は最新内容を確認して再試行

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

- Gitへのコミット作成は原子的に実行

## パフォーマンス要件

- コミット作成は数秒以内

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

- 削除権限の厳格なチェック
- 保護ブランチへの書き込み制御
- コンフリクト検出による整合性確保

## 備考

- 削除後、そのディレクトリが空になる場合はディレクトリも削除される（Gitの仕様）
- 削除はコミットとして記録され、履歴から復元可能

---

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

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

### 推奨読解順序

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

コミットパラメータの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | base_service.rb | `app/services/files/base_service.rb` | ファイル操作の基本パラメータ |

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

コントローラーの削除処理を確認する。

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

**主要処理フロー**:
1. **131-138行目**: destroyアクション、Files::DeleteServiceの呼び出し

#### Step 3: ファイル削除サービスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | delete_service.rb | `app/services/files/delete_service.rb` | ファイル削除ロジック |

**主要処理フロー**:
- **5-14行目**: create_commit!、repository.delete_fileの呼び出し
- **19-24行目**: validate!、コンフリクト検出

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

```
Projects::BlobController#destroy
    │
    ├─ authorize_edit_tree! (権限チェック)
    │
    └─ create_commit (CreatesCommit concern)
           └─ Files::DeleteService#execute
                  ├─ validate! (コンフリクト検出)
                  └─ repository.delete_file (ファイル削除)
```

### データフロー図

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

ファイルパス ───▶ BlobController ───▶ 削除結果
コミットメッセージ      │
ブランチ名             ▼
               Files::DeleteService
                      │
                      ▼
               Repository#delete_file
                      │
                      ▼
               Gitaly RPC ───▶ 削除コミット
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| blob_controller.rb | `app/controllers/projects/blob_controller.rb` | コントローラー | 削除のエントリーポイント |
| creates_commit.rb | `app/controllers/concerns/creates_commit.rb` | Concern | コミット作成処理 |
| delete_service.rb | `app/services/files/delete_service.rb` | サービス | ファイル削除処理 |
| base_service.rb | `app/services/files/base_service.rb` | サービス | ファイル操作基底クラス |
| repository.rb | `app/models/repository.rb` | モデル | リポジトリ操作 |
