docs: general fixes and overall changes (#7258)
* editing halfway * edited second half * adjust starter steps * fix build * typo fix
This commit is contained in:
@@ -43,7 +43,7 @@ export const updateProductHighlights = [
|
||||
["13", "resolve", "Resolve the `ProductService` from the Medusa container."],
|
||||
["16", "previousProductData", "Retrieve the `previousProductData` to pass it to the compensation function."],
|
||||
["19", "", "Update the product."],
|
||||
["33", "", "Revert the product’s data using the `previousProductData` passed from the step to the compensation function."]
|
||||
["39", "", "Revert the product’s data using the `previousProductData` passed from the step to the compensation function."]
|
||||
]
|
||||
|
||||
```ts title="src/workflows/update-product-erp/steps/update-product.ts" highlights={updateProductHighlights}
|
||||
@@ -65,7 +65,7 @@ const updateProduct = createStep(
|
||||
const previousProductData =
|
||||
await productModuleService.retrieve(id)
|
||||
|
||||
const product = await productModuleService.update([input])
|
||||
const product = await productModuleService.update(id, input)
|
||||
|
||||
return new StepResponse(product, {
|
||||
// pass to compensation function
|
||||
@@ -77,15 +77,37 @@ const updateProduct = createStep(
|
||||
const productModuleService: IProductModuleService =
|
||||
context.container.resolve(ModuleRegistrationName.PRODUCT)
|
||||
|
||||
const { type, ...previousData } = previousProductData
|
||||
const {
|
||||
id,
|
||||
type,
|
||||
options,
|
||||
variants,
|
||||
...previousData
|
||||
} = previousProductData
|
||||
|
||||
await productModuleService.update([
|
||||
await productModuleService.update(
|
||||
id,
|
||||
{
|
||||
...previousData,
|
||||
},
|
||||
])
|
||||
variants: variants.map((variant) => {
|
||||
const variantOptions = {}
|
||||
|
||||
await productModuleService.updateTypes(type)
|
||||
variant.options.forEach((option) => {
|
||||
variantOptions[option.option.title] = option.value
|
||||
})
|
||||
|
||||
return {
|
||||
...variant,
|
||||
options: variantOptions
|
||||
}
|
||||
}),
|
||||
options: options.map((option) => ({
|
||||
...option,
|
||||
values: option.values.map((value) => value.value)
|
||||
})),
|
||||
type_id: type.id
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -102,25 +124,25 @@ You also pass a compensation function as a second parameter to `createStep`. The
|
||||
|
||||
In the compensation function, you revert the product’s data using the `previousProductData` passed from the step to the compensation function.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
The compensation functions of each step ensure data consistency across Medusa and external services and systems when errors occur.
|
||||
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
## 3. Create Step 2: Update ERP
|
||||
|
||||
The second step in the workflow receives the same input. It updates the product’s details in the ERP system using the `ErpService`.
|
||||
The second step in the workflow receives the same input. It updates the product’s details in the ERP system.
|
||||
|
||||
<Note>
|
||||
|
||||
The `ErpModuleService` used is assumed to be created in a module.
|
||||
|
||||
</Note>
|
||||
|
||||
Create the file `src/workflows/update-product-erp/steps/update-erp.ts` with the following content:
|
||||
|
||||
export const updateErpHighlights = [
|
||||
["12", "resolve", "Resolve the `ErpService` from the Medusa container."],
|
||||
["12", "resolve", "Resolve the `erpModuleService` from the Medusa container."],
|
||||
["17", "previousErpData", "Retrieve the `previousErpData` to pass it to the compensation function."],
|
||||
["21", "updateProductErpData", "Update the product’s ERP data and return the data from the ERP system."],
|
||||
["34", "updateProductErpData", "Revert the product's data in the ERP system to its previous state using the `previousErpData`."]
|
||||
["37", "updateProductErpData", "Revert the product's data in the ERP system to its previous state using the `previousErpData`."]
|
||||
]
|
||||
|
||||
```ts title="src/workflows/update-product-erp/steps/update-erp.ts" highlights={updateErpHighlights}
|
||||
@@ -129,22 +151,25 @@ import {
|
||||
StepResponse,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { UpdateProductAndErpWorkflowInput } from ".."
|
||||
import ErpService from "../../../services/erp"
|
||||
import ErpModuleService from "../../../modules/erp/service"
|
||||
|
||||
const updateErp = createStep(
|
||||
"update-erp",
|
||||
async (input: UpdateProductAndErpWorkflowInput, context) => {
|
||||
const erpService: ErpService =
|
||||
context.container.resolve("erpService")
|
||||
const erpModuleService: ErpModuleService =
|
||||
context.container.resolve("erpModuleService")
|
||||
|
||||
const { id, ...updatedData } = input
|
||||
|
||||
// get previous ERP data
|
||||
const previousErpData =
|
||||
await erpService.retrieveProductErpDetails(id)
|
||||
await erpModuleService.retrieveProductErpDetails(id)
|
||||
|
||||
const updatedErpData =
|
||||
await erpService.updateProductErpData(id, updatedData)
|
||||
await erpModuleService.updateProductErpData(
|
||||
id,
|
||||
updatedData
|
||||
)
|
||||
|
||||
return new StepResponse(updatedErpData, {
|
||||
// pass to compensation function
|
||||
@@ -154,7 +179,7 @@ const updateErp = createStep(
|
||||
},
|
||||
// compensation function
|
||||
async ({ previousErpData, productId }, context) => {
|
||||
const erpService: ErpService =
|
||||
const erpService: ErpModuleService =
|
||||
context.container.resolve("erpService")
|
||||
|
||||
await erpService.updateProductErpData(
|
||||
@@ -169,7 +194,7 @@ export default updateErp
|
||||
|
||||
In the step:
|
||||
|
||||
- You resolve the `ErpService` from the Medusa container.
|
||||
- You resolve the `erpModuleService` from the Medusa container.
|
||||
- You retrieve the `previousErpData` to pass it to the compensation function.
|
||||
- You update the product’s ERP data and return the data from the ERP system.
|
||||
|
||||
@@ -228,8 +253,13 @@ import updateProductAndErpWorkflow, {
|
||||
UpdateProductAndErpWorkflowInput,
|
||||
} from "../../../../../workflows/update-product-erp"
|
||||
|
||||
type ProductErpReq = Omit<
|
||||
UpdateProductAndErpWorkflowInput,
|
||||
"id"
|
||||
>
|
||||
|
||||
export const POST = async (
|
||||
req: MedusaRequest,
|
||||
req: MedusaRequest<ProductErpReq>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
// skipping validation for simplicity
|
||||
|
||||
@@ -10,9 +10,7 @@ In this chapter, you'll learn how to add a compensation function to a step.
|
||||
|
||||
Errors can occur in a workflow. To avoid data inconsistency, define a function to run when an error occurs in a step. This function is called the compensation function.
|
||||
|
||||
Each step can have a compensation function. The compensation function only runs if an error occurs throughout the Workflow. It’s useful to undo or roll back actions you’ve performed in a step.
|
||||
|
||||
For example, change step one to add a compensation function and step two to throw an error:
|
||||
For example:
|
||||
|
||||
```ts title="src/workflows/hello-world.ts" highlights={[["16"], ["17"], ["18"]]}
|
||||
// other imports...
|
||||
@@ -34,7 +32,16 @@ const step1 = createStep(
|
||||
console.log("Oops! Rolling back my changes...")
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
Each step can have a compensation function. The compensation function only runs if an error occurs throughout the Workflow. It’s useful to undo or roll back actions you’ve performed in a step.
|
||||
|
||||
### Test Compensation Function
|
||||
|
||||
1. Add another step that throws an error:
|
||||
|
||||
```ts title="src/workflows/hello-world.ts"
|
||||
// ...
|
||||
const step2 = createStep(
|
||||
"step-2",
|
||||
async () => {
|
||||
@@ -43,9 +50,7 @@ const step2 = createStep(
|
||||
)
|
||||
```
|
||||
|
||||
### Test Compensation Function
|
||||
|
||||
1. Use the steps in a workflow. For example:
|
||||
2. Use the steps in a workflow. For example:
|
||||
|
||||
```ts title="src/workflows/hello-world.ts"
|
||||
import {
|
||||
@@ -74,7 +79,7 @@ const myWorkflow = createWorkflow<
|
||||
export default myWorkflow
|
||||
```
|
||||
|
||||
2. Execute the workflow from a resource, such as an API route:
|
||||
3. Execute the workflow from a resource, such as an API route:
|
||||
|
||||
```ts title="src/api/store/workflow/route.ts"
|
||||
import type {
|
||||
@@ -94,13 +99,13 @@ export async function GET(
|
||||
}
|
||||
```
|
||||
|
||||
3. Run the Medusa application:
|
||||
4. Run the Medusa application:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run dev
|
||||
```
|
||||
|
||||
4. Send a `GET` request to `/store/workflow`:
|
||||
5. Send a `GET` request to `/store/workflow`:
|
||||
|
||||
```bash apiTesting testApiMethod="GET" testApiUrl="http://localhost:9000/store/workflows"
|
||||
curl http://localhost:9000/store/workflow
|
||||
|
||||
@@ -69,7 +69,7 @@ const myWorkflow = createWorkflow<
|
||||
const str2 = step2(input)
|
||||
|
||||
return {
|
||||
message: `${input.str1}${input.str2}`,
|
||||
message: `${str1}${str2}`,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ A long-running workflow is a workflow that continues its execution in the backgr
|
||||
|
||||
## Configure Long-Running Workflows
|
||||
|
||||
A workflow is considered long-running if one or more of its steps have their `async` configuration set to `true`.
|
||||
A workflow is considered long-running if at least one step has its `async` configuration set to `true`.
|
||||
|
||||
For example, consider the following workflow and steps:
|
||||
|
||||
|
||||
@@ -12,6 +12,12 @@ By default, a workflow doesn’t have a timeout. It continues execution until it
|
||||
|
||||
You can configure a workflow’s timeout to indicate how long the workflow can run. Once the specified time is passed and the workflow is still running, the workflow is considered failed and an error is thrown.
|
||||
|
||||
<Note>
|
||||
|
||||
Timeout doesn't stop the execution of a running step. The timeout only affects the status of the workflow and its result.
|
||||
|
||||
</Note>
|
||||
|
||||
For example:
|
||||
|
||||
```ts title="src/workflows/hello-world.ts" highlights={[["22"]]}
|
||||
@@ -63,6 +69,12 @@ A workflow’s timeout error is returned in the `errors` property of the workflo
|
||||
|
||||
Alternatively, you can configure timeout for a step rather than the entire workflow.
|
||||
|
||||
<Note>
|
||||
|
||||
As mentioned in the previous section, the timeout doesn't stop the execution of the step. It only affects the step's status and output.
|
||||
|
||||
</Note>
|
||||
|
||||
For example:
|
||||
|
||||
```tsx
|
||||
|
||||
Reference in New Issue
Block a user