---
name: shopify-auditoria-tarifas-envio
description: "Solo lectura: recorre cada perfil y zona de envío para verificar que tenga al menos una tarifa válida, y señala las zonas sin tarifas o solo con tarifas manuales. Úsala después de cambiar la configuración de envíos o abrir una región nueva."
---

## Propósito
Audita la configuración de envíos de cada perfil de envío de la tienda. Muestra (a) zonas sin ninguna tarifa de envío configurada (que hacen fallar el checkout), (b) zonas solo con tarifas fijas manuales (sin tarifas calculadas por la transportadora, a menudo un paso de configuración que se olvidó) y (c) perfiles que no cubren con ninguna zona geografías donde se sabe que hay ventas. Una zona mal configurada hace perder conversiones en el checkout sin que nadie lo note: esta skill lo detecta antes que tus clientes. Solo lectura: no hace mutaciones.

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

## Parámetros

| Parámetro | Tipo | Obligatorio | Predeterminado | Descripción |
|-----------|------|-------------|----------------|-------------|
| store | string | sí | — | Dominio de la tienda (p. ej., mitienda.myshopify.com) |
| profile_filter | string | no | — | Nombre opcional de un perfil de envío para limitar la auditoría |
| flag_manual_only | bool | no | true | Marca las zonas que solo tienen tarifas manuales (sin tarifas calculadas por la transportadora) |
| flag_high_price | float | no | — | Opcional: marca cualquier tarifa por encima de este precio, en la moneda de la tienda (probable error de digitación o valor desactualizado) |
| format | string | no | human | Formato de salida: `human` o `json` |

## Seguridad

> ℹ️ Skill de solo lectura: no ejecuta mutaciones. Puedes correrla en cualquier momento. La skill solo lee la configuración de envíos; no cambia cómo se cobran ni se hacen los envíos.

## Pasos

1. **OPERACIÓN:** `deliveryProfiles` — consulta
   **Entradas:** `first: 50`, selecciona `profileLocationGroups`, `profileItems`, `name`, `default` y el cursor de paginación
   **Resultado esperado:** Todos los perfiles de envío, incluido el predeterminado, con sus grupos de ubicaciones y los productos asociados; pagina hasta `hasNextPage: false`

2. Para cada perfil, recorre cada `profileLocationGroups[].locationGroupZones`. Para cada zona, toma: nombre de la zona, códigos de país y definiciones de métodos (tarifas).

3. Marca las zonas que tengan: cero `methodDefinitions`, O solo tarifas manuales basadas en `priceConditions` (ningún método calculado por la transportadora cuando `flag_manual_only: true`), O un método cuyo `price.amount > flag_high_price` si se definió ese umbral.

4. Consolida los hallazgos por perfil y luego arma un resumen general de las zonas mal configuradas en toda la tienda.

## Operaciones GraphQL

```graphql
# deliveryProfiles:query — validada con api_version 2025-01
query DeliveryProfilesAudit($after: String) {
  deliveryProfiles(first: 50, after: $after) {
    edges {
      node {
        id
        name
        default
        profileItems(first: 1) {
          edges {
            node {
              id
            }
          }
        }
        profileLocationGroups {
          locationGroup {
            id
            locations(first: 50) {
              edges {
                node {
                  id
                  name
                  address {
                    countryCode
                  }
                }
              }
            }
          }
          locationGroupZones(first: 50) {
            edges {
              node {
                zone {
                  id
                  name
                  countries {
                    code {
                      countryCode
                    }
                    provinces {
                      code
                    }
                  }
                }
                methodDefinitions(first: 50) {
                  edges {
                    node {
                      id
                      name
                      active
                      rateProvider {
                        __typename
                        ... on DeliveryRateDefinition {
                          price {
                            amount
                            currencyCode
                          }
                        }
                        ... on DeliveryParticipant {
                          carrierService {
                            id
                            name
                          }
                          fixedFee {
                            amount
                            currencyCode
                          }
                          percentageOfRateFee
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

## Seguimiento de la sesión

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

**Al iniciar**, muestra:
```
╔══════════════════════════════════════════════╗
║  SKILL: Auditoría de tarifas de envío        ║
║  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 TARIFAS DE ENVÍO
  Perfiles revisados:              <n>
  Zonas revisadas:                 <n>
  Zonas sin tarifas:               <n>
  Zonas solo con tarifas manuales: <n>
  Tarifas por encima del umbral:   <n>

  Problemas críticos (zonas sin tarifas):
    Perfil: <nombre>  Zona: <nombre>  Países: <lista>
  Archivo: shipping_rate_audit_<date>.csv
══════════════════════════════════════════════
```

Para `format: json`, muestra:
```json
{
  "skill": "shopify-auditoria-tarifas-envio",
  "store": "<dominio>",
  "profiles_inspected": 0,
  "zones_inspected": 0,
  "zones_no_rates": 0,
  "zones_manual_only": 0,
  "rates_above_threshold": 0,
  "issues": [],
  "output_file": "shipping_rate_audit_<date>.csv"
}
```

## Formato de salida
Archivo CSV `shipping_rate_audit_<YYYY-MM-DD>.csv` con las columnas:
`profile_name`, `zone_name`, `countries`, `rate_count`, `manual_rate_count`, `carrier_rate_count`, `min_rate`, `max_rate`, `currency`, `flag`

## 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 |
| El perfil no tiene productos | Perfil vacío | Anótalo en el resultado; no lo marques como crítico |
| La zona solo tiene `DeliveryRateDefinition` (sin transportadora) | Solo tarifas manuales | Márcala si `flag_manual_only: true` |
| La lista de países de una zona es null | Zona comodín de «resto del mundo» | Trátala como comodín; no la marques por falta de países |

## Buenas prácticas
- Ejecútala después de cualquier cambio grande en los envíos (apertura de una región nueva, cambio de transportadora) para confirmar que la cobertura de zonas coincide con lo planeado.
- Las zonas sin tarifas hacen fallar el checkout sin aviso: los clientes de esa zona ven «no hay envíos disponibles» y abandonan la compra. Trátalas como prioridad máxima (P0).
- Las zonas solo con tarifas manuales no siempre están mal: un envío nacional con tarifa fija puede ser una decisión deliberada. Usa `flag_manual_only: false` si tu tienda usa tarifa fija a propósito.
- Cruza los códigos de país marcados con `customers:query` filtrado por país para estimar cuántas ventas están en riesgo.
- Ejecútala cada trimestre para detectar zonas agregadas por integraciones de apps o por tu equipo que se alejen de la configuración documentada.
