# 画面設計書 26-プロジェクト編集

## 概要

本ドキュメントは、GitLabのプロジェクト編集画面（一般設定画面）に関する設計書である。この画面はプロジェクトの基本設定、可視性、機能の有効/無効、高度な設定（パス変更、転送、アーカイブ、削除など）を管理するための設定画面である。

### 本画面の処理概要

プロジェクト編集画面は、プロジェクトの各種設定を管理するための包括的な設定インターフェースを提供する。複数のセクションに分かれており、名前・説明・トピックの編集、可視性と機能権限の設定、バッジ管理、詳細設定（ハウスキーピング、エクスポート、パス変更、転送、削除）などを行うことができる。

**業務上の目的・背景**：プロジェクトのライフサイクル管理において、設定の変更は頻繁に発生する。この画面では、プロジェクトの基本情報変更から、チームのコラボレーション設定、セキュリティに関わる可視性設定、さらにはプロジェクトの移行や削除といった重要な操作まで、一元的に管理できる。適切な権限管理により、意図しない設定変更を防止している。

**画面へのアクセス方法**：
- プロジェクトサイドバーの「Settings」>「General」を選択
- 直接URL `/:namespace/:project/edit` にアクセス
- プロジェクト詳細画面の設定アイコンからアクセス

**主要な操作・処理内容**：
1. 基本情報の編集 - プロジェクト名、説明、アバター、トピックの更新
2. 可視性と機能権限の設定 - 可視性レベル、各機能のアクセスレベル設定
3. バッジ管理 - プロジェクトバッジの追加・編集・削除
4. GitLab Duo設定 - AI機能の有効/無効設定（ライセンス保有時）
5. ハウスキーピング - リポジトリの最適化実行
6. エクスポート - プロジェクトのエクスポートファイル生成
7. パス変更 - プロジェクトパス（URL）の変更
8. 転送 - 別の名前空間への移動
9. アーカイブ/アンアーカイブ - プロジェクトの凍結/解除
10. 削除 - プロジェクトの削除（削除予定への移行）

**画面遷移**：
- 遷移元：プロジェクト詳細画面、サイドバーナビゲーション
- 遷移先：各設定更新後は同画面に留まる、削除後はダッシュボード

**権限による表示制御**：
- `admin_project`権限：全設定セクションへのアクセス
- 権限なし：アーカイブ、削除セクションのみ表示（限定的な操作）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | プロジェクト編集 | 主機能 | プロジェクト設定の編集処理 |
| 3 | プロジェクト削除 | 補助機能 | プロジェクト削除オプション |
| 4 | プロジェクトアーカイブ | 補助機能 | アーカイブ・アンアーカイブ処理 |
| 5 | プロジェクト移行 | 補助機能 | 名前空間移動オプション |

## 画面種別

編集

## URL/ルーティング

- URL: `/:namespace/:project/edit`
- ルーティング: `config/routes.rb` - `resources :projects`
- コントローラ: `ProjectsController#edit`, `ProjectsController#update`

## 入出力項目

| 項目名 | 入力/出力 | 必須 | データ型 | 説明 |
|--------|----------|------|----------|------|
| name | 入力 | 必須 | String | プロジェクト名 |
| description | 入力 | - | Text | プロジェクトの説明 |
| avatar | 入力 | - | File | プロジェクトアバター画像 |
| topics | 入力 | - | Array | プロジェクトトピック |
| visibility_level | 入力 | 必須 | Enum | public/internal/private |
| path | 入力 | - | String | プロジェクトパス（詳細設定） |
| new_namespace_id | 入力 | - | Integer | 転送先名前空間（転送時） |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| プロジェクト名 | Input | 現在の名前と編集フィールド |
| 説明 | Textarea | 現在の説明と編集フィールド |
| アバター | Image/Upload | 現在のアバターとアップロード機能 |
| トピック | Tags | 現在のトピックと編集機能 |
| 可視性レベル | Radio | 現在の可視性と変更オプション |
| 機能アクセスレベル | Select | 各機能のアクセスレベル設定 |
| バッジ一覧 | List | プロジェクトに設定されたバッジ |

## イベント仕様

### 1-ページ読み込み

1. `ProjectsController#edit` が呼び出される
2. `authorize_view_edit_page!` で権限チェック
3. `present_project` でプレゼンターを適用
4. `@badge_api_endpoint` を設定
5. `project_settings`レイアウトでレンダリング

### 2-基本情報更新

1. フォーム送信で `ProjectsController#update` が呼び出される
2. `Projects::UpdateService` でプロジェクト更新
3. 成功時：更新完了メッセージを表示
4. 失敗時：エラーメッセージを表示して編集画面を再表示

### 3-可視性・機能権限更新

1. 権限フォーム送信
2. `project_feature_attributes` と `visibility_level` の更新
3. 可視性変更時は確認モーダルを表示

### 4-ハウスキーピング実行

1. 「Run housekeeping」ボタンをクリック
2. `ProjectsController#housekeeping` が呼び出される
3. `Repositories::HousekeepingService` でリポジトリ最適化
4. 監査イベントを記録

### 5-プロジェクトエクスポート

1. 「Export project」ボタンをクリック
2. `ProjectsController#export` が呼び出される
3. エクスポートジョブをキュー
4. 完了時にメール通知

### 6-パス変更

1. パス変更フォーム送信
2. `ProjectsController#update` でパス更新
3. 確認メッセージ後にリダイレクト

### 7-プロジェクト転送

1. 転送先名前空間を選択して送信
2. `ProjectsController#transfer` が呼び出される
3. `Projects::TransferService` で転送実行

### 8-アーカイブ/アンアーカイブ

1. 「Archive project」または「Unarchive project」ボタンをクリック
2. `ProjectsController#archive` または `#unarchive` が呼び出される
3. `Projects::ArchiveService` または `Projects::UnarchiveService` で実行

### 9-プロジェクト削除

1. 「Delete project」ボタンをクリック
2. 確認モーダルでプロジェクト名を入力
3. `ProjectsController#destroy` が呼び出される
4. `Projects::MarkForDeletionService` で削除予定に設定

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 基本情報更新 | projects | UPDATE | 名前、説明、トピック更新 |
| 可視性更新 | projects | UPDATE | visibility_level更新 |
| 機能権限更新 | project_features | UPDATE | 各機能のアクセスレベル更新 |
| パス変更 | projects | UPDATE | path更新 |
| パス変更 | routes | UPDATE | ルート情報更新 |
| 転送 | projects | UPDATE | namespace_id更新 |
| アーカイブ | projects | UPDATE | archived = true |
| 削除予定 | projects | UPDATE | pending_delete, marked_for_deletion_at |

### テーブル別更新項目詳細

#### projects

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | 入力値 | 基本情報更新 |
| UPDATE | description | 入力値 | 基本情報更新 |
| UPDATE | visibility_level | 入力値 | 可視性更新 |
| UPDATE | path | 入力値 | パス変更 |
| UPDATE | namespace_id | 入力値 | 転送 |
| UPDATE | archived | true/false | アーカイブ |
| UPDATE | pending_delete | true | 削除予定 |

## メッセージ仕様

| 種別 | メッセージID | メッセージ内容 | 表示条件 |
|------|------------|--------------|---------|
| 成功 | housekeeping_started | Housekeeping successfully started | ハウスキーピング開始時 |
| 成功 | export_started | Project export started. A download link will be sent by email | エクスポート開始時 |
| 成功 | fork_removed | The fork relationship has been removed | フォーク関係削除時 |
| 警告 | rename_warning | Renaming a project's repository can have unintended side effects | パス変更時 |
| 情報 | saving_project | Saving project. Please wait a moment | 保存処理中 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| 権限不足 | アクセス拒否 |
| バリデーションエラー | エラーメッセージ表示 |
| ハウスキーピングがすでに実行中 | LeaseTakenエラーを表示 |
| エクスポート制限超過 | エラーメッセージを表示 |
| 転送先が無効 | エラーメッセージ表示 |

## 備考

- 設定は複数のセクション（SettingsBlockComponent）で構成されている
- Vue.jsコンポーネントで一部の設定UIを実装（プロジェクト権限フォーム等）
- `expanded_by_default?` でセクションの初期展開状態を制御
- 管理者のみ表示されるGitLab Duo設定セクション（ライセンス依存）
- `reduce-visibility-form-id` でモーダル確認フローを制御

---

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

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

### 推奨読解順序

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

プロジェクト設定に関連するモデルとサービスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | project.rb | `app/models/project.rb` | Projectモデル、更新可能属性 |
| 1-2 | project_feature.rb | `app/models/project_feature.rb` | 機能アクセスレベル |
| 1-3 | update_service.rb | `app/services/projects/update_service.rb` | 更新ロジック |

**読解のコツ**: `project_feature_attributes`で設定可能な機能アクセスレベルを確認する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | projects_controller.rb | `app/controllers/projects_controller.rb` | edit/updateアクション |

**主要処理フロー**:
1. **109-112行目**: `edit` アクション
2. **110行目**: `@badge_api_endpoint` 設定
3. **127-134行目**: `update` アクション
4. **128行目**: `Projects::UpdateService`呼び出し
5. **264-291行目**: `housekeeping` アクション
6. **293-305行目**: `export` アクション
7. **248-262行目**: `archive`/`unarchive` アクション
8. **201-221行目**: `destroy` アクション

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit.html.haml | `app/views/projects/edit.html.haml` | メインビュー |
| 3-2 | _general.html.haml | `app/views/projects/settings/_general.html.haml` | 基本設定セクション |
| 3-3 | _export.html.haml | `app/views/projects/_export.html.haml` | エクスポートセクション |
| 3-4 | _transfer.html.haml | `app/views/projects/_transfer.html.haml` | 転送セクション |
| 3-5 | _delete.html.haml | `app/views/projects/_delete.html.haml` | 削除セクション |

**主要処理フロー**:
- **12-20行目（edit.html.haml）**: 基本情報セクション
- **22-32行目（edit.html.haml）**: 可視性・権限セクション
- **34-42行目（edit.html.haml）**: バッジセクション
- **60-119行目（edit.html.haml）**: 詳細設定セクション

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

```
ProjectsController#edit
    │
    ├─ authorize_view_edit_page!
    │
    ├─ present_project
    │      └─ @project.present(current_user: current_user)
    │
    └─ render 'edit' (layout: 'project_settings')

ProjectsController#update
    │
    └─ Projects::UpdateService.new(@project, current_user, params).execute
           │
           ├─ update_project_attributes
           │
           ├─ update_project_features
           │
           └─ update_project_settings

ProjectsController#housekeeping
    │
    └─ Repositories::HousekeepingService.new(@project, task).execute
           │
           └─ Gitlab::Audit::Auditor.audit

ProjectsController#destroy
    │
    └─ Projects::MarkForDeletionService.new(@project, current_user).execute
```

### データフロー図

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

フォーム入力 ───▶ ProjectsController#update ───▶ @project
    │                     │
    ├─ 基本情報          ├─ Projects::UpdateService
    ├─ 可視性設定         │      │
    └─ 機能権限           │      ├─ projects更新
                         │      └─ project_features更新
                         │
                         └─────────────────▶ 更新完了/エラー
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| projects_controller.rb | `app/controllers/projects_controller.rb` | コントローラ | リクエストハンドリング |
| edit.html.haml | `app/views/projects/edit.html.haml` | テンプレート | メインビュー |
| _general.html.haml | `app/views/projects/settings/_general.html.haml` | パーシャル | 基本設定 |
| _export.html.haml | `app/views/projects/_export.html.haml` | パーシャル | エクスポート |
| _transfer.html.haml | `app/views/projects/_transfer.html.haml` | パーシャル | 転送設定 |
| _archive.html.haml | `app/views/projects/settings/_archive.html.haml` | パーシャル | アーカイブ |
| _delete.html.haml | `app/views/projects/_delete.html.haml` | パーシャル | 削除 |
| update_service.rb | `app/services/projects/update_service.rb` | サービス | 更新ロジック |
| housekeeping_service.rb | `app/services/repositories/housekeeping_service.rb` | サービス | ハウスキーピング |
