---
name: shopify-auditoria-costos-producto
description: "Solo lectura: encuentra los productos y variantes que no tienen cargado el costo por artículo (inventoryItem.unitCost), para que tus reportes de margen y de valor del inventario sean exactos. Úsala antes de confiar en cualquier cálculo de ganancia."
---

## Propósito
Revisa cada variante del catálogo y muestra las que tienen el `inventoryItem.unitCost` vacío o en cero. El costo de los productos vendidos (COGS) es la base de los reportes de margen, de las decisiones de precio basadas en ganancia y de la valoración del inventario: un solo costo faltante daña en silencio todos los cálculos que dependen de él. Solo lectura, sin mutaciones.

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

## Parámetros

| Parámetro | Tipo | Obligatorio | Predeterminado | Descripción |
|-----------|------|-------------|----------------|-------------|
| store | string | sí | — | Dominio de la tienda (p. ej., mitienda.myshopify.com) |
| status_filter | string | no | ACTIVE | Estado del producto de las variantes que se auditan: `ACTIVE`, `DRAFT`, `ARCHIVED` o `ALL` |
| vendor_filter | string | no | — | Proveedor opcional para limitar la auditoría |
| include_zero_cost | bool | no | true | Considera `unitCost = 0` como faltante (recomendado: un costo en cero rara vez es intencional) |
| only_stocked | bool | no | true | Limita a las variantes con `inventoryQuantity > 0` |
| format | string | no | human | Formato de salida: `human` o `json` |

## Seguridad

> ℹ️ Skill de solo lectura: no ejecuta mutaciones. Puedes usarla en cualquier momento sin riesgo. La skill señala los datos faltantes; la corrección debe hacerse en un proceso posterior que tú controles.

## Pasos

1. **OPERACIÓN:** `productVariants` — consulta
   **Entradas:** `first: 250`, `query: <armada a partir de status_filter y vendor_filter>`, campos `sku`, `price`, `inventoryQuantity`, `inventoryItem { id }`, `product { title, vendor, status, productType }`, cursor de paginación
   **Resultado esperado:** Todas las variantes que coinciden; pagina hasta `hasNextPage: false`

2. **OPERACIÓN:** `inventoryItems` — consulta
   **Entradas:** `inventoryItemIds` en lotes (≤100 por solicitud)
   **Resultado esperado:** `unitCost { amount, currencyCode }`, `tracked`

3. Filtra las variantes donde `unitCost == null` o `unitCost.amount == 0` (cuando `include_zero_cost: true`). Calcula la brecha de margen potencial como `price - 0 = price` para las variantes sin costo: es el margen ficticio que mostrarán los reportes que dependen de este dato.

4. Resume: cantidad de faltantes, % del catálogo e impacto total en el valor del stock (`suma de inventoryQuantity * price` en las filas sin costo, ya que no se pueden valorar por costo).

## Operaciones GraphQL

```graphql
# productVariants:query — validada con api_version 2025-01
query VariantsForCogsAudit($query: String, $after: String) {
  productVariants(first: 250, after: $after, query: $query) {
    edges {
      node {
        id
        sku
        title
        price
        inventoryQuantity
        product {
          id
          title
          vendor
          status
          productType
        }
        inventoryItem {
          id
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

```graphql
# inventoryItems:query — validada con api_version 2025-01
query InventoryItemCosts($ids: [ID!]!) {
  nodes(ids: $ids) {
    ... on InventoryItem {
      id
      tracked
      sku
      unitCost {
        amount
        currencyCode
      }
    }
  }
}
```

## Seguimiento de la sesión

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

**Al iniciar**, muestra:
```
╔══════════════════════════════════════════════╗
║  SKILL: Productos sin costo cargado          ║
║  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>
```

**Al terminar**, muestra:

Para `format: human` (predeterminado):
```
══════════════════════════════════════════════
AUDITORÍA DE COSTOS DE PRODUCTO
  Variantes auditadas:       <n>
  Sin costo por artículo:    <n>  (<pct>%)
  Con stock y sin costo:     <n>
  Valor del catálogo en riesgo: <monto> (con precio, sin costo)

  Proveedores con más variantes sin costo:
    <proveedor>  Sin costo: <n>  Con stock: <n>
  Archivo: cogs_audit_<fecha>.csv
══════════════════════════════════════════════
```

Para `format: json`, muestra:
```json
{
  "skill": "shopify-auditoria-costos-producto",
  "store": "<dominio>",
  "variants_audited": 0,
  "missing_cost": 0,
  "missing_cost_pct": 0,
  "stocked_missing": 0,
  "value_at_risk": 0,
  "currency": "<moneda de la tienda>",
  "output_file": "cogs_audit_<fecha>.csv"
}
```

## Formato de salida
Archivo CSV `cogs_audit_<AAAA-MM-DD>.csv` con las columnas:
`variant_id`, `inventory_item_id`, `sku`, `product_title`, `vendor`, `product_status`, `price`, `unit_cost`, `inventory_quantity`, `value_at_price`, `currency`

## 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 |
| `inventoryItem` es null | La variante no tiene artículo de inventario (poco común) | Omítela y súmala al conteo de errores |
| `unitCost.currencyCode` distinto de la moneda de la tienda | El costo se cargó en otra moneda | Considéralo cargado; no lo marques y reporta la diferencia de moneda por separado |
| Todas las variantes tienen costo | Catálogo sano | Termina con el resumen: 0 faltantes, 100 % completo |

## Buenas prácticas
- Ejecútala cada mes; y cada vez que sumes proveedores o líneas de producto nuevas, ejecútala el mismo día de la activación para detectar costos faltantes antes de confiar en los reportes de margen.
- Filtra con `vendor_filter` para asignar la corrección a la persona de compras responsable de los datos de ese proveedor.
- Combínala con `shopify-valor-inventario`: ese reporte tratará en silencio los SKU sin costo como inventario sin valor si esta auditoría no sale limpia.
- Considera `unitCost = 0` como faltante por defecto. Los SKU con costo cero de verdad (muestras gratis, regalos por compra) son raros; márcalos con la etiqueta de producto `zero-cost-intentional` y exclúyelos de la auditoría con `vendor_filter` o con un filtro posterior.
- Usa el CSV como lista de trabajo: entrégalo al equipo de catálogo para que cargue los costos y vuelve a ejecutarla cada semana hasta que los faltantes lleguen a cero.
