# 画面設計書 123-ユーザーメタデータ編集画面

## 概要

本ドキュメントは、Medusa Admin Dashboardにおけるユーザーメタデータ編集画面の設計を記述したものです。管理者ユーザーに関連付けられたメタデータ（カスタムフィールド）を編集するためのモーダル形式のドロワー画面です。

### 本画面の処理概要

この画面では、ユーザーに関連付けられた任意のキー・バリューペア形式のメタデータを追加、編集、削除できます。メタデータは拡張的な情報を格納するために使用されます。

**業務上の目的・背景**：ECサイト運営において、標準のユーザー属性では表現できないカスタム情報を管理する必要がある場合があります。例えば、部署コード、担当エリア、特別な権限フラグなど、組織固有の情報をメタデータとして格納できます。この画面は、そうしたカスタム情報を柔軟に管理するためのインターフェースを提供します。

**画面へのアクセス方法**：ユーザー詳細画面（No.121）のメタデータセクションから「編集」を選択することでアクセスします。URLパスは `/settings/users/:id/metadata` の形式で、ドロワー（サイドパネル）形式で表示されます。

**主要な操作・処理内容**：
1. 既存のメタデータの表示と編集
2. 新しいメタデータキー・バリューペアの追加
3. 既存のメタデータの削除
4. 保存ボタンクリックでメタデータを更新
5. キャンセルボタンクリックでドロワーを閉じる

**画面遷移**：
- 遷移元：ユーザー詳細画面（No.121）
- 遷移先：保存完了後、ユーザー詳細画面へ戻る

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 62 | ユーザーCRUD | 主機能 | ユーザーメタデータの編集 |

## 画面種別

編集（モーダル形式）

## URL/ルーティング

`/settings/users/:id/metadata`

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 必須 | 説明 |
|--------|----------|----------|------|------|
| id | 入力（URLパラメータ） | string | Yes | ユーザーID |
| metadata | 入力（フォーム） | Record<string, unknown> | No | メタデータオブジェクト |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| メタデータフォーム | MetadataForm | 共通のメタデータ編集フォームコンポーネント |

## イベント仕様

### 1-保存ボタンクリック

保存ボタンをクリックすると、メタデータが更新されます。

- 処理内容:
  - `POST /admin/users/:id` APIを呼び出し（useUpdateUserフック経由）
  - metadataフィールドを更新
  - 成功時: ドロワーを閉じてユーザー詳細画面に戻る
  - 失敗時: エラーメッセージを表示

### 2-キャンセルボタンクリック

キャンセルボタンをクリックすると、変更を保存せずにドロワーを閉じます。

### 3-メタデータ追加

新しいキー・バリューペアを追加します。MetadataFormコンポーネントの機能を使用します。

### 4-メタデータ削除

既存のキー・バリューペアを削除します。MetadataFormコンポーネントの機能を使用します。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | user | SELECT | ユーザー情報の取得（メタデータ含む） |
| 保存ボタン押下 | user | UPDATE | メタデータの更新 |

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

#### user

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, metadata | id = URLパラメータのid | フォーム初期値設定用 |
| UPDATE | metadata | フォームで編集されたメタデータオブジェクト | JSON形式で保存 |

## メッセージ仕様

| メッセージ種別 | 表示条件 | メッセージ内容 |
|--------------|----------|--------------|
| ラベル | 常時 | MetadataFormコンポーネント内で定義 |
| ボタン | 常時 | MetadataFormコンポーネント内で定義 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ユーザーが見つからない | エラーをスロー（isError状態）してエラーバウンダリでハンドリング |
| ローディング中 | MetadataFormコンポーネントにisPendingを渡してローディング状態を表示 |

## 備考

- MetadataFormは共通コンポーネントとして複数の画面で再利用されている
- メタデータの構造は任意のキー・バリュー形式（Record<string, unknown>）

---

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

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

### 推奨読解順序

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

メタデータはRecord<string, unknown>型として定義されています。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | user-metadata.tsx | `packages/admin/dashboard/src/routes/users/user-metadata/user-metadata.tsx` | useUserで取得するuser.metadataの型 |

**読解のコツ**: メタデータは任意のキー・バリューペアを格納できるオブジェクトです。型は厳密に定義されていません。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | user-metadata.tsx | `packages/admin/dashboard/src/routes/users/user-metadata/user-metadata.tsx` | RouteDrawerとMetadataFormの構成 |

**主要処理フロー**:
1. **8行目**: useParamsでURLからユーザーIDを取得
2. **10行目**: useUserフックでユーザーデータを取得
3. **11行目**: useUpdateUserフックでミューテーション関数を取得
4. **17-26行目**: RouteDrawer内にMetadataFormを配置

#### Step 3: 共通メタデータフォームを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | metadata-form.tsx | `packages/admin/dashboard/src/components/forms/metadata-form/metadata-form.tsx` | MetadataFormコンポーネントの実装 |

**読解のコツ**: MetadataFormは複数のエンティティ（ユーザー、商品、注文など）で共通して使用される汎用コンポーネントです。hookプロパティに更新用のmutateAsync関数を渡すことで、任意のエンティティのメタデータを編集できます。

#### Step 4: API呼び出しフックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | users.tsx | `packages/admin/dashboard/src/hooks/api/users.tsx` | useUser、useUpdateUserフックの実装 |

**主要処理フロー**:
- **41-61行目**: useUserフックでユーザー情報（metadata含む）を取得
- **104-127行目**: useUpdateUserフックでmetadataを含むユーザー情報を更新

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

```
UserMetadata (user-metadata.tsx)
    │
    ├─ useParams() → id取得
    │
    ├─ useUser(id) → hooks/api/users.tsx
    │      └─ sdk.admin.user.retrieve()
    │
    ├─ useUpdateUser(id) → hooks/api/users.tsx
    │
    └─ RouteDrawer
           └─ MetadataForm (共通コンポーネント)
                  │
                  ├─ isPending: ローディング状態
                  ├─ isMutating: 更新中状態
                  ├─ hook: mutateAsync (useUpdateUser)
                  └─ metadata: user.metadata
                         │
                         └─ handleSubmit()
                                └─ hook({ metadata: newMetadata })
                                       └─ sdk.admin.user.update()
```

### データフロー図

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

URLパラメータ(:id) ───▶ useParams()              ───▶ id
                              │
                              ▼
                        useUser(id)              ───▶ user.metadata
                              │
                              ▼
user.metadata ─────────▶ MetadataForm
                        (初期値設定)
                              │
                              ▼
フォーム入力 ──────────▶ キー・バリュー編集
(add/edit/remove)             │
                              ▼
                        handleSubmit()
                              │
                              ▼
                        hook({ metadata })
                              │
                              ▼
                        useUpdateUser()
                              │
                              ▼
                        sdk.admin.user.update() ───▶ 更新されたuser
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| user-metadata.tsx | `packages/admin/dashboard/src/routes/users/user-metadata/user-metadata.tsx` | ソース | エントリーポイント |
| metadata-form.tsx | `packages/admin/dashboard/src/components/forms/metadata-form/metadata-form.tsx` | ソース | 共通メタデータフォームコンポーネント |
| users.tsx | `packages/admin/dashboard/src/hooks/api/users.tsx` | ソース | APIフック（useUser, useUpdateUser） |
| index.ts | `packages/admin/dashboard/src/routes/users/user-metadata/index.ts` | ソース | バレルエクスポート |
