# 機能設計書 64-ユーザー一覧表示

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるアカウント内のユーザー一覧を表示する機能の設計を詳述する。

### 本機能の処理概要

**業務上の目的・背景**：アカウント管理者がチームメンバーを管理するため、アカウント内の全ユーザーを一覧で確認できる機能が必要である。この機能により、メンバーの追加、ロール変更、削除などの管理操作の起点となる。

**機能の利用シーン**：アカウント設定画面でユーザー管理を行う場面、カードのアサイン時に担当者を検索する場面、メンション機能でユーザーを選択する場面などで利用される。複数のコンテキストで再利用される基盤的な機能である。

**主要な処理内容**：
1. 現在のアカウントに所属するアクティブなユーザーを取得
2. アルファベット順にソート
3. ページネーション対応（set_page_and_extract_portion_from）
4. ユーザー名、メールアドレス、ロールを表示
5. 管理者には各ユーザーへの操作（ロール変更、削除）ボタンを表示

**関連システム・外部連携**：アカウント設定画面（Account::SettingsController）と連携。ユーザー検索プロンプト（Prompts::UsersController）でも同様のクエリを使用。

**権限による制御**：ユーザー一覧の閲覧は全メンバーが可能。ただし、ロール変更・削除操作はadmin権限を持つユーザーのみ（can_administer?メソッドで判定）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 53 | アカウント設定画面 | 主画面 | アカウント内のユーザー一覧を表示 |
| 75 | ユーザー検索プロンプト画面 | 参照画面 | ユーザー検索用のオートコンプリートプロンプト |
| 76 | ボードユーザー検索プロンプト画面 | 参照画面 | ボード内ユーザー検索用のプロンプト |

## 機能種別

データ参照処理（READ）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| page | Integer | No | ページ番号（ページネーション用） | 正の整数 |

### 入力データソース

- Current.account（現在のアカウント）からユーザーを取得
- URLパラメータ（page）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @users | User::ActiveRecord_Relation | アカウント内のアクティブユーザー一覧 |
| user.name | String | ユーザー名 |
| user.identity.email_address | String | メールアドレス |
| user.role | String | ロール（owner/admin/member） |
| user.avatar | ActiveStorage::Attached | アバター画像 |

### 出力先

- 画面表示（HTML）
- アカウント設定画面の_users.html.erbパーシャル

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信（GET /users）
   └─ UsersController#index
2. ユーザー取得
   └─ Current.account.users.active.alphabetically
3. ページネーション処理
   └─ set_page_and_extract_portion_from
4. ビューレンダリング
   └─ 各ユーザーの情報と操作ボタンを表示
```

### フローチャート

```mermaid
flowchart TD
    A[GET /users] --> B[Current.account.users取得]
    B --> C[.active スコープでアクティブユーザーのみ]
    C --> D[.alphabetically でソート]
    D --> E[set_page_and_extract_portion_from でページネーション]
    E --> F[ビューレンダリング]
    F --> G{Current.user.can_administer?}
    G -->|Yes| H[ロール変更・削除ボタン表示]
    G -->|No| I[ボタン非活性/非表示]
    H --> J[一覧表示完了]
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-64-01 | アクティブユーザーのみ | active = trueのユーザーのみ表示 | 常に |
| BR-64-02 | アルファベット順ソート | ユーザー名のアルファベット順で表示 | 常に |
| BR-64-03 | オーナー保護 | オーナーロールのユーザーは他者から変更・削除不可 | can_administer? |
| BR-64-04 | 自己操作制限 | 自分自身のロール変更・削除は不可 | can_administer? |

### 計算ロジック

can_administer?(other)の判定ロジック:
- admin? が true（管理者権限を持つ）
- かつ other.owner? が false（対象がオーナーではない）
- かつ other != self（対象が自分自身ではない）

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ユーザー取得 | users | SELECT | アクティブユーザーを取得 |
| Identity取得 | identities | SELECT | メールアドレス取得のためのJOIN/プリロード |

### テーブル別操作詳細

#### users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | account_id = Current.account.id, active = true, role IN (owner, admin, member) | system ロールは除外 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 特別なエラーケースなし | - |

### リトライ仕様

読み取り専用のため、リトライ仕様は不要。

## トランザクション仕様

読み取り専用のため、トランザクション制御は不要。

## パフォーマンス要件

- レスポンス時間：500ms以内
- set_page_and_extract_portion_fromによるページネーションで大量ユーザーに対応
- avatarのプリロードでN+1防止

## セキュリティ考慮事項

- 認証必須
- 同一アカウント内のユーザーのみ表示
- 操作権限はcan_administer?で制御

## 備考

- システムユーザー（role: system）は一覧から除外される
- アバターは添付されていない場合、イニシャルSVGが生成される

---

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

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

### 推奨読解順序

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

Userモデルのロールとスコープを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | user.rb | `app/models/user.rb` | Userモデルの基本構造 |
| 1-2 | role.rb | `app/models/user/role.rb` | ロール定義とスコープ |
| 1-3 | schema.rb | `db/schema.rb` | usersテーブルの定義（777-789行目） |

**読解のコツ**: User::Roleモジュール（role.rb）でenumとスコープが定義されている。activeスコープ（10行目）はowner, admin, memberロールのユーザーのみを返す（systemロールを除外）。

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

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

**主要処理フロー**:
1. **5-7行目**: indexアクションでCurrent.account.users.active.alphabeticallyを取得
2. **6行目**: set_page_and_extract_portion_fromでページネーション処理

#### Step 3: ロール判定ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | role.rb | `app/models/user/role.rb` | can_change?, can_administer?の定義 |

**主要処理フロー**:
- **17-19行目**: can_change?(other) - 自分自身または管理者が非オーナーを変更可能
- **21-23行目**: can_administer?(other) - 管理者が自分以外の非オーナーを管理可能

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | _users.html.erb | `app/views/account/settings/_users.html.erb` | ユーザー一覧パーシャル |
| 4-2 | _user.html.erb | `app/views/account/settings/_user.html.erb` | 個別ユーザー表示パーシャル |

**読解のコツ**: _user.html.erbでは各ユーザーに対してロール変更チェックボックスと削除ボタンが表示される。disabled属性でcan_administer?の結果に応じて操作を制限している（17行目、24行目）。

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

```
UsersController#index
    │
    ├─ Current.account.users
    │      └─ .active (スコープ)
    │             └─ where(active: true, role: [:owner, :admin, :member])
    │      └─ .alphabetically (スコープ)
    │             └─ order(name: :asc)
    │
    └─ set_page_and_extract_portion_from
           └─ ページネーション処理

Account::SettingsController#show
    │
    └─ @users = Current.account.users.active.alphabetically
           └─ render "account/settings/_users"
                  └─ render partial: "account/settings/user", collection: users
```

### データフロー図

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

Current.account ───▶ users.active.alphabetically ───▶ @users
                              │
                              ▼
                    set_page_and_extract_portion_from
                              │
                              ▼
                    ┌─────────┴─────────┐
                    ▼                   ▼
              user.name           user.identity.email_address
                    │                   │
                    └─────────┬─────────┘
                              ▼
                        HTML出力
                              │
                    ┌─────────┼─────────┐
                    ▼         ▼         ▼
              アバター     ロール    操作ボタン
                                  (can_administer?で制御)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| users_controller.rb | `app/controllers/users_controller.rb` | コントローラー | ユーザー一覧のエントリーポイント |
| user.rb | `app/models/user.rb` | モデル | ユーザーエンティティ |
| role.rb | `app/models/user/role.rb` | モデルconcern | ロール定義とスコープ |
| _users.html.erb | `app/views/account/settings/_users.html.erb` | ビュー（パーシャル） | ユーザー一覧表示 |
| _user.html.erb | `app/views/account/settings/_user.html.erb` | ビュー（パーシャル） | 個別ユーザー表示 |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（13行目） |
| schema.rb | `db/schema.rb` | スキーマ | usersテーブル定義（777-789行目） |
