Skip to main content
In this document, you’ll learn how the individual operations inside a change are modeled.

Product change action

Each operation inside a change is a ProductChangeAction (table product_change_action, id prefix prodchact). An action belongs to a parent ProductChange, targets a product_id, and names the operation in its action field. The operation’s payload lives in the details JSON, and an applied boolean records whether it has already been written to the product.
Actions carry an autoincrementing ordering so a change with several operations applies them deterministically.

Action types

The action field is one of the ProductChangeActionType values. Each type reads a different shape out of details:
CHANGE_REQUESTED mutates nothing. It’s an audit-only marker for a revision request. The operator’s message rides on both the action’s details.message and the parent change’s external_note. See Status & auto-confirm.

How actions apply

When a change is confirmed, its not-yet-applied actions are bucketed by type and dispatched to the matching Medusa workflows in one pass: product updates, variant creates/updates/deletes, and the attribute batch. Each action is then flipped to applied: true so a re-run never applies it twice.
Audit-trail changes (publish approvals, revision requests) are stored with their actions already applied, so confirming them is a no-op on the product itself. They exist purely as history.