ucp-catalog

Maps a merchant's product data to UCP catalog schema format. Supports Shopify, WooCommerce, CSV, and web scraping as data sources. Outputs UCP-compliant product JSON with field mapping report. Use after ucp-audit to convert existing product data.

UCP Catalog Mapper

Extract merchant product data from various sources and transform it into UCP catalog schema format.

Prerequisites

  • store/clients/{client_name}/audit-report.md must exist
  • For Shopify: store URL (public storefront API)
  • For WooCommerce: store URL + API credentials
  • For CSV: file path
  • For URL: product page URLs to scrape

Step 1: Connect to Data Source

Shopify

# Public Storefront API — no auth needed
GET https://{store}.myshopify.com/products.json?limit=250
# Paginate with ?page=2, ?page=3, etc.

WooCommerce

# REST API — needs consumer_key + consumer_secret
GET https://{store}/wp-json/wc/v3/products?per_page=100
# Auth: query param ?consumer_key=ck_xxx&consumer_secret=cs_xxx

CSV

# Expect columns: title, price, description, sku, image_url, category, stock_status
import csv

Web Scraping

# Parse JSON-LD and structured data from product pages
# Fallback: parse HTML for price, title, images

Step 2: Field Mapping

Transform source fields to UCP product schema:

Product Level (required: id, title, description, price_range, variants)

UCP FieldShopify SourceWooCommerce SourceCSV Source
idid (string)id (string)row index or sku
titletitlenametitle
description.plainbody_html (strip tags)description (strip tags)description
price_range.min/maxmin/max of variants[].priceprice / sale_priceprice
urlurl or construct from handlepermalink
categories[]product_typecategories[].namecategory
media[]images[].srcimages[].srcimage_url
tags[]tags (split comma)tags[].nametags

Variant Level (required: id, title, description, price)

UCP FieldShopify SourceWooCommerce Source
idvariants[].idvariations[].id
titlevariants[].titlevariations[].attributes joined
descriptioninherit from productinherit from product
price.amountvariants[].price × 100 (to minor units)price × 100
price.currencystore currency settingstore currency setting
skuvariants[].skuvariations[].sku
availability.availablevariants[].availablestock_status == "instock"
availability.statusavailable ? in_stock : out_of_stockstock_status
selected_options[]option1/2/3 + options[] namesattributes[]

HARD RULE — Price conversion to minor units. UCP prices are integers in minor units (cents). $29.992999. Always verify currency's minor unit factor (most are ×100, JPY is ×1, BHD is ×1000).

Step 3: Validate Products

For each product, validate against UCP types:

✓ id is non-empty string
✓ title is non-empty string
✓ description has at least one of: plain, html, markdown
✓ price_range.min <= price_range.max
✓ price_range.min.amount >= 0
✓ price_range.min.currency is valid ISO 4217
✓ variants is non-empty array (at least 1)
✓ each variant has id, title, description, price
✓ each variant price.amount is integer >= 0
✓ media URLs are valid and accessible (spot check 3)

Record validation results per product: PASS / FAIL with details.

Step 4: Output

Save to store/clients/{client_name}/:

catalog.json

{
  "products": [
    {
      "id": "prod_001",
      "title": "Example Product",
      "description": {"plain": "A great product."},
      "price_range": {
        "min": {"amount": 2999, "currency": "USD"},
        "max": {"amount": 2999, "currency": "USD"}
      },
      "url": "https://example.com/products/example",
      "categories": [{"value": "Electronics", "taxonomy": "merchant"}],
      "media": [{"type": "image", "url": "https://example.com/img/prod_001.jpg"}],
      "variants": [
        {
          "id": "var_001",
          "title": "Default",
          "description": {"plain": "A great product."},
          "price": {"amount": 2999, "currency": "USD"},
          "sku": "EX-001",
          "availability": {"available": true, "status": "in_stock"}
        }
      ]
    }
  ],
  "metadata": {
    "source": "shopify",
    "total_products": 42,
    "total_variants": 87,
    "exported_at": "2026-03-25T12:00:00Z"
  }
}

mapping-report.md

# Catalog Mapping Report — {client_name}

**Source:** {platform}
**Products mapped:** {count}
**Variants mapped:** {count}
**Validation:** {passed}/{total} products pass

## Field Coverage
| UCP Field | Mapped | Source Field | Notes |
|-----------|--------|-------------|-------|
| title | ✓ | name | — |
| description | ✓ | description | HTML stripped |
| price | ✓ | price × 100 | Converted to minor units |
| media | ✓ | images[].src | — |
| sku | ✗ | — | Not available in source |

## Issues Found
{list of validation failures or data quality problems}

Scripts

ScriptPurposeDependencies
map_catalog.pyMulti-source catalog mapperrequests, beautifulsoup4, csv, json

Collaboration

ucp-audit → (audit-report.md) → ucp-catalog (this skill)
                                      │
                                      ├── outputs → catalog.json
                                      ├── outputs → mapping-report.md
                                      │
                                      └── consumed by → ucp-checkout (product data for line items)