---
name: shopify-antiguedad-inventario
description: "Solo lectura: clasifica tu inventario por antigüedad (0-30, 31-60, 61-90, más de 90 días) según el tiempo desde la última venta o la entrada, y calcula cuánto te cuesta mantenerlo. Úsala cuando quieras decidir qué rebajar o liquidar."
---

## Propósito
Clasifica todo el inventario en rangos de antigüedad según cuánto tiempo llevan los artículos sin venderse. Calcula el costo de mantener el inventario en cada rango para priorizar las decisiones de rebaja o liquidación. Va más allá de identificar inventario muerto porque muestra la antigüedad con más detalle. Solo lectura: no ejecuta mutaciones.

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

## Parámetros

| Parámetro | Tipo | Obligatorio | Por defecto | Descripción |
|-----------|------|-------------|-------------|-------------|
| store | string | sí | — | Dominio de la tienda |
| buckets | string | no | 0-30,31-60,61-90,91-180,181+ | Rangos de antigüedad en días, separados por comas |
| carrying_cost_pct | float | no | 25 | Costo anual de mantener inventario como % de su valor (el promedio de la industria es 20-30%) |
| vendor_filter | string | no | — | Limita el análisis a un proveedor específico |
| format | string | 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`, selecciona `id`, `sku`, `inventoryQuantity`, `inventoryItem { id, unitCost }`, `product { title, vendor, status }`, cursor de paginación
   **Resultado esperado:** Todas las variantes con sus datos de stock y costo

2. Filtra las variantes con `inventoryQuantity > 0`

3. **OPERACIÓN:** `orders` — consulta
   **Entradas:** `query: "created_at:>='<NOW - 365 days>'"`, `first: 250`, selecciona `createdAt`, `lineItems { variant { id }, quantity }`, cursor de paginación
   **Resultado esperado:** Historial de ventas para saber la fecha de la última venta de cada variante

4. Para cada variante con stock, determina la antigüedad:
   - Busca el pedido más reciente que contenga esa variante → fecha de última venta
   - Si nunca se ha vendido, usa como referencia la fecha de creación del producto
   - **Antigüedad** = hoy − fecha de última venta
   - Asígnala a su rango de antigüedad

5. **OPERACIÓN:** `inventoryItems` — consulta
   **Entradas:** IDs de los artículos de inventario, para obtener los costos
   **Resultado esperado:** Costos unitarios para calcular el valor

6. Calcula por rango:
   - Total de unidades
   - Valor total (unidades × unitCost)
   - Costo mensual de mantener inventario = (valor × carrying_cost_pct / 100) / 12
   - % del valor total del inventario

## Operaciones GraphQL

```graphql
# productVariants:query — validado 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 createdAt }
        inventoryItem {
          id
          unitCost { amount currencyCode }
        }
      }
    }
    pageInfo { hasNextPage endCursor }
  }
}
```

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

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

## Seguimiento de la sesión

**Claude DEBE mostrar esta salida en cada etapa. Es obligatorio.**

**Al iniciar**, muestra:
```
╔══════════════════════════════════════════════╗
║  SKILL: Antigüedad del inventario            ║
║  Tienda: <dominio de la tienda>              ║
║  Inicio: <YYYY-MM-DD HH:MM UTC>              ║
╚══════════════════════════════════════════════╝
```

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

**Al terminar**, muestra:

Para `format: human` (por defecto):
```
══════════════════════════════════════════════
REPORTE DE ANTIGÜEDAD DEL INVENTARIO
  SKU con stock:                <n>
  Valor total del inventario:   $<monto>
  ─────────────────────────────
  RANGOS DE ANTIGÜEDAD:
  0-30 días:    <n> SKU  $<valor> (<pct>%)  ✅ Reciente
  31-60 días:   <n> SKU  $<valor> (<pct>%)  ⚠️ Vigilar
  61-90 días:   <n> SKU  $<valor> (<pct>%)  ⚠️ Envejeciendo
  91-180 días:  <n> SKU  $<valor> (<pct>%)  🔴 Estancado
  181+ días:    <n> SKU  $<valor> (<pct>%)  🔴 Muerto

  Costo mensual de mantener inventario: $<monto>
  Costo anual de mantener inventario:   $<monto>

  Artículos más antiguos por valor:
    "<producto>" SKU:<sku>  Antigüedad:<n>d  Cant.:<n>  Valor:$<n>

  Archivo: inventory_aging_<fecha>.csv
══════════════════════════════════════════════
```

## Formato de salida
Archivo CSV `inventory_aging_<YYYY-MM-DD>.csv` con las columnas:
`variant_id`, `sku`, `product_title`, `vendor`, `quantity`, `unit_cost`, `total_value`, `last_sold_date`, `age_days`, `aging_bucket`, `monthly_carrying_cost`

## 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 |
| Falta unitCost | No hay datos de costo (COGS) | Usa 0 como valor y márcalo como «costo desconocido» |
| Sin historial de ventas | Producto nuevo o que nunca se ha vendido | Usa la fecha de creación del producto como inicio de la antigüedad |

## Buenas prácticas
- Usa `carrying_cost_pct: 25` como valor por defecto (incluye almacenamiento, seguros, costo de oportunidad y mermas).
- Los artículos de los rangos de más de 90 días son buenos candidatos para rebajas: usa `shopify-ajuste-masivo-precios`.
- Cruza los resultados con `shopify-inventario-muerto` y `shopify-velocidad-de-venta` para tener una visión completa de la salud del inventario.
- Córrela cada mes para seguir la tendencia de antigüedad y medir qué tan efectivas son las liquidaciones.
