# 画面設計書 181-アプリケーション編集

## 概要

本ドキュメントは、GitLabのグループ設定におけるOAuthアプリケーション編集画面の設計を記述したものである。

### 本画面の処理概要

**業務上の目的・背景**：グループ管理者がグループに紐づくOAuthアプリケーションの設定を更新する必要がある場合に使用する画面である。OAuthアプリケーションは外部サービスとの連携やAPIアクセス制御に必要であり、名前、リダイレクトURI、機密設定、スコープなどを適切に管理することで、セキュリティを維持しながら柔軟な連携を実現する。

**画面へのアクセス方法**：グループ設定 > アプリケーション一覧画面から、既存アプリケーションの「編集」ボタンをクリックして遷移する。URLパターンは `groups/:group_id/-/settings/applications/:id/edit` となる。

**主要な操作・処理内容**：
1. アプリケーション名の変更
2. リダイレクトURIの編集（複数行対応）
3. 機密アプリケーション設定の変更
4. OAuthスコープの選択変更
5. 変更内容の保存

**画面遷移**：
- 遷移元：グループ設定アプリケーション一覧画面（179-アプリケーション一覧）
- 遷移先：保存成功時はアプリケーション詳細画面（180-アプリケーション詳細）へ、キャンセル時は一覧画面へ

**権限による表示制御**：グループ管理者権限（`admin_group`）を持つユーザーのみがこの画面にアクセス可能である。権限がない場合はアクセス拒否エラーとなる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 88 | OAuth2プロバイダ | 主機能 | グループOAuthアプリの編集 |

## 画面種別

編集

## URL/ルーティング

- パス: `groups/:group_id/-/settings/applications/:id/edit`
- HTTPメソッド: GET（画面表示）、PATCH/PUT（更新処理）
- コントローラー: `Groups::Settings::ApplicationsController#edit`、`#update`

## 入出力項目

| 項目名 | 項目ID | データ型 | 必須 | 入力形式 | 説明 |
|--------|--------|----------|------|----------|------|
| アプリケーション名 | name | String | Yes | テキスト | アプリケーションの識別名 |
| リダイレクトURI | redirect_uri | Text | Yes | テキストエリア | コールバックURI（1行に1URI） |
| 機密設定 | confidential | Boolean | No | チェックボックス | 機密アプリケーションかどうか |
| スコープ | scopes | Array | No | チェックボックス群 | 許可するOAuthスコープ |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| ページタイトル | 見出し | "Edit group application" |
| アプリケーション名 | テキスト入力 | 現在の名前がプリフィルされる |
| リダイレクトURI | テキストエリア | 現在のURIがプリフィルされる |
| 機密設定 | チェックボックス | 現在の設定状態が反映される |
| スコープ一覧 | チェックボックスリスト | 利用可能な全スコープと選択状態 |
| 保存ボタン | ボタン | "Save application" |

## イベント仕様

### 1-保存ボタン押下

1. フォームバリデーションを実行
2. バリデーション成功時、`ApplicationsController#update`アクションにPATCHリクエストを送信
3. 更新成功時、フラッシュメッセージ「Application was successfully updated.」を表示し、アプリケーション詳細画面へリダイレクト
4. 更新失敗時、エラーメッセージを表示し編集画面を再表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | oauth_applications | UPDATE | アプリケーション情報の更新 |

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

#### oauth_applications

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | フォーム入力値 | アプリケーション名 |
| UPDATE | redirect_uri | フォーム入力値 | リダイレクトURI |
| UPDATE | confidential | フォーム入力値 | 機密フラグ |
| UPDATE | scopes | フォーム入力値 | 許可スコープ |
| UPDATE | updated_at | 現在時刻 | 更新日時 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | 成功 | Application was successfully updated. | 更新処理成功時 |
| MSG-002 | エラー | Name can't be blank | 名前未入力時 |
| MSG-003 | エラー | Redirect URI can't be blank | リダイレクトURI未入力時 |

## 例外処理

| 例外パターン | 処理内容 |
|-------------|----------|
| 権限不足 | 403エラーページを表示 |
| アプリケーション未存在 | 404エラーページを表示 |
| バリデーションエラー | 編集画面を再表示しエラーメッセージを表示 |

## 備考

- 機密アプリケーション設定は、クライアントシークレットを安全に保管できるバックエンドサーバーでのみ使用すべきである
- リダイレクトURIは1行に1つずつ記載する形式となっている

---

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

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

### 推奨読解順序

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

OAuthアプリケーションのデータ構造を把握することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | oauth_application.rb | `app/models/authn/oauth_application.rb` | OAuthアプリケーションモデルの定義、belongsの関連 |

**読解のコツ**: Doorkeeper::Applicationを継承しているため、親クラスの属性も確認すること。

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

処理の起点となるコントローラーを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | applications_controller.rb | `app/controllers/groups/settings/applications_controller.rb` | editアクションとupdateアクションの処理フロー |

**主要処理フロー**:
1. **行9**: `before_action :authorize_admin_group!` - 権限チェック
2. **行10**: `before_action :set_application` - 対象アプリケーションの取得
3. **行20**: `def edit; end` - 編集画面表示
4. **行36-43**: `def update` - 更新処理

#### Step 3: ビューレイヤーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit.html.haml | `app/views/groups/settings/applications/edit.html.haml` | 画面レイアウトとコンポーネントの配置 |
| 3-2 | _form.html.haml | `app/views/shared/doorkeeper/applications/_form.html.haml` | フォーム要素の定義 |

**主要処理フロー**:
- **行4**: `= render 'shared/doorkeeper/applications/form'` - 共有フォームテンプレートのレンダリング

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

```
edit.html.haml
    │
    ├─ Layouts::PageHeadingComponent
    │      └─ ページヘッダー表示
    │
    └─ shared/doorkeeper/applications/_form.html.haml
           ├─ gitlab_ui_form_for
           ├─ form_errors
           └─ shared/tokens/scopes_form
```

### データフロー図

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

HTTPリクエスト ───▶ ApplicationsController#update
                            │
                            ├─ application_params取得
                            │
                            ├─ @application.update
                            │
                            └─▶ 成功: redirect + flash
                                失敗: render :edit
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| applications_controller.rb | `app/controllers/groups/settings/applications_controller.rb` | コントローラー | リクエスト処理 |
| edit.html.haml | `app/views/groups/settings/applications/edit.html.haml` | ビュー | 画面テンプレート |
| _form.html.haml | `app/views/shared/doorkeeper/applications/_form.html.haml` | 部分テンプレート | フォーム定義 |
| oauth_application.rb | `app/models/authn/oauth_application.rb` | モデル | データ構造定義 |
| oauth_applications.rb | `app/concerns/oauth_applications.rb` | Concern | 共通処理 |
| group.rb | `config/routes/group.rb` | ルーティング | URL定義（行82-84） |
