Skip to content

feat(product-category): add external_id to product-category#14799

Merged
kodiakhq[bot] merged 2 commits intomedusajs:developfrom
asgerjensen:feature/external-id-on-product-category
Apr 10, 2026
Merged

feat(product-category): add external_id to product-category#14799
kodiakhq[bot] merged 2 commits intomedusajs:developfrom
asgerjensen:feature/external-id-on-product-category

Conversation

@asgerjensen
Copy link
Copy Markdown
Contributor

@asgerjensen asgerjensen commented Feb 24, 2026

Summary

What — What changes are introduced in this PR?

This PR adds external_id to the product-category type.
It is available on both /admin and /store, and can be used as filter.

Why — Why are these changes relevant or necessary?

To facilitate runtime lookup from values derived from 3rd party systems (PIM, ERP, Recommendations, CMS-stored-references) of the product-category.

Allows addressing data via its native/real-world identifier, rather than synthetic/instance-specific database identifier.

How — How have these changes been implemented?

Added migration to add field. Added field to schemas and queryInfo blocks.

Testing — How have these changes been tested, or how can the reviewer test the feature?

Integration tests included.


Examples

Provide examples or code snippets that demonstrate how this feature works, or how it can be used in practice.
This helps with documentation and ensures maintainers can quickly understand and verify the change.

await sdk.admin.productCategory.create({
   name: 'test-category',
   external_id: 'my-external_id'
});
sdk.store.category.list({
   external_id: 'my-external_id'
});

Checklist

Please ensure the following before requesting a review:

  • I have added a changeset for this PR
    • Every non-breaking change should be marked as a patch
    • To add a changeset, run yarn changeset and follow the prompts
  • The changes are covered by relevant tests
  • I have verified the code works as intended locally
  • I have linked the related issue(s) if applicable

Additional Context

Add any additional context, related issues, or references that might help the reviewer understand this PR.


Note

Medium Risk
Adds a new nullable DB column and threads it through admin/store API validation, default field selection, and filtering, which could affect migrations and query behavior. Changes are straightforward but touch persisted schema and public API responses.

Overview
Product categories now support a nullable external_id, persisted via a new MikroORM migration and model/schema update.

The admin and store APIs include external_id in default query fields, accept it on create/update payloads, and allow filtering by it (validators and types updated accordingly).

Integration tests are expanded/added to cover returning external_id, creating/updating it, and filtering by it across module, admin HTTP, and store HTTP routes.

Written by Cursor Bugbot for commit 2872ea5. This will update automatically on new commits. Configure here.

@asgerjensen asgerjensen requested a review from a team as a code owner February 24, 2026 16:55
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 24, 2026

🦋 Changeset detected

Latest commit: b9e2e7e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 77 packages
Name Type
@medusajs/product Patch
integration-tests-http Patch
@medusajs/types Patch
@medusajs/medusa Patch
@medusajs/event-bus-redis Patch
@medusajs/draft-order Patch
@medusajs/framework Patch
@medusajs/js-sdk Patch
@medusajs/modules-sdk Patch
@medusajs/orchestration Patch
@medusajs/utils Patch
@medusajs/workflows-sdk Patch
@medusajs/medusa-oas-cli Patch
@medusajs/admin-bundler Patch
@medusajs/dashboard Patch
@medusajs/test-utils Patch
@medusajs/analytics Patch
@medusajs/api-key Patch
@medusajs/auth Patch
@medusajs/cache-inmemory Patch
@medusajs/cache-redis Patch
@medusajs/caching Patch
@medusajs/cart Patch
@medusajs/currency Patch
@medusajs/customer Patch
@medusajs/event-bus-local Patch
@medusajs/file Patch
@medusajs/fulfillment Patch
@medusajs/index Patch
@medusajs/inventory Patch
@medusajs/link-modules Patch
@medusajs/locking Patch
@medusajs/notification Patch
@medusajs/order Patch
@medusajs/payment Patch
@medusajs/pricing Patch
@medusajs/promotion Patch
@medusajs/rbac Patch
@medusajs/region Patch
@medusajs/sales-channel Patch
@medusajs/settings Patch
@medusajs/stock-location Patch
@medusajs/store Patch
@medusajs/tax Patch
@medusajs/translation Patch
@medusajs/user Patch
@medusajs/workflow-engine-inmemory Patch
@medusajs/workflow-engine-redis Patch
@medusajs/analytics-local Patch
@medusajs/analytics-posthog Patch
@medusajs/auth-emailpass Patch
@medusajs/auth-github Patch
@medusajs/auth-google Patch
@medusajs/caching-redis Patch
@medusajs/file-local Patch
@medusajs/file-s3 Patch
@medusajs/fulfillment-manual Patch
@medusajs/locking-postgres Patch
@medusajs/locking-redis Patch
@medusajs/notification-local Patch
@medusajs/notification-sendgrid Patch
@medusajs/payment-stripe Patch
@medusajs/core-flows Patch
@medusajs/oas-github-ci Patch
@medusajs/http-types-generator Patch
@medusajs/cli Patch
@medusajs/deps Patch
@medusajs/telemetry Patch
@medusajs/admin-sdk Patch
@medusajs/admin-shared Patch
@medusajs/admin-vite-plugin Patch
@medusajs/icons Patch
@medusajs/toolbox Patch
@medusajs/ui-preset Patch
create-medusa-app Patch
medusa-dev-cli Patch
@medusajs/ui Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel bot commented Feb 24, 2026

@asgerjensen is attempting to deploy a commit to the medusajs Team on Vercel.

A member of the Team first needs to authorize it.

@asgerjensen asgerjensen force-pushed the feature/external-id-on-product-category branch 3 times, most recently from 53e0dbc to d56b73c Compare February 27, 2026 12:00
@NicolasGorga
Copy link
Copy Markdown
Contributor

NicolasGorga commented Feb 27, 2026

Hey @asgerjensen thanks for the contribution. I think this PR could be expanded to include external_id in the rest of the Product Module models that might find it useful (product_collection, product_tag, product_type, product_variant). Would you be up for it?

@asgerjensen
Copy link
Copy Markdown
Contributor Author

asgerjensen commented Feb 27, 2026

Hey @asgerjensen thanks for the contribution. I think this PR could be expanded to include external_id in the rest of the Product Module models that might find it useful (product_collection, product_tag, product_type, product_variant). Would you be up for it?

Sure, i can work through those. But i think in order to keep the PR size managable, that it should be individual PRs pr type?

I'd say, that for product-variant, there already exists a natural identifier field (sku), so maybe for that it just needs to be searchable via apis, much like barcode/ean.

@asgerjensen asgerjensen force-pushed the feature/external-id-on-product-category branch from d56b73c to ecbebd0 Compare February 27, 2026 16:57
@NicolasGorga
Copy link
Copy Markdown
Contributor

Hey @asgerjensen not necessarily I think it would be okay to have them all in this PR, but whatever you are comfortable with I'm happy with :)

@asgerjensen asgerjensen force-pushed the feature/external-id-on-product-category branch from 36e864f to 693d4b6 Compare March 2, 2026 07:49
@asgerjensen
Copy link
Copy Markdown
Contributor Author

integration-tests/http/tests/product-category/store/product-category.spec.ts

I think i would prefer the seperate-PRs, mostly for my own sake. Easier to navigate for me, being relatively new to the codebase.

@asgerjensen asgerjensen force-pushed the feature/external-id-on-product-category branch from 693d4b6 to 4f58ed7 Compare March 2, 2026 08:05
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@asgerjensen
Copy link
Copy Markdown
Contributor Author

asgerjensen commented Mar 6, 2026

@NicolasGorga seperate PR made for the collection, type and tag. #14855 and variant in #14826

@asgerjensen asgerjensen force-pushed the feature/external-id-on-product-category branch 3 times, most recently from 2872ea5 to f4bd40c Compare March 11, 2026 21:07
@cursor
Copy link
Copy Markdown

cursor bot commented Mar 11, 2026

You have run out of free Bugbot PR reviews for this billing cycle. This will reset on March 17.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@asgerjensen asgerjensen force-pushed the feature/external-id-on-product-category branch 2 times, most recently from f60a1e1 to 4707678 Compare March 17, 2026 17:32
@asgerjensen asgerjensen force-pushed the feature/external-id-on-product-category branch 2 times, most recently from 785fc86 to 393ca0b Compare March 25, 2026 19:22
It is available on both /admin and /store, and can be used as filter.

fix: add missing snapshot

test: fix race condition in test

chore: clean up test-cases. Remove dead code

chore: cleanup tests
@asgerjensen asgerjensen force-pushed the feature/external-id-on-product-category branch from 393ca0b to 6d2440b Compare April 7, 2026 18:22
@medusa-os-bot
Copy link
Copy Markdown

medusa-os-bot bot commented Apr 9, 2026

Thank you for your contribution!

After an initial review, this PR looks good to us. Here's a summary:

✅ PR template is complete
✅ Changeset included with correct format (feat(product-category): add external_id to product-category)
✅ Tests included — module-level and HTTP integration tests for both admin and store
✅ HTTP types updated alongside Zod validator changes
✅ Follows Medusa's conventions

Notes:

  • There's no linked GitHub issue with a closing keyword (e.g. Closes #XXXX). For non-trivial changes like this, we generally ask that an issue be opened first so the feature can be discussed and scoped. Since @NicolasGorga has already indicated support in the comments, this isn't a blocker — just something to keep in mind for future contributions.
  • For the UpdateProductCategory Zod schema, consider using z.string().nullish() instead of z.string().optional() for external_id if clearing the value (setting it back to null) should be supported — consistent with how parent_category_id is handled in the same schema.

A team member will do a final review before this is merged. We appreciate your patience!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants