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

## はじめに

このガイドラインは、Medusaのコードベースを効率的に理解するための手引きです。
TypeScriptに精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- 他言語からの経験者
- コードレビューを行う担当者

---

## 1. 言語基礎

> このセクションでは、TypeScriptの基本構文と概念を解説します。

### 1.1 プログラム構造

TypeScriptはJavaScriptの上位互換言語で、静的型付けをサポートしています。Medusaプロジェクトでは、ES2021をターゲットとしたモダンなTypeScriptが使用されています。

**基本的なファイル構造:**
```typescript
// ファイル: packages/core/core-flows/src/promotion/steps/delete-promotions.ts:1-10
import type { IPromotionModuleService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
import { StepResponse, createStep } from "@medusajs/framework/workflows-sdk"

/**
 * The IDs of the promotions to delete.
 */
export type DeletePromotionsStepInput = string[]

export const deletePromotionsStepId = "delete-promotions"
```

### 1.2 データ型と変数

TypeScriptでは型を明示的に宣言します。

**基本的な型宣言:**
```typescript
// 文字列型
const stepId: string = "delete-promotions"

// 数値型
const version: number = 1

// 配列型
const ids: string[] = ["id1", "id2"]

// オブジェクト型（インターフェース）
interface InjectedDependencies {
  baseRepository: DAL.RepositoryService
  orderService: OrderService
}
```

**ファイル: packages/modules/order/src/services/order-module-service.ts:94-116**
```typescript
type InjectedDependencies = {
  baseRepository: DAL.RepositoryService
  orderService: OrderService
  orderAddressService: ModulesSdkTypes.IMedusaInternalService<any>
  orderLineItemService: ModulesSdkTypes.IMedusaInternalService<any>
  // ... 他の依存関係
}
```

### 1.3 制御構造

条件分岐とループの基本パターンです。

**条件分岐:**
```typescript
// ファイル: packages/core/core-flows/src/order/workflows/update-order.ts:76-96
if (
  input.shipping_address?.country_code &&
  order.shipping_address?.country_code !==
    input.shipping_address?.country_code
) {
  throw new MedusaError(
    MedusaError.Types.INVALID_DATA,
    "Country code cannot be changed"
  )
}
```

**オプショナルチェイニング（?.）:**
入れ子になったプロパティへの安全なアクセスを提供します。上記の例で`input.shipping_address?.country_code`は、`shipping_address`が存在する場合のみ`country_code`にアクセスします。

### 1.4 関数/メソッド定義

TypeScriptでの関数定義パターンです。

**アロー関数:**
```typescript
// ファイル: packages/core/core-flows/src/promotion/steps/delete-promotions.ts:14-24
export const deletePromotionsStep = createStep(
  deletePromotionsStepId,
  async (ids: DeletePromotionsStepInput, { container }) => {
    const promotionModule = container.resolve<IPromotionModuleService>(
      Modules.PROMOTION
    )
    await promotionModule.softDeletePromotions(ids)
    return new StepResponse(void 0, ids)
  },
  // 補償関数（ロールバック用）
  async (idsToRestore, { container }) => {
    if (!idsToRestore?.length) {
      return
    }
    const promotionModule = container.resolve<IPromotionModuleService>(
      Modules.PROMOTION
    )
    await promotionModule.restorePromotions(idsToRestore)
  }
)
```

**クラスメソッド（デコレーター付き）:**
```typescript
// ファイル: packages/modules/api-key/src/services/api-key-module-service.ts:69-77
@InjectManager()
@EmitEvents()
async deleteApiKeys(
  ids: string | string[],
  @MedusaContext() sharedContext: Context = {}
) {
  return await this.deleteApiKeys_(ids, sharedContext)
}
```

### 1.5 モジュール/インポート

ESモジュールシステムを使用しています。

**インポートパターン:**
```typescript
// 型のみのインポート（type-only import）
import type { IPromotionModuleService } from "@medusajs/framework/types"

// 名前付きインポート
import { Modules, MedusaError } from "@medusajs/framework/utils"

// デフォルトインポート
import OrderService from "./order-service"

// パスエイリアスを使用したインポート
import { ApiKey } from "@models"
import { CreateApiKeyDTO } from "@types"
```

**パスエイリアス（tsconfig.jsonで設定）:**
- `@models` - エンティティモデル
- `@types` - DTO型定義
- `@services` - サービス依存関係
- `@repositories` - データアクセス層

---

## 2. プロジェクト固有の概念

> このセクションでは、Medusaプロジェクト特有の概念を解説します。

### 2.1 フレームワーク固有の概念

#### モジュール（Commerce Modules）

Medusaは30以上のコマースモジュールで構成されています。各モジュールは特定のドメイン機能を担当します。

```typescript
// モジュールの解決
import { Modules } from "@medusajs/framework/utils"

const promotionModule = container.resolve<IPromotionModuleService>(
  Modules.PROMOTION
)
```

**主要モジュール:**
- `Modules.ORDER` - 注文管理
- `Modules.PRODUCT` - 商品管理
- `Modules.CART` - カート管理
- `Modules.PAYMENT` - 決済処理
- `Modules.PROMOTION` - プロモーション

#### DIコンテナ（依存性注入）

Awilixライブラリを使用した依存性注入パターンです。

```typescript
// コンテナからサービスを解決
const paymentService: IPaymentModuleService = container.resolve(
  Modules.PAYMENT
)
```

### 2.2 プロジェクト独自のパターン

#### MedusaServiceパターン

モジュールサービスは`MedusaService`を継承して構築されます。

```typescript
// ファイル: packages/modules/api-key/src/services/api-key-module-service.ts:44-48
export class ApiKeyModuleService
  extends MedusaService<{
    ApiKey: { dto: ApiKeyTypes.ApiKeyDTO }
  }>({ ApiKey })
  implements IApiKeyModuleService
```

#### DMLモデル定義

Domain Modeling Language（DML）を使用してエンティティを定義します。

```typescript
// ファイル: packages/modules/product/src/models/product.ts:11-64
const Product = model
  .define("Product", {
    id: model.id({ prefix: "prod" }).primaryKey(),
    title: model.text().searchable().translatable(),
    handle: model.text(),
    subtitle: model.text().searchable().translatable().nullable(),
    description: model.text().searchable().translatable().nullable(),
    is_giftcard: model.boolean().default(false),
    status: model
      .enum(ProductUtils.ProductStatus)
      .default(ProductUtils.ProductStatus.DRAFT),
    // ... 他のフィールド
    variants: model.hasMany(() => ProductVariant, {
      mappedBy: "product",
    }),
  })
  .cascades({
    delete: ["variants", "options", "images"],
  })
  .indexes([
    {
      name: "IDX_product_handle_unique",
      on: ["handle"],
      unique: true,
      where: "deleted_at IS NULL",
    },
  ])
```

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| kebab-case.ts | 一般的なファイル名 | `order-module-service.ts` |
| route.ts | APIルートファイル | `packages/medusa/src/api/admin/orders/route.ts` |
| middlewares.ts | ミドルウェア定義 | `packages/medusa/src/api/admin/orders/middlewares.ts` |
| validators.ts | バリデーター定義 | `packages/medusa/src/api/admin/orders/validators.ts` |
| index.ts | バレルエクスポート | 各ディレクトリの`index.ts` |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| I〜 | インターフェース | `IOrderModuleService` |
| 〜Service | サービスクラス | `OrderModuleService` |
| 〜DTO | データ転送オブジェクト | `OrderDTO` |
| 〜Step | ワークフローステップ | `deletePromotionsStep` |
| 〜Workflow | ワークフロー | `deletePromotionsWorkflow` |
| 〜Module | モジュール識別子 | `Modules.ORDER` |
| Admin〜 | 管理者API関連 | `AdminGetOrdersParams` |
| Store〜 | ストアAPI関連 | `StoreCartRoutesMiddlewares` |
| 〜_ | 内部メソッド（protected） | `deleteApiKeys_` |

### 3.3 プログラム分類一覧

| 分類 | 配置場所 | 説明 |
|-----|---------|------|
| コマースモジュール | `packages/modules/*` | ドメイン固有のビジネスロジック |
| コアフレームワーク | `packages/core/framework` | フレームワーク基盤 |
| ワークフロー | `packages/core/core-flows` | ビジネスプロセスの定義 |
| APIルート | `packages/medusa/src/api` | HTTPエンドポイント |
| 型定義 | `packages/core/types` | TypeScript型定義 |
| ユーティリティ | `packages/core/utils` | 共通ユーティリティ |

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
/packages/
├── medusa/              # メインMedusaパッケージ
│   └── src/
│       ├── api/         # APIルート（admin/, store/, auth/）
│       ├── commands/    # CLIコマンド
│       ├── jobs/        # バックグラウンドジョブ
│       ├── loaders/     # アプリケーションローダー
│       ├── modules/     # 内部モジュール
│       ├── policies/    # 認可ポリシー
│       ├── subscribers/ # イベントサブスクライバー
│       ├── types/       # ローカル型定義
│       └── utils/       # ユーティリティ
├── core/                # コアフレームワークパッケージ
│   ├── framework/       # コアランタイム
│   ├── types/           # TypeScript定義
│   ├── utils/           # ユーティリティ
│   ├── workflows-sdk/   # ワークフロー構成
│   ├── core-flows/      # 事前定義ワークフロー
│   └── modules-sdk/     # モジュール開発
├── modules/             # 30以上のコマースモジュール
│   ├── product/         # 商品モジュール
│   ├── order/           # 注文モジュール
│   ├── cart/            # カートモジュール
│   ├── payment/         # 決済モジュール
│   └── providers/       # 15以上のプロバイダー実装
├── admin/               # ダッシュボードパッケージ
│   └── dashboard/       # React管理UI
├── cli/                 # CLIツール
└── design-system/       # UIコンポーネント
/integration-tests/      # フルスタックテスト
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| `packages/medusa/src/api/admin` | 管理者向けAPIエンドポイント | `route.ts`, `middlewares.ts`, `validators.ts` |
| `packages/medusa/src/api/store` | ストアフロント向けAPI | `route.ts`, `middlewares.ts` |
| `packages/core/core-flows/src` | 事前定義されたワークフロー | `*/steps/*.ts`, `*/workflows/*.ts` |
| `packages/modules/*/src/services` | モジュールサービス | `*-module-service.ts` |
| `packages/modules/*/src/models` | エンティティモデル | `*.ts` |
| `packages/core/types/src` | 型定義 | `http/*.ts`, `*.ts` |

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

Medusaは**モジュラーモノリス**アーキテクチャを採用しています。コマースモジュールは疎結合で、依存性注入を通じて統合されます。

```
┌─────────────────────────────────────────────────────────────┐
│                        HTTP Layer                           │
│            (API Routes, Middlewares, Validators)            │
├─────────────────────────────────────────────────────────────┤
│                     Workflow Layer                          │
│           (core-flows: Steps + Workflows)                   │
├─────────────────────────────────────────────────────────────┤
│                    Service Layer                            │
│     (Module Services: OrderModuleService, etc.)             │
├─────────────────────────────────────────────────────────────┤
│                     Model Layer                             │
│            (DML Models + MikroORM Entities)                 │
├─────────────────────────────────────────────────────────────┤
│                   Infrastructure                            │
│        (Database, Cache, Event Bus, File Storage)           │
└─────────────────────────────────────────────────────────────┘
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| HTTP | APIエンドポイント、リクエスト検証 | `packages/medusa/src/api/admin/orders/route.ts` |
| Workflow | ビジネスプロセスの構成、トランザクション管理 | `packages/core/core-flows/src/order/workflows/update-order.ts` |
| Service | ドメインロジック、CRUD操作 | `packages/modules/order/src/services/order-module-service.ts` |
| Model | データ構造定義、リレーション | `packages/modules/order/src/models/order.ts` |

### 5.3 データフロー

1. **リクエスト受信**: HTTPルートがリクエストを受信
2. **バリデーション**: Zodスキーマによる入力検証
3. **ワークフロー実行**: 複数ステップのビジネスロジック
4. **サービス呼び出し**: モジュールサービスでCRUD操作
5. **レスポンス返却**: 型付きレスポンスの返却

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

**APIルート（route.ts）:**
```typescript
// ファイル: packages/medusa/src/api/admin/orders/route.ts:1-38
import { getOrdersListWorkflow } from "@medusajs/core-flows"
import { HttpTypes, OrderDTO } from "@medusajs/framework/types"
import {
  AuthenticatedMedusaRequest,
  MedusaResponse,
} from "@medusajs/framework/http"

export const GET = async (
  req: AuthenticatedMedusaRequest<HttpTypes.AdminOrderFilters>,
  res: MedusaResponse<HttpTypes.AdminOrderListResponse>
) => {
  const variables = {
    filters: {
      ...req.filterableFields,
      is_draft_order: false,
    },
    ...req.queryConfig.pagination,
  }

  const workflow = getOrdersListWorkflow(req.scope)
  const { result } = await workflow.run({
    input: {
      fields: req.queryConfig.fields,
      variables,
    },
  })

  const { rows, metadata } = result as {
    rows: OrderDTO[]
    metadata: any
  }
  res.json({
    orders: rows as unknown as HttpTypes.AdminOrder[],
    count: metadata.count,
    offset: metadata.skip,
    limit: metadata.take,
  })
}
```

### 6.2 ビジネスロジック

**ワークフロー定義:**
```typescript
// ファイル: packages/core/core-flows/src/promotion/workflows/delete-promotions.ts:39-51
export const deletePromotionsWorkflow = createWorkflow(
  deletePromotionsWorkflowId,
  (input: WorkflowData<DeletePromotionsWorkflowInput>) => {
    const deletedPromotions = deletePromotionsStep(input.ids)
    const promotionsDeleted = createHook("promotionsDeleted", {
      ids: input.ids,
    })

    return new WorkflowResponse(deletedPromotions, {
      hooks: [promotionsDeleted],
    })
  }
)
```

**ステップ定義:**
```typescript
// ファイル: packages/core/core-flows/src/promotion/steps/delete-promotions.ts:14-36
export const deletePromotionsStep = createStep(
  deletePromotionsStepId,
  async (ids: DeletePromotionsStepInput, { container }) => {
    const promotionModule = container.resolve<IPromotionModuleService>(
      Modules.PROMOTION
    )
    await promotionModule.softDeletePromotions(ids)
    return new StepResponse(void 0, ids)
  },
  async (idsToRestore, { container }) => {
    if (!idsToRestore?.length) {
      return
    }
    const promotionModule = container.resolve<IPromotionModuleService>(
      Modules.PROMOTION
    )
    await promotionModule.restorePromotions(idsToRestore)
  }
)
```

### 6.3 データアクセス

**モジュールサービス:**
```typescript
// ファイル: packages/modules/api-key/src/services/api-key-module-service.ts:44-63
export class ApiKeyModuleService
  extends MedusaService<{
    ApiKey: { dto: ApiKeyTypes.ApiKeyDTO }
  }>({ ApiKey })
  implements IApiKeyModuleService
{
  protected baseRepository_: DAL.RepositoryService
  protected readonly apiKeyService_: ModulesSdkTypes.IMedusaInternalService<
    InferEntityType<typeof ApiKey>
  >

  constructor(
    { baseRepository, apiKeyService }: InjectedDependencies,
    protected readonly moduleDeclaration: InternalModuleDeclaration
  ) {
    super(...arguments)
    this.baseRepository_ = baseRepository
    this.apiKeyService_ = apiKeyService
  }
}
```

### 6.4 ユーティリティ/共通機能

**バリデーター（Zod）:**
```typescript
// ファイル: packages/medusa/src/api/admin/orders/validators.ts:44-64
const AdminGetOrdersParamsBase = createFindParams({
  limit: 15,
  offset: 0,
}).merge(
  z.object({
    id: z
      .union([z.string(), z.array(z.string()), createOperatorMap()])
      .optional(),
    status: z
      .union([z.string(), z.array(z.string()), createOperatorMap()])
      .optional(),
    name: z.union([z.string(), z.array(z.string())]).optional(),
    sales_channel_id: z.array(z.string()).optional(),
    region_id: z.union([z.string(), z.array(z.string())]).optional(),
    customer_id: z.union([z.string(), z.array(z.string())]).optional(),
    q: z.string().optional(),
    created_at: createOperatorMap().optional(),
    updated_at: createOperatorMap().optional(),
  })
)
```

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| デコレーターパターン | メソッドへの横断的関心事の注入 | 高 | `*-module-service.ts` |
| ワークフローパターン | 複数ステップのビジネスプロセス | 高 | `core-flows/src/*/workflows/*.ts` |
| ステップパターン | 補償可能な単一操作 | 高 | `core-flows/src/*/steps/*.ts` |
| リポジトリパターン | データアクセスの抽象化 | 中 | モジュールサービス内 |
| バリデーターパターン | Zodによる入力検証 | 高 | `validators.ts` |

### 各パターンの詳細

#### パターン1: デコレーターパターン

**目的:** トランザクション管理、イベント発行などの横断的関心事をメソッドに注入する。

**実装例:**
```typescript
// ファイル: packages/modules/api-key/src/services/api-key-module-service.ts:69-77
@InjectManager()
@EmitEvents()
async deleteApiKeys(
  ids: string | string[],
  @MedusaContext() sharedContext: Context = {}
) {
  return await this.deleteApiKeys_(ids, sharedContext)
}

@InjectTransactionManager()
protected async deleteApiKeys_(
  ids: string | string[],
  @MedusaContext() sharedContext: Context = {}
) {
  // トランザクション内での処理
}
```

**解説:**
- `@InjectManager()`: パブリックメソッドにエンティティマネージャーを注入
- `@InjectTransactionManager()`: protectedメソッドにトランザクションマネージャーを注入
- `@EmitEvents()`: 操作完了後にドメインイベントを発行
- `@MedusaContext()`: 共有コンテキストをパラメータとして注入

#### パターン2: ワークフロー + ステップパターン

**目的:** 複数の操作を組み合わせ、失敗時に自動ロールバックを行う。

**実装例:**
```typescript
// ファイル: packages/core/core-flows/src/order/workflows/update-order.ts:126-160
export const updateOrderWorkflow = createWorkflow(
  updateOrderWorkflowId,
  function (
    input: WorkflowData<OrderWorkflow.UpdateOrderWorkflowInput>
  ): WorkflowResponse<OrderPreviewDTO> {
    // 1. 既存注文のクエリ
    const orderQuery = useQueryGraphStep({
      entity: "order",
      fields: ["id", "status", "email", "locale", ...],
      filters: { id: input.id },
      options: { throwIfKeyNotFound: true },
    }).config({ name: "order-query" })

    // 2. データ変換
    const order = transform(
      { orderQuery },
      ({ orderQuery }) => orderQuery.data[0]
    )

    // 3. バリデーション
    updateOrderValidationStep({ order, input })

    // 4. 更新処理
    const updatedOrders = updateOrdersStep({
      selector: { id: input.id },
      update: updateInput,
    })

    // 5. イベント発行
    emitEventStep({
      eventName: OrderWorkflowEvents.UPDATED,
      data: { id: input.id },
    })

    return new WorkflowResponse(previewOrderChangeStep(input.id))
  }
)
```

**解説:**
- `createWorkflow`: ワークフローを定義
- `createStep`: 補償関数付きのステップを定義
- `transform`: データ変換
- `when`: 条件分岐
- `parallelize`: 並列実行

#### パターン3: エラーハンドリングパターン

**目的:** 一貫したエラー処理とユーザーフレンドリーなエラーメッセージ。

**実装例:**
```typescript
// ファイル: packages/core/core-flows/src/order/workflows/update-order.ts:81-84
if (
  input.shipping_address?.country_code &&
  order.shipping_address?.country_code !==
    input.shipping_address?.country_code
) {
  throw new MedusaError(
    MedusaError.Types.INVALID_DATA,
    "Country code cannot be changed"
  )
}
```

**主要なエラータイプ:**
- `MedusaError.Types.NOT_FOUND`: リソースが見つからない
- `MedusaError.Types.INVALID_DATA`: 不正な入力やステート
- `MedusaError.Types.NOT_ALLOWED`: 操作が許可されていない

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイントを特定（APIルートファイル）
2. 処理の流れを追跡（ワークフロー → ステップ → サービス）
3. データの変換を確認（transform関数、バリデーター）
4. 最終的な出力を確認（レスポンス型）

### 8.2 フロー追跡の実例

#### 例1: 注文更新フロー

**概要:** 管理者が注文情報（住所、メールなど）を更新するフロー

**処理フロー:**
```
API Route (route.ts) → Workflow (update-order.ts) → Steps → Service → Response
```

**詳細な追跡:**

1. **APIエンドポイント** (`packages/medusa/src/api/admin/orders/[id]/route.ts`)
   - HTTPメソッド: `POST /admin/orders/:id`
   - リクエストバリデーション: `AdminUpdateOrder`

2. **バリデーション** (`packages/medusa/src/api/admin/orders/validators.ts:159-166`)
   ```typescript
   export const AdminUpdateOrder = z.object({
     email: z.string().optional(),
     shipping_address: AddressPayload.optional(),
     billing_address: AddressPayload.optional(),
     locale: z.string().nullish(),
     metadata: z.record(z.unknown()).nullish(),
   })
   ```

3. **ワークフロー呼び出し** (`packages/core/core-flows/src/order/workflows/update-order.ts:126`)
   ```typescript
   export const updateOrderWorkflow = createWorkflow(
     updateOrderWorkflowId,
     function (input: WorkflowData<OrderWorkflow.UpdateOrderWorkflowInput>) {
       // 既存注文の取得
       const orderQuery = useQueryGraphStep({...})

       // バリデーション
       updateOrderValidationStep({ order, input })

       // 更新実行
       const updatedOrders = updateOrdersStep({...})

       // 変更履歴の登録
       registerOrderChangesStep(orderChangeInput)

       // イベント発行
       emitEventStep({
         eventName: OrderWorkflowEvents.UPDATED,
         data: { id: input.id },
       })

       return new WorkflowResponse(previewOrderChangeStep(input.id))
     }
   )
   ```

4. **サービス層での処理** (`packages/modules/order/src/services/order-module-service.ts`)
   - `updateOrders`メソッドが呼び出される
   - MikroORMを使用してデータベースを更新

5. **レスポンス**
   - 更新後の注文プレビューが返却される

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイント（route.ts）を特定したか
- [ ] バリデーター（validators.ts）を確認したか
- [ ] ワークフロー/ステップの流れを追跡したか
- [ ] 使用されているモジュールサービスを特定したか
- [ ] エラーハンドリングを確認したか
- [ ] イベント発行を確認したか
- [ ] 最終的なレスポンス型を確認したか

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. README.md
2. アーキテクチャ設計書
3. 機能一覧

#### 特定機能を理解したい場合
1. 機能一覧で対象機能を特定
2. 機能設計書で詳細確認
3. 対応するAPIルート（`packages/medusa/src/api/`）を確認
4. ワークフロー（`packages/core/core-flows/`）を追跡

#### 改修作業を行う場合
1. 対象機能の設計書
2. 影響範囲確認（モジュール間の依存関係）
3. テストケース一覧
4. 単体テストの実行方法確認

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| README.md | プロジェクト概要、セットアップ方法 | 初期参画時 |
| CLAUDE.md | 開発ガイドライン、コード規約 | 開発作業前 |
| 機能設計書 | 各機能の詳細仕様 | 機能理解時 |
| API設計書 | APIエンドポイント仕様 | API開発時 |
| データベース設計書 | エンティティ構造、リレーション | データモデル理解時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: デコレーターの動作がわからない
A: `@InjectManager()`や`@EmitEvents()`は`packages/core/utils/src/modules-sdk/decorators`で定義されています。メソッドをラップして追加機能を注入します。

#### Q: ワークフローとステップの違いは？
A: ステップは単一の操作単位で補償関数を持ちます。ワークフローは複数のステップを組み合わせてビジネスプロセスを構成します。

#### Q: モジュール間の連携方法は？
A: DIコンテナ（`container.resolve()`）を通じて他モジュールのサービスを取得します。直接のインポートは行いません。

#### Q: 型定義が見つからない
A: `packages/core/types/src`を確認してください。HTTPタイプは`http/`サブディレクトリにあります。

### デバッグのヒント

1. **ワークフローのデバッグ**
   - ワークフローIDをログ出力で追跡
   - `WorkflowManager`のデバッグモードを有効化

2. **サービスメソッドのデバッグ**
   - `@MedusaContext()`で渡されるコンテキストを確認
   - トランザクション境界を意識する

3. **APIルートのデバッグ**
   - `req.filterableFields`と`req.queryConfig`の内容を確認
   - ミドルウェアチェーンを追跡

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| DML | Domain Modeling Language。Medusa独自のモデル定義言語 |
| MikroORM | TypeScript ORMライブラリ。データベース操作に使用 |
| Workflow | 複数ステップで構成されるビジネスプロセス |
| Step | 補償関数を持つ単一操作の単位 |
| Module | 特定ドメインを担当する独立したパッケージ |
| Joiner | モジュール間のリレーションを定義する設定 |
| Soft Delete | 物理削除ではなくdeleted_atフラグで論理削除 |
| Context | トランザクションやメタデータを共有するオブジェクト |

### B. ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `packages/medusa/` | メインパッケージ | APIルート、ポリシー、サブスクライバー |
| `packages/core/core-flows/` | コアワークフロー | ステップ、ワークフロー定義 |
| `packages/core/framework/` | フレームワーク基盤 | HTTP、データベース、設定 |
| `packages/core/types/` | 型定義 | DTO、インターフェース |
| `packages/modules/*/` | コマースモジュール | サービス、モデル、リポジトリ |
| `integration-tests/` | 統合テスト | HTTP、API、モジュールテスト |

### C. 参考資料

- [Medusa公式ドキュメント](https://docs.medusajs.com)
- [Medusaアーキテクチャ概要](https://docs.medusajs.com/learn/advanced-development/architecture/overview)
- [コマースモジュールリファレンス](https://docs.medusajs.com/resources/commerce-modules)
- [TypeScript公式ドキュメント](https://www.typescriptlang.org/docs/)
- [MikroORM公式ドキュメント](https://mikro-orm.io/docs)
- [Zodバリデーションライブラリ](https://zod.dev/)
