# 機能設計書 69-ストア設定管理

## 概要

本ドキュメントは、Medusaコマースプラットフォームにおけるストアのデフォルト設定管理機能の設計を記述する。ストアのデフォルト通貨、地域、販売チャネル、ロケーション、ロケール等の設定を管理する。

### 本機能の処理概要

**業務上の目的・背景**：ECサイトの運営では、注文処理やカート作成時にデフォルトで使用される通貨、地域、販売チャネル等を設定しておくことで、運用の効率化と一貫性を保つことができる。ストア設定管理機能は、これらのデフォルト設定を一元管理し、システム全体で参照可能にする。また、サポートする通貨やロケールを設定することで、多通貨・多言語対応の基盤を提供する。

**機能の利用シーン**：
- ストアのデフォルト販売チャネル設定
- ストアのデフォルト地域設定
- ストアのデフォルトロケーション設定
- サポート通貨の追加とデフォルト通貨の設定
- 通貨ごとの税込価格設定
- サポートロケールの追加

**主要な処理内容**：
1. デフォルト販売チャネルID設定
2. デフォルト地域ID設定
3. デフォルトロケーションID設定
4. サポート通貨リストの管理（追加・削除・デフォルト設定）
5. 通貨ごとの税込設定（is_tax_inclusive）
6. サポートロケールリストの管理

**関連システム・外部連携**：
- 販売チャネルモジュール（デフォルト販売チャネル）
- 地域モジュール（デフォルト地域）
- 在庫ロケーションモジュール（デフォルトロケーション）
- 価格設定モジュール（税込設定の反映）

**権限による制御**：ストア設定の変更は認証済み管理者のみ可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 108 | ストア詳細画面 | 補助機能 | ストア設定の表示 |
| 110 | 通貨追加画面 | 主画面 | ストアに通貨を追加 |
| 111 | ロケール追加画面 | 主画面 | ストアにロケールを追加 |

## 機能種別

設定管理

## 入力仕様

### 入力パラメータ

#### ストア設定更新

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| default_sales_channel_id | string | No | デフォルト販売チャネルID | 有効なIDまたはnull |
| default_region_id | string | No | デフォルト地域ID | 有効なIDまたはnull |
| default_location_id | string | No | デフォルトロケーションID | 有効なIDまたはnull |
| supported_currencies | StoreCurrencyInput[] | No | サポート通貨リスト | - |
| supported_locales | StoreLocaleInput[] | No | サポートロケールリスト | - |

#### StoreCurrencyInput

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| currency_code | string | Yes | 通貨コード | 小文字に正規化 |
| is_default | boolean | No | デフォルト通貨フラグ | 1つのみtrue可能 |
| is_tax_inclusive | boolean | No | 税込価格フラグ | - |

#### StoreLocaleInput

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| locale_code | string | Yes | ロケールコード（BCP 47形式） | 重複なし |

### 入力データソース

- Admin API HTTPリクエスト（ストア更新API）

## 出力仕様

### 出力データ

設定更新後のストア情報が返却される。

| 項目名 | 型 | 説明 |
|--------|-----|------|
| default_sales_channel_id | string | null | デフォルト販売チャネルID |
| default_region_id | string | null | デフォルト地域ID |
| default_location_id | string | null | デフォルトロケーションID |
| supported_currencies | StoreCurrencyDTO[] | サポート通貨リスト |
| supported_locales | StoreLocaleDTO[] | サポートロケールリスト |

### 出力先

- Admin API HTTPレスポンス（ストアCRUDの出力に含まれる）
- 価格優先設定テーブル（税込設定時）

## 処理フロー

### 処理シーケンス

```
1. 設定更新リクエスト受信
   └─ ストア更新APIの一部として実行

2. 入力正規化
   ├─ supported_currencies.currency_code小文字化
   └─ supported_locales正規化

3. バリデーション
   ├─ 通貨重複チェック
   ├─ デフォルト通貨チェック（1つ必須、複数禁止）
   └─ ロケール重複チェック

4. データベース更新
   ├─ store.default_*_id更新
   ├─ store_currency upsert（追加・更新・削除）
   └─ store_locale upsert（追加・更新・削除）

5. 価格優先設定更新（税込設定がある場合）
   └─ updatePricePreferencesAsArrayStep実行
```

### フローチャート

```mermaid
flowchart TD
    A[ストア更新リクエスト] --> B{設定項目の種別}
    B -->|デフォルトID設定| C[store.default_*_id更新]
    B -->|通貨設定| D[通貨バリデーション]
    B -->|ロケール設定| E[ロケールバリデーション]

    D --> F{バリデーションOK?}
    F -->|No| G[INVALID_DATAエラー]
    F -->|Yes| H[store_currency upsert]
    H --> I{is_tax_inclusive設定あり?}
    I -->|Yes| J[価格優先設定更新]
    I -->|No| K[完了]
    J --> K

    E --> L{バリデーションOK?}
    L -->|No| G
    L -->|Yes| M[store_locale upsert]
    M --> K

    C --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-69-01 | デフォルトID任意設定 | default_*_idはnull設定可能（未設定状態） | 設定更新時 |
| BR-69-02 | 税込設定の反映 | is_tax_inclusiveは価格優先設定テーブルに反映 | 通貨設定更新時 |
| BR-69-03 | 通貨置換 | supported_currencies更新時は既存を全置換 | 通貨設定更新時 |
| BR-69-04 | ロケール置換 | supported_locales更新時は既存を全置換 | ロケール設定更新時 |
| BR-69-05 | BCP 47形式 | ロケールコードはBCP 47形式（例: en-US）を推奨 | ロケール設定時 |

### 計算ロジック

**税込設定の価格優先設定反映**:
```typescript
// is_tax_inclusiveがあれば価格優先設定を更新
upsertPricePreferences = supported_currencies.map(currency => ({
  attribute: "currency_code",
  value: currency.currency_code,
  is_tax_inclusive: currency.is_tax_inclusive
}))
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| デフォルト設定 | store | UPDATE | default_*_idの更新 |
| 通貨設定 | store_currency | UPSERT | 全置換（削除→作成） |
| ロケール設定 | store_locale | UPSERT | 全置換（削除→作成） |
| 税込設定 | price_preference | UPSERT | 通貨ごとのis_tax_inclusive |

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

#### store

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | default_sales_channel_id | 入力値またはnull | - |
| UPDATE | default_region_id | 入力値またはnull | - |
| UPDATE | default_location_id | 入力値またはnull | - |

#### store_currency

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPSERT | currency_code | 入力値（小文字化） | - |
| UPSERT | is_default | 入力値 | - |
| UPSERT | store_id | ストアID | 外部キー |

#### price_preference

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPSERT | attribute | "currency_code" | 固定値 |
| UPSERT | value | 通貨コード | - |
| UPSERT | is_tax_inclusive | 入力値 | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| INVALID_DATA | MedusaError | 通貨コード重複 | 400レスポンス |
| INVALID_DATA | MedusaError | デフォルト通貨が複数 | 400レスポンス |
| INVALID_DATA | MedusaError | デフォルト通貨が0個（通貨設定時） | 400レスポンス |
| INVALID_DATA | MedusaError | ロケールコード重複 | 400レスポンス |

### リトライ仕様

ワークフローエンジンによるリトライ管理。

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

- ストア設定更新はワークフロー内でトランザクション管理
- upsertWithReplaceでストア・通貨・ロケールを一括更新
- 価格優先設定更新は別ステップで実行

## パフォーマンス要件

- 設定更新は即座に反映
- upsertWithReplaceで効率的な全置換

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

- 認証必須エンドポイント
- 設定変更は管理者権限が必要

## 備考

- デフォルト設定はシステム全体で参照される重要な設定
- 税込設定は価格計算に影響するため、設定変更時は注意が必要
- ロケール設定は翻訳機能と連携

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | store.ts | `packages/modules/store/src/models/store.ts` | Storeモデルのdefault_*_idフィールド |
| 1-2 | currency.ts | `packages/modules/store/src/models/currency.ts` | StoreCurrencyモデルのis_defaultフィールド |
| 1-3 | locale.ts | `packages/modules/store/src/models/locale.ts` | StoreLocaleモデルのlocale_codeフィールド |

**読解のコツ**: default_*_idは外部モジュールへの参照。supported_currenciesとsupported_localesはストアに紐づく設定データ。

#### Step 2: ワークフローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | update-stores.ts | `packages/core/core-flows/src/store/workflows/update-stores.ts` | 更新ワークフローの税込設定処理 |

**主要処理フロー**:
1. **47-66行目**: 入力正規化（supported_currenciesの処理）
2. **68行目**: updateStoresStep実行
3. **70-84行目**: is_tax_inclusiveがあれば価格優先設定を更新

#### Step 3: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | store-module-service.ts | `packages/modules/store/src/services/store-module-service.ts` | validateCreateRequest、normalizeInput |

**主要処理フロー**:
- **225-263行目**: validateCreateRequest - 通貨・ロケールバリデーション
- **90-95行目**: upsertWithReplace - リレーション含めた更新

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

```
updateStoresWorkflow
    │
    ├─ transform (normalizedInput)
    │      └─ supported_currencies.map (currency_code, is_default抽出)
    │
    ├─ updateStoresStep
    │      └─ storeService.update_
    │             ├─ normalizeInput
    │             ├─ validateUpdateRequest
    │             └─ upsertWithReplace
    │
    └─ when (is_tax_inclusive設定あり)
           └─ updatePricePreferencesAsArrayStep
                  └─ pricingService.updatePricePreferences
```

### データフロー図

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

supported_currencies ───▶ normalizeInput ───────────▶ store_currency
  ├─ currency_code              │
  ├─ is_default                 ▼
  └─ is_tax_inclusive    validateCreateRequest
                                │
                                ▼
                         upsertWithReplace
                                │
                         ┌──────┴──────┐
                         ▼             ▼
                   store_currency   price_preference
                   テーブル更新      テーブル更新
                                   (is_tax_inclusive)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| store.ts | `packages/modules/store/src/models/store.ts` | ソース | Storeモデル（default_*_id） |
| currency.ts | `packages/modules/store/src/models/currency.ts` | ソース | StoreCurrencyモデル |
| locale.ts | `packages/modules/store/src/models/locale.ts` | ソース | StoreLocaleモデル |
| store-module-service.ts | `packages/modules/store/src/services/store-module-service.ts` | ソース | バリデーション、更新処理 |
| update-stores.ts | `packages/core/core-flows/src/store/workflows/update-stores.ts` | ソース | 更新ワークフロー |
