---
name: shopify-normalizar-variantes
description: "Detecta nombres de opciones de variante escritos de formas distintas (Sm, Small, S) y los corrige en lote a un estándar que tú defines. Úsala cuando los filtros de talla o de color de tu tienda no agrupan bien las variantes."
---

## Propósito
Revisa las variantes de tus productos en busca de valores de opción inconsistentes (p. ej., "Sm", "Small", "small" y "S" significan la misma talla) y los actualiza en lote a un conjunto estándar que tú defines. Los nombres de opción inconsistentes dañan los filtros de talla, confunden a los clientes e impiden que las apps de búsqueda agrupen bien las variantes.

## Requisitos
- Sesión autenticada de Shopify CLI: `shopify store auth --store <tu-tienda>.myshopify.com --scopes read_products,write_products`
- Las consultas se ejecutan con `shopify store execute`.
- Permisos (scopes) de API: `read_products`, `write_products`

## Parámetros

| Parámetro | Tipo | Obligatorio | Predeterminado | Descripción |
|-----------|------|-------------|----------------|-------------|
| store | string | sí | — | Dominio de la tienda (p. ej., tu-tienda.myshopify.com) |
| option_name | string | sí | — | Opción que se va a normalizar (p. ej., `Talla`, `Color`) |
| mapping | object | sí | — | Mapa de valores no estándar → valores estándar (p. ej., `{"Sm": "S", "small": "S", "Sml": "S"}`) |
| filter | string | no | — | Filtro opcional de productos (p. ej., `tag:apparel`) |
| dry_run | bool | no | true | Muestra los cambios sin ejecutar mutaciones |
| format | string | no | human | Formato de salida: `human` o `json` |

## Seguridad

> ⚠️ `productVariantsBulkUpdate` modifica los valores de opción de las variantes. Estos cambios afectan cómo ven los clientes la variante en la tienda y pueden romper enlaces existentes al carrito o listas de deseos guardadas. Ejecútala con `dry_run: true` para revisar todas las variantes afectadas antes de aplicar los cambios.

## Pasos

1. **OPERACIÓN:** `products` — consulta
   **Entradas:** `query: <filter>` (o todos los productos si no hay filtro), `first: 250`, selecciona `options`, `variants { selectedOptions }` y el cursor de paginación
   **Resultado esperado:** Los productos con los valores de opción de sus variantes; pagina hasta que `hasNextPage: false`

2. Compara los valores de opción de las variantes con las claves de `mapping` y reúne las variantes que hay que actualizar

3. **OPERACIÓN:** `productVariantsBulkUpdate` — mutación
   **Entradas:** `productId` y la lista de `variants { id, options: [<normalized_value>] }` de las variantes afectadas
   **Resultado esperado:** `productVariants { id, selectedOptions }`, `userErrors`

## Operaciones GraphQL

```graphql
# products:query — validado con api_version 2025-01
query ProductVariantOptions($query: String!, $after: String) {
  products(first: 250, after: $after, query: $query) {
    edges {
      node {
        id
        title
        options {
          id
          name
          values
        }
        variants(first: 100) {
          edges {
            node {
              id
              title
              sku
              selectedOptions {
                name
                value
              }
            }
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

```graphql
# productVariantsBulkUpdate:mutation — validado con api_version 2025-01
mutation ProductVariantsBulkUpdate($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
  productVariantsBulkUpdate(productId: $productId, variants: $variants) {
    productVariants {
      id
      title
      selectedOptions {
        name
        value
      }
    }
    userErrors {
      field
      message
    }
  }
}
```

## Seguimiento de la sesión

**Claude DEBE mostrar lo siguiente en cada etapa. Es obligatorio.**

**Al iniciar**, muestra:
```
╔═══════════════════════════════════════════════╗
║  SKILL: Unifica los nombres de tus variantes  ║
║  Tienda: <dominio de la tienda>               ║
║  Inicio: <AAAA-MM-DD HH:MM UTC>               ║
╚═══════════════════════════════════════════════╝
```

**Después de cada paso**, muestra:
```
[N/TOTAL] <CONSULTA|MUTACIÓN>  <OperationName>
          → Parámetros: <resumen breve de las entradas clave>
          → Resultado: <cantidad o desenlace>
```

Si `dry_run: true`, antepón `[SIMULACIÓN]` a cada paso de mutación y no lo ejecutes.

**Al terminar**, muestra:

Para `format: human` (predeterminado):
```
══════════════════════════════════════════════
RESUMEN DEL RESULTADO
  Productos revisados:      <n>
  Variantes por corregir:   <n>
  Variantes actualizadas:   <n>
  Errores:                  <n>
  Archivo:                  option_normalizer_<fecha>.csv
══════════════════════════════════════════════
```

Para `format: json`, muestra:
```json
{
  "skill": "shopify-normalizar-variantes",
  "store": "<dominio>",
  "started_at": "<ISO8601>",
  "completed_at": "<ISO8601>",
  "dry_run": true,
  "option_name": "Talla",
  "outcome": {
    "products_scanned": 0,
    "variants_needing_fix": 0,
    "variants_updated": 0,
    "errors": 0,
    "output_file": "option_normalizer_<fecha>.csv"
  }
}
```

## Formato de salida
Archivo CSV `option_normalizer_<AAAA-MM-DD>.csv` con las columnas:
`product_id`, `product_title`, `variant_id`, `sku`, `option_name`, `old_value`, `new_value`

## Manejo de errores
| Error | Causa | Solución |
|-------|-------|----------|
| `THROTTLED` | Se superó el límite de solicitudes de la API | Espera 2 segundos y reintenta hasta 3 veces |
| `userErrors` en la actualización en lote | Conflicto de valores de opción dentro del producto | Registra el error, omite el producto y continúa |
| No hay variantes que coincidan | Las claves de `mapping` no aparecen en el catálogo | Termina con 0 coincidencias y revisa el mapeo |

## Buenas prácticas
- Arma el `mapping` ejecutando primero con `dry_run: true` y revisando los valores de opción detectados: puede que encuentres más variantes de las que esperabas.
- Normaliza un `option_name` a la vez (primero Talla y luego Color, por separado) para que el mapeo sea manejable y reducir el riesgo de errores.
- Después de normalizar, verifica que las reglas de las colecciones automáticas que usan valores de opción sigan incluyendo los productos correctos.
