# バッチ設計書 1-JobLoader

## 概要

本ドキュメントはMedusaフレームワークのJobLoader機能について、その設計内容を記述したバッチ設計書です。JobLoaderはcronスケジュールで定期実行されるジョブを登録・管理するフレームワーク機能であり、ワークフローとして登録することでスケジュール実行を実現します。

### 本バッチの処理概要

JobLoaderは、Medusaアプリケーション内でスケジュールジョブ（cronジョブ）を動的に読み込み、ワークフローとして登録・管理するためのフレームワーク機能です。

**業務上の目的・背景**：Eコマースプラットフォームでは、注文サマリーの集計、在庫の自動更新、レポート生成など、定期的に実行すべき処理が多数存在します。JobLoaderは、これらの定期処理を一元管理し、開発者が簡単にスケジュールジョブを追加・管理できる仕組みを提供します。プラグインやカスタム実装からも利用可能であり、拡張性の高いバッチ処理基盤を実現しています。

**バッチの実行タイミング**：アプリケーション起動時にジョブ定義ファイルを読み込み、ワークフローとして登録します。その後、各ジョブは定義されたcronスケジュールに従って自動的に実行されます。

**主要な処理内容**：
1. 指定されたソースディレクトリからジョブ定義ファイルを再帰的に探索
2. 各ジョブファイルの設定（config）とハンドラ（default export）を検証
3. ジョブをワークフローとしてMedusaのワークフローエンジンに登録
4. 開発サーバーリソースとして登録（HMR対応）

**前後の処理との関連**：JobLoaderはアプリケーション起動時のローダー処理の一部として実行されます。依存関係としてMedusaContainer（DIコンテナ）が必要であり、登録されたジョブはMedusaのワークフローエンジンによってスケジュール管理されます。

**影響範囲**：JobLoaderで登録されたジョブは、アプリケーション全体で利用可能となり、データベースへのアクセス、外部API呼び出し、通知送信など、様々な処理を定期実行できます。

## バッチ種別

フレームワーク機能 / ジョブローダー

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | アプリケーション起動時（1回） |
| 実行時刻 | 起動時 |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | アプリケーション起動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| MedusaContainerの初期化 | DIコンテナが初期化済みであること |
| ソースディレクトリの存在 | ジョブ定義ファイルを配置するディレクトリが存在すること |

### 実行可否判定

- ソースディレクトリが存在しない場合はスキップ（エラーではない）
- `isFileSkipped`による除外判定を通過したファイルのみ処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| sourceDir | string \| string[] | Yes | - | ジョブ定義ファイルを探索するディレクトリパス |
| container | MedusaContainer | Yes | - | Medusaの依存性注入コンテナ |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| ジョブ定義ファイル | TypeScript/JavaScript | `jobs/`ディレクトリ配下のファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| ワークフローエンジン | ワークフロー登録 | cronスケジュール付きワークフローとして登録 |
| 開発サーバーリソース | メモリ | HMR対応のためのリソース登録 |

### 出力ファイル仕様

ファイル出力なし（メモリ上での登録のみ）

## 処理フロー

### 処理シーケンス

```
1. load()メソッド呼び出し
   └─ discoverResources()でソースディレクトリを走査
2. 各ファイルに対してloadFile()を実行
   └─ dynamicImportでファイルを読み込み
3. onFileLoaded()で設定を検証
   └─ isFileSkippedチェック
   └─ validateConfig()で必須項目チェック
4. register()でワークフロー登録
   └─ createStepでステップ定義
   └─ createWorkflowでワークフロー作成
   └─ registerDevServerResourceで開発サーバー登録
```

### フローチャート

```mermaid
flowchart TD
    A[load開始] --> B[discoverResources]
    B --> C{ソースディレクトリ存在?}
    C -->|あり| D[ファイル一覧取得]
    C -->|なし| E[スキップ]
    D --> F[各ファイルをループ]
    F --> G[dynamicImport]
    G --> H{isFileSkipped?}
    H -->|Yes| F
    H -->|No| I[validateConfig]
    I --> J{設定有効?}
    J -->|No| K[MedusaError]
    J -->|Yes| L[register]
    L --> M[createStep]
    M --> N[createWorkflow]
    N --> O[registerDevServerResource]
    O --> F
    F --> P[load完了]
    E --> P
```

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

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

JobLoader自体はデータベース操作を行いません。登録されたジョブ内で実行される処理によってデータベース操作が発生する可能性があります。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| INVALID_ARGUMENT | MedusaError | configがnull/undefined | ジョブファイルにconfigをexportする |
| INVALID_ARGUMENT | MedusaError | scheduleが未定義 | config.scheduleを定義する |
| INVALID_ARGUMENT | MedusaError | nameが未定義 | config.nameを定義する |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（ローダーレベル） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

- ジョブ登録失敗時はエラーログを出力し、該当ジョブのみスキップ
- アプリケーション起動は継続される

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | なし（メモリ操作のみ） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 数十ファイル程度 |
| 目標処理時間 | 数秒以内 |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

アプリケーション起動時の1回のみ実行されるため、排他制御は不要です。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| デバッグログ | ジョブ登録時 | `Registering job from ${path}.` |
| デバッグログ | 読み込み完了時 | `Jobs registered.` |
| エラーログ | ジョブ実行失敗時 | `Scheduled job ${name} failed with error: ${message}` |
| 情報ログ | ディレクトリ不在時 | `No job to load from ${sourcePath}. skipped.` |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| ジョブ登録エラー | 発生時 | アプリケーションログ |
| ジョブ実行エラー | 発生時 | アプリケーションログ |

## 備考

- ジョブ定義ファイルは`config`オブジェクトと`default`関数をexportする必要があります
- CronJobConfig:
  - `name`: ジョブ名（必須）
  - `schedule`: cron式またはSchedulerOptionsオブジェクト（必須）
  - `numberOfExecutions`: 実行回数制限（オプション）
- ワークフロー名は`job-${config.name}`の形式で生成されます
