Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(workflows,medusa,utils): add medusa v2 feature flag #5603

Merged
merged 14 commits into from
Nov 13, 2023
Merged
7 changes: 7 additions & 0 deletions .changeset/selfish-planets-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@medusajs/workflows": minor
"@medusajs/medusa": patch
"@medusajs/utils": minor
---

feat(workflows,medusa,utils): add medusa v2 feature flag
2 changes: 1 addition & 1 deletion .github/workflows/test-cli-with-database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,4 @@ jobs:
working-directory: ../cli-test

- name: Testing server
uses: ./.github/actions/test-server
uses: ./.github/actions/test-server
22 changes: 12 additions & 10 deletions integration-tests/environment-helpers/use-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ const path = require("path")

const { getConfigFile } = require("medusa-core-utils")
const { asValue } = require("awilix")
const { isObject, createMedusaContainer } = require("@medusajs/utils")
const {
isObject,
createMedusaContainer,
MedusaV2Flag,
} = require("@medusajs/utils")
const { dropDatabase } = require("pg-god")
const { DataSource } = require("typeorm")
const dbFactory = require("./use-template-db")
Expand Down Expand Up @@ -140,27 +144,25 @@ module.exports = {

instance.setDb(dbDataSource)

const IsolateProductDomainFeatureFlag =
require("@medusajs/medusa/dist/loaders/feature-flags/isolate-product-domain").default
const IsolatePricingDomainFeatureFlag =
require("@medusajs/medusa/dist/loaders/feature-flags/isolate-pricing-domain").default

if (
featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key) ||
featureFlagRouter.isFeatureEnabled(IsolatePricingDomainFeatureFlag.key)
) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
const pgConnectionLoader =
require("@medusajs/medusa/dist/loaders/pg-connection").default

const featureFlagLoader =
require("@medusajs/medusa/dist/loaders/feature-flags").default

const medusaAppLoader =
require("@medusajs/medusa/dist/loaders/medusa-app").default

const container = createMedusaContainer()

const featureFlagRouter = await featureFlagLoader(configModule)

container.register({
[ContainerRegistrationKeys.CONFIG_MODULE]: asValue(configModule),
[ContainerRegistrationKeys.LOGGER]: asValue(console),
[ContainerRegistrationKeys.MANAGER]: asValue(dbDataSource.manager),
featureFlagRouter: asValue(featureFlagRouter),
})

const pgConnection = await pgConnectionLoader({ configModule, container })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ const adminHeaders = {
}

const env = {
MEDUSA_FF_ISOLATE_PRICING_DOMAIN: true,
MEDUSA_FF_ISOLATE_PRODUCT_DOMAIN: true,
MEDUSA_FF_MEDUSA_V2: true,
}

describe("Link Modules", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ const adminHeaders = {
}

const env = {
MEDUSA_FF_ISOLATE_PRICING_DOMAIN: true,
MEDUSA_FF_ISOLATE_PRODUCT_DOMAIN: true,
MEDUSA_FF_MEDUSA_V2: true,
}

describe("[Product & Pricing Module] POST /admin/products", () => {
Expand Down
46 changes: 27 additions & 19 deletions integration-tests/plugins/__tests__/product/admin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import adminSeeder from "../../../../helpers/admin-seeder"
import productSeeder from "../../../../helpers/product-seeder"

import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
import { Workflows } from "@medusajs/workflows"
import { MedusaV2Flag } from "@medusajs/utils"
import { AxiosInstance } from "axios"
import { getContainer } from "../../../../environment-helpers/use-container"
import {
simpleProductFactory,
simpleSalesChannelFactory,
} from "../../../../factories"
import { createDefaultRuleTypes } from "../../../helpers/create-default-rule-types"

jest.setTimeout(5000000)

Expand All @@ -23,15 +24,19 @@ const adminHeaders = {
},
}

const env = {
MEDUSA_FF_MEDUSA_V2: true,
}

describe("/admin/products", () => {
let dbConnection
let shutdownServer
let medusaContainer

beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", "..", ".."))
dbConnection = await initDb({ cwd })
shutdownServer = await startBootstrapApp({ cwd })
dbConnection = await initDb({ cwd, env })
shutdownServer = await startBootstrapApp({ cwd, env })
medusaContainer = getContainer()
})

Expand All @@ -52,9 +57,7 @@ describe("/admin/products", () => {
it("Should have enabled workflows feature flag", function () {
const flagRouter = medusaContainer.resolve("featureFlagRouter")

const workflowsFlag = flagRouter.isFeatureEnabled({
workflows: Workflows.CreateProducts,
})
const workflowsFlag = flagRouter.isFeatureEnabled(MedusaV2Flag.key)

expect(workflowsFlag).toBe(true)
})
Expand All @@ -63,6 +66,7 @@ describe("/admin/products", () => {
beforeEach(async () => {
await productSeeder(dbConnection)
await adminSeeder(dbConnection)
await createDefaultRuleTypes(medusaContainer)

await simpleSalesChannelFactory(dbConnection, {
name: "Default channel",
Expand Down Expand Up @@ -196,25 +200,28 @@ describe("/admin/products", () => {
id: expect.stringMatching(/^ma_*/),
currency_code: "usd",
amount: 100,
created_at: expect.any(String),
updated_at: expect.any(String),
variant_id: expect.stringMatching(/^variant_*/),
// TODO: enable this in the Pricing Module PR
// created_at: expect.any(String),
// updated_at: expect.any(String),
// variant_id: expect.stringMatching(/^variant_*/),
Comment on lines +203 to +206
Copy link
Contributor Author

@riqwan riqwan Nov 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pKorsholm FYI: something we missed in the prices response. We have to sneak this in our PRs

}),
expect.objectContaining({
id: expect.stringMatching(/^ma_*/),
currency_code: "eur",
amount: 45,
created_at: expect.any(String),
updated_at: expect.any(String),
variant_id: expect.stringMatching(/^variant_*/),
// TODO: enable this in the Pricing Module PR
// created_at: expect.any(String),
// updated_at: expect.any(String),
// variant_id: expect.stringMatching(/^variant_*/),
}),
expect.objectContaining({
id: expect.stringMatching(/^ma_*/),
currency_code: "dkk",
amount: 30,
created_at: expect.any(String),
updated_at: expect.any(String),
variant_id: expect.stringMatching(/^variant_*/),
// TODO: enable this in the Pricing Module PR
// created_at: expect.any(String),
// updated_at: expect.any(String),
// variant_id: expect.stringMatching(/^variant_*/),
}),
]),
options: expect.arrayContaining([
Expand Down Expand Up @@ -576,10 +583,11 @@ describe("/admin/products", () => {
expect(response?.data.product).toEqual(
expect.objectContaining({
id: toUpdateWithSalesChannels,
sales_channels: [
expect.objectContaining({ id: "channel-2" }),
expect.objectContaining({ id: "channel-3" }),
],
// TODO: Introduce this in the sale channel PR
Copy link
Contributor Author

@riqwan riqwan Nov 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fPolic do you think this can be added to your PR?

I commented it out because the remote query is not currently returning sales channels

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes!

// sales_channels: [
// expect.objectContaining({ id: "channel-2" }),
// expect.objectContaining({ id: "channel-3" }),
// ],
})
)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ const adminHeaders = {
}

const env = {
MEDUSA_FF_ISOLATE_PRICING_DOMAIN: true,
MEDUSA_FF_ISOLATE_PRODUCT_DOMAIN: true,
MEDUSA_FF_MEDUSA_V2: true,
}

describe("[Product & Pricing Module] POST /admin/products/:id/variants/:id", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ const adminHeaders = {
}

const env = {
MEDUSA_FF_ISOLATE_PRICING_DOMAIN: true,
MEDUSA_FF_ISOLATE_PRODUCT_DOMAIN: true,
MEDUSA_FF_MEDUSA_V2: true,
}

describe("[Product & Pricing Module] POST /admin/products/:id", () => {
Expand Down
8 changes: 2 additions & 6 deletions integration-tests/plugins/medusa-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ const DB_NAME = process.env.DB_TEMP_NAME
const DB_URL = `postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME}`
process.env.POSTGRES_URL = DB_URL

const enablePricing = process.env.MEDUSA_FF_ISOLATE_PRICING_DOMAIN == "true"
const enableProduct = process.env.MEDUSA_FF_ISOLATE_PRODUCT_DOMAIN == "true"
const enableMedusaV2 = process.env.MEDUSA_FF_MEDUSA_V2 == "true"

module.exports = {
plugins: [
Expand Down Expand Up @@ -37,11 +36,8 @@ module.exports = {
database_extra: { idle_in_transaction_session_timeout: 0 },
},
featureFlags: {
isolate_product_domain: enableProduct,
isolate_pricing_domain: enablePricing,
medusa_v2: enableMedusaV2,
workflows: {
[Workflows.CreateProducts]: true,
[Workflows.UpdateProducts]: true,
[Workflows.CreateCart]: true,
olivermrbl marked this conversation as resolved.
Show resolved Hide resolved
},
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { NextFunction, Request, Response } from "express"

import { FlagRouter } from "@medusajs/utils"
import { FlagRouter, MedusaV2Flag } from "@medusajs/utils"
import SalesChannelFeatureFlag from "../../loaders/feature-flags/sales-channels"
import { SalesChannelService } from "../../services"
import IsolateProductDomain from "../../loaders/feature-flags/isolate-product-domain"

/**
* Middleware that includes the default sales channel on the request, if no sales channels present
Expand All @@ -25,7 +24,7 @@ export function withDefaultSalesChannel(
if (
!featureFlagRouter.isFeatureEnabled(SalesChannelFeatureFlag.key) ||
// Do not attach the default SC if the isolate product domain feature flag is enabled
featureFlagRouter.isFeatureEnabled(IsolateProductDomain.key) ||
featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key) ||
req.query.sales_channel_id?.length ||
req.get("x-publishable-api-key")
) {
Expand Down
16 changes: 6 additions & 10 deletions packages/medusa/src/api/routes/admin/products/create-product.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IInventoryService, WorkflowTypes } from "@medusajs/types"
import { createProducts, Workflows } from "@medusajs/workflows"
import { Workflows, createProducts } from "@medusajs/workflows"
import {
IsArray,
IsBoolean,
Expand Down Expand Up @@ -39,10 +39,9 @@ import {
} from "./transaction/create-product-variant"

import { DistributedTransaction } from "@medusajs/orchestration"
import { FlagRouter, promiseAll } from "@medusajs/utils"
import { FlagRouter, MedusaV2Flag, promiseAll } from "@medusajs/utils"
import { Type } from "class-transformer"
import { EntityManager } from "typeorm"
import IsolateProductDomainFeatureFlag from "../../../../loaders/feature-flags/isolate-product-domain"
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
import { ProductStatus } from "../../../../models"
import { Logger } from "../../../../types/global"
Expand Down Expand Up @@ -137,20 +136,17 @@ export default async (req, res) => {

const entityManager: EntityManager = req.scope.resolve("manager")
const productModuleService = req.scope.resolve("productModuleService")
const isMedusaV2Enabled = featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)

const isWorkflowEnabled = featureFlagRouter.isFeatureEnabled({
workflows: Workflows.CreateProducts,
})

if (isWorkflowEnabled && !productModuleService) {
if (isMedusaV2Enabled && !productModuleService) {
logger.warn(
`Cannot run ${Workflows.CreateProducts} workflow without '@medusajs/product' installed`
)
}

let product

if (isWorkflowEnabled && !!productModuleService) {
if (isMedusaV2Enabled && !!productModuleService) {
const createProductWorkflow = createProducts(req.scope)

const input = {
Expand Down Expand Up @@ -260,7 +256,7 @@ export default async (req, res) => {
}

let rawProduct
if (featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key)) {
if (isMedusaV2Enabled) {
rawProduct = await getProductWithIsolatedProductModule(req, product.id)
} else {
rawProduct = await productService.retrieve(product.id, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {
SalesChannelService,
} from "../../../../services"

import IsolateProductDomainFeatureFlag from "../../../../loaders/feature-flags/isolate-product-domain"
import { MedusaError, promiseAll } from "@medusajs/utils"
import { MedusaError, MedusaV2Flag, promiseAll } from "@medusajs/utils"
import { FindParams } from "../../../../types/common"
import { defaultAdminProductRemoteQueryObject } from "./index"

Expand Down Expand Up @@ -76,7 +75,7 @@ export default async (req, res) => {
)

let rawProduct
if (featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key)) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
riqwan marked this conversation as resolved.
Show resolved Hide resolved
rawProduct = await getProductWithIsolatedProductModule(
req,
id,
Expand Down
11 changes: 5 additions & 6 deletions packages/medusa/src/api/routes/admin/products/list-products.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ import {
SalesChannelService,
} from "../../../../services"

import { FilterableProductProps } from "../../../../types/product"
import { IInventoryService } from "@medusajs/types"
import IsolateProductDomainFeatureFlag from "../../../../loaders/feature-flags/isolate-product-domain"
import { PricedProduct } from "../../../../types/pricing"
import { Product } from "../../../../models"
import { MedusaV2Flag, promiseAll } from "@medusajs/utils"
import { Type } from "class-transformer"
import { Product } from "../../../../models"
import { PricedProduct } from "../../../../types/pricing"
import { FilterableProductProps } from "../../../../types/product"
import { defaultAdminProductRemoteQueryObject } from "./index"
import { promiseAll } from "@medusajs/utils"

/**
* @oas [get] /admin/products
Expand Down Expand Up @@ -248,7 +247,7 @@ export default async (req, res) => {
let rawProducts
let count

if (featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key)) {
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
const [products, count_] =
await listAndCountProductWithIsolatedProductModule(
req,
Expand Down
Loading