Pure mapping from a Shopify Admin API product payload's "options"/
"variants" into the shape PhoenixKitEcommerce.Catalogue.Writer. sync_variants/2 attaches as catalogue attribute sets: one set per real
option (Shopify's auto-generated single-option "no variants" product —
option name "Title", its lone value "Default Title" — is skipped,
same as it never becomes a _option_slots entry on the legacy CSV
path), values in the order they first appear across variants[], and
a per-value price modifier.
No I/O, no catalogue/entities lookups — build/1 never needs a live
set to exist. slug (both the set's and each modifier map's key) is
PhoenixKitEcommerce.Catalogue.SetSlug.normalise/1 of the option's
OWN name; resolving a raw variant-option VALUE label to a value slug
is a separate, stateful step (PhoenixKitEcommerce.Catalogue. ValueResolver) Writer.sync_variants/2 runs afterward, against
whatever catalogue set that slug now names.
Modifier rule
For each option, group variants[] by that option's value
(variant["option<position>"]); a value's modifier is
min(price of variants carrying that value) − min(price of every priced variant on the product). Grouping by MIN rather than "first
variant seen" (the legacy Import.OptionBuilder's rule, correct only
when a single option drives price) matters here because two options
combine on one variant — the cheapest variant carrying value X is the
fair anchor for X's modifier regardless of what its OTHER option
happened to be. The overall cheapest value's modifier is exactly
Decimal.new("0.00") (equal minima, not a rounded near-zero) as long
as Shopify's own price strings carry two decimals, which
Decimal.sub/2 preserves.
Summary
Functions
Builds %{sets: [...], modifiers: %{set_slug => %{label => Decimal}}}
from shopify_product's "options" and "variants". Both keys
default to [] when absent (a payload with no options at all — every
variant on the default "Title" option — yields sets: [], modifiers: %{}).
Types
Functions
Builds %{sets: [...], modifiers: %{set_slug => %{label => Decimal}}}
from shopify_product's "options" and "variants". Both keys
default to [] when absent (a payload with no options at all — every
variant on the default "Title" option — yields sets: [], modifiers: %{}).