# 画面設計書 312-Jira接続状態

## 概要

本ドキュメントは、GitLabにおけるJira Connect接続状態画面の設計仕様を定義するものである。

### 本画面の処理概要

Jira接続状態画面は、GitLab for Jira Cloud アプリケーションにおいて、JiraとGitLabの接続状態を管理するための画面である。この画面はJiraのiframe内で表示され、GitLabの名前空間（グループ）をJiraインストールに紐付けるサブスクリプションの管理を行う。

**業務上の目的・背景**：Jira CloudとGitLabを連携させることで、Jiraのイシューに関連するGitLabのコミット、ブランチ、マージリクエストなどの情報を自動的に表示できる。この画面は、その連携設定の中核となるもので、どのGitLabグループをJiraに接続するかを管理者が設定するために使用される。Atlassian Marketplaceから提供される「GitLab for Jira Cloud」アプリの一部として機能する。

**画面へのアクセス方法**：Jira Cloudの「アプリ」セクションからGitLabアプリを選択することでアクセスする。GitLab側のURL `/jira_connect/subscriptions` に対応するが、通常はJiraからのiframe経由でのみアクセスされる。

**主要な操作・処理内容**：
1. GitLabへのサインイン - OAuth認証を使用してGitLabアカウントでログイン
2. 名前空間の追加 - GitLabグループをJiraインストールに紐付け
3. 名前空間の削除 - 既存の紐付けを解除
4. サブスクリプション一覧表示 - 現在紐付けられているグループの一覧を表示

**画面遷移**：
- Jira Cloudアプリ画面からのアクセス
- OAuth認証後、サインインページからサブスクリプション管理ページへ遷移

**権限による表示制御**：
- 未ログイン状態：サインインページを表示
- ログイン済み：サブスクリプション管理ページを表示
- Jiraの管理者権限が必要（Atlassian JWT検証による）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 96 | Jira連携 | 主機能 | Jira Connect状態表示 |

## 画面種別

一覧/管理

## URL/ルーティング

- パス: `/jira_connect/subscriptions`
- コントローラ: `JiraConnect::SubscriptionsController#index`
- ルート定義: `config/routes/jira_connect.rb` (14行目)

## 入出力項目

| 項目名 | 項目種別 | データ型 | 必須 | 説明 |
|--------|----------|----------|------|------|
| namespace_path | 入力（作成時） | String | はい | 追加する名前空間のパス |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| グループ名 | String | 紐付けられたGitLabグループの名前 |
| グループパス | String | グループへのリンク |
| アクション | Button | サブスクリプションの削除ボタン |

## イベント仕様

### 1-サインイン

未ログイン状態でOAuth認証ボタンを押下すると、GitLabのOAuth認証フローが開始される。

**処理フロー**：
1. OAuth認証ボタン押下
2. ポップアップウィンドウでGitLabのOAuth認可画面を表示
3. ユーザーが認可を承認
4. コールバック処理でトークンを取得
5. ユーザー情報を取得してログイン状態に更新
6. サブスクリプション一覧を取得

### 2-名前空間追加

「Add namespace」ボタンを押下すると、グループ選択モーダルが表示される。

**処理フロー**：
1. モーダル表示
2. グループ一覧をAPIから取得
3. ユーザーがグループを選択
4. POST `/jira_connect/subscriptions` でサブスクリプション作成
5. 成功時：一覧を更新
6. 失敗時：エラーメッセージを表示

### 3-名前空間削除

サブスクリプションの削除ボタンを押下すると、紐付けが解除される。

**処理フロー**：
1. DELETE `/jira_connect/subscriptions/:id` を実行
2. 成功時：一覧から該当項目を削除
3. 失敗時：エラーメッセージを表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 一覧表示 | jira_connect_subscriptions | SELECT | サブスクリプション一覧を取得 |
| 名前空間追加 | jira_connect_subscriptions | INSERT | 新規サブスクリプションを作成 |
| 名前空間削除 | jira_connect_subscriptions | DELETE | サブスクリプションを削除 |

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

#### jira_connect_subscriptions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | jira_connect_installation_id | 現在のインストールID | |
| SELECT | namespace_id | - | 関連グループ |
| INSERT | jira_connect_installation_id | 現在のインストールID | |
| INSERT | namespace_id | 選択されたグループID | |
| DELETE | id | 指定されたサブスクリプションID | |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|-----------|----------|
| エラー | サインインエラー | OAuth認証に失敗した場合 |
| エラー | has already been added | 既に追加済みのグループを追加しようとした場合 |
| 成功 | サブスクリプション作成成功 | 名前空間追加成功時 |

## 例外処理

| 状態 | 処理内容 |
|------|----------|
| JWT検証失敗 | 401エラーを返す |
| ブラウザ非対応 | ブラウザサポートアラートを表示 |
| セルフマネージド連携時 | 適切なCSP設定を追加 |

## 備考

- この画面はJiraのiframe内で表示されるため、特別なContent-Security-Policy設定が必要
- `*.atlassian.net` と `*.jira.com` からのiframe埋め込みが許可される
- 公開鍵ストレージが有効な場合、異なる認証フローが使用される可能性がある

---

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

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

### 推奨読解順序

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

まず、Jira Connect連携のデータモデルを理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | jira_connect_subscription.rb | `app/models/jira_connect_subscription.rb` | サブスクリプションモデルの構造を理解する |
| 1-2 | jira_connect_installation.rb | `app/models/jira_connect_installation.rb` | インストールモデルとサブスクリプションの関係を理解する |

**読解のコツ**: `JiraConnectSubscription` は `JiraConnectInstallation` と `Namespace` の中間テーブルとして機能する。

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

コントローラでのリクエスト処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | subscriptions_controller.rb | `app/controllers/jira_connect/subscriptions_controller.rb` | CSP設定、JWT検証、CRUD操作を理解する |

**主要処理フロー**:
1. **4-28行目**: Content-Security-Policy設定でiframe埋め込みを許可
2. **35-43行目**: `index` アクションでサブスクリプション一覧を取得
3. **46-53行目**: `create` アクションでサブスクリプション作成
4. **56-64行目**: `destroy` アクションでサブスクリプション削除

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/jira_connect/subscriptions/index.html.haml` | Vueアプリのマウント設定を理解する |

**主要処理フロー**:
- **1行目**: `jira_connect_app_data` ヘルパーでVueアプリに必要なデータを渡す

#### Step 4: フロントエンドコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | app.vue | `app/assets/javascripts/jira_connect/subscriptions/components/app.vue` | メインアプリコンポーネントの構造を理解する |
| 4-2 | sign_in_page.vue | `app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_page.vue` | サインインフローを理解する |
| 4-3 | subscriptions_page.vue | `app/assets/javascripts/jira_connect/subscriptions/pages/subscriptions_page.vue` | サブスクリプション管理ページを理解する |

**主要処理フロー**:
- **37-47行目**: ユーザーのサインイン状態とサブスクリプションの有無を判定
- **66-79行目**: サブスクリプションの取得と初期表示

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

```
JiraConnect::SubscriptionsController
    │
    ├─ #index
    │      ├─ verify_qsh_claim! (JWT検証)
    │      ├─ current_jira_installation.subscriptions
    │      └─ JiraConnect::AppDataSerializer
    │
    ├─ #create
    │      └─ JiraConnectSubscriptions::CreateService
    │
    └─ #destroy
           └─ JiraConnectSubscriptions::DestroyService

Vueアプリ (app.vue)
    │
    ├─ SignInPage
    │      ├─ SignInOauthButton
    │      └─ OAuth認証フロー
    │
    └─ SubscriptionsPage
           ├─ SubscriptionsList
           ├─ AddNamespaceButton
           └─ AddNamespaceModal
                  └─ GroupsList
```

### データフロー図

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

Jira iframe          ───▶  subscriptions_controller  ───▶  JSON/HTML
(JWT付きリクエスト)         │                               │
                          │                               └─ サブスクリプション一覧
                          ▼
                    JiraConnectInstallation
                          │
                          ▼
                    JiraConnectSubscription
                          │
                          ▼
                    Namespace (グループ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| subscriptions_controller.rb | `app/controllers/jira_connect/subscriptions_controller.rb` | コントローラ | リクエスト処理、CSP設定 |
| application_controller.rb | `app/controllers/jira_connect/application_controller.rb` | コントローラ | 基底コントローラ、JWT検証 |
| index.html.haml | `app/views/jira_connect/subscriptions/index.html.haml` | ビュー | 画面テンプレート |
| jira_connect_subscription.rb | `app/models/jira_connect_subscription.rb` | モデル | サブスクリプションモデル |
| jira_connect_installation.rb | `app/models/jira_connect_installation.rb` | モデル | インストールモデル |
| app.vue | `app/assets/javascripts/jira_connect/subscriptions/components/app.vue` | Vue | メインアプリコンポーネント |
| subscriptions_page.vue | `app/assets/javascripts/jira_connect/subscriptions/pages/subscriptions_page.vue` | Vue | サブスクリプション管理ページ |
| sign_in_page.vue | `app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_page.vue` | Vue | サインインページ |
| jira_connect.rb | `config/routes/jira_connect.rb` | ルーティング | URLルート定義 |
