mcpField
B
building-with-medusa

building-with-medusa

github.com/medusajs開発2344.6k 回インストール1 週間前に更新
リポジトリ

building-with-medusa について

building-with-medusaは、Medusaバックエンド開発者向けのスキルです。アーキテクチャ、型安全性、ビジネスロジック、データアクセスを扱い、作業別の参考ファイルと実装確認手順を示します。

主な機能

  1. 016分野にわたるバックエンド開発指針
  2. 02アーキテクチャとレイヤー構成の規約
  3. 03型安全性とデータアクセスのルール
  4. 04作業に応じた参考ファイルの案内
  5. 05ビルドとlintによる検証手順

活用シーン

  1. 01Medusaのカスタムモジュール作成
  2. 02変更ワークフローやAPIルートの実装
  3. 03モジュール間の関連データの検索
  4. 04バックエンドコードの一般的な問題の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/medusajs/medusa-agent-skills --skill building-with-medusa

インストール後、Claude Code で/building-with-medusaを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

reference/
api-routes.md
authentication.md
custom-modules.md
data-models.md
error-handling.md
frontend-integration.md
module-links.md
querying-data.md
scheduled-jobs.md
subscribers-and-events.md
troubleshooting.md
workflow-hooks.md
workflows.md

詳細

Medusa バックエンド開発

Medusa アプリケーション向けの包括的なバックエンド開発ガイドです。アーキテクチャ、型安全性、ビジネスロジックの配置、よくある落とし穴を扱う6つのカテゴリにわたるパターンを紹介します。

適用する場面

以下を含む、あらゆるバックエンド開発タスクでこのスキルを読み込んでください:

  • カスタムモジュールやデータモデルの作成または変更
  • ミューテーション用ワークフローの実装
  • API ルート(ストアまたは管理者向け)の構築
  • エンティティ間のモジュールリンクの定義
  • ビジネスロジックやバリデーションの記述
  • モジュール間のデータのクエリ
  • 認証/認可の実装

次の場合も、これらのスキルを読み込んでください:

  • building-admin-dashboard-customizations: 管理 UI(ウィジェット、ページ、フォーム)の構築
  • building-storefronts: ストアフロントからバックエンド API ルートを呼び出す場合(SDK 統合)

重要:必要に応じてリファレンスファイルを読み込む

以下のクイックリファレンスだけでは実装に不十分です。 コードを書く前に、そのコンポーネントに関連するリファレンスファイルを必ず読み込んでください。

実装内容に応じて、以下のリファレンスを読み込んでください:

  • モジュールを作成する場合? → まず reference/custom-modules.md を必ず読み込んでください
  • ワークフローを作成する場合? → まず reference/workflows.md を必ず読み込んでください
  • API ルートを作成する場合? → まず reference/api-routes.md を必ず読み込んでください
  • モジュールリンクを作成する場合? → まず reference/module-links.md を必ず読み込んでください
  • データをクエリする場合? → まず reference/querying-data.md を必ず読み込んでください
  • 認証を追加する場合? → まず reference/authentication.md を必ず読み込んでください

最低要件: 実装前に、具体的なタスクに関連するリファレンスファイルを少なくとも1~2個読み込んでください。

重要なアーキテクチャパターン

必ず次のフローに従ってください。レイヤーを迂回してはいけません:

Module (data models + CRUD operations)
  ↓ used by
Workflow (business logic + mutations with rollback)
  ↓ executed by
API Route (HTTP interface, validation middleware)
  ↓ called by
Frontend (admin dashboard/storefront via SDK)

主な規約:

  • GET、POST、DELETE メソッドのみを使用します(PUT/PATCH は使用しません)
  • すべてのミューテーションでワークフローが必須です
  • ビジネスロジックはルートではなく、ワークフローのステップに記述します
  • モジュール間のデータ取得には query.graph() を使ってクエリします
  • リンクを持つ別々のモジュール間のフィルタリングには、Index Module の query.index() を使ってクエリします
  • モジュールリンクによってモジュール間の分離を維持します

優先度別のルールカテゴリ

優先度カテゴリ影響プレフィックス
1アーキテクチャ違反重大arch-
2型安全性重大type-
3ビジネスロジックの配置高logic-
4インポートとコードの整理高import-
5データアクセスパターン中(重大な価格ルールを含む)data-
6ファイルの整理中file-

クイックリファレンス

1. アーキテクチャ違反(重大)
  • arch-workflow-required - すべてのミューテーションにワークフローを使用し、ルートからモジュールサービスを直接呼び出さないでください
  • arch-layer-bypass - レイヤーを迂回しないでください(ワークフローを介さず、ルートからサービスを呼び出すなど)
  • arch-http-methods - GET、POST、DELETE のみを使用してください(PUT/PATCH は使用しません)
  • arch-module-isolation - モジュール間でサービスを直接呼び出さず、モジュールリンクを使用してください
  • arch-query-config-fields - req.queryConfig を使用する場合、fields を明示的に設定しないでください
2. 型安全性(重大)
  • type-request-schema - req.validatedBody を使用する場合、Zod から推論した型を MedusaRequest<T> に渡してください
  • type-authenticated-request - 保護されたルートでは MedusaRequest ではなく AuthenticatedMedusaRequest を使用してください
  • type-export-schema - ミドルウェアから Zod スキーマと推論した型の両方をエクスポートしてください
  • type-linkable-auto - データモデルに .linkable() を追加しないでください(自動的に追加されます)
  • type-module-name-camelcase - モジュール名は必ず camelCase にしてください。ハイフンは使用しないでください(実行時エラーの原因になります)
3. ビジネスロジックの配置(高)
  • logic-workflow-validation - ビジネスバリデーションは API ルートではなく、ワークフローのステップに記述してください
  • logic-ownership-checks - 所有権/権限の検証はルートではなく、ワークフローで行ってください
  • logic-module-service - モジュールはシンプルに保ち(CRUD のみ)、ロジックはワークフローに記述してください
4. インポートとコードの構成(高)
  • import-top-level - ワークフロー/モジュールはファイルの先頭でインポートし、ルートの本文で await import() を使わないでください
  • import-static-only - すべての依存関係に静的インポートを使用してください
  • import-no-dynamic-routes - 動的インポートはオーバーヘッドを増やし、型チェックを妨げます
  • import-zod-framework - Zod は @medusajs/framework/zod からインポートし、zod から直接インポートしないでください。Medusa は v2.14.0 以降 Zod v4 を使用しています。z.string().email() などの代わりに z.email()/z.url()/z.uuid() を、.merge(other) の代わりに .extend(other.shape) を、.strict()/.passthrough() の代わりに z.strictObject()/z.looseObject() を、z.nativeEnum() の代わりに z.enum(MyEnum) を、z.record(value) の代わりに z.record(z.string(), value) を使用してください
5. データアクセスのパターン(中)
  • data-price-format - 重要:Medusa では価格はそのまま保存されます(49.99 は 49.99 として保存され、セント単位にはなりません)。保存時に 100 を掛けたり、表示時に 100 で割ったりしないでください
  • data-query-method - データの取得には query.graph() を使用してください。リンクされたモジュールをまたいでフィルタリングするには query.index()(Index Module)を使用してください
  • data-query-graph - モジュールをまたぐクエリには、ドット記法を使って(モジュールをまたぐフィルタリングをせずに)query.graph() を使用してください
  • data-query-index - 別々のモジュールにあるリンク済みデータモデルのプロパティでフィルタリングする場合は、query.index() を使用してください
  • data-list-and-count - 単一モジュールのページネーション付きクエリには listAndCount を使用してください
  • data-linked-filtering - query.graph() ではリンクされたモジュールのフィールドでフィルタリングできません。query.index() を使用するか、そのエンティティを直接クエリしてください
  • data-no-js-filter - リンクされたデータに JavaScript の .filter() を使用しないでください。データベースフィルター(query.index() またはエンティティのクエリ)を使用してください
  • data-same-module-ok - query.graph() では同じモジュール内のリレーションでフィルタリングできます(例:product.variants)
  • data-auth-middleware - authenticate ミドルウェアを信頼し、req.auth_context を手動で確認しないでください
6. ファイル構成(中)
  • file-workflow-steps - 推奨:ステップは src/workflows/steps/[name].ts に作成してください
  • file-workflow-composition - 合成関数は src/workflows/[name].ts に配置してください
  • file-middleware-exports - ミドルウェアファイルからスキーマと型をエクスポートしてください
  • file-links-directory - モジュールリンクは src/links/[name].ts で定義してください

ワークフロー合成のルール

ワークフロー関数には重要な制約があります:

// ✅ CORRECT
const myWorkflow = createWorkflow(
  "name",
  function (input) { // Regular function, not async, not arrow
    const result = myStep(input) // No await
    return new WorkflowResponse(result)
  }
)

// ❌ WRONG
const myWorkflow = createWorkflow(
  "name",
  async (input) => { // ❌ No async, no arrow functions
    const result = await myStep(input) // ❌ No await
    if (input.condition) { /* ... */ } // ❌ No conditionals
    return new WorkflowResponse(result)
  }
)

制約:

  • async/await は使用できません(ロード時に実行されます)
  • アロー関数は使用できません(function を使用してください)
  • 条件式/三項演算子は使用できません(when() を使用してください)
  • 変数の操作はできません(transform() を使用してください)
  • 日付の作成はできません(transform() を使用してください)
  • ステップ呼び出しが複数ある場合は、競合を避けるため .config({ name: "unique-name" }) が必要です

よくある間違いのチェックリスト

実装を始める前に、以下の項目に該当していないことを確認してください。

アーキテクチャ:

  • API ルートからモジュールサービスを直接呼び出している
  • PUT または PATCH メソッドを使用している
  • ミューテーションでワークフローを経由していない
  • req.queryConfig で fields を明示的に設定している
  • モジュールリンクの作成後にマイグレーションを実行していない

型安全性:

  • MedusaRequest<SchemaType> の型引数を指定していない
  • 保護されたルートで AuthenticatedMedusaRequest ではなく MedusaRequest を使用している
  • ミドルウェアから Zod の推論型をエクスポートしていない
  • データモデルに .linkable() を追加している
  • モジュール名にハイフンを使用している(キャメルケースにする必要があります)

ビジネスロジック:

  • API ルートでビジネスルールを検証している
  • ワークフローではなくルートで所有権を確認している
  • ミドルウェアがすでに適用されているのに、req.auth_context?.actor_id を手動で確認している

インポート:

  • ルートハンドラーの本体で await import() を使用している
  • ワークフローまたはモジュールを動的にインポートしている

データアクセス:

  • 重要: 保存時に価格に100を掛けたり、表示時に100で割ったりしている(価格はそのまま保存されます:$49.99 = 49.99)
  • query.graph() でリンク先モジュールのフィールドを使って絞り込んでいる(代わりに query.index() を使うか、反対側からクエリしてください)
  • リンクされたデータに JavaScript の .filter() を使用している(代わりに query.index() を使うか、リンク先エンティティに直接クエリしてください)
  • モジュール間のデータ取得に query.graph() を使用していない
  • 別々のモジュールをまたいで絞り込む必要があるときに query.graph() を使用している(代わりに query.index() を使用してください)

実装の検証

重要:型エラーや実行時の問題を検出するため、実装が完了したら必ずビルドコマンドを実行してください。

検証するタイミング
  • 新機能を実装した後
  • モジュール、ワークフロー、API ルートを変更した後
  • タスクを完了として報告する前
  • ユーザーから依頼されるのを待たず、事前に
ビルドの実行方法

パッケージマネージャーを判別し、適切なコマンドを実行します。

npm run build      # or pnpm build / yarn build
ビルドエラーへの対処

ビルドに失敗した場合:

  1. エラーメッセージを注意深く読みます
  2. 型エラー、インポートの問題、構文エラーを修正します
  3. 修正を確認するため、再度ビルドを実行します
  4. ビルドが成功するまで、実装を完了として報告しないでください

よくあるビルドエラー:

  • インポートまたはエクスポートの不足
  • 型の不一致(例:MedusaRequest<T> の型引数が不足)
  • ワークフローの構成ミス(非同期関数、条件分岐)
リント

Medusa v2.16.0 以降、プロジェクトに @medusajs/eslint-plugin をインストールすると、型チェックでは検出できない Medusa の規約違反(API ルート、サブスクライバー、スケジュールされたジョブ、管理画面のカスタマイズ、モジュールのパターン)を検出できます。

  • プロジェクトに @medusajs/eslint-plugin を含む eslint.config.* がある場合、medusa build と medusa develop はデフォルトでリントを実行し、リントエラーがあると失敗します。--no-lint を指定するのではなく、リントエラーを修正してください。
  • npx medusa lint で明示的にリントを実行できます(--fix と --quiet に対応)。機能の実装後、ビルドと併せて実行してください。
  • プロジェクトに ESLint の設定がない場合は、追加するよう提案してください(開発依存関係として @medusajs/eslint-plugin、eslint、jiti を追加し、defineConfig([...medusa.configs.recommended]) をエクスポートする eslint.config.ts を用意します)。ただし、依頼されていないのに追加しないでください。

次のステップ - 実装のテスト

機能の実装に成功した後は、必ずユーザーに以下の次のステップを案内してください。

1. 開発サーバーを起動する

サーバーがすでに実行されていない場合は、起動します。

npm run dev      # or pnpm dev / yarn dev
2. 管理ダッシュボードにアクセスする

ブラウザーを開き、以下にアクセスします。

管理者の認証情報でログインし、管理画面に関連する機能をテストします。

3. API ルートをテストする

カスタム API ルートを実装した場合は、ユーザーがテストできるように一覧を記載します。

Admin ルート(認証が必要):

  • POST http://localhost:9000/admin/[your-route] - 実行内容の説明
  • GET http://localhost:9000/admin/[your-route] - 実行内容の説明

Store ルート(公開、または顧客認証が必要):

  • POST http://localhost:9000/store/[your-route] - 実行内容の説明
  • GET http://localhost:9000/store/[your-route] - 実行内容の説明

cURL を使ったテスト例:

# Admin route (requires authentication)
curl -X POST http://localhost:9000/admin/reviews/123/approve \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  --cookie "connect.sid=YOUR_SESSION_COOKIE"

# Store route
curl -X POST http://localhost:9000/store/reviews \
  -H "Content-Type: application/json" \
  -d '{"product_id": "prod_123", "rating": 5, "comment": "Great product!"}'
4. 追加のテスト手順

実装した内容に応じて、以下を記載します。

  • ワークフロー: ミューテーション操作をテストし、エラー時にロールバックされることを確認します
  • サブスクライバー: イベントを発生させ、サブスクライバーが実行されたことをログで確認します
  • スケジュール済みジョブ: ジョブの実行を待つか、cron の出力をログで確認します
次のステップを提示する形式

実装後は、次のステップを常に明確で実行可能な形式で提示します。

## Implementation Complete

The [feature name] has been successfully implemented. Here's how to test it:

### Start the Development Server
[server start command based on package manager]

### Access the Admin Dashboard
Open http://localhost:9000/app in your browser

### Test the API Routes
I've added the following routes:

**Admin Routes:**
- POST /admin/[route] - [description]
- GET /admin/[route] - [description]

**Store Routes:**
- POST /store/[route] - [description]

### What to Test
1. [Specific test case 1]
2. [Specific test case 2]
3. [Specific test case 3]

使用方法

詳しいパターンと例については、参照ファイルを読み込みます。

reference/custom-modules.md    - Creating modules with data models
reference/workflows.md          - Workflow creation and step patterns
reference/api-routes.md         - API route structure and validation
reference/module-links.md       - Linking entities across modules
reference/querying-data.md      - Query patterns and filtering rules
reference/authentication.md     - Protecting routes and accessing users
reference/error-handling.md     - MedusaError types and patterns
reference/scheduled-jobs.md     - Cron jobs and periodic tasks
reference/subscribers-and-events.md - Event handling
reference/troubleshooting.md    - Common errors and solutions

各参照ファイルには、以下が含まれています。

  • 実装のチェックリスト(手順ごと)
  • 正しいコード例と誤ったコード例
  • TypeScript のパターンと型安全性
  • よくある落とし穴と解決策

このスキルと MedusaDocs MCP サーバーの使い分け

⚠️ 重要:計画と実装では、まずこのスキルを参照してください。

このスキルを使用する場面(主な情報源):

  • 計画 - Medusa のバックエンド機能をどのように構成するかを理解する
  • アーキテクチャ - モジュール → ワークフロー → API ルートのパターン
  • ベストプラクティス - 正しいコードパターンと誤ったコードパターン
  • 重要なルール - やってはいけないこと(よくある間違いやアンチパターン)
  • 実装パターン - チェックリスト付きの手順ガイド

MedusaDocs MCP サーバーを使用する場面(二次情報源):

  • 使用するメソッドがわかった後で、特定のメソッドシグネチャを確認する
  • 組み込みモジュールの設定オプションを確認する
  • 公式の型定義を確認する
  • フレームワークレベルの設定詳細を確認する

スキルを先に使う理由:

  • スキルには、MCP にない、明確な方針に基づくガイダンスやアンチパターンが含まれています
  • スキルでは、計画に必要なアーキテクチャパターンを確認できます
  • MCP は参考資料であり、スキルは具体的な指針を示します

フロントエンドアプリケーションとの統合

⚠️ 重要:フロントエンドアプリケーションでは、すべての API リクエストに Medusa JS SDK を必ず使用してください。

バックエンドとフロントエンドにまたがる機能を構築する場合:

Admin ダッシュボードの場合:

  1. バックエンド(このスキル): モジュール → ワークフロー → API ルート
  2. フロントエンド: building-admin-dashboard-customizations スキルを読み込みます
  3. 接続:
    • 組み込みエンドポイント:既存の SDK メソッド(sdk.admin.product.list())を使用します
    • カスタム API ルート:sdk.client.fetch("/admin/my-route") を使用します
    • 通常の fetch() は絶対に使用しないでください - 認証ヘッダーがないとエラーが発生します

ストアフロントの場合:

  1. バックエンド(このスキル): モジュール → ワークフロー → API ルート
  2. フロントエンド: building-storefronts スキルを読み込みます
  3. 接続:
    • 組み込みエンドポイント:既存の SDK メソッド(sdk.store.product.list())を使用します
    • カスタム API ルート:sdk.client.fetch("/store/my-route") を使用します
    • 通常の fetch() は絶対に使用しないでください - 公開可能な API キーがないとエラーが発生します

SDK が必要な理由:

  • Store ルートでは x-publishable-api-key ヘッダーが必要です
  • Admin ルートでは Authorization ヘッダーとセッションヘッダーが必要です
  • SDK は必要なヘッダーをすべて自動的に処理します
  • ヘッダーなしで通常の fetch() を使用すると、認証/認可エラーが発生します

統合パターンの詳細については、それぞれのフロントエンドスキルを参照してください。

コメント