# 画面設計書 119-ユーザー一覧画面

## 概要

本ドキュメントは、Medusa Admin Dashboardにおけるユーザー一覧画面に関する設計書です。この画面により、システムに登録されている管理者ユーザーを一覧表示し、検索・ソート・詳細表示などの操作を行うことができます。

### 本画面の処理概要

**業務上の目的・背景**：ECサイト管理に関わるチームメンバーを確認・管理するため、登録済みユーザーの一覧を提供します。ユーザー招待、権限管理、アカウント管理の起点となる画面です。

**画面へのアクセス方法**：サイドバーの「設定」>「チーム」を選択、またはURL直接アクセス（/settings/users）。

**主要な操作・処理内容**：
1. 登録済みユーザーをテーブル形式で一覧表示
2. 検索フィールドによるユーザー絞り込み
3. カラムヘッダーによるソート機能
4. 日付フィルター（作成日・更新日）による絞り込み
5. ユーザー行クリックで詳細画面へ遷移
6. 「ユーザーを招待」ボタンで招待画面へ遷移

**画面遷移**：
- 遷移元：サイドバーナビゲーション、設定画面
- 遷移先：ユーザー詳細画面（/settings/users/:id）、ユーザー招待画面（/settings/users/invite）、ユーザー編集画面（/settings/users/:id/edit）

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 68 | ユーザーCRUD | 主機能 | ユーザー一覧の表示・検索・ソート |

## 画面種別

シングルカラムページ形式（SingleColumnPage）の一覧画面

## URL/ルーティング

`/settings/users`

## 入出力項目

### 検索・フィルター項目

| 項目名 | 項目ID | 型 | 必須 | 説明 |
|--------|--------|------|------|------|
| 検索キーワード | q | string | - | メールアドレス・名前で検索 |
| ソート順 | order | string | - | ソート順序（例：email, -email） |
| オフセット | offset | number | - | ページネーション開始位置 |

### フィルター項目

| 項目名 | 項目ID | 型 | 説明 |
|--------|--------|------|------|
| 作成日 | created_at | DateFilter | 作成日による絞り込み |
| 更新日 | updated_at | DateFilter | 更新日による絞り込み |

## 表示項目

### ユーザー一覧テーブル

| 項目名 | 項目ID | 型 | 説明 |
|--------|--------|------|------|
| メールアドレス | email | string | ユーザーのメールアドレス |
| 名 | first_name | string | ユーザーの名（未設定時は「-」） |
| 姓 | last_name | string | ユーザーの姓（未設定時は「-」） |
| 作成日 | created_at | date | 登録日時 |
| 更新日 | updated_at | date | 最終更新日時 |
| アクションメニュー | actions | - | 編集アクション |

## イベント仕様

### 1-検索

**トリガー**：検索フィールドへの入力

**処理内容**：
1. 入力値をURLパラメータ（q）に設定
2. useQueryParamsでパラメータを取得
3. useUsersフックで検索条件付きAPI呼び出し
4. 検索結果でテーブルを更新

### 2-ソート

**トリガー**：テーブルヘッダーのソートボタンをクリック

**処理内容**：
1. ソート対象カラム：email, first_name, last_name, created_at, updated_at
2. 昇順/降順を切り替え
3. URLパラメータ（order）を更新
4. ソート結果でテーブルを再表示

### 3-フィルター

**トリガー**：日付フィルターの設定

**処理内容**：
1. useDataTableDateFiltersで日付フィルターUI提供
2. created_at, updated_atによる絞り込み
3. フィルター条件でAPI再呼び出し

### 4-ページネーション

**トリガー**：ページ移動ボタンをクリック

**処理内容**：
1. ページサイズ：20件固定
2. URLパラメータ（offset）を更新
3. keepPreviousDataでちらつき防止
4. 該当ページのデータを表示

### 5-行クリック

**トリガー**：テーブル行をクリック

**処理内容**：
1. 該当ユーザーの詳細画面（/settings/users/:id）へ遷移

### 6-編集アクション

**トリガー**：アクションメニューから「編集」を選択

**処理内容**：
1. 該当ユーザーの編集画面（/settings/users/:id/edit）へ遷移

### 7-招待ボタン

**トリガー**：「ユーザーを招待」ボタンをクリック

**処理内容**：
1. ユーザー招待画面（/settings/users/invite）へ遷移

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | 本画面での更新操作なし（参照のみ） |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| users.list.empty.heading | 情報 | ユーザーがいません | ユーザーが0件の場合 |
| users.list.empty.description | 情報 | ユーザーを招待してください | ユーザーが0件の場合 |
| users.list.filtered.heading | 情報 | 該当するユーザーがいません | フィルター結果が0件の場合 |
| users.list.filtered.description | 情報 | 検索条件を変更してください | フィルター結果が0件の場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| API呼び出しエラー | エラーをスローしてエラーバウンダリで処理 |

## 備考

- ページサイズは20件固定（PAGE_SIZE = 20）
- keepPreviousDataオプションによりページ遷移時のちらつきを防止
- ウィジェット拡張ポイント：user.list.before, user.list.after
- 名前（first_name, last_name）が未設定の場合は「-」を表示

---

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

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

### 推奨読解順序

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

ユーザーデータの構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | users.tsx | `packages/admin/dashboard/src/hooks/api/users.tsx` | useUsersフックの戻り値（63-82行目） |

**読解のコツ**: HttpTypes.AdminUserListResponseの構造（users配列とcount）を把握します。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | user-list.tsx | `packages/admin/dashboard/src/routes/users/user-list/user-list.tsx` | コンポーネントのエントリーポイント |

**主要処理フロー**:
1. **6行目**: useExtensionでウィジェット取得関数を取得
2. **9-16行目**: SingleColumnPageでUserListTableをラップ
3. **11-12行目**: before/afterウィジェットを設定

#### Step 3: テーブルコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | user-list-table.tsx | `packages/admin/dashboard/src/routes/users/user-list/components/user-list-table/user-list-table.tsx` | メインテーブルコンポーネント |

**主要処理フロー**:
- **15行目**: PAGE_SIZE定数（20件）
- **18行目**: useQueryParamsでURLパラメータ取得
- **19-29行目**: useUsersでユーザー一覧取得（keepPreviousData使用）
- **31-32行目**: useColumns, useFiltersでテーブル設定取得
- **36-38行目**: エラー時はエラーをスロー
- **40-68行目**: DataTableコンポーネントでテーブル描画
- **52-55行目**: actionプロップで招待ボタン設定
- **73-123行目**: useColumnsでカラム定義（email, first_name, last_name, 日付カラム, アクション）
- **125-131行目**: useFiltersで日付フィルター設定

#### Step 4: APIフックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | users.tsx | `packages/admin/dashboard/src/hooks/api/users.tsx` | ユーザーAPIフック |

**主要処理フロー**:
- **63-82行目**: useUsers - ユーザー一覧取得（sdk.admin.user.list）

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

```
UserList (user-list.tsx)
    │
    ├─ useExtension()
    │      └─ getWidgets()
    │
    └─ UserListTable
           │
           ├─ useQueryParams()
           │      └─ URLパラメータ取得 (q, order, offset)
           │
           ├─ useUsers()
           │      └─ sdk.admin.user.list()
           │
           ├─ useColumns()
           │      ├─ useDataTableDateColumns()
           │      └─ カラム定義 (email, first_name, last_name, actions)
           │
           ├─ useFilters()
           │      └─ useDataTableDateFilters()
           │
           └─ DataTable
                  └─ テーブル描画・インタラクション
```

### データフロー図

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

URLパラメータ ────────▶ useQueryParams() ──────────▶ q, order, offset
(q, order, offset)
                              │
                              ▼
                       useUsers(params)
                              │
                              ▼
                  sdk.admin.user.list()
                              │
                              ▼
                    [User API サーバー]
                              │
                              ▼
                  { users, count } 取得
                              │
                              ▼
検索/ソート/フィルター ──▶ DataTable ──────────────▶ テーブル表示
                              │
                              ▼
行クリック ───────────▶ navigate(`${id}`) ─────────▶ 詳細画面遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| user-list.tsx | `packages/admin/dashboard/src/routes/users/user-list/user-list.tsx` | ソース | エントリーポイント |
| user-list-table.tsx | `packages/admin/dashboard/src/routes/users/user-list/components/user-list-table/user-list-table.tsx` | ソース | メインテーブルコンポーネント |
| users.tsx | `packages/admin/dashboard/src/hooks/api/users.tsx` | ソース | ユーザーAPIフック |
| single-column-page.tsx | `packages/admin/dashboard/src/components/layout/pages/` | ソース | ページレイアウト |
| data-table.tsx | `packages/admin/dashboard/src/components/data-table/` | ソース | データテーブルコンポーネント |
| use-data-table-date-columns.tsx | `packages/admin/dashboard/src/components/data-table/helpers/general/` | ソース | 日付カラムヘルパー |
| use-data-table-date-filters.tsx | `packages/admin/dashboard/src/components/data-table/helpers/general/` | ソース | 日付フィルターヘルパー |
