building-with-medusa について
building-with-medusaは、Medusaバックエンド開発者向けのスキルです。アーキテクチャ、型安全性、ビジネスロジック、データアクセスを扱い、作業別の参考ファイルと実装確認手順を示します。
主な機能
- 016分野にわたるバックエンド開発指針
- 02アーキテクチャとレイヤー構成の規約
- 03型安全性とデータアクセスのルール
- 04作業に応じた参考ファイルの案内
- 05ビルドとlintによる検証手順
活用シーン
- 01Medusaのカスタムモジュール作成
- 02変更ワークフローやAPIルートの実装
- 03モジュール間の関連データの検索
- 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.mdauthentication.mdcustom-modules.mddata-models.mderror-handling.mdfrontend-integration.mdmodule-links.mdquerying-data.mdscheduled-jobs.mdsubscribers-and-events.mdtroubleshooting.mdworkflow-hooks.mdworkflows.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
ビルドエラーへの対処
ビルドに失敗した場合:
- エラーメッセージを注意深く読みます
- 型エラー、インポートの問題、構文エラーを修正します
- 修正を確認するため、再度ビルドを実行します
- ビルドが成功するまで、実装を完了として報告しないでください
よくあるビルドエラー:
- インポートまたはエクスポートの不足
- 型の不一致(例:
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. 管理ダッシュボードにアクセスする
ブラウザーを開き、以下にアクセスします。
- 管理ダッシュボード: http://localhost:9000/app
管理者の認証情報でログインし、管理画面に関連する機能をテストします。
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 ダッシュボードの場合:
- バックエンド(このスキル): モジュール → ワークフロー → API ルート
- フロントエンド:
building-admin-dashboard-customizationsスキルを読み込みます - 接続:
- 組み込みエンドポイント:既存の SDK メソッド(
sdk.admin.product.list())を使用します - カスタム API ルート:
sdk.client.fetch("/admin/my-route")を使用します - 通常の fetch() は絶対に使用しないでください - 認証ヘッダーがないとエラーが発生します
- 組み込みエンドポイント:既存の SDK メソッド(
ストアフロントの場合:
- バックエンド(このスキル): モジュール → ワークフロー → API ルート
- フロントエンド:
building-storefrontsスキルを読み込みます - 接続:
- 組み込みエンドポイント:既存の SDK メソッド(
sdk.store.product.list())を使用します - カスタム API ルート:
sdk.client.fetch("/store/my-route")を使用します - 通常の fetch() は絶対に使用しないでください - 公開可能な API キーがないとエラーが発生します
- 組み込みエンドポイント:既存の SDK メソッド(
SDK が必要な理由:
- Store ルートでは
x-publishable-api-keyヘッダーが必要です - Admin ルートでは
Authorizationヘッダーとセッションヘッダーが必要です - SDK は必要なヘッダーをすべて自動的に処理します
- ヘッダーなしで通常の fetch() を使用すると、認証/認可エラーが発生します
統合パターンの詳細については、それぞれのフロントエンドスキルを参照してください。