Repository navigation
Closed
Description
Environment
- Mercur 2.3.5:
@mercurjs/core@2.3.5,@mercurjs/admin@2.3.5,@mercurjs/vendor@2.3.5 - Medusa 2.20.1 (
@medusajs/core-flows) - Confirmed from published npm
.medusa/server(not a downstream fork of core workflows)
Problem / current behavior
Mercur models Product ≠ Offer. Soft-deleting a catalog product does not soft-delete or deactivate seller offers that point at it:
- Admin
DELETE /admin/products/:idsoft-deletes the product (and variants) immediately. - Vendor
DELETE /vendor/products/:idonly stagesPRODUCT_DELETE; after operator confirm the product is soft-deleted the same way. - Neither path cleans offers. Admin Offers (
/dashboard/offers) then shows blank orphan rows (offer still live, product gone). - Discovery already listens to
product.deleted/product.product.deletedfor re-index, but core does not clean offers on those events. - Offer events include
offer.deletedwith{ id, product_id }— useful after cleanup, not a substitute for product→offer cascade.
Marketplaces must invent a subscriber themselves or live with orphan Admin Offers UI.
Proposed solution / API
Pick one (or both) of:
- Cascade / built-in side effect: When a product is soft-deleted (admin direct or confirmed vendor
PRODUCT_DELETE), soft-delete (or officially deactivate) seller offers for thatproduct_idvia the same path asdeleteOffersWorkflow(@mercurjs/core/workflows), emittingoffer.deleted. - Documented extension hook: Export/document a recommended subscriber or workflow hook (event names, payload shape, “resolve offer ids by product_id →
deleteOffersWorkflow”) so marketplaces do not rediscover orphan Offers rows. Vendor confirm path must be covered the same as admin delete.
Empty offer list should be a no-op. Batching for many offers is fine. Failures should not leave the product delete half-applied without logging.
Why it matters
Operators soft-delete catalog products expecting listings to disappear. Orphan offers break Admin Offers, confuse moderation, and leave storefront/discovery edges inconsistent until someone hand-deletes each offer.
Affected apps
- Core / API product delete workflows (admin + vendor
PRODUCT_DELETEconfirm) - Admin Offers list / product delete UX
- Vendor product delete → operator confirm path (same end state)
Suggested implementation notes
| Piece | Location / contract |
|---|---|
| Admin delete | @mercurjs/core api/admin/products/[id]/route.js → deleteProductsWorkflow |
| Vendor delete | DELETE /vendor/products/{id} — stages PRODUCT_DELETE only |
| Offer delete workflow | deleteOffersWorkflow — input { ids[] }; hooks offersDeleted; emits offer.deleted |
| Events already used downstream | product.deleted, product.product.deleted (discovery bridges) |
| Grams workaround | Subscriber cleanup-offers-on-product-deleted + cleanupOffersForDeletedProducts (packages/api) — on those product delete events, query offers by product_id, batch deleteOffersWorkflow. |
Related existing GitHub issues
None known that ask for product soft-delete → offer cascade or an official cleanup hook. Re-scan before filing.
Acceptance criteria
- Soft-deleting a product that has seller offers removes/deactivates those offers (Admin Offers no longer shows blank orphans)
- Same behavior for admin direct delete and confirmed vendor
PRODUCT_DELETE - Zero offers → no-op; many offers → batched / resilient
- Docs describe cascade or the recommended subscriber/workflow hook (event names +
deleteOffersWorkflow) -
offer.deletedstill fires so discovery / integrations can react
Metadata
Metadata
Assignees
Labels
No labels
Activity
feat(core): cascade product delete to seller offers (mercurjs#1583)
feat(core): cascade product delete to seller offers (mercurjs#1583)