---
name: shopify-etiquetar-pedidos-reglas
description: "Etiqueta pedidos según reglas que tú defines: país de envío, valor, tipo de producto, nivel de riesgo o tipo de cliente. Úsala cuando quieras segmentar tus pedidos para filtrarlos o automatizar acciones, probando siempre primero en modo simulación."
---

## Propósito
Aplica etiquetas a los pedidos según conjuntos de reglas configurables: por geografía (nacional/internacional), por valor (alto valor, bajo valor), por tipo de producto, por nivel del cliente o por condiciones personalizadas. Tiene modo de simulación (dry run) para revisar los cambios sin riesgo.

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

## Parámetros

| Parámetro | Tipo | Obligatorio | Predeterminado | Descripción |
|-----------|------|-------------|----------------|-------------|
| store | string | sí | — | Dominio de la tienda |
| rules | object[] | sí | — | Lista de reglas de etiquetado (ver «Formato de las reglas» más abajo) |
| days_back | integer | no | 7 | Ventana de días hacia atrás de los pedidos a etiquetar |
| skip_tagged | boolean | no | true | Omite los pedidos que ya tienen la etiqueta objetivo |
| dry_run | boolean | no | true | Solo vista previa: no aplica etiquetas |
| format | string | no | human | Formato de salida: `human` o `json` |

## Formato de las reglas

Cada regla tiene una `condition` y una `tag`:

```json
[
  { "condition": "total_price > 500", "tag": "high-value" },
  { "condition": "total_price < 20", "tag": "low-value" },
  { "condition": "shipping_country != US", "tag": "international" },
  { "condition": "shipping_country = US", "tag": "domestic" },
  { "condition": "line_items_count > 5", "tag": "bulk-order" },
  { "condition": "customer_orders > 3", "tag": "repeat-buyer" },
  { "condition": "customer_orders = 1", "tag": "first-time" },
  { "condition": "risk_level = HIGH", "tag": "needs-review" },
  { "condition": "financial_status = PARTIALLY_REFUNDED", "tag": "partial-refund" },
  { "condition": "fulfillment_status = null", "tag": "unfulfilled" },
  { "condition": "discount_codes contains WELCOME", "tag": "welcome-discount" },
  { "condition": "product_type contains Subscription", "tag": "subscription-order" }
]
```

## Seguridad

> ⚠️ Skill que modifica la tienda: ejecútala siempre primero con `dry_run: true` para revisar qué etiquetas se asignarían antes de aplicarlas.

## Pasos

1. **OPERACIÓN:** `orders` — consulta
   **Entradas:** `query: "created_at:>='<NOW - days_back days>'"`, `first: 250`, selecciona `id`, `name`, `tags`, `totalPriceSet`, `shippingAddress { countryCode }`, `customer { numberOfOrders }`, `displayFinancialStatus`, `displayFulfillmentStatus`, `riskLevel`, `lineItems { product { productType } }`, `discountCodes` y el cursor de paginación
   **Resultado esperado:** Todos los pedidos recientes con los datos necesarios para evaluar las reglas

2. Para cada pedido, evalúa todas las reglas:
   - Interpreta cada condición con los datos del pedido
   - Reúne todas las etiquetas que coinciden
   - Si `skip_tagged: true`, excluye las etiquetas que el pedido ya tiene

3. Si `dry_run: true`: reporta las coincidencias sin aplicarlas
   Si `dry_run: false`:

4. **OPERACIÓN:** `orderUpdate` — mutación (para cada pedido que necesite etiquetas nuevas)
   **Entradas:** `{ id: <order_id>, tags: <existing_tags + new_tags> }`
   **Resultado esperado:** El pedido actualizado con las etiquetas nuevas
   **Lotes:** Procesa en lotes de 10 para respetar los límites de solicitudes

## Operaciones GraphQL

```graphql
# orders:query — validado con api_version 2025-01
query OrdersForTagging($query: String!, $after: String) {
  orders(first: 250, after: $after, query: $query) {
    edges {
      node {
        id
        name
        tags
        totalPriceSet { shopMoney { amount currencyCode } }
        shippingAddress { countryCode provinceCode }
        customer { id numberOfOrders }
        displayFinancialStatus
        displayFulfillmentStatus
        riskLevel
        discountCodes
        lineItems(first: 20) {
          edges {
            node {
              product { productType }
              quantity
            }
          }
        }
      }
    }
    pageInfo { hasNextPage endCursor }
  }
}
```

```graphql
# orderUpdate:mutation — validado con api_version 2025-01
mutation TagOrder($input: OrderInput!) {
  orderUpdate(input: $input) {
    order { id name tags }
    userErrors { field message }
  }
}
```

## Seguimiento de la sesión

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

**Al iniciar**, muestra:
```
╔══════════════════════════════════════════════╗
║  SKILL: Etiqueta pedidos con reglas          ║
║  Tienda: <dominio de la tienda>              ║
║  Modo: <SIMULACIÓN | EN VIVO>                ║
║  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):
```
══════════════════════════════════════════════
REPORTE DE ETIQUETADO DE PEDIDOS  (<days_back> días, <modo>)
  Pedidos revisados:       <n>
  Pedidos que coinciden:   <n>
  Etiquetas aplicadas:     <n>  (o "se aplicarían" en simulación)
  ─────────────────────────────
  COINCIDENCIAS POR REGLA:
    "high-value"       → <n> pedidos
    "international"    → <n> pedidos
    "first-time"       → <n> pedidos
    "repeat-buyer"     → <n> pedidos

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

## Formato de salida
Archivo CSV `order_tags_<AAAA-MM-DD>.csv` con las columnas:
`order_id`, `order_name`, `existing_tags`, `new_tags`, `matched_rules`

## 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 |
| Regla no válida | Una condición que no se puede interpretar | Omite la regla y avisa en el resultado |
| `ACCESS_DENIED` | Falta el permiso write_orders | Cambia a modo de solo lectura y reporta solo las coincidencias |

## Buenas prácticas
- Ejecútala siempre primero con `dry_run: true` para revisar los cambios.
- Las etiquetas se suman: esta skill nunca quita etiquetas existentes.
- Úsala junto con `shopify-reporte-riesgo-pedidos` para etiquetar automáticamente los niveles de riesgo.
- Combínala con herramientas de automatización para las acciones posteriores al etiquetado (p. ej., etiqueta "high-value" → asignar el pedido a la fila de despacho VIP).
- Sirve para filtrar pedidos en el panel de Shopify: con las etiquetas, los segmentos de pedidos más complejos se pueden buscar.
