// app/utils/shopify-products.server.js /** * Given a Turn14 item object and a Shopify Admin client, * creates the product + media + joins the specified collection + * sets price + sets SKU. */ export async function createFullProductFromTurn14Item(admin, item, collectionId) { // 1️⃣ Create product + media + join collection const createRes = await admin.graphql( `mutation CreateFullProduct($product: ProductCreateInput!, $media: [CreateMediaInput!]) { productCreate(product: $product, media: $media) { product { id variants(first:1) { nodes { id inventoryItem { id } } } } userErrors { field message } } }`, { variables: { product: { title: item.attributes.product_name, descriptionHtml: item.attributes.part_description, vendor: item.attributes.brand.name, productType: item.attributes.category, handle: item.attributes.part_number.toLowerCase(), tags: [item.attributes.category, item.attributes.subcategory], collectionsToJoin: collectionId ? [collectionId] : [], status: "ACTIVE", }, media: [{ originalSource: item.attributes.images?.[0]?.url, mediaContentType: "IMAGE", alt: `${item.attributes.product_name} image`, }], }, } ); const { productCreate } = await createRes.json(); if (productCreate.userErrors.length) { throw new Error(productCreate.userErrors.map(e => e.message).join(", ")); } const newProduct = productCreate.product; const variantNode = newProduct.variants.nodes[0]; const variantId = variantNode.id; const inventoryItemId = variantNode.inventoryItem.id; // 2️⃣ Update price const priceRes = await admin.graphql( `mutation UpdatePrice($productId: ID!, $variants: [ProductVariantsBulkInput!]!) { productVariantsBulkUpdate(productId: $productId, variants: $variants) { productVariants { id price } userErrors { field message } } }`, { variables: { productId: newProduct.id, variants: [{ id: variantId, price: parseFloat(item.attributes.price) || 0 }], }, } ); const { productVariantsBulkUpdate } = await priceRes.json(); if (productVariantsBulkUpdate.userErrors.length) { throw new Error(productVariantsBulkUpdate.userErrors.map(e => e.message).join(", ")); } // 3️⃣ Set SKU const skuRes = await admin.graphql( `mutation SetSKU($id: ID!, $input: InventoryItemInput!) { inventoryItemUpdate(id: $id, input: $input) { inventoryItem { sku } userErrors { field message } } }`, { variables: { id: inventoryItemId, input: { sku: item.attributes.part_number }, }, } ); const { inventoryItemUpdate } = await skuRes.json(); if (inventoryItemUpdate.userErrors.length) { throw new Error(inventoryItemUpdate.userErrors.map(e => e.message).join(", ")); } return { productId: newProduct.id }; }