---
name: shopify-inventario-muerto
description: "Solo lectura: cruza el inventario con las ventas para encontrar los SKU que tienen stock pero no han vendido nada en N días, y estima cuánto dinero tienen quieto. Úsala antes de decidir una rebaja o una liquidación."
---

## Propósito
Identifica los SKU que tienen inventario disponible pero no han vendido ninguna unidad en una ventana de tiempo configurable. El inventario muerto inmoviliza capital, espacio en bodega y costos de almacenamiento. Solo lectura: no ejecuta mutaciones. Te da la base de datos para decidir una rebaja o una liquidación.

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

## Parámetros

| Parámetro | Tipo | Obligatorio | Predeterminado | Descripción |
|-----------|------|-------------|----------------|-------------|
| store | texto | sí | — | Dominio de la tienda (p. ej., tu-tienda.myshopify.com) |
| days_back | entero | no | 90 | Ventana de ventas hacia atrás: se marcan los SKU sin ventas en este periodo |
| min_quantity | entero | no | 1 | Cantidad mínima disponible para incluirlo (excluye los que de verdad están en cero) |
| vendor_filter | texto | no | — | Proveedor opcional para acotar la auditoría |
| format | texto | no | human | Formato de salida: `human` o `json` |

## Seguridad

> ℹ️ Skill de solo lectura: no ejecuta mutaciones. Puedes correrla en cualquier momento.

## Pasos

1. **OPERACIÓN:** `productVariants` — consulta
   **Entradas:** `first: 250`, `query: <vendor_filter, si se indicó>`; selecciona `sku`, `inventoryQuantity`, `inventoryItem { id }` y el cursor de paginación
   **Resultado esperado:** Todas las variantes con su nivel de stock; pagina hasta que `hasNextPage: false`

2. Filtra las variantes con `inventoryQuantity >= min_quantity`

3. **OPERACIÓN:** `orders` — consulta
   **Entradas:** `query: "created_at:>='<HOY - days_back días>'"`, `first: 250`; selecciona `lineItems { variant { id }, quantity }` y el cursor de paginación
   **Resultado esperado:** Todas las líneas de pedido vendidas en la ventana, para armar el conjunto de "IDs de variantes vendidas"

4. **OPERACIÓN:** `inventoryItems` — consulta
   **Entradas:** Lote de `inventoryItemIds` de las variantes con stock
   **Resultado esperado:** Costo de cada artículo de inventario, para calcular el valor del inventario muerto

5. Cruce: las variantes del paso 2 que NO están en el conjunto de vendidas del paso 3 → inventario muerto

## Operaciones GraphQL

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

```graphql
# orders:query — validada con api_version 2025-01
query OrderLineItemsInPeriod($query: String!, $after: String) {
  orders(first: 250, after: $after, query: $query) {
    edges {
      node {
        lineItems(first: 50) {
          edges {
            node {
              quantity
              variant {
                id
              }
            }
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

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

## Seguimiento de la sesión

**Claude DEBE mostrar la siguiente salida en cada etapa. Es obligatorio.**

**Al iniciar**, muestra:
```
╔══════════════════════════════════════════════╗
║  SKILL: Inventario que no se vende           ║
║  Tienda: <dominio de la tienda>              ║
║  Inicio: <YYYY-MM-DD HH:MM UTC>              ║
╚══════════════════════════════════════════════╝
```

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

**Al terminar**, muestra:

Para `format: human` (predeterminado):
```
══════════════════════════════════════════════
REPORTE DE INVENTARIO MUERTO  (sin ventas en <days_back> días)
  SKU con stock:                 <n>
  SKU sin ventas:                <n>  (<pct>%)
  Valor estimado inmovilizado:   $<monto>

  Inventario muerto con más valor:
    "<producto>"  SKU: <sku>  Cant.: <n>  Valor: $<n>
  Archivo: dead_stock_<fecha>.csv
══════════════════════════════════════════════
```

Para `format: json`, muestra:
```json
{
  "skill": "shopify-inventario-muerto",
  "store": "<dominio>",
  "period_days": 90,
  "stocked_skus": 0,
  "dead_stock_skus": 0,
  "dead_stock_pct": 0,
  "estimated_value": 0,
  "currency": "USD",
  "output_file": "dead_stock_<fecha>.csv"
}
```

## Formato de salida
Archivo CSV `dead_stock_<YYYY-MM-DD>.csv` con las columnas:
`variant_id`, `sku`, `product_title`, `vendor`, `quantity_on_hand`, `days_since_last_sale`, `unit_cost`, `total_cost_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 |
| No hay pedidos en la ventana | Tienda nueva o periodo de muy pocas ventas | Se marcarán todos los SKU con stock: es lo esperado |
| Variante sin artículo de inventario | Kit o producto virtual | Omite el costo de inventario, pero inclúyela en la lista |

## Buenas prácticas
- Usa `days_back: 90` para productos de temporada; `days_back: 180` o `days_back: 365` para el catálogo permanente.
- Ordena por `total_cost_value` de mayor a menor para priorizar las rebajas según el capital que liberan.
- Crúzalo con `shopify-velocidad-de-venta` para distinguir el inventario realmente muerto de los productos lentos que todavía se venden de vez en cuando.
- Usa los resultados como base para una campaña de descuento: ponles una etiqueta de rebaja con `shopify-etiquetas-productos-masivas` y luego crea una colección de liquidación.
