# 画面設計書 245-アプリケーション新規作成

## 概要

本ドキュメントは、GitLab管理者が新規OAuthアプリケーションを登録する画面の設計書です。

### 本画面の処理概要

アプリケーション新規作成画面は、GitLabインスタンスで新しいOAuthアプリケーションを登録する管理者専用画面です。

**業務上の目的・背景**：外部システムやサードパーティアプリケーションがGitLab APIにアクセスするためには、OAuth 2.0認証が必要です。管理者はこの画面から新しいOAuthアプリケーションを登録し、アプリケーションID とクライアントシークレットを発行します。これにより、GitLabをOAuth 2.0プロバイダとして利用できるようになります。

**画面へのアクセス方法**：
1. 管理者としてGitLabにログイン
2. 左サイドメニューから「Admin Area」をクリック
3. 「Applications」をクリック
4. 「Add new application」ボタンをクリック

**主要な操作・処理内容**：
1. アプリケーション名の入力
2. リダイレクトURI（コールバックURL）の入力
3. Trusted オプションの設定
4. Confidential オプションの設定
5. OAuthスコープの選択
6. 「Save application」ボタンで保存

**画面遷移**：
- 遷移元：アプリケーション一覧画面
- 遷移先（成功時）：アプリケーション詳細画面（シークレット表示）
- 遷移先（失敗時）：本画面（エラーメッセージ表示）
- キャンセル時：アプリケーション一覧画面

**権限による表示制御**：管理者権限を持つユーザーのみがこの画面にアクセス可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 88 | OAuth2プロバイダ | 主機能 | OAuthアプリケーション作成 |

## 画面種別

登録（新規作成）

## URL/ルーティング

- URL: `/admin/applications/new`
- HTTP メソッド: GET（画面表示）/ POST（アプリケーション作成）
- ルート名: `new_admin_application` / `admin_applications`

## 入出力項目

| 項目名 | 項目ID | 型 | 必須 | 最大長 | バリデーション | 備考 |
|--------|--------|-----|------|--------|----------------|------|
| Name | name | String | ○ | - | Doorkeeper標準 | アプリケーション名 |
| Redirect URI | redirect_uri | Text | ○ | - | URI形式 | 複数行対応 |
| Trusted | trusted | Boolean | - | - | - | 自動認可フラグ |
| Confidential | confidential | Boolean | - | - | - | 機密クライアントフラグ |
| Scopes | scopes | Array | ○ | - | 1つ以上必須 | OAuthスコープ |

## 表示項目

| 項目名 | 表示形式 | 備考 |
|--------|----------|------|
| ページタイトル | テキスト | "Add new application" |
| パンくずリスト | リンク | Applications > Add new application |
| Name入力欄 | テキストフィールド | |
| Redirect URI入力欄 | テキストエリア | 複数行入力可能 |
| Trustedチェックボックス | チェックボックス | 説明テキスト付き |
| Confidentialチェックボックス | チェックボックス | 説明テキスト付き |
| Scopesチェックボックス群 | チェックボックス | 各スコープの説明付き |

## イベント仕様

### 1-アプリケーション作成（Save application）

**トリガー**: 「Save application」ボタンクリック

**処理フロー**:
1. フォームデータのサーバー送信
2. `Admin::ApplicationsController#create`アクション呼び出し
3. `Applications::CreateService.new(current_user, request, application_params).execute`
4. バリデーション実行
5. 成功時: アプリケーション詳細画面表示（シークレット付き、`@created = true`）
6. 失敗時: 本画面再表示（エラーメッセージ表示）

### 2-キャンセル

**トリガー**: 「Cancel」リンククリック

**処理フロー**: アプリケーション一覧画面へ遷移

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Save application押下 | oauth_applications | INSERT | アプリケーションレコード作成 |

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

#### oauth_applications

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | フォーム入力値 | アプリケーション名 |
| INSERT | redirect_uri | フォーム入力値 | リダイレクトURI |
| INSERT | scopes | フォーム選択値 | スコープ文字列 |
| INSERT | confidential | フォームチェック状態 | 機密フラグ |
| INSERT | trusted | フォームチェック状態 | 信頼フラグ |
| INSERT | secret | 自動生成 | クライアントシークレット |
| INSERT | uid | 自動生成 | アプリケーションID |
| INSERT | owner_id | NULL | インスタンスレベル |
| INSERT | organization_id | Current.organization.id | 組織ID |
| INSERT | created_at | 現在日時 | 作成日時 |
| INSERT | updated_at | 現在日時 | 更新日時 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 成功 | Application created successfully | 作成成功時（Doorkeeper標準） |
| MSG002 | エラー | Scopes can't be blank | スコープ未選択時 |
| MSG003 | エラー | Name can't be blank | 名前未入力時 |
| MSG004 | エラー | Redirect URI can't be blank | リダイレクトURI未入力時 |

## 例外処理

| 例外条件 | 処理内容 | 表示メッセージ |
|----------|----------|---------------|
| 権限不足 | 403エラー画面へリダイレクト | アクセスが拒否されました |
| バリデーションエラー | 画面再表示 | 各フィールドにエラーメッセージ表示 |

## 備考

- `Applications::CreateService`を使用してアプリケーション作成
- スコープは必須（1つ以上選択必要）
- 作成成功時は詳細画面に遷移し、平文のシークレットが表示される
- Trustedアプリケーションは認可画面をスキップ（セキュリティ上の注意が必要）
- owner_id = NULLでインスタンスレベルのアプリケーションとして登録
- organization_id = Current.organization.idが自動設定される

---

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

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

### 推奨読解順序

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

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | applications_controller.rb | `app/controllers/admin/applications_controller.rb` | new/createアクション |

**主要処理フロー**:
1. **7行目**: `before_action :load_scopes`でスコープロード
2. **19-21行目**: `new`アクション - 空のインスタンス作成
3. **25-36行目**: `create`アクション - CreateService使用
4. **79-84行目**: `application_params` - owner=nil, organization設定

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create_service.rb | `app/services/applications/create_service.rb` | 作成ロジック |

**主要処理フロー**:
- **24-36行目**: `execute`メソッド
- **27-31行目**: スコープ必須チェック
- **34行目**: `@application.save`

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | new.html.haml | `app/views/admin/applications/new.html.haml` | 新規作成画面 |
| 4-2 | _form.html.haml | `app/views/admin/applications/_form.html.haml` | 入力フォーム |

**主要処理フロー**:
- **6行目**: @url設定
- **7行目**: フォームパーシャル呼び出し

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

```
ブラウザ (GET /admin/applications/new)
    │
    ├─ before_action :load_scopes
    │
    ├─ Admin::ApplicationsController#new
    │      └─ Authn::OauthApplication.new
    │
    └─ View: admin/applications/new.html.haml
           └─ Partial: admin/applications/_form
                  └─ スコープ選択フォーム

ブラウザ (POST /admin/applications)
    │
    └─ Admin::ApplicationsController#create
           ├─ Applications::CreateService.new(...).execute
           │      ├─ Authn::OauthApplication.new(params)
           │      ├─ スコープ必須チェック
           │      └─ application.save
           ├─ 成功: @created = true, render :show
           └─ 失敗: render :new
```

### データフロー図

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

フォームデータ ───────▶ ApplicationsController#create ──▶ 成功: 詳細画面
  - name                      │                              (シークレット表示)
  - redirect_uri              ├─ CreateService.execute
  - trusted                   │      └─ OauthApplication.new
  - confidential              │      └─ save
  - scopes                    │
                              └───────────────────────▶ 失敗: 新規作成画面
                                                            (エラーメッセージ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| applications_controller.rb | `app/controllers/admin/applications_controller.rb` | コントローラ | リクエスト処理 |
| oauth_application.rb | `app/models/authn/oauth_application.rb` | モデル | データ定義 |
| create_service.rb | `app/services/applications/create_service.rb` | サービス | 作成ロジック |
| new.html.haml | `app/views/admin/applications/new.html.haml` | ビュー | 新規作成画面 |
| _form.html.haml | `app/views/admin/applications/_form.html.haml` | ビュー | 入力フォーム |
| admin.rb | `config/routes/admin.rb` | 設定 | ルーティング |
| oauth_applications.rb | `app/controllers/concerns/oauth_applications.rb` | Concern | 共通処理 |
