@mercurjs/docs 2.3.8-canary.2 → 2.3.8-canary.4
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/content/learn/architecture.mdx +166 -263
- package/content/platform/attribute/concepts/attribute-types.mdx +73 -46
- package/content/platform/attribute/concepts/global-vs-inline.mdx +54 -32
- package/content/platform/attribute/concepts/variant-axes.mdx +54 -32
- package/content/platform/attribute/guides/attach-attributes-to-a-product.mdx +96 -53
- package/content/platform/attribute/guides/create-a-variant-axis.mdx +106 -57
- package/content/platform/attribute/guides/create-an-attribute.mdx +105 -56
- package/content/platform/attribute/overview.mdx +37 -33
- package/content/platform/attribute/reference/data-models.mdx +53 -38
- package/content/platform/attribute/reference/events.mdx +47 -24
- package/content/platform/attribute/reference/links.mdx +98 -27
- package/content/platform/attribute/reference/service.mdx +71 -32
- package/content/platform/attribute/reference/workflows.mdx +158 -28
- package/content/platform/catalog/concepts/master-products.mdx +39 -37
- package/content/platform/catalog/concepts/product-seller-allowlist.mdx +56 -35
- package/content/platform/catalog/concepts/status-lifecycle.mdx +55 -49
- package/content/platform/catalog/concepts/variants-categories-collections.mdx +55 -35
- package/content/platform/catalog/guides/allowlist-stores.mdx +100 -37
- package/content/platform/catalog/guides/create-a-master-product.mdx +124 -48
- package/content/platform/catalog/guides/publish-or-reject-a-product.mdx +120 -55
- package/content/platform/catalog/overview.mdx +39 -35
- package/content/platform/catalog/reference/data-models.mdx +154 -43
- package/content/platform/catalog/reference/events.mdx +41 -25
- package/content/platform/catalog/reference/links.mdx +196 -28
- package/content/platform/catalog/reference/service.mdx +57 -35
- package/content/platform/catalog/reference/workflows.mdx +124 -30
- package/content/platform/commission/concepts/order-commission-lines.mdx +54 -52
- package/content/platform/commission/concepts/rule-matching.mdx +53 -63
- package/content/platform/commission/concepts/rules-and-rates.mdx +61 -59
- package/content/platform/commission/guides/batch-update-rules.mdx +69 -41
- package/content/platform/commission/guides/create-a-rate.mdx +101 -53
- package/content/platform/commission/guides/refresh-order-commission-lines.mdx +104 -35
- package/content/platform/commission/overview.mdx +43 -35
- package/content/platform/commission/reference/data-models.mdx +59 -45
- package/content/platform/commission/reference/events.mdx +28 -34
- package/content/platform/commission/reference/links.mdx +42 -33
- package/content/platform/commission/reference/service.mdx +103 -28
- package/content/platform/commission/reference/workflows.mdx +101 -27
- package/content/platform/offer/concepts/pricing-and-inventory.mdx +63 -49
- package/content/platform/offer/concepts/shipping.mdx +28 -29
- package/content/platform/offer/concepts/what-is-an-offer.mdx +48 -45
- package/content/platform/offer/guides/bulk-create-offers.mdx +97 -61
- package/content/platform/offer/guides/create-an-offer.mdx +112 -60
- package/content/platform/offer/guides/manage-offer-inventory.mdx +78 -38
- package/content/platform/offer/overview.mdx +39 -32
- package/content/platform/offer/reference/data-models.mdx +77 -47
- package/content/platform/offer/reference/events.mdx +44 -18
- package/content/platform/offer/reference/links.mdx +92 -40
- package/content/platform/offer/reference/service.mdx +66 -31
- package/content/platform/offer/reference/workflows.mdx +146 -37
- package/content/platform/order-group/concepts/computed-totals.mdx +40 -37
- package/content/platform/order-group/concepts/order-splitting.mdx +41 -39
- package/content/platform/order-group/concepts/the-order-group.mdx +39 -32
- package/content/platform/order-group/guides/list-order-groups.mdx +96 -56
- package/content/platform/order-group/guides/retrieve-an-order-group.mdx +93 -42
- package/content/platform/order-group/guides/split-a-cart.mdx +115 -40
- package/content/platform/order-group/overview.mdx +42 -32
- package/content/platform/order-group/reference/data-models.mdx +48 -31
- package/content/platform/order-group/reference/events.mdx +29 -17
- package/content/platform/order-group/reference/links.mdx +90 -29
- package/content/platform/order-group/reference/service.mdx +55 -31
- package/content/platform/order-group/reference/workflows.mdx +83 -24
- package/content/platform/payout/concepts/account-lifecycle.mdx +64 -67
- package/content/platform/payout/concepts/accounts-and-onboarding.mdx +50 -40
- package/content/platform/payout/concepts/payout-pipeline.mdx +70 -73
- package/content/platform/payout/guides/create-a-payout-account.mdx +65 -41
- package/content/platform/payout/guides/process-a-provider-webhook.mdx +84 -38
- package/content/platform/payout/guides/start-provider-onboarding.mdx +90 -46
- package/content/platform/payout/overview.mdx +43 -34
- package/content/platform/payout/reference/data-models.mdx +63 -36
- package/content/platform/payout/reference/events.mdx +56 -30
- package/content/platform/payout/reference/links.mdx +52 -22
- package/content/platform/payout/reference/service.mdx +72 -33
- package/content/platform/payout/reference/workflows.mdx +80 -19
- package/content/platform/product-edit/concepts/change-actions.mdx +52 -45
- package/content/platform/product-edit/concepts/change-pipeline.mdx +60 -52
- package/content/platform/product-edit/concepts/status-and-auto-confirm.mdx +43 -46
- package/content/platform/product-edit/guides/confirm-or-decline-a-change.mdx +104 -56
- package/content/platform/product-edit/guides/edit-a-product.mdx +126 -46
- package/content/platform/product-edit/guides/request-a-revision.mdx +99 -39
- package/content/platform/product-edit/overview.mdx +41 -34
- package/content/platform/product-edit/reference/data-models.mdx +73 -47
- package/content/platform/product-edit/reference/events.mdx +39 -29
- package/content/platform/product-edit/reference/links.mdx +32 -24
- package/content/platform/product-edit/reference/service.mdx +45 -26
- package/content/platform/product-edit/reference/workflows.mdx +173 -31
- package/content/platform/review/concepts/product-vs-seller-reviews.mdx +42 -41
- package/content/platform/review/concepts/ratings-and-moderation.mdx +45 -44
- package/content/platform/review/concepts/the-review-model.mdx +52 -45
- package/content/platform/review/guides/compute-aggregate-ratings.mdx +62 -37
- package/content/platform/review/guides/create-a-review.mdx +109 -39
- package/content/platform/review/guides/moderate-a-review.mdx +83 -37
- package/content/platform/review/guides/respond-to-a-review.mdx +85 -40
- package/content/platform/review/overview.mdx +43 -33
- package/content/platform/review/reference/data-models.mdx +41 -27
- package/content/platform/review/reference/events.mdx +55 -37
- package/content/platform/review/reference/links.mdx +80 -22
- package/content/platform/review/reference/service.mdx +61 -33
- package/content/platform/review/reference/workflows.mdx +80 -24
- package/content/platform/store/concepts/lifecycle.mdx +68 -44
- package/content/platform/store/concepts/store-entity.mdx +45 -27
- package/content/platform/store/concepts/team.mdx +56 -35
- package/content/platform/store/guides/create-a-store.mdx +102 -35
- package/content/platform/store/guides/manage-the-team.mdx +122 -32
- package/content/platform/store/guides/moderate-a-store.mdx +107 -38
- package/content/platform/store/overview.mdx +41 -34
- package/content/platform/store/reference/data-models.mdx +132 -57
- package/content/platform/store/reference/events.mdx +42 -17
- package/content/platform/store/reference/links.mdx +67 -49
- package/content/platform/store/reference/service.mdx +105 -33
- package/content/platform/store/reference/workflows.mdx +304 -24
- package/content/references/panel-extensions/layouts.mdx +169 -0
- package/llms.txt +112 -111
- package/package.json +1 -1
|
@@ -1,35 +1,315 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
2
|
+
title: "Seller module workflows"
|
|
3
3
|
sidebarTitle: "Workflows"
|
|
4
|
-
description: "
|
|
4
|
+
description: "Every store, lifecycle, business-detail, and team workflow in the Seller module, with inputs, hooks, and events."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
This reference lists
|
|
8
|
-
domain. Import workflows from `@mercurjs/core/workflows` and run them against the
|
|
9
|
-
Medusa container.
|
|
7
|
+
This reference lists every workflow that writes Seller module data. Import them from `@mercurjs/core/workflows` and run them against the Medusa container: `await workflow(container).run({ input })`. Workflows roll back their completed steps when a later step fails.
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
```ts
|
|
10
|
+
import { approveSellerWorkflow } from "@mercurjs/core/workflows"
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
await approveSellerWorkflow(container).run({
|
|
13
|
+
input: { seller_id: "sel_01JD8Q1234567" },
|
|
14
|
+
})
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Workflows that take `additional_data` pass it to their hooks. Register a hook handler with `workflow.hooks.<hookName>(handler)`.
|
|
18
|
+
|
|
19
|
+
## createSellersWorkflow
|
|
20
|
+
|
|
21
|
+
Creates one or more stores, links each to the default region plus `region_ids`, and invites one member per store with `role_seller_administration`. Returns `SellerDTO[]`.
|
|
22
|
+
|
|
23
|
+
| Input | Type | Description |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| `sellers` | `CreateSellerDTO & { member, region_ids? }[]` | Store fields; `status` defaults to `pending_approval` |
|
|
26
|
+
| `sellers[].member` | `{ email: string }` | Required, the address that gets the invite |
|
|
27
|
+
| `sellers[].region_ids` | `string[]` | Optional, regions besides the default one |
|
|
28
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
29
|
+
|
|
30
|
+
- **Hooks**: `validate` (`{ input }`), `sellersCreated` (`{ sellers, additional_data }`)
|
|
31
|
+
- **Events**: `seller.created` per store, `member_invite.created` per invite
|
|
32
|
+
|
|
33
|
+
## createSellerAccountWorkflow
|
|
34
|
+
|
|
35
|
+
Creates one store in `pending_approval` and adds a member as its owner with `role_seller_administration`. Returns `SellerDTO`.
|
|
36
|
+
|
|
37
|
+
| Input | Type | Description |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| `auth_identity_id` | `string` | The auth identity to attach the member to |
|
|
40
|
+
| `seller` | `CreateSellerDTO` | Store fields; `status` is forced to `pending_approval` |
|
|
41
|
+
| `member_id` | `string` | Optional, an existing member to make owner |
|
|
42
|
+
| `member_email` | `string` | Used when `member_id` is absent to upsert a member |
|
|
43
|
+
| `first_name`, `last_name` | `string` | Optional, set on a new member |
|
|
44
|
+
| `address` | `UpdateSellerAddressDTO` | Optional, written through `updateSellerAddressWorkflow` |
|
|
45
|
+
| `professional_details` | `UpdateProfessionalDetailsDTO` | Optional |
|
|
46
|
+
| `payment_details` | `UpdatePaymentDetailsDTO` | Optional |
|
|
47
|
+
| `region_ids` | `string[]` | Optional, regions besides the default one |
|
|
48
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
49
|
+
|
|
50
|
+
- **Hooks**: `validate` (`{ input }`), `sellerAccountCreated` (`{ seller, member_id, additional_data }`)
|
|
51
|
+
- **Events**: `seller.created`
|
|
52
|
+
|
|
53
|
+
## updateSellersWorkflow
|
|
54
|
+
|
|
55
|
+
Updates every store that matches `selector` with the same `update`. Returns `SellerDTO[]`.
|
|
56
|
+
|
|
57
|
+
| Input | Type | Description |
|
|
58
|
+
| --- | --- | --- |
|
|
59
|
+
| `selector` | `Record<string, unknown>` | Filters, such as `{ id: "sel_01JD8Q1234567" }` |
|
|
60
|
+
| `update` | `UpdateSellerDTO` | Fields to set |
|
|
61
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
62
|
+
|
|
63
|
+
- **Hooks**: `sellersUpdated` (`{ sellers, additional_data }`)
|
|
64
|
+
- **Events**: `seller.updated` per store
|
|
65
|
+
|
|
66
|
+
## deleteSellersWorkflow
|
|
67
|
+
|
|
68
|
+
Soft deletes stores by id. Compensation restores them.
|
|
69
|
+
|
|
70
|
+
| Input | Type | Description |
|
|
71
|
+
| --- | --- | --- |
|
|
72
|
+
| `ids` | `string[]` | Seller ids |
|
|
73
|
+
|
|
74
|
+
- **Hooks**: none
|
|
75
|
+
- **Events**: `seller.deleted` per store
|
|
76
|
+
|
|
77
|
+
## approveSellerWorkflow
|
|
78
|
+
|
|
79
|
+
Moves a `pending_approval` store to `open`, clears `status_reason`, and sets `approved_at` if it’s empty.
|
|
80
|
+
|
|
81
|
+
| Input | Type | Description |
|
|
82
|
+
| --- | --- | --- |
|
|
83
|
+
| `seller_id` | `string` | The store to approve |
|
|
84
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
85
|
+
|
|
86
|
+
- **Hooks**: `sellerApproved` (`{ seller_id, additional_data }`)
|
|
87
|
+
- **Events**: `seller.approved`
|
|
88
|
+
|
|
89
|
+
## suspendSellerWorkflow
|
|
90
|
+
|
|
91
|
+
Moves a `pending_approval` or `open` store to `suspended`, saves `reason` in `status_reason`, and sets `rejected_at` if it’s empty.
|
|
92
|
+
|
|
93
|
+
| Input | Type | Description |
|
|
94
|
+
| --- | --- | --- |
|
|
95
|
+
| `seller_id` | `string` | The store to suspend |
|
|
96
|
+
| `reason` | `string` | Optional |
|
|
97
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
98
|
+
|
|
99
|
+
- **Hooks**: `sellerSuspended` (`{ seller_id, additional_data }`)
|
|
100
|
+
- **Events**: `seller.suspended`
|
|
101
|
+
|
|
102
|
+
## unsuspendSellerWorkflow
|
|
103
|
+
|
|
104
|
+
Moves a `suspended` store to `open` and clears `status_reason`.
|
|
105
|
+
|
|
106
|
+
| Input | Type | Description |
|
|
107
|
+
| --- | --- | --- |
|
|
108
|
+
| `seller_id` | `string` | The store to reopen |
|
|
109
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
110
|
+
|
|
111
|
+
- **Hooks**: `sellerUnsuspended` (`{ seller_id, additional_data }`)
|
|
112
|
+
- **Events**: `seller.unsuspended`
|
|
113
|
+
|
|
114
|
+
## terminateSellerWorkflow
|
|
115
|
+
|
|
116
|
+
Moves a `pending_approval` or `suspended` store to `terminated` and saves `reason` in `status_reason`. Fails for an `open` store.
|
|
117
|
+
|
|
118
|
+
| Input | Type | Description |
|
|
119
|
+
| --- | --- | --- |
|
|
120
|
+
| `seller_id` | `string` | The store to terminate |
|
|
121
|
+
| `reason` | `string` | Optional |
|
|
122
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
123
|
+
|
|
124
|
+
- **Hooks**: `sellerTerminated` (`{ seller_id, additional_data }`)
|
|
125
|
+
- **Events**: `seller.terminated`
|
|
126
|
+
|
|
127
|
+
## unterminateSellerWorkflow
|
|
128
|
+
|
|
129
|
+
Moves a `terminated` store to `suspended` and clears `status_reason`.
|
|
130
|
+
|
|
131
|
+
| Input | Type | Description |
|
|
132
|
+
| --- | --- | --- |
|
|
133
|
+
| `seller_id` | `string` | The store to restore |
|
|
134
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
135
|
+
|
|
136
|
+
- **Hooks**: `sellerUnterminated` (`{ seller_id, additional_data }`)
|
|
137
|
+
- **Events**: `seller.unterminated`
|
|
138
|
+
|
|
139
|
+
## linkSellerRegionsWorkflow
|
|
140
|
+
|
|
141
|
+
Adds and removes store region links in one run. Fails if a region or seller doesn’t exist, or if a store would be left with no region.
|
|
142
|
+
|
|
143
|
+
| Input | Type | Description |
|
|
144
|
+
| --- | --- | --- |
|
|
145
|
+
| `add` | `{ seller_id, region_id }[]` | Optional, links to create |
|
|
146
|
+
| `remove` | `{ seller_id, region_id }[]` | Optional, links to dismiss |
|
|
147
|
+
|
|
148
|
+
- **Hooks**: none
|
|
149
|
+
- **Events**: none
|
|
150
|
+
|
|
151
|
+
## updateSellerAddressWorkflow
|
|
152
|
+
|
|
153
|
+
Creates or updates a store’s `SellerAddress`. Returns `SellerAddressDTO`.
|
|
154
|
+
|
|
155
|
+
| Input | Type | Description |
|
|
156
|
+
| --- | --- | --- |
|
|
157
|
+
| `seller_id` | `string` | The store |
|
|
158
|
+
| `data` | `UpdateSellerAddressDTO` | Address fields |
|
|
159
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
160
|
+
|
|
161
|
+
- **Hooks**: `addressUpdated` (`{ address, additional_data }`)
|
|
162
|
+
- **Events**: none
|
|
163
|
+
|
|
164
|
+
## updateSellerProfessionalDetailsWorkflow
|
|
165
|
+
|
|
166
|
+
Creates or updates a store’s `ProfessionalDetails`. Returns `ProfessionalDetailsDTO`.
|
|
167
|
+
|
|
168
|
+
| Input | Type | Description |
|
|
169
|
+
| --- | --- | --- |
|
|
170
|
+
| `seller_id` | `string` | The store |
|
|
171
|
+
| `data` | `UpdateProfessionalDetailsDTO` | `corporate_name`, `registration_number`, `tax_id` |
|
|
172
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
173
|
+
|
|
174
|
+
- **Hooks**: `professionalDetailsUpdated` (`{ professional_details, additional_data }`)
|
|
175
|
+
- **Events**: none
|
|
176
|
+
|
|
177
|
+
## deleteSellerProfessionalDetailsWorkflow
|
|
178
|
+
|
|
179
|
+
Deletes a store’s `ProfessionalDetails`, if it has any.
|
|
180
|
+
|
|
181
|
+
| Input | Type | Description |
|
|
182
|
+
| --- | --- | --- |
|
|
183
|
+
| `seller_id` | `string` | The store |
|
|
184
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
185
|
+
|
|
186
|
+
- **Hooks**: `professionalDetailsDeleted` (`{ seller_id, additional_data }`)
|
|
187
|
+
- **Events**: none
|
|
188
|
+
|
|
189
|
+
## updateSellerPaymentDetailsWorkflow
|
|
190
|
+
|
|
191
|
+
Creates or updates a store’s `PaymentDetails`. Returns `PaymentDetailsDTO`.
|
|
192
|
+
|
|
193
|
+
| Input | Type | Description |
|
|
194
|
+
| --- | --- | --- |
|
|
195
|
+
| `seller_id` | `string` | The store |
|
|
196
|
+
| `data` | `UpdatePaymentDetailsDTO` | Bank account fields |
|
|
197
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
198
|
+
|
|
199
|
+
- **Hooks**: `paymentDetailsUpdated` (`{ payment_details, additional_data }`)
|
|
200
|
+
- **Events**: none
|
|
201
|
+
|
|
202
|
+
## inviteSellerWorkflow
|
|
203
|
+
|
|
204
|
+
Sends an email that invites someone to register a new store. It creates a notification with the template `newSellerInvitation` on the `email` channel, and writes no Seller module records.
|
|
205
|
+
|
|
206
|
+
| Input | Type | Description |
|
|
207
|
+
| --- | --- | --- |
|
|
208
|
+
| `email` | `string` | The prospective seller |
|
|
209
|
+
| `registration_url` | `string` | Optional, the link in the email’s button |
|
|
210
|
+
|
|
211
|
+
- **Hooks**: none
|
|
212
|
+
- **Events**: none
|
|
213
|
+
|
|
214
|
+
## createMemberInvitesWorkflow
|
|
215
|
+
|
|
216
|
+
Creates team invites with signed tokens. Fails if an email already belongs to the store. Returns `MemberInviteDTO[]`.
|
|
217
|
+
|
|
218
|
+
| Input | Type | Description |
|
|
219
|
+
| --- | --- | --- |
|
|
220
|
+
| `[].seller_id` | `string` | The store |
|
|
221
|
+
| `[].email` | `string` | The invitee |
|
|
222
|
+
| `[].role_id` | `string` | A `SellerRole` value |
|
|
223
|
+
|
|
224
|
+
The input is an array of invites, not an object.
|
|
225
|
+
|
|
226
|
+
- **Hooks**: none
|
|
227
|
+
- **Events**: `member_invite.created` per invite
|
|
228
|
+
|
|
229
|
+
## resendMemberInviteWorkflow
|
|
230
|
+
|
|
231
|
+
Deletes an invite and creates a replacement with the same email and role, a new token, and a new expiry. Returns `MemberInviteDTO[]`.
|
|
232
|
+
|
|
233
|
+
| Input | Type | Description |
|
|
234
|
+
| --- | --- | --- |
|
|
235
|
+
| `invite_id` | `string` | The invite to replace |
|
|
236
|
+
| `seller_id` | `string` | The store that owns it |
|
|
237
|
+
|
|
238
|
+
- **Hooks**: none
|
|
239
|
+
- **Events**: `member_invite.created`
|
|
240
|
+
|
|
241
|
+
## deleteMemberInviteWorkflow
|
|
242
|
+
|
|
243
|
+
Deletes an invite.
|
|
244
|
+
|
|
245
|
+
| Input | Type | Description |
|
|
246
|
+
| --- | --- | --- |
|
|
247
|
+
| `invite_id` | `string` | The invite to delete |
|
|
248
|
+
|
|
249
|
+
- **Hooks**: none
|
|
250
|
+
- **Events**: none
|
|
251
|
+
|
|
252
|
+
## acceptMemberInviteWorkflow
|
|
253
|
+
|
|
254
|
+
Validates an invite token, upserts the member by email, creates the membership with the invite’s role, and deletes the invite. The member becomes owner when the store has no owner yet. Returns `MemberDTO`.
|
|
255
|
+
|
|
256
|
+
| Input | Type | Description |
|
|
257
|
+
| --- | --- | --- |
|
|
258
|
+
| `invite_token` | `string` | The token from the invite |
|
|
259
|
+
| `auth_identity_id` | `string` | The invitee’s auth identity |
|
|
260
|
+
| `member_id` | `string` | Optional; when set, the auth identity isn’t updated |
|
|
261
|
+
| `first_name`, `last_name` | `string` | Optional, set on a new member |
|
|
262
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
263
|
+
|
|
264
|
+
- **Hooks**: `validate` (`{ input, invite }`), `memberInviteAccepted` (`{ member, invite, additional_data }`)
|
|
265
|
+
- **Events**: `member_invite.accepted`
|
|
266
|
+
|
|
267
|
+
## addSellerMemberWorkflow
|
|
268
|
+
|
|
269
|
+
Adds an existing member to a store. Returns the `SellerMember`.
|
|
270
|
+
|
|
271
|
+
| Input | Type | Description |
|
|
272
|
+
| --- | --- | --- |
|
|
273
|
+
| `seller_id` | `string` | The store |
|
|
274
|
+
| `member_id` | `string` | The existing member |
|
|
275
|
+
| `role_id` | `string` | A `SellerRole` value |
|
|
276
|
+
|
|
277
|
+
- **Hooks**: none
|
|
278
|
+
- **Events**: `seller_member.created`
|
|
279
|
+
|
|
280
|
+
## updateMemberRoleWorkflow
|
|
281
|
+
|
|
282
|
+
Changes the role on a membership. Fails for the owner membership.
|
|
283
|
+
|
|
284
|
+
| Input | Type | Description |
|
|
14
285
|
| --- | --- | --- |
|
|
15
|
-
| `
|
|
16
|
-
| `
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
286
|
+
| `seller_member_id` | `string` | The membership id (`selmem_…`) |
|
|
287
|
+
| `role_id` | `string` | A `SellerRole` value |
|
|
288
|
+
|
|
289
|
+
- **Hooks**: none
|
|
290
|
+
- **Events**: `seller_member.updated`
|
|
291
|
+
|
|
292
|
+
## removeSellerMemberWorkflow
|
|
293
|
+
|
|
294
|
+
Deletes a membership and keeps the `Member` record. Fails for the owner membership.
|
|
295
|
+
|
|
296
|
+
| Input | Type | Description |
|
|
297
|
+
| --- | --- | --- |
|
|
298
|
+
| `seller_member_id` | `string` | The membership id |
|
|
299
|
+
| `seller_id` | `string` | The store, included in the event payload |
|
|
300
|
+
|
|
301
|
+
- **Hooks**: none
|
|
302
|
+
- **Events**: `seller_member.deleted`
|
|
303
|
+
|
|
304
|
+
## updateMemberWorkflow
|
|
22
305
|
|
|
23
|
-
|
|
306
|
+
Updates the profile of every member that matches `selector`. Returns `MemberDTO[]`.
|
|
24
307
|
|
|
25
|
-
|
|
|
308
|
+
| Input | Type | Description |
|
|
26
309
|
| --- | --- | --- |
|
|
27
|
-
| `
|
|
28
|
-
| `
|
|
29
|
-
| `
|
|
30
|
-
| `removeSellerMemberWorkflow` | `{ seller_id, member_id }` | Revoke access |
|
|
31
|
-
| `updateMemberRoleWorkflow` | `{ id, role_id }` | Change a member's role |
|
|
310
|
+
| `selector` | `Record<string, unknown>` | Filters, such as `{ id: "mem_01JD8Q1234567" }` |
|
|
311
|
+
| `update` | `{ first_name?, last_name?, locale? }` | Profile fields |
|
|
312
|
+
| `additional_data` | `Record<string, unknown>` | Optional, passed to hooks |
|
|
32
313
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
a store changes, see the [Event reference](/platform/store/reference/events).
|
|
314
|
+
- **Hooks**: `membersUpdated` (`{ members, additional_data }`)
|
|
315
|
+
- **Events**: none
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Layouts and layers"
|
|
3
|
+
sidebarTitle: "Layouts and layers"
|
|
4
|
+
description: "How extensions from plugins and your project stack, how a page exposes its sections, and how to hide, reorder, replace or wrap what a page renders."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Every panel extension comes from an ordered list of **layers**:
|
|
8
|
+
|
|
9
|
+
1. `@mercurjs/admin` or `@mercurjs/vendor` itself,
|
|
10
|
+
2. each plugin in `medusa-config` `plugins` order, from its built `.medusa/server/src/<admin|vendor>/index.mjs`,
|
|
11
|
+
3. your Medusa project's `src/admin` or `src/vendor` folder (next to `medusa-config.ts`),
|
|
12
|
+
4. the panel app's own `src` folder.
|
|
13
|
+
|
|
14
|
+
A later layer wins. A route at a path an earlier layer declared replaces it, a widget with the same `id`
|
|
15
|
+
replaces it, a translation key overrides it, and a layout preference overrides it field by field. Every
|
|
16
|
+
layer uses the same folders: `routes/`, `widgets/`, `custom-fields/`, `layouts/`, `i18n/` and a
|
|
17
|
+
`_layouts.ts` file.
|
|
18
|
+
|
|
19
|
+
## Pages expose named entries
|
|
20
|
+
|
|
21
|
+
A detail or list page renders a `LayoutComposer`. It names the zone widgets target, the layout it uses,
|
|
22
|
+
and gives each section a stable entry id:
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import { CORE_LAYOUT_IDS } from "@mercurjs/dashboard-sdk"
|
|
26
|
+
import { LayoutComposer, detailPageDefaultEntries } from "@mercurjs/dashboard-shared"
|
|
27
|
+
|
|
28
|
+
<LayoutComposer
|
|
29
|
+
widgetsZonePrefix="product.detail"
|
|
30
|
+
preferredLayoutId={CORE_LAYOUT_IDS.TWO_COLUMN}
|
|
31
|
+
data={product}
|
|
32
|
+
sections={{
|
|
33
|
+
main: (
|
|
34
|
+
<>
|
|
35
|
+
<LayoutComposer.Entry id="ProductGeneralSection">
|
|
36
|
+
<ProductGeneralSection product={product} />
|
|
37
|
+
</LayoutComposer.Entry>
|
|
38
|
+
{detailPageDefaultEntries(product)}
|
|
39
|
+
</>
|
|
40
|
+
),
|
|
41
|
+
side: (
|
|
42
|
+
<LayoutComposer.Entry id="ProductOrganizationSection">
|
|
43
|
+
<ProductOrganizationSection product={product} />
|
|
44
|
+
</LayoutComposer.Entry>
|
|
45
|
+
),
|
|
46
|
+
}}
|
|
47
|
+
/>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The page's own sections become entries `core:ProductGeneralSection`, `core:MetadataSection` and so on;
|
|
51
|
+
widgets become `widget:<id>`. Use the same component on your own pages and the build emits their zones and
|
|
52
|
+
entry ids into `extension-targets.d.ts`, so the next layer gets autocompletion for them.
|
|
53
|
+
|
|
54
|
+
## Place a widget
|
|
55
|
+
|
|
56
|
+
`zone` is the page prefix or one of its sections. `section` and `order` place the widget among the page's
|
|
57
|
+
entries; core entries sit at order `0`, so a negative order renders before them and no order renders after.
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
export const config = defineWidgetConfig({
|
|
61
|
+
zone: "product.detail",
|
|
62
|
+
id: "seller-offers",
|
|
63
|
+
section: "side",
|
|
64
|
+
order: -1,
|
|
65
|
+
})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`replace` takes the slot of a page entry. The widget receives `renderDefault` to render what it replaced:
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
export const config = defineWidgetConfig({
|
|
72
|
+
zone: "product.detail",
|
|
73
|
+
id: "general-with-seller",
|
|
74
|
+
replace: "core:ProductGeneralSection",
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
export default function GeneralWithSeller({ data, renderDefault }) {
|
|
78
|
+
return (
|
|
79
|
+
<>
|
|
80
|
+
{renderDefault?.()}
|
|
81
|
+
<SellerBadge product={data} />
|
|
82
|
+
</>
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The legacy `product.detail.side.before` and `.after` zones still work and map to the first and last
|
|
88
|
+
position of that section.
|
|
89
|
+
|
|
90
|
+
## Hide, reorder and move entries: `_layouts.ts`
|
|
91
|
+
|
|
92
|
+
A layer's `_layouts.ts` holds per-zone preferences that apply to everyone. The sidebars are zones too
|
|
93
|
+
(`nav.main`, `nav.settings`) with `nav:<path>` entries, which replaces `_navigation.ts`.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { defineLayoutPreferences } from "@mercurjs/dashboard-sdk"
|
|
97
|
+
import { Tag } from "@medusajs/icons"
|
|
98
|
+
|
|
99
|
+
export default defineLayoutPreferences({
|
|
100
|
+
"product.detail": {
|
|
101
|
+
entries: {
|
|
102
|
+
"core:ProductMediaSection": { hidden: true },
|
|
103
|
+
"widget:seller-offers": { section: "main", order: 1 },
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
"nav.main": {
|
|
107
|
+
groups: [{ id: "finance", label: "Finance", rank: 5 }],
|
|
108
|
+
entries: {
|
|
109
|
+
"nav:/products": { label: "Catalog", icon: Tag, order: -1 },
|
|
110
|
+
"nav:/payouts": { section: "finance" },
|
|
111
|
+
"nav:/price-lists": { parent: null },
|
|
112
|
+
"nav:/settings/commissions": { hidden: true },
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
})
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Override a page
|
|
119
|
+
|
|
120
|
+
A `page.tsx` at a path an earlier layer already serves replaces it. The component receives `renderDefault`,
|
|
121
|
+
which renders the page it replaced:
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
export default function ProductDetail({ renderDefault }) {
|
|
125
|
+
return (
|
|
126
|
+
<>
|
|
127
|
+
<ApprovalBanner />
|
|
128
|
+
{renderDefault?.()}
|
|
129
|
+
</>
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Block the panel behind a flow
|
|
135
|
+
|
|
136
|
+
There is no app-wrapper seam, as in Medusa. A flow every member must complete before using the panel
|
|
137
|
+
(terms acceptance, a verification step) is a page plus a redirect: a `routes/<flow>/page.tsx` with
|
|
138
|
+
`config.public = true` so it renders in the bare public layout, and a widget on the `topbar` zone that
|
|
139
|
+
checks the status with `useQuery` and `navigate`s to the page while the flow is outstanding. The API keeps
|
|
140
|
+
enforcing the rule with a 403 for everything else.
|
|
141
|
+
|
|
142
|
+
## Register a layout
|
|
143
|
+
|
|
144
|
+
A file under `layouts/` registers a layout other pages can pick. Augment `LayoutSectionRegistry` so the
|
|
145
|
+
`sections` prop is typed.
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
import { defineLayoutConfig } from "@mercurjs/dashboard-sdk"
|
|
149
|
+
|
|
150
|
+
export default defineLayoutConfig({
|
|
151
|
+
id: "erp:three-column",
|
|
152
|
+
sections: [{ id: "main" }, { id: "left" }, { id: "right" }],
|
|
153
|
+
Component: ({ sections }) => (
|
|
154
|
+
<div className="grid grid-cols-3 gap-3">
|
|
155
|
+
{sections.left}
|
|
156
|
+
{sections.main}
|
|
157
|
+
{sections.right}
|
|
158
|
+
</div>
|
|
159
|
+
),
|
|
160
|
+
})
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
declare module "@mercurjs/dashboard-sdk" {
|
|
165
|
+
interface LayoutSectionRegistry {
|
|
166
|
+
"erp:three-column": "main" | "left" | "right"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|