Highlights
Improved Product Imports
This release overhauls the bulk import process to make it more performant and include strict validations to catch formatting issues or typos during the pre-processing phase.
Import phases
A CSV file with products to import goes through the following two phases.
- Pre-processing: In the pre-processing phase, we validate the contents of the entire file, check for typos, unknown columns, invalid data types, or missing values, and report errors as soon as you upload the file.
- Importing: Products are imported in the background (as it could be time-consuming with large product catalogs). Since the validations have already been performed during the pre-processing phase, the chances of failure during the import phase are rare. However, certain database constraints around duplicate data might result in a failure.
Changes to import template
Earlier, the import template (downloaded from the admin dashboard) was out of sync with our documentation and supported many columns that were part of Medusa V1.
However, now the import template strictly allows the columns mentioned in the documentation, and an error will be raised if an unknown column is specified in the CSV file.
Performance improvements
The following changes have been made to the internals to improve the import performance and memory consumption.
- Use S3 direct uploads instead of self-importing and storing huge CSV files on a Medusa server. For this, you must configure the S3 file provider in production.
- Read the CSV contents as a stream of chunks and process/validate 1000 rows at a time. As a result, we never read or process the entire CSV file in memory. From our tests, this led to a memory drop from 4GB to 500MB when processing a file with 62000 rows.
Tax-inclusive Promotions
This release introduces an option to specify if fixed promotions take effect before or after taxes. Up until now, fixed promotions would always be applied before taxes, which could lead to unexpected total calculations in scenarios where pricing was otherwise tax-inclusive.
For example, consider a fixed promotion with a value of $10 applied to a tax-inclusive cart of $100 in a tax region with a 25% tax rate.
Before promotion is applied:
- Cart total (tax-inclusive) -> $100 ($80 ex. 25% VAT)
After promotion is applied:
- Cart total (tax-inclusive) -> $87.5 ($70 ex. 25% VAT)
As you can see, the cart is reduced by $12.5 even though the promotion value was $10. The calculation we used to perform to find the promotion adjustment was:
const adjustmentTotal = (cartWithoutTax - promotion.value) * (1 + tax_rate)
In our example, this would be:
const adjustmentTotal = (80 - 10) * (1.25) = 87.5
In this release, we updated this calculation to ensure the correct adjustment total. It looks as follows:
const adjustmentTotal = (cartWithoutTax - (promotion.value / 1 + tax_rate)) * (1 + tax_rate)
In our example, this would be:
const adjustmentTotal = (80 - 8) * (1.25) = 90
The tax-inclusivity option on a promotion is part of the promotion creation flow in the admin dashboard.
Improved application startup time
This release reduces application startup time by around ~75%. For example, on Medusa Cloud, the startup time for a relatively simple Medusa application has gone from 20 seconds to around 4 seconds. This improvement comes from parallelizing the bootstrapping of modules. Modules are strictly independent from each other, so this should have no side effects.
Querying deleted records
This release fixes issues with querying for deleted database records.
Up until now, filtering data by providing any value to the deleted_at
filter would be treated as if you wanted to fetch deleted records.
For example:
const { data } = await query.graph({
entity: "product",
filters: { deleted_at: { $eq: null } }
})
In this query request, we are asking for all non-deleted records; however, we mistakenly assumed that any deleted_at
filter would always be filtering for deleted records, so in this case, the result set would contain deleted records.
In this release, we remove the autodetection mechanism in favor of an explicit flag withDeleted
.
To query deleted records, you now need to pass the flag to the request:
const { data } = await query.graph({
entity: "product",
filters: { deleted_at: { "<some timestamp>" } }
withDeleted: true
})
Features
- feat: wire up direct uploads with local file provider by @thetutlage in #12643
- feat(promotion, dashboard, core-flows, cart, types, utils, medusa): tax inclusive promotions by @fPolic in #12412
- feat(dashboard,types): add credit lines + loyalty changes by @riqwan in #11885
- feat: Improve startup time by parallelizing module and link loading by @sradevski in #12731
- feat: Normalize payment method data and options when passed to Stripe by @sradevski in #12757
- fix(dashboard, types): loyalty UI changes by @fPolic in #12764
- feat(): Add support for jwt asymetric keys by @adrien2p in #12813
- feat: add cookie options by @riqwan in #12720
Bugs
- fix(workflow-sdk): Async/nested runAsStep propagation by @adrien2p in #12675
- fix: update product import template by @thetutlage in #12697
- fix(create-medusa-app): remove "Created admin user" message by @shahednasser in #12707
- fix(promotion, types): non discountable items check by @fPolic in #12644
- fix: remote query types by @thetutlage in #12712
- fix(core-flows): cart complete order address creation by @fPolic in #12493
- fix(utils): medusa internal service returned data should match typings by @adrien2p in #12715
- fix(utils): Typecasting non-text fields in FTS by @olivermrbl in #12729
- fix: Disable ensure database checks when establishing DB connection by @sradevski in #12734
- fix(create-medusa-app): ensure the same package manager is used consistently by @shahednasser in #12714
- fix(payment): add account holder methods to the manual provider by @fPolic in #12751
- fix(core, medusa-test-utils): Fix medusa test runner plugin modules loading by @adrien2p in #12753
- fix: Add missing partially funded event handler for Stripe by @sradevski in #12763
- fix: initiate request container before other express middleware by @thetutlage in #12761
- fix(dashboard): fix subtitle for tax inclusive fields in promotions by @shahednasser in #12776
- fix(workflow-engine-redis): Ensure PK is set without errors by @olivermrbl in #12775
- fix: add operators to RemoteQueryFilters by @peterlgh7 in #12735
- fix: Return and set the correct status when a session is created with… by @sradevski in #12769
- fix: Allow setting the status of a payment session when updating by @sradevski in #12809
- fix(workflow-engine-*): Cleanup expired executions and reduce redis storage usage by @adrien2p in #12795
- fix(medusa): Query Config update Order By filter by @juanzgc in #12781
- fix(payment): round currency precision by @carlos-r-l-rodrigues in #12803
- fix(dashboard): fix currency input locale formatting by @fPolic in #12812
- fix(utils): build query withDeleted remove auto detection by @adrien2p in #12788
- fix: Add missing migration for payment statuses by @sradevski in #12821
Documentation
- docs: add options to feedback component by @shahednasser in #12698
- docs: remove databaseSchema configuration by @shahednasser in #12699
- docs: fixes to references for draft orders and files by @shahednasser in #12693
- docs: ensure files are always sorted when generating llms-full.txt by @shahednasser in #12701
- docs: add missing export for CreateBundledProduct component by @Amar2Kk in #12704
- docs: added cloud documentation app by @shahednasser in #12711
- docs: added cloud introduction page by @shahednasser in #12716
- docs: added slack integration guide by @shahednasser in #12696
- docs: fixed a typo in variable name from currnetProductPage to currentProductPage by @Amar2Kk in #12719
- docs: add link to the Slack tutorial in the integrations page by @shahednasser in #12721
- docs: added cloud organizations documentation by @shahednasser in #12723
- docs: fix to organizations title by @shahednasser in #12725
- docs: fix vercel link in deployment guides by @shahednasser in #12732
- docs: add cloud projects documentation by @shahednasser in #12730
- docs: document index module by @shahednasser in #12594
- docs: fix URLs to OpenTelemetry docs by @shahednasser in #12742
- docs: fix route matcher in brands guide by @shahednasser in #12741
- docs: fix collapsed navbar overlapping release notification by @shahednasser in #12745
- docs: add a section on heavy operations in loaders by @shahednasser in #12749
- docs: add index module to framework dropdown by @shahednasser in #12748
- docs: added cloud environments documentation by @shahednasser in #12750
- docs: added cloud deployments guide by @shahednasser in #12755
- docs: added cloud notifications guide by @shahednasser in #12756
- docs: add cloud database guides by @shahednasser in #12758
- docs: added cloud redis documentation by @shahednasser in #12760
- docs: added cloud s3 documentation by @shahednasser in #12762
- docs: added cloud plugins documentation by @shahednasser in #12765
- docs: add cloud billing docs by @shahednasser in #12766
- docs: added cloud logs guide by @shahednasser in #12772
- docs: added cloud support guide by @shahednasser in #12777
- docs: add cloud update guide by @shahednasser in #12778
- docs: added cloud connect storefront guide by @shahednasser in #12779
- docs: add re-use error handler section + clarify allowUnregistered by @shahednasser in #12780
- docs: added cloud infrastructure guide by @shahednasser in #12783
- docs: prepare cloud docs by @shahednasser in #12784
- docs: fix padding when AI assistant is open on some screens by @shahednasser in #12786
- docs: use Kapa React SDK by @shahednasser in #12792
- docs: fix recaptcha messing up page layout by @shahednasser in #12799
- docs: added sentry guide by @shahednasser in #12744
- docs: added list of restricted envs and subdomains by @shahednasser in #12810
- docs: added malchimp integration guide by @shahednasser in #12807
- docs: add loyalty plugin routes to OAS by @shahednasser in #12811
- docs: wording and structural changes to cloud by @shahednasser in #12820
Chores
- chore(core-flows,types,utils): fixes to TSDocs by @shahednasser in #12692
- chore(): re enable integration tests bp by @adrien2p in #12724
- chore(): Add retry strategy to database connection by @adrien2p in #12713
- chore: Remove source maps for icons by @sradevski in #12752
- chore: upgrade to use glob 10 by @thetutlage in #12754
- chore: remove ignore tag for import function + update version tag by @shahednasser in #12774
Other Changes
- fix: keep enum values in types generation by @peterlgh7 in #12684
- feat: Search by billing_address and shipping_address on Order model by @juanzgc in #12814
- Enable filtering admin products by variant EAN, UPC, and barcode by @anteprimorac in #12815
New Contributors
- @anteprimorac made their first contribution in #12815
Full Changelog: v2.8.4...v2.8.5