---
name: shopify-actualizar-guias
description: "Actualiza en lote los números de guía y los enlaces de rastreo de despachos ya creados. Úsala cuando la transportadora reasigne guías, reimprimas etiquetas o tu operador logístico te envíe correcciones."
---

## Propósito
Busca los despachos (fulfillments) existentes de los pedidos y actualiza en lote sus números de guía y los enlaces de rastreo de la transportadora. Sirve cuando una transportadora emite nuevas guías después de reimprimir una etiqueta, cuando un operador logístico (3PL) sube en lote guías corregidas o cuando una integración con la transportadora envía números de guía equivocados. Reemplaza la corrección manual de guías, pedido por pedido, en el admin de Shopify.

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

## Parámetros

| Parámetro | Tipo | Obligatorio | Predeterminado | Descripción |
|-----------|------|-------------|----------------|-------------|
| store | string | sí | — | Dominio de la tienda (p. ej., mitienda.myshopify.com) |
| updates | array | sí | — | Lista de objetos `{order_id, fulfillment_id, tracking_number, tracking_url, carrier}` |
| notify_customer | bool | no | false | Vuelve a enviar la confirmación de envío con la guía actualizada |
| dry_run | bool | no | true | Muestra una vista previa de las actualizaciones sin ejecutar cambios |
| format | string | no | human | Formato de salida: `human` o `json` |

## Seguridad

> ⚠️ `fulfillmentUpdate` sobrescribe la información de rastreo existente. Deja `notify_customer: false` a menos que quieras reenviar a propósito las notificaciones de envío: si lo activas, los clientes recibirán un correo nuevo por cada despacho actualizado. Ejecuta con `dry_run: true` para confirmar la lista de despachos antes de aplicar los cambios.

## Pasos

1. **OPERACIÓN:** `order` — query
   **Entradas:** `id: <order_id>` para cada pedido de `updates`
   **Resultado esperado:** El pedido con `fulfillments { id, trackingInfo }` para confirmar que los IDs de despacho existentes coinciden

2. **OPERACIÓN:** `fulfillmentUpdate` — mutation
   **Entradas:** `fulfillmentId: <id>`, `trackingInfoUpdateInput: { company, number, url }`, `notifyCustomer`
   **Resultado esperado:** `fulfillment { id, trackingInfo }`, `userErrors`

## Operaciones GraphQL

```graphql
# order:query — validado con api_version 2025-01
query OrderFulfillments($id: ID!) {
  order(id: $id) {
    id
    name
    fulfillments {
      id
      status
      trackingInfo {
        company
        number
        url
      }
    }
  }
}
```

```graphql
# fulfillmentUpdate:mutation — validado con api_version 2025-01
mutation FulfillmentUpdate($fulfillmentId: ID!, $trackingInfoInput: FulfillmentTrackingInput!, $notifyCustomer: Boolean) {
  fulfillmentUpdate(
    fulfillmentId: $fulfillmentId
    trackingInfoUpdateInput: $trackingInfoInput
    notifyCustomer: $notifyCustomer
  ) {
    fulfillment {
      id
      status
      trackingInfo {
        company
        number
        url
      }
    }
    userErrors {
      field
      message
    }
  }
}
```

## Seguimiento de la sesión

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

**Al iniciar**, muestra:
```
╔══════════════════════════════════════════════╗
║  SKILL: Actualiza números de guía en lote    ║
║  Tienda: <dominio de la tienda>              ║
║  Inicio: <AAAA-MM-DD HH:MM UTC>              ║
╚══════════════════════════════════════════════╝
```

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

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

**Al terminar**, muestra:

Para `format: human` (predeterminado):
```
══════════════════════════════════════════════
RESUMEN DEL RESULTADO
  Despachos procesados:          <n>
  Números de guía actualizados:  <n>
  Notificaciones enviadas:       <n>
  Errores:                       <n>
  Archivo:                       tracking_update_<fecha>.csv
══════════════════════════════════════════════
```

Para `format: json`, muestra:
```json
{
  "skill": "shopify-actualizar-guias",
  "store": "<dominio>",
  "started_at": "<ISO8601>",
  "completed_at": "<ISO8601>",
  "dry_run": true,
  "outcome": {
    "targeted": 0,
    "updated": 0,
    "notifications_sent": 0,
    "errors": 0,
    "output_file": "tracking_update_<fecha>.csv"
  }
}
```

## Formato de salida
Archivo CSV `tracking_update_<AAAA-MM-DD>.csv` con las columnas:
`order_name`, `fulfillment_id`, `old_tracking_number`, `new_tracking_number`, `carrier`, `notify_customer`, `status`

## 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 fulfillmentUpdate | El despacho se canceló o no existe | Registra el error, omítelo y continúa |
| El ID de despacho no pertenece al pedido | ID desactualizado en la lista de actualizaciones | Registra la diferencia, omítelo y continúa |

## Buenas prácticas
- Deja `notify_customer: false` a menos que la transportadora esté rastreando un envío de reposición: los correos de envío repetidos confunden a los clientes y pueden generar tickets de soporte innecesarios.
- Cuando puedas, incluye el `fulfillment_id` directamente en `updates` para saltarte por completo el paso de búsqueda del pedido.
- Si tu operador logístico (3PL) envía las guías corregidas en un CSV, convierte ese CSV en la lista `updates` antes de correr esta skill.
