# 機能設計書 84-ビュー設定管理

## 概要

本ドキュメントは、Medusaコマースプラットフォームにおけるビュー設定管理機能の設計について記述する。設定モジュールの中核機能として、管理画面のユーザーインターフェース表示設定（カラム表示/非表示、並び順、フィルタ、ソートなど）の管理を行う。

### 本機能の処理概要

**業務上の目的・背景**：ECサイト管理画面では、ユーザーごとに表示したいカラムや並び順が異なる。ビュー設定管理機能は、各ユーザーがカスタマイズした表示設定を保存し、次回ログイン時にも同じ設定で利用できるようにする。また、システムデフォルトビューを設定することで、新規ユーザーにも適切な初期表示を提供できる。業務効率の向上、ユーザー体験の向上を実現する。

**機能の利用シーン**：商品一覧画面でカラムの表示/非表示を切り替える場面、注文一覧のフィルタ条件を保存する場面、管理者がデフォルトビュー設定を作成する場面などで利用される。

**主要な処理内容**：
1. ビュー設定の作成（createViewConfigurations）：エンティティ、ユーザーID、設定内容を指定して新規作成
2. ビュー設定の一覧取得（listViewConfigurations）：フィルタ条件を指定して設定を検索・取得
3. ビュー設定の更新（updateViewConfigurations）：設定内容を更新（置換方式）
4. ビュー設定の削除（deleteViewConfigurations）：不要な設定を削除
5. アクティブビューの取得（getActiveViewConfiguration）：ユーザーの現在有効なビュー設定を取得
6. アクティブビューの設定（setActiveViewConfiguration）：ユーザーのアクティブビューを変更
7. ユーザー設定の管理（getUserPreference / setUserPreference）：キーバリュー形式の設定管理

**関連システム・外部連携**：管理画面ダッシュボード（表示設定の適用）、ユーザーモジュール（ユーザーID参照）と連携する。

**権限による制御**：自身のビュー設定のみ編集可能。システムデフォルト設定は管理者権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 105 | 設定トップ画面 | 主機能 | 設定メニューの表示 |

## 機能種別

CRUD操作 / ユーザー設定管理

## 入力仕様

### 入力パラメータ

#### ビュー設定作成（createViewConfigurations）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| entity | string | Yes | 対象エンティティ名（product, orderなど） | 空文字不可 |
| name | string | No | ビュー設定名 | - |
| user_id | string | No | ユーザーID（システムデフォルトの場合はnull） | - |
| is_system_default | boolean | No | システムデフォルトフラグ | user_idと排他 |
| configuration | object | Yes | 表示設定（後述） | JSON形式 |

#### configuration オブジェクト

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|-----|------|
| visible_columns | string[] | No | 表示するカラム一覧 |
| column_order | string[] | No | カラムの表示順序 |
| column_widths | object | No | カラム幅の設定 |
| filters | object | No | フィルタ条件 |
| sorting | object/null | No | ソート設定 |
| search | string | No | 検索クエリ |

### 入力データソース

API経由でのJSON形式リクエストボディ、管理画面からの操作

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | string | ビュー設定ID（プレフィックス: vconf_） |
| entity | string | 対象エンティティ名 |
| name | string/null | ビュー設定名 |
| user_id | string/null | ユーザーID |
| is_system_default | boolean | システムデフォルトフラグ |
| configuration | object | 表示設定 |
| created_at | Date | 作成日時 |
| updated_at | Date | 更新日時 |

### 出力先

APIレスポンス（JSON形式）、管理画面への設定適用

## 処理フロー

### 処理シーケンス

```
1. アクティブビュー取得（getActiveViewConfiguration）
   └─ ユーザー設定からアクティブビューIDを取得
   └─ 設定されていない場合は個人ビュー → システムデフォルトの順で取得

2. ビュー設定更新（updateViewConfigurations）
   └─ configurationは置換方式（マージではない）
   └─ upsertWithReplaceでJSON完全置換

3. システムデフォルト作成
   └─ is_system_default=trueかつuser_id=nullを検証
   └─ 同一エンティティに既存デフォルトがないことを確認
```

### フローチャート

```mermaid
flowchart TD
    A[アクティブビュー取得要求] --> B[ユーザー設定確認]
    B --> C{アクティブビューID設定あり?}
    C -->|あり| D[指定ビュー取得]
    C -->|なし| E{明示的なnull?}
    E -->|いいえ| F[個人ビュー検索]
    E -->|はい| G[システムデフォルト検索]
    F -->|存在| H[個人ビュー返却]
    F -->|不存在| G
    G --> I[デフォルトビュー返却]
    D --> J[ビュー返却]
    H --> J
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-84-1 | システムデフォルト排他 | is_system_default=trueの場合、user_idはnullでなければならない | ビュー作成時 |
| BR-84-2 | デフォルト一意 | 同一エンティティにシステムデフォルトは1つのみ | ビュー作成時 |
| BR-84-3 | 設定置換 | configuration更新時はマージではなく完全置換 | ビュー更新時 |
| BR-84-4 | アクセス制御 | user_id付きビューは所有者のみアクセス可能 | アクティブビュー設定時 |
| BR-84-5 | フォールバック | アクティブビューなし→個人ビュー→システムデフォルトの順で取得 | アクティブビュー取得時 |

### 計算ロジック

アクティブビュー決定ロジック：
1. `active_view.{entity}`キーでユーザー設定を検索
2. viewConfigurationIdが設定されていれば、そのビューを返却
3. 明示的にnullでなければ、個人ビュー（user_id=currentUser）を検索
4. 個人ビューが存在しなければ、システムデフォルト（is_system_default=true）を返却

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| createViewConfigurations | view_configuration | INSERT | ビュー設定作成 |
| listViewConfigurations | view_configuration | SELECT | ビュー設定一覧取得 |
| updateViewConfigurations | view_configuration | UPDATE | ビュー設定更新（置換） |
| deleteViewConfigurations | view_configuration | DELETE | ビュー設定削除 |
| getUserPreference | user_preference | SELECT | ユーザー設定取得 |
| setUserPreference | user_preference | INSERT/UPDATE | ユーザー設定保存 |

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

#### view_configuration

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | vconf_プレフィックス + UUID | 自動生成 |
| INSERT | entity | エンティティ名 | 必須 |
| INSERT | user_id | ユーザーID | 任意 |
| INSERT | is_system_default | true/false | デフォルト: false |
| INSERT | configuration | JSON設定 | 必須 |
| UPDATE | configuration | 完全置換 | マージではない |

#### user_preference

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | usrpref_プレフィックス + UUID | 自動生成 |
| INSERT | user_id | ユーザーID | 必須 |
| INSERT | key | 設定キー | 必須 |
| INSERT | value | JSON値 | 必須 |
| UPSERT | value | 新しい値 | 既存時は更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| INVALID_DATA | 検証エラー | is_system_default=trueでuser_id指定 | user_idを削除 |
| DUPLICATE_ERROR | 重複エラー | 同一エンティティにデフォルト重複 | 既存デフォルトを変更 |
| NOT_ALLOWED | 権限エラー | 他ユーザーのビューをアクティブに設定 | 自身のビューを使用 |
| INVALID_DATA | 検証エラー | 別エンティティのビューをアクティブに設定 | 正しいエンティティのビューを指定 |

### リトライ仕様

データベースデッドロック発生時は、トランザクションマネージャーにより自動リトライされる。

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

- 更新操作は`@InjectTransactionManager()`デコレータによりトランザクション管理される
- configurationの置換は`upsertWithReplace`メソッドで実行
- ユーザー設定の作成/更新も同一トランザクション内で処理可能

## パフォーマンス要件

- ビュー設定取得：100件以下で200ms以内
- アクティブビュー取得：100ms以内
- entity + user_idインデックス、entity + is_system_defaultインデックスによる検索高速化

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

- ユーザーは自身のビュー設定のみ編集可能
- システムデフォルト設定の作成/編集には管理者権限が必要
- 他ユーザーのビュー設定にはアクセス不可

## 備考

- configuration更新時はJSONのマージではなく完全置換される
- これはMikroORMのデフォルト動作（JSONマージ）を回避するための設計
- `upsertWithReplace`メソッドで`nativeUpdateMany`を使用し完全置換を実現

---

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

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

### 推奨読解順序

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

ビュー設定とユーザー設定のエンティティ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | view-configuration.ts | `packages/modules/settings/src/models/view-configuration.ts` | entity/user_id/is_system_default/configurationフィールド |
| 1-2 | user-preference.ts | `packages/modules/settings/src/models/user-preference.ts` | user_id/key/valueフィールド、複合一意制約 |

**読解のコツ**: view_configurationは`entity + user_id`と`entity + is_system_default`の2つのインデックスを持つ。user_preferenceは`user_id + key`の複合一意制約を持つ。

#### Step 2: ビュー設定作成処理を理解する

システムデフォルト作成時のバリデーションロジック。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | settings-module-service.ts | `packages/modules/settings/src/services/settings-module-service.ts` | createViewConfigurationsメソッド |

**主要処理フロー**:
- **54-106行目**: `createViewConfigurations`メソッド
  - **71-76行目**: is_system_default=trueでuser_id指定時のエラー
  - **78-95行目**: 同一エンティティにデフォルト重複チェック

#### Step 3: ビュー設定更新処理を理解する

configuration置換ロジックの実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | settings-module-service.ts | `packages/modules/settings/src/services/settings-module-service.ts` | updateViewConfigurations, updateViewConfigurations_メソッド |

**主要処理フロー**:
- **108-129行目**: `updateViewConfigurations`公開メソッド
- **131-202行目**: `updateViewConfigurations_`保護メソッド
  - **146-156行目**: configurationが含まれる場合の特別処理
  - **159-182行目**: 新しいconfigurationオブジェクトを完全構築
  - **185-190行目**: `upsertWithReplace`で完全置換

#### Step 4: アクティブビュー取得を理解する

フォールバックロジックの実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | settings-module-service.ts | `packages/modules/settings/src/services/settings-module-service.ts` | getActiveViewConfigurationメソッド |

**主要処理フロー**:
- **260-314行目**: `getActiveViewConfiguration`メソッド
  - **267-271行目**: ユーザー設定からアクティブビューIDを取得
  - **274-288行目**: 設定されたビューIDがあれば取得を試みる
  - **294-304行目**: 明示的null以外なら個人ビューを検索
  - **307-312行目**: 最終フォールバックでシステムデフォルトを返却

#### Step 5: ユーザー設定管理を理解する

キーバリュー形式の設定保存。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | settings-module-service.ts | `packages/modules/settings/src/services/settings-module-service.ts` | getUserPreference, setUserPreferenceメソッド |

**主要処理フロー**:
- **204-223行目**: `getUserPreference`メソッド（user_id + keyで検索）
- **225-258行目**: `setUserPreference`メソッド（存在チェック後に作成or更新）

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

```
API Route / 管理画面
    │
    └─ SettingsModuleService
           │
           ├─ MedusaService (継承)
           │      └─ 基本CRUD操作
           │
           ├─ viewConfigurationService_
           │      ├─ list()
           │      ├─ create()
           │      ├─ update()
           │      └─ upsertWithReplace()
           │
           └─ userPreferenceService_
                  ├─ list()
                  ├─ create()
                  └─ update()
```

### データフロー図

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

ビュー設定作成要求 ───▶ SettingsModuleService.createViewConfigurations() ───▶ ViewConfigurationDTO
                              │
                              ├─▶ バリデーション（is_system_default/user_id排他）
                              │
                              └─▶ viewConfigurationService_.create()

アクティブビュー取得 ───▶ SettingsModuleService.getActiveViewConfiguration() ───▶ ViewConfigurationDTO
        │                      │
        ├─ entity              ├─▶ getUserPreference()（アクティブビューID）
        │                      │
        └─ userId              ├─▶ 設定ビュー取得 or 個人ビュー検索
                               │
                               └─▶ システムデフォルト検索
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| settings-module-service.ts | `packages/modules/settings/src/services/settings-module-service.ts` | サービス | ビュー設定・ユーザー設定管理 |
| view-configuration.ts | `packages/modules/settings/src/models/view-configuration.ts` | モデル | ビュー設定エンティティ定義 |
| user-preference.ts | `packages/modules/settings/src/models/user-preference.ts` | モデル | ユーザー設定エンティティ定義 |
| index.ts | `packages/modules/settings/src/index.ts` | エクスポート | モジュールエクスポート |
