# 画面設計書 287-GitHubインポート詳細

## 概要

本ドキュメントは、GitLabのGitHubインポート詳細画面の設計を記載したものである。

### 本画面の処理概要

**業務上の目的・背景**：GitHubインポート詳細画面は、GitHubからのインポート処理が完了した後、インポートに失敗した項目の詳細を確認するための画面である。インポートは成功しても一部のリレーション（Issue、Pull Request、コメントなど）がエラーで取り込めなかった場合があり、本画面でその詳細を確認し、必要に応じて手動対応を行うことができる。

**画面へのアクセス方法**：GitHubインポート状態画面（status）からインポート完了後に「View details」リンクをクリックして遷移する。または直接 `/import/github/details?project_id=XXX` にアクセスする。

**主要な操作・処理内容**：
1. インポート失敗項目の一覧を表示する
2. 失敗項目のタイプ（Issue、Pull Request等）を確認する
3. 失敗項目のタイトルを確認する
4. GitHubの元URLへリンクして詳細を確認する
5. エラー詳細（例外クラス、メッセージ）を確認する
6. ページネーションで大量の失敗項目を閲覧する

**画面遷移**：
- 遷移元：GitHubインポート状態画面
- 遷移先：GitHubの各リソースURL（外部リンク）

**権限による表示制御**：
- ログインユーザーのみアクセス可能
- project_idで指定されたプロジェクトへのアクセス権限が必要
- インポートが完了している必要がある（完了前はエラー）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 105 | GitHubインポート | 主機能 | GitHubインポート失敗詳細の表示 |

## 画面種別

一覧 / 参照

## URL/ルーティング

| メソッド | パス | コントローラー#アクション | 説明 |
|----------|------|---------------------------|------|
| GET | `/import/github/details` | `import/github#details` | 詳細画面表示（HTML） |
| GET | `/import/github/failures` | `import/github#failures` | 失敗項目一覧取得（JSON） |

## 入出力項目

### 詳細画面表示（details）

| 項目名 | 項目ID | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| プロジェクトID | project_id | Integer | Yes | 対象プロジェクトID |

### 失敗項目取得（failures）

| 項目名 | 項目ID | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| プロジェクトID | project_id | Integer | Yes | 対象プロジェクトID |
| ページ番号 | page | Integer | No | ページネーション用 |
| 1ページあたり件数 | per_page | Integer | No | デフォルト20件 |

## 表示項目

| 項目名 | 説明 |
|--------|------|
| ページタイトル | 「GitHub import details」 |
| タイプ（Type） | 失敗項目の種別（issue, pull_request, note等） |
| タイトル（Title） | 失敗項目のタイトルまたは識別情報 |
| URL | GitHub上の元リソースへのリンク |
| 詳細（Details） | エラー詳細（例外クラス、メッセージ） |
| ページネーション | 失敗項目一覧のページ切り替え |
| 空状態表示 | 失敗項目がない場合の表示 |

## イベント仕様

### 1-画面初期表示

**トリガー**：画面アクセス時

**処理フロー**：
1. Vue.jsアプリケーションがマウント
2. `failuresPath` データ属性から失敗項目取得APIパスを取得
3. `GET /import/github/failures` を呼び出し
4. 失敗項目一覧をテーブルに表示
5. ページネーション情報を設定

### 2-ページ切り替え

**トリガー**：ページネーションボタンをクリック

**処理フロー**：
1. 選択されたページ番号でAPIを再取得
2. `GET /import/github/failures?page=N&per_page=M` を呼び出し
3. テーブルを更新

### 3-1ページあたり件数変更

**トリガー**：件数選択を変更

**処理フロー**：
1. 選択された件数でAPIを再取得
2. ページを1にリセット
3. テーブルを更新
4. LocalStorageに選択を保存

### 4-外部リンククリック

**トリガー**：URL列のリンクをクリック

**処理フロー**：
1. 新しいタブでGitHubの該当リソースを開く

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 失敗項目取得 | import_failures | SELECT | 失敗レコードの取得（更新なし） |

### テーブル別参照項目詳細

#### import_failures

| 項目（カラム名） | 説明 | 用途 |
|-----------------|------|------|
| id | 主キー | 識別子 |
| project_id | プロジェクトID | フィルタ条件 |
| external_identifiers | 外部識別子（JSON） | タイプ、タイトル、URL生成 |
| exception_class | 例外クラス名 | エラー詳細表示 |
| exception_message | 例外メッセージ | エラー詳細表示 |
| correlation_id_value | 相関ID | デバッグ用 |
| source | ソース | 発生箇所 |
| created_at | 作成日時 | 発生日時表示 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | エラー | The import is not complete. | インポート未完了時にfailures API呼び出し |
| MSG002 | エラー | An error occurred while fetching import details. | API呼び出し失敗時 |
| MSG003 | 情報 | No import details | 失敗項目がない場合 |

## 例外処理

| 例外条件 | 画面表示・動作 |
|----------|---------------|
| インポート未完了 | 400 Bad Request、「The import is not complete.」メッセージ |
| プロジェクト未存在 | 404エラー |
| 権限不足 | 404エラー |
| API取得失敗 | アラートでエラーメッセージ表示 |

## 備考

- デフォルトのページサイズは20件
- ページサイズはLocalStorageに保存（キー: `gl-import-details-page-size`）
- 失敗項目のタイプには以下がある：
  - issue, pull_request, pull_request_merged_by, pull_request_review_request
  - pull_request_review, collaborator, protected_branch, issue_event
  - label, milestone, release, note, diff_note
  - issue_attachment, merge_request_attachment, release_attachment, note_attachment
  - lfs_object
- GitHubのURLは external_identifiers の内容から動的に構築される
- lfs_object と note_attachment はURL構築不可（空文字）

---

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

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

### 推奨読解順序

#### Step 1: コントローラーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | github_controller.rb | `app/controllers/import/github_controller.rb` | details, failures アクション |

**主要処理フロー**:
1. **行70**: `details` アクションは空（ビューのみ）
2. **行88-99**: `failures` アクションでインポート失敗項目を取得
3. **行89**: `project.import_finished?` でインポート完了チェック
4. **行95**: `import_failures.with_external_identifiers` で外部識別子付きの失敗のみ取得
5. **行96**: `GithubFailureSerializer` でページネーション付きシリアライズ

#### Step 2: ビューテンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | details.html.haml | `app/views/import/github/details.html.haml` | Vue.jsマウントポイント |

**主要要素**（行1-4）:
- パンくずリスト設定
- ページタイトル「GitHub import details」
- `.js-import-details` マウントポイント
- `failures_path` データ属性

#### Step 3: Vue.jsコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.js | `app/assets/javascripts/import/details/index.js` | エントリーポイント |
| 3-2 | import_details_app.vue | `app/assets/javascripts/import/details/components/import_details_app.vue` | メインコンポーネント |
| 3-3 | import_details_table.vue | `app/assets/javascripts/import/details/components/import_details_table.vue` | テーブルコンポーネント |
| 3-4 | api.js | `app/assets/javascripts/import/details/api.js` | API呼び出し |

**Vue.jsコンポーネント構造**:
- `ImportDetailsApp`: ページタイトルとテーブルを含むルートコンポーネント
- `ImportDetailsTable`: GlTableベースの失敗項目一覧テーブル
- フィールド定義: type, title, provider_url, details

#### Step 4: シリアライザーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | github_failure_serializer.rb | `app/serializers/import/github_failure_serializer.rb` | シリアライザー定義 |
| 4-2 | github_failure_entity.rb | `app/serializers/import/github_failure_entity.rb` | エンティティ定義 |

**エンティティのexpose項目**:
- `type`: external_identifiers['object_type']
- `title`: タイプに応じた動的生成
- `provider_url`: GitHubのURLを動的構築
- `details`: exception_class, exception_message, correlation_id等

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

```
Import::GithubController#details
    │
    └─ details.html.haml
           │
           └─ .js-import-details (data-failures-path)
                  │
                  └─ Vue.js ImportDetailsApp
                         │
                         └─ ImportDetailsTable
                                │
                                └─ fetchImportFailures (api.js)
                                       │
                                       └─ GET /import/github/failures

Import::GithubController#failures
    │
    ├─ project.import_finished? チェック
    │      └─ false → 400 Bad Request
    │
    └─ project.import_failures.with_external_identifiers
           │
           └─ Import::GithubFailureSerializer
                  │
                  └─ Import::GithubFailureEntity
                         ├─ type: object_type
                         ├─ title: 動的生成
                         ├─ provider_url: URL構築
                         └─ details: エラー詳細
```

### データフロー図

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

画面アクセス ───▶ GithubController#details
                    │
                    └─ details.html.haml ───▶ Vue.js初期化

Vue.js初期化 ───▶ ImportDetailsTable.mounted()
                    │
                    └─ loadImportFailures()
                           │
                           └─ fetchImportFailures(failuresPath)
                                  │
                                  └─ GET /import/github/failures

API呼び出し ───▶ GithubController#failures
                    │
                    ├─ import_finished? チェック
                    │
                    └─ import_failures 取得
                           │
                           └─ GithubFailureSerializer ───▶ JSON応答

JSON応答 ───▶ ImportDetailsTable
                    │
                    ├─ items 配列に格納
                    ├─ ページネーション情報設定
                    └─ テーブル表示 ───▶ ユーザーに表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| details.html.haml | `app/views/import/github/details.html.haml` | テンプレート | 詳細画面のビュー |
| github_controller.rb | `app/controllers/import/github_controller.rb` | コントローラー | details/failuresアクション |
| index.js | `app/assets/javascripts/import/details/index.js` | JavaScript | Vue.jsエントリーポイント |
| import_details_app.vue | `app/assets/javascripts/import/details/components/import_details_app.vue` | Vue | メインコンポーネント |
| import_details_table.vue | `app/assets/javascripts/import/details/components/import_details_table.vue` | Vue | テーブルコンポーネント |
| api.js | `app/assets/javascripts/import/details/api.js` | JavaScript | API呼び出し |
| github_failure_serializer.rb | `app/serializers/import/github_failure_serializer.rb` | シリアライザー | 失敗項目シリアライズ |
| github_failure_entity.rb | `app/serializers/import/github_failure_entity.rb` | エンティティ | 失敗項目フォーマット |
| import_failure.rb | `app/models/import_failure.rb` | モデル | インポート失敗モデル |
| import.rb | `config/routes/import.rb` | 設定 | ルーティング定義 |
