@mercurjs/docs 2.2.0-canary.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/content/blocks.mdx +209 -0
- package/content/learn/architecture.mdx +215 -0
- package/content/learn/attributes.mdx +89 -0
- package/content/learn/blocks.mdx +99 -0
- package/content/learn/commissions.mdx +175 -0
- package/content/learn/concepts.mdx +84 -0
- package/content/learn/installation.mdx +117 -0
- package/content/learn/introduction.mdx +71 -0
- package/content/learn/offers.mdx +78 -0
- package/content/learn/order-groups.mdx +114 -0
- package/content/learn/payouts.mdx +175 -0
- package/content/learn/product-requests.mdx +82 -0
- package/content/learn/products.mdx +79 -0
- package/content/learn/registry.mdx +155 -0
- package/content/learn/seller-members.mdx +62 -0
- package/content/learn/sellers.mdx +118 -0
- package/content/migration/from-1-x-to-2-0.mdx +152 -0
- package/content/migration/from-2-0-to-2-1.mdx +105 -0
- package/content/migration/overview.mdx +58 -0
- package/content/references/api/admin/commission-rates/batch-commission-rules.mdx +70 -0
- package/content/references/api/admin/commission-rates/create-commission-rate.mdx +95 -0
- package/content/references/api/admin/commission-rates/delete-commission-rate.mdx +40 -0
- package/content/references/api/admin/commission-rates/list-commission-rates.mdx +92 -0
- package/content/references/api/admin/commission-rates/retrieve-commission-rate.mdx +70 -0
- package/content/references/api/admin/commission-rates/update-commission-rate.mdx +84 -0
- package/content/references/api/admin/members/list-members.mdx +61 -0
- package/content/references/api/admin/offers/batch-create-offers.mdx +130 -0
- package/content/references/api/admin/offers/delete-offer.mdx +40 -0
- package/content/references/api/admin/offers/list-offers.mdx +106 -0
- package/content/references/api/admin/offers/retrieve-offer.mdx +82 -0
- package/content/references/api/admin/order-groups/list-order-groups.mdx +77 -0
- package/content/references/api/admin/order-groups/retrieve-order-group.mdx +56 -0
- package/content/references/api/admin/orders/get-order-commission-lines.mdx +65 -0
- package/content/references/api/admin/orders/get-order-order-group.mdx +56 -0
- package/content/references/api/admin/orders/list-orders.mdx +79 -0
- package/content/references/api/admin/payouts/list-payouts.mdx +75 -0
- package/content/references/api/admin/payouts/retrieve-payout.mdx +62 -0
- package/content/references/api/admin/product-attributes/create-attribute-value.mdx +76 -0
- package/content/references/api/admin/product-attributes/create-product-attribute.mdx +99 -0
- package/content/references/api/admin/product-attributes/delete-attribute-value.mdx +52 -0
- package/content/references/api/admin/product-attributes/delete-product-attribute.mdx +40 -0
- package/content/references/api/admin/product-attributes/list-product-attributes.mdx +91 -0
- package/content/references/api/admin/product-attributes/retrieve-product-attribute.mdx +81 -0
- package/content/references/api/admin/product-attributes/update-attribute-value.mdx +66 -0
- package/content/references/api/admin/product-attributes/update-product-attribute.mdx +76 -0
- package/content/references/api/admin/product-changes/cancel-product-change.mdx +68 -0
- package/content/references/api/admin/product-changes/confirm-product-change.mdx +47 -0
- package/content/references/api/admin/products/batch-product-attributes.mdx +96 -0
- package/content/references/api/admin/products/confirm-product.mdx +59 -0
- package/content/references/api/admin/products/create-product-variant.mdx +78 -0
- package/content/references/api/admin/products/create-product.mdx +169 -0
- package/content/references/api/admin/products/delete-product-variant.mdx +48 -0
- package/content/references/api/admin/products/delete-product.mdx +40 -0
- package/content/references/api/admin/products/list-product-variants.mdx +91 -0
- package/content/references/api/admin/products/list-products.mdx +109 -0
- package/content/references/api/admin/products/preview-product.mdx +78 -0
- package/content/references/api/admin/products/reject-product.mdx +59 -0
- package/content/references/api/admin/products/request-product-changes.mdx +59 -0
- package/content/references/api/admin/products/retrieve-product-variant.mdx +73 -0
- package/content/references/api/admin/products/retrieve-product.mdx +96 -0
- package/content/references/api/admin/products/set-product-sellers.mdx +47 -0
- package/content/references/api/admin/products/update-product-variant.mdx +89 -0
- package/content/references/api/admin/products/update-product.mdx +133 -0
- package/content/references/api/admin/sellers/add-seller-member.mdx +63 -0
- package/content/references/api/admin/sellers/approve-seller.mdx +54 -0
- package/content/references/api/admin/sellers/create-seller.mdx +100 -0
- package/content/references/api/admin/sellers/delete-member-invite.mdx +42 -0
- package/content/references/api/admin/sellers/delete-professional-details.mdx +52 -0
- package/content/references/api/admin/sellers/invite-seller-member.mdx +63 -0
- package/content/references/api/admin/sellers/list-member-invites.mdx +71 -0
- package/content/references/api/admin/sellers/list-seller-members.mdx +71 -0
- package/content/references/api/admin/sellers/list-seller-products.mdx +85 -0
- package/content/references/api/admin/sellers/list-sellers.mdx +96 -0
- package/content/references/api/admin/sellers/remove-seller-member.mdx +42 -0
- package/content/references/api/admin/sellers/resend-member-invite.mdx +55 -0
- package/content/references/api/admin/sellers/retrieve-seller.mdx +81 -0
- package/content/references/api/admin/sellers/suspend-seller.mdx +60 -0
- package/content/references/api/admin/sellers/terminate-seller.mdx +60 -0
- package/content/references/api/admin/sellers/unsuspend-seller.mdx +52 -0
- package/content/references/api/admin/sellers/unterminate-seller.mdx +52 -0
- package/content/references/api/admin/sellers/update-seller.mdx +83 -0
- package/content/references/api/admin/sellers/upsert-payment-details.mdx +88 -0
- package/content/references/api/admin/sellers/upsert-professional-details.mdx +78 -0
- package/content/references/api/admin/sellers/upsert-seller-address.mdx +91 -0
- package/content/references/api/admin.mdx +134 -0
- package/content/references/api/conventions.mdx +109 -0
- package/content/references/api/store/carts/add-line-item.mdx +115 -0
- package/content/references/api/store/carts/add-shipping-methods.mdx +84 -0
- package/content/references/api/store/carts/apply-promotions.mdx +83 -0
- package/content/references/api/store/carts/complete-cart.mdx +98 -0
- package/content/references/api/store/offers/list-offers.mdx +161 -0
- package/content/references/api/store/offers/retrieve-offer.mdx +112 -0
- package/content/references/api/store/order-groups/list-order-groups.mdx +105 -0
- package/content/references/api/store/order-groups/retrieve-order-group.mdx +78 -0
- package/content/references/api/store/product-attributes/list-product-attributes.mdx +134 -0
- package/content/references/api/store/product-attributes/retrieve-product-attribute.mdx +78 -0
- package/content/references/api/store/product-categories/list-product-categories.mdx +126 -0
- package/content/references/api/store/product-categories/retrieve-product-category.mdx +79 -0
- package/content/references/api/store/products/list-products.mdx +184 -0
- package/content/references/api/store/products/retrieve-product.mdx +107 -0
- package/content/references/api/store/search/search.mdx +136 -0
- package/content/references/api/store/sellers/list-sellers.mdx +105 -0
- package/content/references/api/store/sellers/retrieve-seller.mdx +62 -0
- package/content/references/api/store/shipping-options/list-shipping-options.mdx +74 -0
- package/content/references/api/store.mdx +67 -0
- package/content/references/api/vendor/members/accept-member-invite.mdx +65 -0
- package/content/references/api/vendor/members/retrieve-current-member.mdx +51 -0
- package/content/references/api/vendor/members/update-current-member.mdx +70 -0
- package/content/references/api/vendor/offers/batch-create-offers.mdx +123 -0
- package/content/references/api/vendor/offers/batch-offer-inventory-items.mdx +103 -0
- package/content/references/api/vendor/offers/create-offer.mdx +141 -0
- package/content/references/api/vendor/offers/delete-offer.mdx +51 -0
- package/content/references/api/vendor/offers/list-offers.mdx +125 -0
- package/content/references/api/vendor/offers/retrieve-offer.mdx +74 -0
- package/content/references/api/vendor/offers/update-offer.mdx +82 -0
- package/content/references/api/vendor/orders/cancel-fulfillment.mdx +63 -0
- package/content/references/api/vendor/orders/cancel-order.mdx +56 -0
- package/content/references/api/vendor/orders/complete-order.mdx +55 -0
- package/content/references/api/vendor/orders/create-fulfillment.mdx +76 -0
- package/content/references/api/vendor/orders/create-shipment.mdx +99 -0
- package/content/references/api/vendor/orders/get-order-commission-lines.mdx +66 -0
- package/content/references/api/vendor/orders/list-order-changes.mdx +75 -0
- package/content/references/api/vendor/orders/list-orders.mdx +103 -0
- package/content/references/api/vendor/orders/mark-fulfillment-delivered.mdx +62 -0
- package/content/references/api/vendor/orders/preview-order.mdx +65 -0
- package/content/references/api/vendor/orders/retrieve-order.mdx +84 -0
- package/content/references/api/vendor/payout-accounts/create-onboarding.mdx +68 -0
- package/content/references/api/vendor/payout-accounts/create-payout-account.mdx +59 -0
- package/content/references/api/vendor/payout-accounts/retrieve-payout-account-by-id.mdx +60 -0
- package/content/references/api/vendor/payout-accounts/retrieve-payout-account.mdx +77 -0
- package/content/references/api/vendor/payouts/list-payouts.mdx +90 -0
- package/content/references/api/vendor/payouts/retrieve-payout.mdx +63 -0
- package/content/references/api/vendor/product-attributes/list-product-attributes.mdx +135 -0
- package/content/references/api/vendor/product-attributes/retrieve-product-attribute.mdx +71 -0
- package/content/references/api/vendor/product-variants/list-variants.mdx +136 -0
- package/content/references/api/vendor/products/batch-product-attributes.mdx +104 -0
- package/content/references/api/vendor/products/cancel-product-change.mdx +62 -0
- package/content/references/api/vendor/products/create-product-variant.mdx +92 -0
- package/content/references/api/vendor/products/create-product.mdx +197 -0
- package/content/references/api/vendor/products/delete-product-variant.mdx +68 -0
- package/content/references/api/vendor/products/delete-product.mdx +62 -0
- package/content/references/api/vendor/products/list-product-variants.mdx +114 -0
- package/content/references/api/vendor/products/list-products.mdx +163 -0
- package/content/references/api/vendor/products/preview-product.mdx +61 -0
- package/content/references/api/vendor/products/retrieve-product-variant.mdx +76 -0
- package/content/references/api/vendor/products/retrieve-product.mdx +69 -0
- package/content/references/api/vendor/products/update-product-variant.mdx +104 -0
- package/content/references/api/vendor/products/update-product.mdx +148 -0
- package/content/references/api/vendor/sellers/create-seller.mdx +150 -0
- package/content/references/api/vendor/sellers/delete-professional-details.mdx +54 -0
- package/content/references/api/vendor/sellers/invite-seller-member.mdx +67 -0
- package/content/references/api/vendor/sellers/list-member-invites.mdx +82 -0
- package/content/references/api/vendor/sellers/list-seller-members.mdx +80 -0
- package/content/references/api/vendor/sellers/list-sellers.mdx +71 -0
- package/content/references/api/vendor/sellers/remove-seller-member.mdx +48 -0
- package/content/references/api/vendor/sellers/retrieve-current-seller-member.mdx +59 -0
- package/content/references/api/vendor/sellers/retrieve-current-seller.mdx +69 -0
- package/content/references/api/vendor/sellers/select-seller.mdx +44 -0
- package/content/references/api/vendor/sellers/update-current-seller.mdx +108 -0
- package/content/references/api/vendor/sellers/update-member-role.mdx +51 -0
- package/content/references/api/vendor/sellers/upsert-payment-details.mdx +74 -0
- package/content/references/api/vendor/sellers/upsert-professional-details.mdx +70 -0
- package/content/references/api/vendor/sellers/upsert-seller-address.mdx +81 -0
- package/content/references/api/vendor.mdx +150 -0
- package/content/references/configuration.mdx +155 -0
- package/content/references/modules/commission.mdx +106 -0
- package/content/references/modules/custom-fields.mdx +45 -0
- package/content/references/modules/media.mdx +55 -0
- package/content/references/modules/offer.mdx +64 -0
- package/content/references/modules/payout.mdx +121 -0
- package/content/references/modules/product-attribute.mdx +111 -0
- package/content/references/modules/product-edit.mdx +80 -0
- package/content/references/modules/search.mdx +112 -0
- package/content/references/modules/seller.mdx +175 -0
- package/content/references/overview.mdx +70 -0
- package/content/references/workflows/cart/add-seller-shipping-method-to-cart.mdx +44 -0
- package/content/references/workflows/cart/complete-cart-with-split-orders.mdx +36 -0
- package/content/references/workflows/cart/list-seller-shipping-options-for-cart.mdx +39 -0
- package/content/references/workflows/cart/update-cart-seller-promotions.mdx +42 -0
- package/content/references/workflows/commission/batch-commission-rules.mdx +45 -0
- package/content/references/workflows/commission/create-commission-rates.mdx +41 -0
- package/content/references/workflows/commission/delete-commission-rates.mdx +34 -0
- package/content/references/workflows/commission/refresh-order-commission-lines.mdx +30 -0
- package/content/references/workflows/commission/update-commission-rates.mdx +35 -0
- package/content/references/workflows/media/set-category-images.mdx +41 -0
- package/content/references/workflows/media/set-collection-images.mdx +41 -0
- package/content/references/workflows/member/accept-member-invite.mdx +33 -0
- package/content/references/workflows/member/add-seller-member.mdx +30 -0
- package/content/references/workflows/member/create-member-invites.mdx +34 -0
- package/content/references/workflows/member/delete-member-invite.mdx +24 -0
- package/content/references/workflows/member/remove-seller-member.mdx +28 -0
- package/content/references/workflows/member/resend-member-invite.mdx +28 -0
- package/content/references/workflows/member/update-member-role.mdx +28 -0
- package/content/references/workflows/member/update-member.mdx +35 -0
- package/content/references/workflows/offer/batch-offer-inventory-items.mdx +58 -0
- package/content/references/workflows/offer/create-offers.mdx +63 -0
- package/content/references/workflows/offer/delete-offers.mdx +35 -0
- package/content/references/workflows/offer/update-offers.mdx +51 -0
- package/content/references/workflows/order/cancel-order-fulfillment.mdx +34 -0
- package/content/references/workflows/order/confirm-claim-request.mdx +25 -0
- package/content/references/workflows/order/confirm-exchange-request.mdx +25 -0
- package/content/references/workflows/order/confirm-order-edit-request.mdx +25 -0
- package/content/references/workflows/order/confirm-return-receive.mdx +25 -0
- package/content/references/workflows/order/create-order-fulfillment.mdx +45 -0
- package/content/references/workflows/order-group/get-order-group-detail.mdx +29 -0
- package/content/references/workflows/order-group/get-order-groups-list.mdx +36 -0
- package/content/references/workflows/overview.mdx +72 -0
- package/content/references/workflows/payout/create-onboarding.mdx +36 -0
- package/content/references/workflows/payout/create-payout-account.mdx +33 -0
- package/content/references/workflows/payout/create-payout.mdx +30 -0
- package/content/references/workflows/payout/process-payout-for-webhook.mdx +32 -0
- package/content/references/workflows/product/confirm-products.mdx +46 -0
- package/content/references/workflows/product/create-products.mdx +63 -0
- package/content/references/workflows/product/link-sellers-to-product-category.mdx +40 -0
- package/content/references/workflows/product/link-sellers-to-product.mdx +40 -0
- package/content/references/workflows/product/reject-product.mdx +46 -0
- package/content/references/workflows/product/request-product-change.mdx +46 -0
- package/content/references/workflows/product-attribute/add-product-attributes-to-product.mdx +49 -0
- package/content/references/workflows/product-attribute/create-and-link-product-attributes-to-product.mdx +46 -0
- package/content/references/workflows/product-attribute/create-product-attribute-values.mdx +43 -0
- package/content/references/workflows/product-attribute/create-product-attributes.mdx +56 -0
- package/content/references/workflows/product-attribute/delete-product-attribute-values.mdx +30 -0
- package/content/references/workflows/product-attribute/delete-product-attributes.mdx +30 -0
- package/content/references/workflows/product-attribute/remove-product-attributes-from-product.mdx +29 -0
- package/content/references/workflows/product-attribute/update-product-attribute-values.mdx +44 -0
- package/content/references/workflows/product-attribute/update-product-attributes-on-product.mdx +41 -0
- package/content/references/workflows/product-attribute/update-product-attributes.mdx +48 -0
- package/content/references/workflows/product-attribute/upsert-product-attribute-values.mdx +43 -0
- package/content/references/workflows/product-edit/auto-confirm-product-change.mdx +39 -0
- package/content/references/workflows/product-edit/cancel-product-change.mdx +49 -0
- package/content/references/workflows/product-edit/confirm-product-change.mdx +57 -0
- package/content/references/workflows/product-edit/create-product-change.mdx +72 -0
- package/content/references/workflows/product-edit/reject-product-change.mdx +54 -0
- package/content/references/workflows/product-edit/stage-product-change.mdx +75 -0
- package/content/references/workflows/seller/approve-seller.mdx +34 -0
- package/content/references/workflows/seller/create-seller-account.mdx +59 -0
- package/content/references/workflows/seller/create-seller-defaults.mdx +22 -0
- package/content/references/workflows/seller/create-sellers.mdx +65 -0
- package/content/references/workflows/seller/delete-seller-professional-details.mdx +37 -0
- package/content/references/workflows/seller/delete-sellers.mdx +24 -0
- package/content/references/workflows/seller/invite-seller.mdx +28 -0
- package/content/references/workflows/seller/suspend-seller.mdx +35 -0
- package/content/references/workflows/seller/terminate-seller.mdx +35 -0
- package/content/references/workflows/seller/unsuspend-seller.mdx +34 -0
- package/content/references/workflows/seller/unterminate-seller.mdx +34 -0
- package/content/references/workflows/seller/update-seller-address.mdx +55 -0
- package/content/references/workflows/seller/update-seller-payment-details.mdx +52 -0
- package/content/references/workflows/seller/update-seller-professional-details.mdx +48 -0
- package/content/references/workflows/seller/update-sellers.mdx +57 -0
- package/content/resources/ai/llms.mdx +74 -0
- package/content/resources/ai/mcp.mdx +152 -0
- package/content/resources/ai/overview.mdx +97 -0
- package/content/resources/customization/custom-fields.mdx +182 -0
- package/content/resources/customization/extend-a-workflow.mdx +39 -0
- package/content/resources/customization/extending-panels.mdx +309 -0
- package/content/resources/deployment/medusa-cloud.mdx +167 -0
- package/content/resources/integrations/notifications.mdx +39 -0
- package/content/resources/integrations/search.mdx +122 -0
- package/content/resources/integrations/stripe-connect.mdx +395 -0
- package/content/resources/tutorials/add-a-block.mdx +74 -0
- package/content/resources/tutorials/attributes-and-variant-axes.mdx +111 -0
- package/content/resources/tutorials/build-a-block.mdx +134 -0
- package/content/resources/tutorials/configure-commissions.mdx +127 -0
- package/content/resources/tutorials/custom-api-route.mdx +142 -0
- package/content/resources/tutorials/custom-panel-page.mdx +78 -0
- package/content/resources/tutorials/first-marketplace.mdx +45 -0
- package/content/resources/tutorials/handle-product-requests.mdx +80 -0
- package/content/resources/tutorials/import-export-products.mdx +96 -0
- package/content/resources/tutorials/master-products-and-offers.mdx +89 -0
- package/content/resources/tutorials/recompose-a-page.mdx +129 -0
- package/content/resources/tutorials/replace-panel-components.mdx +116 -0
- package/content/resources/tutorials/seller-payouts-stripe.mdx +89 -0
- package/content/telemetry.mdx +67 -0
- package/content/tools/api-client.mdx +155 -0
- package/content/tools/cli.mdx +196 -0
- package/content/tools/dashboard-sdk.mdx +35 -0
- package/content/user-guide/admin/overview.mdx +23 -0
- package/content/user-guide/admin/stores.mdx +193 -0
- package/content/user-guide/vendor/overview.mdx +23 -0
- package/content/user-guide/vendor/stores.mdx +209 -0
- package/llms.txt +307 -0
- package/package.json +33 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Custom Fields module"
|
|
3
|
+
description: "Add extra columns to any entity without writing a custom module."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The Custom Fields module lets a project attach arbitrary extra fields to existing entities — sellers, products, orders, anything with a joiner alias — without defining a new Medusa module. Fields are declared in configuration; the module generates and manages a `<entity>_custom_fields` table per configured entity and reads/writes it directly.
|
|
7
|
+
|
|
8
|
+
For the usage guide, see [Custom fields](/rc/resources/customization/custom-fields).
|
|
9
|
+
|
|
10
|
+
## How it works
|
|
11
|
+
|
|
12
|
+
- On application start, the module builds a map from joiner aliases (e.g. `seller`, `product`) to entity names for every entity listed in its options.
|
|
13
|
+
- Each configured entity gets a dedicated table named `<entity>_custom_fields` with one column per declared field plus a `<entity>_id` foreign key.
|
|
14
|
+
- Rows are soft-deleted (`deleted_at`).
|
|
15
|
+
|
|
16
|
+
There are no `model.define` models and no links — the module operates dynamically over its own tables.
|
|
17
|
+
|
|
18
|
+
## Module options
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
interface CustomFieldsModuleOptions {
|
|
22
|
+
customFields?: {
|
|
23
|
+
[entityName: string]: Record<string, Field>
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
A `Field` is either a `BaseField` (scalar type) or an `EnumField` (fixed set of values). Both types are exported from the module.
|
|
29
|
+
|
|
30
|
+
## Service
|
|
31
|
+
|
|
32
|
+
`CustomFieldsModuleService` is a plain service (not `MedusaService`):
|
|
33
|
+
|
|
34
|
+
| Method | Behavior |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| `list(alias, filters?, config?)` | Queries the entity's custom-fields table; supports array filters (`IN`) and field selection |
|
|
37
|
+
| `upsert(alias, data)` | Diffs against existing rows per entity ID, inserts new rows and updates changed ones in a transaction |
|
|
38
|
+
| `delete(alias, ids)` | Soft-deletes the rows for the given entity IDs |
|
|
39
|
+
|
|
40
|
+
## Next steps
|
|
41
|
+
|
|
42
|
+
<CardGroup cols={2}>
|
|
43
|
+
<Card title="Custom fields guide" href="/rc/resources/customization/custom-fields" />
|
|
44
|
+
<Card title="Configuration" href="/rc/references/configuration" />
|
|
45
|
+
</CardGroup>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Media module"
|
|
3
|
+
description: "Image records for categories and collections — galleries, thumbnails, banners, and icons."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The Media module owns generic image records attached to marketplace entities through module links. It powers the media galleries on **product categories** and **product collections**, including thumbnail, banner, and icon designations.
|
|
7
|
+
|
|
8
|
+
The model is deliberately named `MediaImage` (table `media_image`) to avoid colliding with Medusa's product `Image` model.
|
|
9
|
+
|
|
10
|
+
## Data models
|
|
11
|
+
|
|
12
|
+
### `MediaImage`
|
|
13
|
+
|
|
14
|
+
Table `media_image`, ID prefix `medimg`.
|
|
15
|
+
|
|
16
|
+
| Field | Type | Notes |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| `url` | text | |
|
|
19
|
+
| `type` | text | Nullable; `"icon"` for icons, `null` for gallery images |
|
|
20
|
+
| `is_thumbnail` | boolean | Default `false` |
|
|
21
|
+
| `is_banner` | boolean | Default `false` |
|
|
22
|
+
| `rank` | number | Default `0`; gallery ordering |
|
|
23
|
+
| `metadata` | json | Nullable |
|
|
24
|
+
|
|
25
|
+
Ownership lives in the link table, not on the record — the same module serves any linked entity.
|
|
26
|
+
|
|
27
|
+
## Links
|
|
28
|
+
|
|
29
|
+
| Link | Alias | Purpose |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| `Product.productCategory` ↔ `MediaImage` | `media_images` | Category gallery + icon |
|
|
32
|
+
| `Product.productCollection` ↔ `MediaImage` | `media_images` | Collection gallery + icon |
|
|
33
|
+
|
|
34
|
+
## Invariants
|
|
35
|
+
|
|
36
|
+
The service is plain CRUD; the invariants are enforced by the `setCategoryImagesWorkflow` / `setCollectionImagesWorkflow`:
|
|
37
|
+
|
|
38
|
+
- At most **one thumbnail**, **one banner**, and **one icon** per entity.
|
|
39
|
+
- The same image may be both thumbnail and banner.
|
|
40
|
+
- Setting `icon: null` clears the icon; deleting the entity removes its linked images (no orphans).
|
|
41
|
+
|
|
42
|
+
Create/update/delete of categories and collections goes through thin wrapper workflows (`createProductCollectionWithImagesWorkflow`, etc.) that combine Medusa's core workflow with the image-set step.
|
|
43
|
+
|
|
44
|
+
## Related endpoints
|
|
45
|
+
|
|
46
|
+
- `GET/POST/DELETE /admin/collections[/:id]` — accept `media[]` (with thumbnail/banner designations) and `icon` in the body; responses include the linked `images`.
|
|
47
|
+
- Admin product-category routes accept the same shape.
|
|
48
|
+
- Vendor collection and category routes expose the images read-only.
|
|
49
|
+
|
|
50
|
+
## Next steps
|
|
51
|
+
|
|
52
|
+
<CardGroup cols={2}>
|
|
53
|
+
<Card title="Workflows" href="/rc/references/workflows" />
|
|
54
|
+
<Card title="Admin API" href="/rc/references/api/admin" />
|
|
55
|
+
</CardGroup>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Offer module"
|
|
3
|
+
description: "Data models, links, and service methods for the Offer module."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The Offer module owns a seller's **listing** — the binding of a shared product variant to that seller's SKU, shipping profile, price, and inventory. Products in Mercur are master catalog records; the offer is what makes a variant purchasable *from a specific seller*.
|
|
7
|
+
|
|
8
|
+
## Data models
|
|
9
|
+
|
|
10
|
+
### `Offer`
|
|
11
|
+
|
|
12
|
+
Table `offer`, ID prefix `offer`. Unique on (`seller_id`, `sku`).
|
|
13
|
+
|
|
14
|
+
| Field | Type | Notes |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| `seller_id` | text | The listing seller |
|
|
17
|
+
| `product_id` | text | The master product |
|
|
18
|
+
| `variant_id` | text | The listed variant |
|
|
19
|
+
| `shipping_profile_id` | text | The seller's shipping profile for this offer |
|
|
20
|
+
| `sku` | text | Searchable; unique per seller |
|
|
21
|
+
| `ean` / `upc` | text | Nullable, searchable |
|
|
22
|
+
| `created_by` | text | Actor that created the offer |
|
|
23
|
+
| `variant_count` | number | Computed; only populated in `group_by_seller` mode |
|
|
24
|
+
| `metadata` | json | Nullable |
|
|
25
|
+
|
|
26
|
+
Indexes exist on `variant_id`, `product_id`, `seller_id`, `shipping_profile_id`, `ean`, and `upc`.
|
|
27
|
+
|
|
28
|
+
## Links
|
|
29
|
+
|
|
30
|
+
Prices and inventory attach to the offer through links, not columns:
|
|
31
|
+
|
|
32
|
+
| Linked entity | Cardinality | Purpose |
|
|
33
|
+
| --- | --- | --- |
|
|
34
|
+
| `Pricing.price` | one offer — many prices | The offer's own price set |
|
|
35
|
+
| `Inventory.inventoryItem` | many-to-many (`offer_inventory_item`, with `required_quantity`, default 1) | The stock backing the offer |
|
|
36
|
+
| `Cart.lineItem` / `Order.orderLineItem` | one offer — many items | Traces cart and order lines back to the offer they were bought from |
|
|
37
|
+
| `Product.product` / `productVariant`, `Seller`, `Fulfillment.shippingProfile` | read-only | Resolved from the `*_id` columns |
|
|
38
|
+
|
|
39
|
+
<Warning>
|
|
40
|
+
Offer inventory links to the **offer**, not the variant. For offer-backed
|
|
41
|
+
order lines, `variant.inventory_items` is empty — always read stock through
|
|
42
|
+
the offer's inventory link.
|
|
43
|
+
</Warning>
|
|
44
|
+
|
|
45
|
+
## Service
|
|
46
|
+
|
|
47
|
+
`OfferModuleService` extends `MedusaService` with auto-generated CRUD, plus a grouped listing mode:
|
|
48
|
+
|
|
49
|
+
| Method | Behavior |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| `listOffers(filters, config)` / `listAndCountOffers(...)` | When `filters.group_by_seller` is set, collapses results to one row per (`product_id`, `seller_id`) and computes `variant_count` per group; otherwise standard listing |
|
|
52
|
+
|
|
53
|
+
## Related endpoints
|
|
54
|
+
|
|
55
|
+
- `GET /admin/offers`, `POST /admin/offers/batch` — operator visibility and bulk creation
|
|
56
|
+
- `GET/POST /vendor/offers`, `POST /vendor/offers/batch`, `POST /vendor/offers/:id/inventory-items/batch` — seller listing management
|
|
57
|
+
- `GET /store/offers`, `GET /store/offers/:id` — storefront discovery with per-offer calculated prices
|
|
58
|
+
|
|
59
|
+
## Next steps
|
|
60
|
+
|
|
61
|
+
<CardGroup cols={2}>
|
|
62
|
+
<Card title="Seller module" href="/rc/references/modules/seller" />
|
|
63
|
+
<Card title="Search module" href="/rc/references/modules/search" />
|
|
64
|
+
</CardGroup>
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Payout module"
|
|
3
|
+
description: "Data models, links, service methods, and the provider interface for the Payout module."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The Payout module owns vendor payout accounts, provider onboarding, and payout records. It delegates account creation, onboarding, and payout execution to a single registered **payout provider** — Stripe Connect ships out of the box — and enforces that payouts only fire for `active` accounts.
|
|
7
|
+
|
|
8
|
+
For the conceptual introduction, see [Payouts](/rc/learn/payouts).
|
|
9
|
+
|
|
10
|
+
## Data models
|
|
11
|
+
|
|
12
|
+
### `PayoutAccount`
|
|
13
|
+
|
|
14
|
+
Table `payout_account`, ID prefix `pacc`. One per seller (linked via the seller module).
|
|
15
|
+
|
|
16
|
+
| Field | Type | Notes |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| `status` | enum | `PayoutAccountStatus`, default `pending` |
|
|
19
|
+
| `data` | json | Provider-owned account data |
|
|
20
|
+
| `context` | json | Nullable; creation context passed to the provider |
|
|
21
|
+
|
|
22
|
+
Relations: `onboarding` (one-to-one), `payouts` (one-to-many).
|
|
23
|
+
|
|
24
|
+
### `Payout`
|
|
25
|
+
|
|
26
|
+
Table `payout`, ID prefix `pout`.
|
|
27
|
+
|
|
28
|
+
| Field | Type | Notes |
|
|
29
|
+
| --- | --- | --- |
|
|
30
|
+
| `display_id` | autoincrement | Human-readable number |
|
|
31
|
+
| `currency_code` | text | |
|
|
32
|
+
| `amount` | bigNumber | |
|
|
33
|
+
| `status` | enum | `PayoutStatus`, default `pending` |
|
|
34
|
+
| `data` | json | Nullable; provider response data |
|
|
35
|
+
|
|
36
|
+
### `Onboarding`
|
|
37
|
+
|
|
38
|
+
Table `onboarding`, ID prefix `onb`. Holds the provider's onboarding state for an account:
|
|
39
|
+
|
|
40
|
+
| Field | Type | Notes |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| `data` | json | Nullable; e.g. the Stripe onboarding link |
|
|
43
|
+
| `context` | json | Nullable; e.g. return/refresh URLs |
|
|
44
|
+
|
|
45
|
+
## Enums
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
enum PayoutAccountStatus {
|
|
49
|
+
PENDING = "pending",
|
|
50
|
+
ACTIVE = "active",
|
|
51
|
+
RESTRICTED = "restricted",
|
|
52
|
+
REJECTED = "rejected",
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
enum PayoutStatus {
|
|
56
|
+
PENDING = "pending",
|
|
57
|
+
PROCESSING = "processing",
|
|
58
|
+
PAID = "paid",
|
|
59
|
+
FAILED = "failed",
|
|
60
|
+
CANCELED = "canceled",
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Links
|
|
65
|
+
|
|
66
|
+
| Linked entity | Cardinality | Purpose |
|
|
67
|
+
| --- | --- | --- |
|
|
68
|
+
| `Seller` ↔ `PayoutAccount` | one-to-one | A seller's provider account |
|
|
69
|
+
| `Seller` ↔ `Payout` | one seller — many payouts | Settlement history |
|
|
70
|
+
| `Order.order` ↔ `Payout` | one order — many payouts | Traces a payout back to the order it settles |
|
|
71
|
+
|
|
72
|
+
## Service
|
|
73
|
+
|
|
74
|
+
`PayoutModuleService` extends `MedusaService` with auto-generated CRUD, plus:
|
|
75
|
+
|
|
76
|
+
| Method | Behavior |
|
|
77
|
+
| --- | --- |
|
|
78
|
+
| `createPayoutAccount(input)` | Creates the local record, calls the provider with an idempotency key, stores the provider's data and status; deletes the local record if the provider call fails |
|
|
79
|
+
| `createOnboarding(input)` | Calls the provider and upserts the onboarding record for the account |
|
|
80
|
+
| `createPayouts(input)` | Asserts the account is `active`, calls the provider, persists the payout with the provider's data and status |
|
|
81
|
+
| `getWebhookActionAndData(input)` | Resolves an incoming provider webhook into a payout action (consumed by `POST /hooks/payout`) |
|
|
82
|
+
| `getOptions()` | Returns the merged module options |
|
|
83
|
+
|
|
84
|
+
## Module options
|
|
85
|
+
|
|
86
|
+
| Option | Type | Default | Purpose |
|
|
87
|
+
| --- | --- | --- | --- |
|
|
88
|
+
| `providers` | array | — | Provider registrations (`resolve`, `id`, `options`) |
|
|
89
|
+
| `disabled` | boolean | `false` | Turns payout processing off |
|
|
90
|
+
| `authorizationWindowMs` | number | 7 days | How long a payment authorization is trusted before capture must happen |
|
|
91
|
+
| `sellerActionWindowMs` | number | 72 h | How long the seller has to act (e.g. fulfill) before escalation |
|
|
92
|
+
| `captureSafetyBufferMs` | number | 24 h | Safety margin before the authorization expires |
|
|
93
|
+
| `requiredFulfillmentStatus` | string | `"fulfilled"` | Fulfillment state an order must reach before its payout is generated |
|
|
94
|
+
|
|
95
|
+
## Provider interface
|
|
96
|
+
|
|
97
|
+
Exactly one payout provider must be registered (under the `payout_` registration prefix); the module throws at boot otherwise. A provider implements four verbs:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
interface PayoutProvider {
|
|
101
|
+
createPayoutAccount(input): Promise<{ data; status }>
|
|
102
|
+
createOnboarding(input): Promise<{ data }>
|
|
103
|
+
createPayout(input): Promise<{ data; status }>
|
|
104
|
+
getWebhookActionAndData(payload): Promise<PayoutWebhookResult>
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The Stripe Connect implementation lives in `@mercurjs/payout-stripe-connect` — see [Configuration](/rc/references/configuration#stripe-connect-payout-provider) for its options and [Stripe Connect integration](/rc/resources/integrations/stripe-connect) for the setup guide.
|
|
109
|
+
|
|
110
|
+
## Related endpoints
|
|
111
|
+
|
|
112
|
+
- `GET /admin/payouts` — platform-wide payout monitoring
|
|
113
|
+
- `GET /vendor/payouts`, `GET/POST /vendor/payout-accounts`, `POST /vendor/payout-accounts/:id/onboarding` — seller-side account and history
|
|
114
|
+
- `POST /hooks/payout` — provider webhook receiver
|
|
115
|
+
|
|
116
|
+
## Next steps
|
|
117
|
+
|
|
118
|
+
<CardGroup cols={2}>
|
|
119
|
+
<Card title="Stripe Connect integration" href="/rc/resources/integrations/stripe-connect" />
|
|
120
|
+
<Card title="Configuration" href="/rc/references/configuration" />
|
|
121
|
+
</CardGroup>
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Product Attribute module"
|
|
3
|
+
description: "Data models, links, and service methods for the Product Attribute module."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The Product Attribute module owns configurable **attributes** and their allowed **values** — the structured properties that describe products (material, color, size, condition, …). Attributes can be global (shared across the catalog) or product-scoped, can be restricted to categories, and — for `multi_select` attributes — can act as **variant axes** backed by Medusa's native global product options.
|
|
7
|
+
|
|
8
|
+
## Data models
|
|
9
|
+
|
|
10
|
+
### `ProductAttribute`
|
|
11
|
+
|
|
12
|
+
Table `product_attribute`, ID prefix `pattr`.
|
|
13
|
+
|
|
14
|
+
| Field | Type | Notes |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| `name` | text | Searchable |
|
|
17
|
+
| `handle` | text | Nullable; unique when set; auto-generated for global attributes |
|
|
18
|
+
| `description` | text | Nullable |
|
|
19
|
+
| `type` | enum | `AttributeType`; immutable after creation |
|
|
20
|
+
| `is_required` | boolean | Default `false` |
|
|
21
|
+
| `is_filterable` | boolean | Default `false`; filterable attributes are tokenized into the search index |
|
|
22
|
+
| `is_variant_axis` | boolean | Default `false`; only valid for `multi_select` |
|
|
23
|
+
| `rank` | number | Default `0`; display ordering |
|
|
24
|
+
| `is_active` | boolean | Default `true` |
|
|
25
|
+
| `product_id` | text | Nullable — `null` means global, set means product-scoped (inline) |
|
|
26
|
+
| `product_option_id` | text | Nullable; mirror to the native `ProductOption` for axis attributes |
|
|
27
|
+
| `created_by` | text | Nullable |
|
|
28
|
+
| `metadata` | json | Nullable |
|
|
29
|
+
|
|
30
|
+
### `ProductAttributeValue`
|
|
31
|
+
|
|
32
|
+
Table `product_attribute_value`, ID prefix `pattrval`. Unique on (`attribute_id`, `handle`) when the handle is set.
|
|
33
|
+
|
|
34
|
+
| Field | Type | Notes |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| `name` | text | Display label |
|
|
37
|
+
| `handle` | text | Nullable; auto-generated for global select attributes |
|
|
38
|
+
| `rank` | number | Default `0` |
|
|
39
|
+
| `is_active` | boolean | Default `true` |
|
|
40
|
+
| `product_option_value_id` | text | Nullable; mirror to the native `ProductOptionValue` |
|
|
41
|
+
| `metadata` | json | Nullable |
|
|
42
|
+
|
|
43
|
+
## Enums
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
enum AttributeType {
|
|
47
|
+
SINGLE_SELECT = "single_select",
|
|
48
|
+
MULTI_SELECT = "multi_select",
|
|
49
|
+
UNIT = "unit",
|
|
50
|
+
TOGGLE = "toggle",
|
|
51
|
+
TEXT = "text",
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## How each type is stored
|
|
56
|
+
|
|
57
|
+
| Type | Variant axis? | Backing store |
|
|
58
|
+
| --- | --- | --- |
|
|
59
|
+
| `multi_select` (axis) | yes | Native Medusa `ProductOption` + option values; the product links a subset of values |
|
|
60
|
+
| `multi_select` / `single_select` (non-axis) | no | Product ↔ value link rows |
|
|
61
|
+
| `text` / `unit` | no | A value record is created for the entered text, then linked |
|
|
62
|
+
| `toggle` | no | Two seeded fixed values (`true` / `false`); the matching one is linked |
|
|
63
|
+
|
|
64
|
+
Only `multi_select` attributes may be variant axes. A global axis maps to a shared (`is_exclusive: false`) product option; an inline, product-scoped axis maps to an exclusive option.
|
|
65
|
+
|
|
66
|
+
## Links
|
|
67
|
+
|
|
68
|
+
| Link | Purpose |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| `product_category_attribute` | Restricts an attribute to categories (many-to-many) |
|
|
71
|
+
| `product_attribute_value_link` | Product ↔ selected values (non-axis selections, and a mirror of axis selections) |
|
|
72
|
+
| `scoped_attributes` (read-only) | Product → its product-scoped attributes via `product_id` |
|
|
73
|
+
| Option mirror (read-only) | `ProductAttribute.product_option_id` → native `ProductOption` |
|
|
74
|
+
| Option-value mirror (read-only) | `ProductAttributeValue.product_option_value_id` → native `ProductOptionValue` |
|
|
75
|
+
|
|
76
|
+
## Service
|
|
77
|
+
|
|
78
|
+
`ProductAttributeModuleService` extends `MedusaService` with auto-generated CRUD, plus:
|
|
79
|
+
|
|
80
|
+
| Method | Behavior |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `createProductAttributes(data)` | Auto-generates handles for global attributes; seeds `true`/`false` values for `toggle` attributes |
|
|
83
|
+
| `updateProductAttributes(data)` | Rejects any attempt to change an attribute's `type` |
|
|
84
|
+
| `listProductAttributes` / `listAndCountProductAttributes` | Attach `values` only for select/toggle types; other types return `values: []` |
|
|
85
|
+
| `createProductAttributeValues(data)` | Auto-generates value handles for global select attributes |
|
|
86
|
+
|
|
87
|
+
## Attaching attributes to products
|
|
88
|
+
|
|
89
|
+
Attributes are applied to products through the batch endpoint rather than the module service directly:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
POST /admin/products/:id/attributes/batch
|
|
93
|
+
POST /vendor/products/:id/attributes/batch
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The body is `{ add?, remove?, update? }`, applied in the order remove → add → update by the `createAndLinkProductAttributesToProductWorkflow`. Product create and update payloads also accept a unified `attributes[]` array.
|
|
97
|
+
|
|
98
|
+
Product GET responses expose the attribute graph as native `options` (variant axes), `product_attribute_values` (each with its parent `attribute` and, for global selects, `all_values`), and `scoped_attributes`.
|
|
99
|
+
|
|
100
|
+
## Related endpoints
|
|
101
|
+
|
|
102
|
+
- `GET/POST /admin/product-attributes`, value sub-routes — catalog management
|
|
103
|
+
- `GET /vendor/product-attributes` — category-filtered read access for sellers
|
|
104
|
+
- `GET /store/product-attributes` — storefront filter facets
|
|
105
|
+
|
|
106
|
+
## Next steps
|
|
107
|
+
|
|
108
|
+
<CardGroup cols={2}>
|
|
109
|
+
<Card title="Product Edit module" href="/rc/references/modules/product-edit" />
|
|
110
|
+
<Card title="Search module" href="/rc/references/modules/search" />
|
|
111
|
+
</CardGroup>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Product Edit module"
|
|
3
|
+
description: "Data models and lifecycle for product change requests on master products."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The Product Edit module owns the **product change** — the request/approval record through which sellers propose edits to the shared catalog. Products in Mercur are master records that no seller owns; any seller may request a change to any product, and the operator confirms, declines, or lets the platform auto-confirm it.
|
|
7
|
+
|
|
8
|
+
## The master products model
|
|
9
|
+
|
|
10
|
+
A `product` row is a shared catalog entry — it has no owner column. Three rules follow:
|
|
11
|
+
|
|
12
|
+
- **Selling eligibility** is a separate allowlist: the `product_seller` link. One or more rows restrict the product to those sellers; zero rows mean the product is unrestricted.
|
|
13
|
+
- **Creator attribution** lives on the change record (`product_change.created_by` plus a `PRODUCT_ADD` action), and is used only for scoping vendor list views — a seller sees products they created, plus published products not restricted to other sellers.
|
|
14
|
+
- **Edits are requests.** Vendor product update endpoints stage a change instead of writing directly; there is no ownership gate on requesting a change.
|
|
15
|
+
|
|
16
|
+
## Data models
|
|
17
|
+
|
|
18
|
+
### `ProductChange`
|
|
19
|
+
|
|
20
|
+
Table `product_change`, ID prefix `prodch`.
|
|
21
|
+
|
|
22
|
+
| Field | Type | Notes |
|
|
23
|
+
| --- | --- | --- |
|
|
24
|
+
| `product_id` | text | Target product |
|
|
25
|
+
| `status` | enum | `ProductChangeStatus`, default `pending` |
|
|
26
|
+
| `created_by` | text | Nullable; requesting actor |
|
|
27
|
+
| `internal_note` / `external_note` | text | Nullable |
|
|
28
|
+
| `confirmed_by` / `confirmed_at` | text / dateTime | Nullable; audit trail |
|
|
29
|
+
| `declined_by` / `declined_at` / `declined_reason` | text / dateTime / text | Nullable |
|
|
30
|
+
| `canceled_by` / `canceled_at` | text / dateTime | Nullable |
|
|
31
|
+
| `requires_action_by` / `requires_action_at` / `requires_action_reason` | text / dateTime / text | Nullable; "changes requested" state |
|
|
32
|
+
| `metadata` | json | Nullable |
|
|
33
|
+
|
|
34
|
+
Relations: `actions` (one-to-many, deleted with the change).
|
|
35
|
+
|
|
36
|
+
### `ProductChangeAction`
|
|
37
|
+
|
|
38
|
+
Table `product_change_action`, ID prefix `prodchact`. The ordered operations a change applies:
|
|
39
|
+
|
|
40
|
+
| Field | Type | Notes |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| `product_id` | text | |
|
|
43
|
+
| `ordering` | autoincrement | Apply order |
|
|
44
|
+
| `action` | text | Operation type (e.g. `PRODUCT_ADD`, update, variant, attribute operations) |
|
|
45
|
+
| `details` | json | Default `{}`; the operation payload |
|
|
46
|
+
| `applied` | boolean | Default `false` |
|
|
47
|
+
| `internal_note` | text | Nullable |
|
|
48
|
+
|
|
49
|
+
## Enums
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
enum ProductChangeStatus {
|
|
53
|
+
PENDING = "pending",
|
|
54
|
+
CONFIRMED = "confirmed",
|
|
55
|
+
DECLINED = "declined",
|
|
56
|
+
CANCELED = "canceled",
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Links
|
|
61
|
+
|
|
62
|
+
| Link | Purpose |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| `changes` (read-only) | Product → its change records via `product_id` |
|
|
65
|
+
|
|
66
|
+
## Service
|
|
67
|
+
|
|
68
|
+
`ProductChangeModuleService` extends `MedusaService` with auto-generated CRUD only — the lifecycle logic lives in workflows: `createProductChangeWorkflow`, `stageProductChangeWorkflow`, `confirmProductChangeWorkflow`, `autoConfirmProductChangeWorkflow`, `cancelProductChangeWorkflow`, `rejectProductChangeWorkflow`, and the `applyProductChangeActionsWorkflow` family that replays the staged actions onto the product. See [Workflows](/rc/references/workflows#product-edit).
|
|
69
|
+
|
|
70
|
+
## Related endpoints
|
|
71
|
+
|
|
72
|
+
- Vendor: `POST /vendor/products/:id` and variant/attribute sub-routes stage changes; `GET /vendor/products/:id/preview` shows the product with pending changes applied; `POST /vendor/products/:id/cancel` withdraws a request.
|
|
73
|
+
- Admin: `GET /admin/products/:id/preview`, `POST /admin/products/:id/confirm`, `POST /admin/products/:id/reject`, `POST /admin/products/:id/request-changes`, plus `POST /admin/product-changes/:id/confirm` and `/cancel`.
|
|
74
|
+
|
|
75
|
+
## Next steps
|
|
76
|
+
|
|
77
|
+
<CardGroup cols={2}>
|
|
78
|
+
<Card title="Product Attribute module" href="/rc/references/modules/product-attribute" />
|
|
79
|
+
<Card title="Offer module" href="/rc/references/modules/offer" />
|
|
80
|
+
</CardGroup>
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Search module"
|
|
3
|
+
description: "The provider-agnostic search module, its document shapes, and the provider contract."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The Search module is a **provider abstraction**: it owns no data models and wraps exactly one registered search provider behind three verbs — `index`, `remove`, `search`. Mercur ships a default in-process provider built on [Orama](https://oramasearch.com) that requires zero external infrastructure; operators can swap in Algolia, Meilisearch, or anything else by implementing the same contract.
|
|
7
|
+
|
|
8
|
+
Both **products** (master catalog entries) and **offers** (per-seller listings with offer-scoped prices) are indexed.
|
|
9
|
+
|
|
10
|
+
## Document shape
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
interface SearchDoc {
|
|
14
|
+
id: string
|
|
15
|
+
type: "product" | "offer"
|
|
16
|
+
title: string
|
|
17
|
+
description?: string
|
|
18
|
+
handle: string
|
|
19
|
+
thumbnail?: string
|
|
20
|
+
seller_handle?: string // offers only
|
|
21
|
+
collection_id?: string
|
|
22
|
+
collection?: string
|
|
23
|
+
category_ids?: string[]
|
|
24
|
+
categories?: string[]
|
|
25
|
+
product_id?: string // offers
|
|
26
|
+
variant_id?: string // offers
|
|
27
|
+
sku?: string // offers
|
|
28
|
+
attribute_tokens: string[] // facetable: "attr:<handle>:<value_id>"
|
|
29
|
+
attributes: Record<string, string> // stored label map
|
|
30
|
+
prices: Record<string, SearchDocPrice> // keyed by region_id, stored not indexed
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Prices are **stored, not searched**: each document carries a per-region price map (`calculated_amount`, `original_amount`, `currency_code`), and the provider projects `calculated_price` for the requested region at query time. Suspended sellers' offers and unpublished products are excluded at index time. Attributes flagged `is_filterable` are tokenized into `attribute_tokens` for faceting.
|
|
35
|
+
|
|
36
|
+
## Query and results
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
interface SearchQueryBase {
|
|
40
|
+
q?: string
|
|
41
|
+
limit?: number
|
|
42
|
+
offset?: number
|
|
43
|
+
context?: Record<string, unknown> // pricing/display context, not a filter
|
|
44
|
+
filters?: Record<string, unknown> // provider-owned shape
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface SearchResults {
|
|
48
|
+
hits: SearchDoc[]
|
|
49
|
+
count: number
|
|
50
|
+
facets: { collections; categories; attributes } // pre-labelled by the provider
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`filters` is an open passthrough — each provider defines its own filter shape. The built-in Orama provider accepts:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
filters?: {
|
|
58
|
+
type?: "product" | "offer"
|
|
59
|
+
collection_ids?: string[]
|
|
60
|
+
category_ids?: string[]
|
|
61
|
+
seller_handle?: string
|
|
62
|
+
attributes?: Record<string, string[]> // attribute handle -> selected value ids
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Service
|
|
67
|
+
|
|
68
|
+
`SearchModuleService` exposes:
|
|
69
|
+
|
|
70
|
+
| Method | Behavior |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `index(docs)` | Upserts documents into the provider index |
|
|
73
|
+
| `remove(ids)` | Removes documents by ID |
|
|
74
|
+
| `search(query)` | Runs a query against the provider |
|
|
75
|
+
| `getProviderIdentifier()` | Returns the active provider's identifier |
|
|
76
|
+
|
|
77
|
+
## Provider contract
|
|
78
|
+
|
|
79
|
+
Implement `AbstractSearchProvider` (exported from the module) and register it via the module's `provider` option. Exactly one provider must be registered — the module throws at boot otherwise. If no provider is configured, the Orama provider registers automatically.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
abstract class AbstractSearchProvider<TQuery extends SearchQueryBase> {
|
|
83
|
+
static identifier: string
|
|
84
|
+
abstract index(docs: SearchDoc[]): Promise<void>
|
|
85
|
+
abstract remove(ids: string[]): Promise<void>
|
|
86
|
+
abstract search(query: TQuery): Promise<SearchResults>
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
<Warning>
|
|
91
|
+
The built-in Orama provider holds its index **in process memory**. It starts
|
|
92
|
+
empty, is rebuilt on boot via the reindex event, and does not share state
|
|
93
|
+
across processes. For multi-instance deployments, use an external provider.
|
|
94
|
+
</Warning>
|
|
95
|
+
|
|
96
|
+
## Index synchronization
|
|
97
|
+
|
|
98
|
+
Sync is event-driven — there are no search workflows:
|
|
99
|
+
|
|
100
|
+
- Subscribers react to product, offer, and seller changes (`search-product-changed`, `search-product-deleted`, `search-offer-changed`, `search-seller-changed`) and reindex or remove the affected documents.
|
|
101
|
+
- A full rebuild runs when the `search.reindex` event (`SEARCH_REINDEX_EVENT`) is emitted; in worker mode the module emits it automatically on application start.
|
|
102
|
+
|
|
103
|
+
## Related endpoints
|
|
104
|
+
|
|
105
|
+
`POST /store/search` — the storefront query route. Body: `q`, `limit` (default 12, max 100), `offset`, `region_id` / `country_code` / `province` (pricing context), and the provider-owned `filters`. Responds with `{ hits, count, limit, offset, facets }`. Customer authentication is optional.
|
|
106
|
+
|
|
107
|
+
## Next steps
|
|
108
|
+
|
|
109
|
+
<CardGroup cols={2}>
|
|
110
|
+
<Card title="Search integrations" href="/rc/resources/integrations/search" />
|
|
111
|
+
<Card title="Store API" href="/rc/references/api/store" />
|
|
112
|
+
</CardGroup>
|