# 画面設計書 185-組織ユーザー

## 概要

本ドキュメントは、GitLabの組織ユーザー管理画面の設計を記述したものである。

### 本画面の処理概要

**業務上の目的・背景**：組織には複数のユーザーが所属し、それぞれに異なるアクセスレベル（オーナー、メンバー等）が設定される。この画面は組織に所属するユーザーの一覧を表示し、管理者がユーザーの役割を確認・変更するための機能を提供する。組織全体のユーザー管理を一元的に行うことで、アクセス制御の効率化とセキュリティの向上を実現する。

**画面へのアクセス方法**：組織詳細画面（184-組織詳細）のユーザー統計カードをクリックするか、直接URL `/-/organizations/:organization_path/users` にアクセスする。

**主要な操作・処理内容**：
1. 組織ユーザーの一覧表示（ページネーション付き）
2. ユーザー詳細情報の確認（ドロワー表示）
3. ユーザーの役割（アクセスレベル）の変更
4. バッジ情報の表示
5. 最後のオーナー警告の表示

**画面遷移**：
- 遷移元：組織詳細画面（184-組織詳細）
- 遷移先：管理者ユーザー詳細画面（管理者の場合）

**権限による表示制御**：
- `read_organization_user` 権限を持つユーザーのみがアクセス可能
- ユーザー役割の変更は適切な権限を持つユーザーのみ実行可能
- 最後のオーナーは役割を変更できない（`isLastOwner` フラグで制御）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 134 | 組織管理 | 主機能 | 組織ユーザーの管理 |

## 画面種別

一覧

## URL/ルーティング

- パス: `/-/organizations/:organization_path/users`
- HTTPメソッド: GET
- コントローラー: `Organizations::OrganizationsController#users`

## 入出力項目

| 項目名 | 項目ID | データ型 | 必須 | 入力形式 | 説明 |
|--------|--------|----------|------|----------|------|
| ページネーションカーソル | after/before | String | No | クエリパラメータ | ページネーション用 |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| ページタイトル | 見出し | "Users" |
| ユーザー一覧 | テーブル | ユーザー情報を行形式で表示 |
| ユーザーアバター | 画像 | ユーザーのプロフィール画像 |
| ユーザー名 | テキスト | ユーザーの表示名 |
| ユーザー名（handle） | テキスト | @で始まるユーザー名 |
| メールアドレス | テキスト | 公開メールアドレス |
| バッジ | ラベル | 管理者、ブロック等のステータス |
| アクセスレベル | ドロップダウン | Owner/User等の役割 |
| ページネーション | ナビゲーション | 前ページ/次ページボタン |

## イベント仕様

### 1-ユーザー行クリック

1. ユーザー詳細ドロワーを表示
2. 管理者の場合、管理者ユーザー画面へのリンクを表示

### 2-アクセスレベル変更

1. 新しいアクセスレベルを選択
2. GraphQL Mutationでアクセスレベルを更新
3. 成功時、isLastOwnerフラグを再計算するためキャッシュを更新
4. 他ページのキャッシュを無効化

### 3-ページネーション操作

1. GraphQL APIで次/前ページのデータを取得
2. 一覧を更新表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | organization_users | SELECT | ユーザー一覧の取得 |
| 画面表示 | users | SELECT | ユーザー情報の取得 |
| アクセスレベル変更 | organization_users | UPDATE | アクセスレベルの更新 |

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

#### organization_users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | access_level | 選択されたレベル | Owner/User等 |
| UPDATE | updated_at | 現在時刻 | 更新日時 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | エラー | An error occurred loading the organization users. Please refresh the page to try again. | データ取得エラー時 |

## 例外処理

| 例外パターン | 処理内容 |
|-------------|----------|
| 権限不足 | アクセス拒否（403） |
| データ取得エラー | アラートでエラーメッセージを表示 |
| 最後のオーナー変更試行 | 変更を無効化し警告を表示 |
| キャッシュ更新エラー | ページを強制リロード |

## 備考

- 1ページあたりの表示件数は `ORGANIZATION_USERS_PER_PAGE` 定数で定義
- 最後のオーナー（`isLastOwner`）の役割変更は防止される
- 役割変更後、他ページの `isLastOwner` フラグが変わる可能性があるためキャッシュを無効化する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | organization_user.rb | `app/models/organizations/organization_user.rb` | アクセスレベルの定義 |

**読解のコツ**: `access_level` のenum定義と、オーナー判定ロジックを確認すること。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | organizations_controller.rb | `app/controllers/organizations/organizations_controller.rb` | usersアクション |
| 2-2 | application_controller.rb | `app/controllers/organizations/application_controller.rb` | authorize_read_organization_user! |

**主要処理フロー**:
1. **行52-54**: `def users` - 権限チェック後に画面表示
2. **行53**: `authorize_read_organization_user!` - 権限確認

#### Step 3: ヘルパーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | organization_helper.rb | `app/helpers/organizations/organization_helper.rb` | organization_user_app_data |

**主要処理フロー**:
- **行47-52**: `organization_user_app_data` - Vue用データ準備

#### Step 4: フロントエンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | users.html.haml | `app/views/organizations/organizations/users.html.haml` | マウントポイント |
| 4-2 | app.vue | `app/assets/javascripts/organizations/users/components/app.vue` | メインコンポーネント |
| 4-3 | users_view.vue | `app/assets/javascripts/organizations/users/components/users_view.vue` | 一覧表示 |

**主要処理フロー**:
- **行42-54**: Apollo GraphQL によるデータ取得
- **行111-139**: `onRoleChange` - 役割変更後のキャッシュ処理

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

```
users.html.haml
    │
    └─ #js-organizations-users (Vue mount point)
           │
           └─ OrganizationsUsersApp (app.vue)
                  │
                  ├─ Apollo Query: organizationUsersQuery
                  │      └─ GraphQL API
                  │
                  └─ UsersView
                         ├─ ユーザー行 (各ユーザー)
                         │      ├─ アバター
                         │      ├─ 名前・メール
                         │      ├─ バッジ
                         │      └─ アクセスレベルドロップダウン
                         │
                         ├─ UserDetailsDrawer
                         │
                         └─ GlKeysetPagination
```

### データフロー図

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

URLアクセス ───▶ OrganizationsController#users
                      │
                      ├─ authorize_read_organization_user!
                      │
                      └─ organization_user_app_data
                              │
                              └─▶ Vue.js App
                                      │
                                      ├─ GraphQL Query
                                      │      └─ organizationUsersQuery
                                      │
                                      └─▶ ユーザー一覧表示

役割変更 ───────▶ GraphQL Mutation
                      │
                      ├─ access_level更新
                      │
                      └─ キャッシュ無効化
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| organizations_controller.rb | `app/controllers/organizations/organizations_controller.rb` | コントローラー | リクエスト処理 |
| users.html.haml | `app/views/organizations/organizations/users.html.haml` | ビュー | マウントポイント |
| app.vue | `app/assets/javascripts/organizations/users/components/app.vue` | Vue | メインコンポーネント |
| users_view.vue | `app/assets/javascripts/organizations/users/components/users_view.vue` | Vue | 一覧表示 |
| user_details_drawer.vue | `app/assets/javascripts/organizations/users/components/user_details_drawer.vue` | Vue | 詳細ドロワー |
| organization_helper.rb | `app/helpers/organizations/organization_helper.rb` | ヘルパー | app_data生成 |
| constants.js | `app/assets/javascripts/organizations/users/constants.js` | 定数 | ページサイズ等 |
