{{-- ── LEGEND ───────────────────────────────────────────────────────────── --}}
External / Shopify
Job / Service
Confirmed working
Gap / Warning
Decision
DB / Data store
{{-- ── DIAGRAM 1: Listing status lifecycle ─────────────────────────────── --}}
STATUS Listing status lifecycle channel_listings.status · drives tab counts in ManageListingsV2
{{-- ── DIAGRAM 2: Create new listings ──────────────────────────────────── --}}
CREATE Create new Shopify listings — ShopifyBatchCreateJob ManageListingsV2 · Not Listed tab → "Create Listings"
{{-- ── DIAGRAM 3: Batch sync phases ────────────────────────────────────── --}}
SYNC Update existing listings — ShopifyBatchSyncJob phases ManageListingsV2 → "Sync Selected" / "Sync All" · or per-product "Sync Now"
{{-- ── DIAGRAM 4: Price sync routing ───────────────────────────────────── --}}
PRICE Price sync — all paths to Shopify Three distinct routes depending on trigger
{{-- ── DIAGRAM 5: Observer-driven incremental sync ─────────────────────── --}}
AUTO Observer-driven incremental sync — stock, price, data changes ProductObserver · ProductQuantityObserver · fires SyncProductToChannels per product
{{-- ── API REFERENCE TABLE ───────────────────────────────────────────────── --}}
API Shopify API field routing — what goes where Which mutation / endpoint handles each field
Field Shopify mutation / endpoint Mode Used in Notes
Title productUpdate Bulk JSONL ShopifyBatchSyncJob Phase 1 Works on new product model ✓
Description (body HTML) productUpdate Bulk JSONL ShopifyBatchSyncJob Phase 1
Vendor productUpdate Bulk JSONL ShopifyBatchSyncJob Phase 1
Product type productUpdate Bulk JSONL ShopifyBatchSyncJob Phase 1
Tags productUpdate Bulk JSONL ShopifyBatchSyncJob Phase 1
Published status productUpdate Bulk JSONL ShopifyBatchSyncJob Phase 1
URL handle productUpdate Per-product GraphQL ShopifyBatchSyncJob Phase 3.6 redirectNewHandle: true — bulk JSONL silently ignores handle changes
Images REST /products/{id} REST per-product ShopifyBatchSyncJob Phase 3.5 GraphQL bulk ops don't support src image uploads
Price productVariantsBulkUpdate Bulk JSONL Per-product BulkPriceUpdateJob · ShopifyBatchSyncJob Phase 3.6b ⚠ NOT productUpdate — silently ignored on new product model (2024+)
Compare-at price productVariantsBulkUpdate Per-product Not currently pushed Supported in ProductVariantsBulkInput
Barcode / EAN productVariantsBulkUpdate Per-product ShopifyBatchSyncJob Phase 3.6b
Weight productVariantsBulkUpdate Per-product ShopifyBatchSyncJob Phase 3.6b via inventoryItem.measurement.weight
Cost price productVariantsBulkUpdate Bulk JSONL Per-product BulkPriceUpdateJob · ShopifyBatchSyncJob Phase 3.6b via inventoryItem.cost
Stock quantity REST inventory adjust REST per-product SyncProductToChannels Via observer on ProductQuantity change or order fulfilment
SKU productCreate / productVariantsBulkUpdate GraphQL ShopifyBatchCreateJob Set at creation; stored in channels_sku_mappings
{{-- ── KEY RULE CALLOUT ─────────────────────────────────────────────────── --}}
⚠ Critical Shopify rule — new product model (2024+)
• productUpdate JSONL silently ignores all variant fields (price, barcode, weight, cost) on stores migrated to the new product model.
• Including a variants array in a productUpdate JSONL line causes Shopify to silently reject the entire line — title and all other product-level fields also fail.
• Use productVariantsBulkUpdate for all variant-level fields. It works on both old and new product models and supports bulkOperationRunMutation.
{{-- ── MERMAID ───────────────────────────────────────────────────────────────── --}}