# 画面設計書 87-顧客グループ詳細画面

## 概要

本ドキュメントは、Medusa Admin Dashboard における顧客グループ詳細画面の設計仕様を定義したものである。特定の顧客グループの詳細情報を表示し、所属する顧客を管理するための画面について記述する。

### 本画面の処理概要

顧客グループ詳細画面は、選択した顧客グループの詳細情報と、そのグループに所属する顧客の一覧を表示する画面である。グループの編集・削除、顧客の追加・削除などの管理操作を行うことができる。

**業務上の目的・背景**：ECサイト運営において、顧客グループは顧客セグメンテーションの中核となる。特定のグループの詳細を確認し、所属顧客を把握することで、ターゲットマーケティングの効果測定や顧客構成の分析が可能になる。本画面は、グループ単位での顧客管理を効率化し、顧客戦略の立案と実行を支援する。

**画面へのアクセス方法**：顧客グループ一覧画面でグループ行をクリック、または顧客グループ作成完了後、またはURLパス `/customer-groups/:id` に直接アクセスすることで本画面を開く。

**主要な操作・処理内容**：
1. グループ名と顧客数の表示
2. グループ情報の編集（編集画面へ遷移）
3. グループの削除（確認ダイアログ付き）
4. 所属顧客一覧の表示（ページネーション、検索、フィルター付き）
5. 顧客の追加（追加画面へ遷移）
6. 顧客の削除（一括または個別）
7. 顧客詳細画面への遷移
8. メタデータの表示・編集
9. JSONデータの表示

**画面遷移**：顧客グループ一覧画面または作成画面から遷移。編集アクションで編集画面、顧客追加で追加画面、顧客行クリックで顧客詳細画面へ遷移。削除成功時は一覧画面に戻る。

**権限による表示制御**：認証済みの管理者ユーザーのみがアクセス可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 27 | 顧客グループ管理 | 主機能 | 顧客グループ詳細の表示 |
| 25 | 顧客CRUD | 補助機能 | グループ内顧客の表示 |

## 画面種別

詳細

## URL/ルーティング

`/customer-groups/:id`

## 入出力項目

本画面は参照が主目的のため、入力項目は顧客テーブルの検索・フィルター・ソートのみ。

| 項目名 | 項目ID | データ型 | 必須 | 最大長 | 入力/出力 | バリデーション | 備考 |
|--------|--------|----------|------|--------|-----------|----------------|------|
| 検索キーワード | q | string | - | - | 入力 | なし | 顧客検索用 |
| ソート順 | order | string | - | - | 入力 | なし | カラム名と方向 |
| オフセット | offset | number | - | - | 入力 | なし | ページネーション用 |

## 表示項目

### 一般情報セクション

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| グループ名 | セクションヘッダー | 顧客グループの名前 |
| アクションメニュー | ヘッダー右側 | 編集・削除アクション |
| 顧客数 | 詳細情報 | グループに所属する顧客の数 |

### 顧客セクション

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| セクションヘッダー | セクション上部 | 「顧客」（customers.domain） |
| 追加ボタン | ヘッダー右側 | 顧客追加画面へ遷移 |
| 選択チェックボックス | 各行先頭 | 一括操作用 |
| メールアドレス | テーブルカラム | 顧客のメールアドレス |
| 名 | テーブルカラム | 顧客の名 |
| 姓 | テーブルカラム | 顧客の姓 |
| アカウント状態 | テーブルカラム | アカウント有無 |
| アクションメニュー | 各行末尾 | 編集・削除アクション |
| ページネーション | テーブルフッター | ページ切り替え |

## イベント仕様

### 1-編集アクション（グループ）

アクションメニューの「編集」を選択すると、顧客グループ編集画面 `/customer-groups/:id/edit` へ遷移する。

### 2-削除アクション（グループ）

アクションメニューの「削除」を選択すると、以下の処理が実行される：
1. 削除確認ダイアログを表示
2. ユーザーが確認
3. `useDeleteCustomerGroup` フックを通じて API を呼び出し
4. 成功時：成功トーストを表示し、一覧画面 `/customer-groups` へ遷移
5. 失敗時：エラートーストを表示

### 3-顧客追加ボタン

「追加」ボタンをクリックすると、顧客追加画面 `/customer-groups/:id/add-customers` へ遷移する。

### 4-顧客行クリック

テーブルの行をクリックすると、該当顧客の詳細画面 `/customers/:id` へ遷移する。

### 5-顧客削除（一括）

チェックボックスで選択した顧客を一括でグループから削除する：
1. 削除確認ダイアログを表示
2. `useRemoveCustomersFromGroup` フックを通じて API を呼び出し
3. 成功時：選択状態をクリアし、一覧を更新

### 6-顧客削除（個別）

アクションメニューの「削除」を選択すると、該当顧客をグループから削除する：
1. 削除確認ダイアログを表示
2. `useRemoveCustomersFromGroup` フックを通じて API を呼び出し
3. 成功時：一覧を更新

### 7-顧客編集アクション

アクションメニューの「編集」を選択すると、顧客編集画面 `/customers/:id/edit` へ遷移する。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| グループ削除 | customer_group | DELETE | 顧客グループの削除 |
| 顧客削除 | customer_group_customer | DELETE | 顧客とグループの紐付けを削除 |

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

#### customer_group

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | id = URL パラメータの id | グループ全体を削除 |

#### customer_group_customer（中間テーブル）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | customer_id | 選択された顧客ID | 紐付けを削除 |
| DELETE | customer_group_id | URL パラメータの id | 紐付けを削除 |

## メッセージ仕様

| 種別 | メッセージキー | 表示条件 | メッセージ内容（参考） |
|------|---------------|----------|----------------------|
| 成功 | customerGroups.delete.successToast | グループ削除成功時 | グループ {name} を削除しました |
| エラー | (動的) | API エラー時 | エラーメッセージを表示 |
| 空状態 | customerGroups.customers.list.noRecordsMessage | 顧客なし時 | このグループには顧客がいません |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| グループデータ取得エラー | エラーをスローしてエラー境界で処理 |
| 顧客一覧取得エラー | エラーをスローしてエラー境界で処理 |
| グループ削除エラー | エラートーストを表示 |
| 顧客削除エラー | エラートーストを表示 |

## 備考

- SingleColumnPage レイアウトを使用し、拡張ウィジェットの挿入ポイントを提供
- 顧客テーブルは _DataTable コンポーネントを使用し、ページネーション、検索、フィルター機能を提供
- 1ページあたりの表示件数は10件（PAGE_SIZE = 10）
- 顧客テーブルは `groups` パラメータでグループIDをフィルタとして渡す
- グループ取得時に顧客情報も含めて取得（CUSTOMER_GROUP_DETAIL_FIELDS を使用）
- ローダー（loader.ts）でサーバーサイドデータフェッチを実行
- showJSON と showMetadata オプションでJSON/メタデータセクションを表示
- 顧客削除はグループからの削除であり、顧客自体は削除されない

---

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

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

### 推奨読解順序

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

顧客グループと顧客の型定義を把握することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | constants.ts | `packages/admin/dashboard/src/routes/customer-groups/customer-group-detail/constants.ts` | CUSTOMER_GROUP_DETAIL_FIELDS で取得するフィールドを定義 |

**読解のコツ**: fields パラメータでAPIに渡すフィールド指定を確認。

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

ルートコンポーネントの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | customer-group-detail.tsx | `packages/admin/dashboard/src/routes/customer-groups/customer-group-detail/customer-group-detail.tsx` | CustomerGroupDetail コンポーネント（13-51行目）。useLoaderData でプリフェッチデータを取得、useCustomerGroup でリアルタイム更新 |

**主要処理フロー**:
1. **14-16行目**: useLoaderData でローダーからの初期データを取得
2. **18-25行目**: useCustomerGroup でグループデータを取得（initialData で初期値を使用）
3. **37-49行目**: SingleColumnPage 内に GeneralSection と CustomerSection を配置

#### Step 3: セクションコンポーネントを理解する

各セクションの実装詳細を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | customer-group-general-section.tsx | `packages/admin/dashboard/src/routes/customer-groups/customer-group-detail/components/customer-group-general-section/customer-group-general-section.tsx` | 一般情報セクション（14-90行目）。グループ名、顧客数、アクションメニューを表示 |
| 3-2 | customer-group-customer-section.tsx | `packages/admin/dashboard/src/routes/customer-groups/customer-group-detail/components/customer-group-customer-section/customer-group-customer-section.tsx` | 顧客セクション（24-243行目）。顧客一覧テーブル、追加・削除操作 |

**主要処理フロー（GeneralSection）**:
- **21行目**: useDeleteCustomerGroup で削除用ミューテーションを取得
- **23-50行目**: handleDelete で削除処理（確認ダイアログ含む）
- **57-77行目**: ActionMenu で編集・削除アクションを提供

**主要処理フロー（CustomerSection）**:
- **31-35行目**: useCustomers でグループに属する顧客を取得（groups パラメータ）
- **61行目**: useRemoveCustomersFromGroup で削除用ミューテーションを取得
- **63-86行目**: handleRemove で一括削除処理
- **92行目**: 「追加」ボタンで追加画面へのリンク

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

バックエンドとの通信処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | customer-groups.tsx | `packages/admin/dashboard/src/hooks/api/customer-groups.tsx` | useCustomerGroup（20-40行目）、useDeleteCustomerGroup（106-128行目）、useRemoveCustomersFromGroup（181-207行目） |

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

```
CustomerGroupDetail (customer-group-detail.tsx)
    │
    ├─ useLoaderData() ─── ローダーからの初期データ
    │
    ├─ useCustomerGroup(id) ─── グループデータ取得
    │      └─ sdk.admin.customerGroup.retrieve()
    │
    ├─ useExtension() ─── ウィジェット取得
    │
    └─ SingleColumnPage
           │
           ├─ CustomerGroupGeneralSection
           │      │
           │      ├─ useDeleteCustomerGroup()
           │      │      └─ sdk.admin.customerGroup.delete()
           │      │
           │      └─ ActionMenu ─── 編集・削除アクション
           │
           └─ CustomerGroupCustomerSection
                  │
                  ├─ useCustomers() ─── 顧客一覧取得
                  │      └─ sdk.admin.customer.list()
                  │
                  ├─ useRemoveCustomersFromGroup()
                  │      └─ sdk.admin.customerGroup.batchCustomers()
                  │
                  └─ _DataTable ─── 顧客テーブル表示
```

### データフロー図

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

URL パラメータ (id) ───▶ useParams() ───▶ グループID
                              │
                              ▼
ローダー ───────────────▶ customerGroupLoader() ───▶ 初期データ
                              │
                              ▼
API呼び出し ───────────▶ useCustomerGroup() ───▶ グループ詳細
                              │
                              ▼
                        SingleColumnPage ───▶ レイアウト
                              │
                              ├───▶ GeneralSection ───▶ 基本情報表示
                              │
                              └───▶ CustomerSection ───▶ 顧客一覧表示
                                          │
顧客検索/フィルタ ────────▶ useCustomers(groups: id) ───▶ フィルタ済み顧客一覧
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| customer-group-detail.tsx | `packages/admin/dashboard/src/routes/customer-groups/customer-group-detail/customer-group-detail.tsx` | ソース | ルートコンポーネント |
| loader.ts | `packages/admin/dashboard/src/routes/customer-groups/customer-group-detail/loader.ts` | ソース | サーバーサイドローダー |
| constants.ts | `packages/admin/dashboard/src/routes/customer-groups/customer-group-detail/constants.ts` | ソース | 定数定義 |
| customer-group-general-section.tsx | `packages/admin/dashboard/src/routes/customer-groups/customer-group-detail/components/customer-group-general-section/customer-group-general-section.tsx` | ソース | 一般情報セクション |
| customer-group-customer-section.tsx | `packages/admin/dashboard/src/routes/customer-groups/customer-group-detail/components/customer-group-customer-section/customer-group-customer-section.tsx` | ソース | 顧客セクション |
| customer-groups.tsx | `packages/admin/dashboard/src/hooks/api/customer-groups.tsx` | ソース | 顧客グループ API フック |
| customers.tsx | `packages/admin/dashboard/src/hooks/api/customers.tsx` | ソース | 顧客 API フック |
| SingleColumnPage | `packages/admin/dashboard/src/components/layout/pages/` | ソース | 単一カラムレイアウト |
| _DataTable | `packages/admin/dashboard/src/components/table/data-table/` | ソース | データテーブルコンポーネント |
