Saltar al contenido principal

Solución de problemas de integración

Esta guía os ayuda a diagnosticar y resolver problemas comunes de integración con Eaternity Forecast.

Problemas de autenticación

La clave de interfaz de programación de aplicaciones no funciona

Síntomas:

  • Respuestas 401 No autorizado
  • Errores de "Autenticación fallida"

Causas comunes y soluciones:

1. Formato incorrecto de clave de interfaz de programación de aplicaciones

Problema: Espacios o caracteres adicionales en la clave de interfaz de programación de aplicaciones

Solución:

# Incorrecto (espacio al final)
API_KEY="sk_live_abc123 "

# Correcto (sin espacios adicionales)
API_KEY="sk_live_abc123"

# Probar autenticación
curl -X GET "https://api.eaternity.org/v1/forecast/ping" \
-H "Authorization: Bearer $API_KEY"

2. Uso de clave de pruebas en producción

Problema: Intento de usar clave de interfaz de programación de aplicaciones de pruebas con URL de producción

Solución:

# Clave de pruebas (comienza con sk_sandbox_)
sk_sandbox_abc123 → Usar con https://sandbox-api.eaternity.org

# Clave de producción (comienza con sk_live_)
sk_live_abc123 → Usar con https://api.eaternity.org

3. Clave de interfaz de programación de aplicaciones expirada

Problema: La clave de interfaz de programación de aplicaciones ha sido rotada o ha expirado

Solución:

  1. Entrad en el panel de control de Forecast
  2. Navegad a Configuración → Claves de interfaz de programación de aplicaciones
  3. Generad una nueva clave de interfaz de programación de aplicaciones
  4. Actualizad vuestra integración con la nueva clave

4. Falta la cabecera de autorización

Problema: Olvidar incluir la cabecera de autenticación

Solución:

# Incorrecto (sin autenticación)
curl -X GET "https://api.eaternity.org/v1/forecast/predictions?date=2024-01-20"

# Correcto (con autenticación)
curl -X GET "https://api.eaternity.org/v1/forecast/predictions?date=2024-01-20" \
-H "Authorization: Bearer your_api_key"

Problemas con token OAuth

Síntomas:

  • Errores de token expirado
  • Respuestas de token inválido

Soluciones:

Implementar renovación de token

async function getValidToken() {
// Comprobar si el token existe y sigue siendo válido
if (accessToken && tokenExpiresAt > Date.now()) {
return accessToken;
}

// Renovar token
const response = await fetch('https://api.eaternity.org/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'refresh_token',
refresh_token: refreshToken,
client_id: clientId,
client_secret: clientSecret
})
});

const data = await response.json();
accessToken = data.access_token;
tokenExpiresAt = Date.now() + (data.expires_in * 1000);

return accessToken;
}

Problemas de envío de datos

Fallo en la importación de datos históricos

Síntomas:

  • Importación atascada en estado "procesando"
  • Importación falla con errores de validación
  • Algunos registros omitidos

Causas comunes y soluciones:

1. Formato de fecha incorrecto

Problema: Uso del formato de fecha incorrecto

Formatos incorrectos:

{
"date": "20-01-2024", // ❌ Orden incorrecto
"date": "2024/01/20", // ❌ Barras en lugar de guiones
"date": "2024-1-20", // ❌ Sin relleno de ceros
"date": "Jan 20, 2024" // ❌ Formato de texto
}

Formato correcto:

{
"date": "2024-01-20" // ✅ AAAA-MM-DD
}

2. Campos obligatorios faltantes

Problema: Omitir campos de datos obligatorios

Solución:

{
"kitchen_id": "your_kitchen_id", // ✅ Obligatorio
"date": "2024-01-20", // ✅ Obligatorio
"items": [ // ✅ Obligatorio
{
"item_id": "pasta_carbonara", // ✅ Obligatorio
"quantity_sold": 52, // ✅ Obligatorio
"name": "Pasta Carbonara", // ⚠️ Recomendado
"price": 14.50, // ⚠️ Recomendado
"category": "Main Course" // ⚠️ Recomendado
}
]
}

3. ID de artículos inconsistentes

Problema: Los ID de artículos cambian entre envíos

Incorrecto:

// Día 1
{"item_id": "pasta_carbonara", "quantity_sold": 52}

// Día 2
{"item_id": "Pasta_Carbonara", "quantity_sold": 48} // ❌ Diferente mayúsculas

// Día 3
{"item_id": "pasta-carbonara", "quantity_sold": 55} // ❌ Formato diferente

Correcto:

// Todos los días usan el mismo ID
{"item_id": "pasta_carbonara", "quantity_sold": 52}
{"item_id": "pasta_carbonara", "quantity_sold": 48}
{"item_id": "pasta_carbonara", "quantity_sold": 55}

Corregir datos inconsistentes:

# Solicitar actualización de mapeo de ID de artículos
POST /v1/forecast/items/map
{
"kitchen_id": "your_kitchen_id",
"mappings": [
{
"variants": ["pasta_carbonara", "Pasta_Carbonara", "pasta-carbonara"],
"canonical_id": "pasta_carbonara"
}
]
}

4. Envíos de datos duplicados

Problema: Enviar la misma fecha varias veces

Solución:

# Primer envío (Día 1)
POST /v1/forecast/sales
{"date": "2024-01-20", "items": [...]}

# Corrección posterior necesaria
# Usad PATCH en lugar de POST
PATCH /v1/forecast/sales/2024-01-20
{"items": [{"item_id": "pasta_carbonara", "quantity_sold": 54}]}

5. Datos demasiado grandes

Problema: Exceder los límites de tamaño de solicitud

Solución:

# Incorrecto: Todos los datos en una solicitud
bulk_import(sales_data_90_days) # Puede exceder el límite

# Correcto: Dividir en fragmentos
def chunk_data(data, chunk_size=30):
for i in range(0, len(data), chunk_size):
yield data[i:i + chunk_size]

for chunk in chunk_data(sales_data, chunk_size=30):
bulk_import(chunk)
time.sleep(1) # Evitar límites de tasa

Fallos en envío de ventas diarias

Síntomas:

  • Errores de validación 422
  • Datos de ventas no aparecen en el panel de control
  • Predicciones no se actualizan

Soluciones:

Verificar calidad de datos

Punto de acceso de validación:

POST /v1/forecast/sales/validate
{
"kitchen_id": "your_kitchen_id",
"date": "2024-01-20",
"items": [...]
}

# La respuesta muestra problemas de validación
{
"valid": false,
"errors": [
{
"field": "items[2].quantity_sold",
"value": -5,
"issue": "La cantidad no puede ser negativa"
}
]
}

Errores de validación comunes

ErrorCausaSolución
La cantidad no puede ser negativaValor de cantidad negativoUsad 0 para artículos no vendidos
El ID del artículo contiene caracteres no válidosCaracteres especiales en el IDUsad solo alfanuméricos, guion bajo, guion
Fecha en el futuroLa fecha aún no ha ocurridoSolo enviad datos históricos
El precio excede el máximoPrecio > 999,99Contactad soporte si es legítimo

Problemas de recuperación de predicciones

Predicciones no disponibles

Síntomas:

  • 404 No encontrado para solicitudes de predicción
  • Matriz de predicciones vacía
  • Mensaje "No se generaron predicciones"

Causas comunes y soluciones:

1. Datos de entrenamiento insuficientes

Problema: El modelo aún no ha terminado de entrenar

Comprobar estado del entrenamiento:

GET /v1/forecast/training/status

# Respuesta
{
"status": "training",
"progress": 45,
"expected_completion": "2024-01-25T10:00:00Z"
}

Solución: Esperad a que se complete el entrenamiento (típicamente 1-2 semanas)

2. Sin datos de ventas recientes

Problema: No habéis enviado datos de ventas recientemente

Comprobar último envío de datos:

GET /v1/forecast/sales/last

# Respuesta
{
"last_submission": "2024-01-15",
"days_ago": 5,
"warning": "Sin datos enviados en 5 días. La precisión de predicción puede disminuir."
}

Solución: Enviad los datos de ventas faltantes

3. Solicitar fecha futura más allá del rango

Problema: Solicitar predicciones demasiado adelante en el tiempo

Incorrecto:

# Hoy es 2024-01-20
GET /v1/forecast/predictions?date=2024-02-15 # 26 días adelante ❌

Correcto:

# Máximo 14 días adelante
GET /v1/forecast/predictions?date=2024-02-03 # 14 días adelante ✅

4. Artículo descontinuado

Problema: Solicitar predicciones para un artículo del menú eliminado

Comprobar estado del artículo:

GET /v1/forecast/items/pasta_carbonara

# Respuesta
{
"item_id": "pasta_carbonara",
"status": "discontinued",
"last_sold": "2024-01-10",
"reason": "Cero ventas durante 10 días consecutivos"
}

Solución: Reactivad el artículo o eliminadlo de las solicitudes de predicción

Problemas de precisión de predicción

Síntomas:

  • Predicciones consistentemente demasiado altas o bajas
  • Intervalos de confianza amplios
  • Error porcentual absoluto medio > 20%

Pasos de diagnóstico:

1. Comprobar puntuación de calidad de datos

GET /v1/forecast/analytics/data-quality

# Respuesta
{
"overall_score": 65, # ⚠️ Por debajo del 80%
"issues": [
{
"type": "missing_dates",
"severity": "high",
"details": "Faltan datos de ventas para 12 días en los últimos 30 días"
},
{
"type": "inconsistent_naming",
"severity": "medium",
"details": "15 artículos con variaciones de nombre"
}
],
"recommendations": [
"Enviad datos de ventas faltantes para: 2024-01-05, 2024-01-08, ..."
]
}

Solución: Abordad los problemas de calidad de datos identificados

2. Verificar cambios recientes

Problema: Cambios de menú, cambios operativos no reflejados

Comprobar registro de cambios:

GET /v1/forecast/changelog

# Respuesta
{
"recent_changes": [
{
"date": "2024-01-15",
"type": "menu_change",
"details": "5 nuevos artículos añadidos, 3 artículos eliminados"
}
]
}

Solución:

  • Esperad 2-3 semanas después de cambios importantes del menú
  • Proporcionad anulaciones manuales durante el período de transición
  • Enviad retroalimentación sobre razones de varianza

3. Identificar errores sistemáticos

Analizar patrones de varianza:

GET /v1/forecast/analytics/variance-analysis?days=30

# La respuesta muestra patrones
{
"patterns": [
{
"pattern": "consistently_over_predicting",
"items_affected": ["salad_items"],
"magnitude": "+15%",
"possible_cause": "Declive estacional aún no aprendido"
}
]
}

Solución: El modelo aprende con el tiempo, o proporcionad datos de factores externos (clima, eventos)

Problemas de red y conectividad

Errores de tiempo de espera agotado

Síntomas:

  • Tiempo de espera de solicitud agotado después de 30 segundos
  • Errores 504 Tiempo de espera de la puerta de enlace

Soluciones:

1. Aumentar tiempo de espera del cliente

import requests

# Incorrecto: Tiempo de espera predeterminado demasiado corto
response = requests.get(url)

# Correcto: Especificar tiempo de espera
response = requests.get(url, timeout=60) # 60 segundos

2. Usar operaciones asíncronas para operaciones masivas

// Incorrecto: Solicitudes secuenciales (lento)
for (const date of dates) {
await submitSales(date);
}

// Correcto: Solicitudes paralelas (rápido)
await Promise.all(dates.map(date => submitSales(date)));

Errores de límite de tasa

Síntomas:

  • 429 Demasiadas solicitudes
  • Mensaje "Límite de tasa excedido"

Soluciones:

1. Respetar la cabecera Retry-After

import time
import requests

def make_request(url):
response = requests.get(url)

if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Límite de tasa alcanzado. Esperando {retry_after} segundos...")
time.sleep(retry_after)
return make_request(url) # Reintentar

return response

2. Implementar cola de solicitudes

from time import sleep
from collections import deque

class RateLimitedClient:
def __init__(self, requests_per_minute=100):
self.requests_per_minute = requests_per_minute
self.request_times = deque()

def make_request(self, url):
now = time.time()

# Eliminar solicitudes más antiguas de 1 minuto
while self.request_times and self.request_times[0] < now - 60:
self.request_times.popleft()

# Comprobar si está en el límite
if len(self.request_times) >= self.requests_per_minute:
sleep_time = 60 - (now - self.request_times[0])
sleep(sleep_time)

# Hacer solicitud
response = requests.get(url)
self.request_times.append(time.time())
return response

3. Solicitar aumento del límite de tasa

Para integraciones de alto volumen:

  • Enviad correo a forecast-api@eaternity.org
  • Proporcionad caso de uso y volumen de solicitudes esperado
  • Límites de tasa personalizados disponibles

Problemas de integración con Necta

El módulo de Forecast no aparece

Síntomas:

  • Sin pestaña "Forecast" en el módulo de Planificación de Necta
  • Activación confirmada pero interfaz sin cambios

Soluciones:

1. Borrar caché del navegador

1. Cerrad Necta completamente
2. Borrad la caché del navegador:
- Chrome: Configuración → Privacidad → Borrar datos de navegación
- Firefox: Opciones → Privacidad → Borrar datos
3. Reiniciad el navegador
4. Entrad en Necta de nuevo

2. Verificar estado de activación

Contactad soporte de Necta:

Asunto: Estado de activación del módulo de Forecast

ID de cuenta: [Vuestro ID de cuenta de Necta]
Problema: Módulo de Forecast no visible después de la activación
Fecha de activación: [Fecha en que os dijeron que estaba activado]

3. Comprobar permisos de usuario

Problema: El rol de usuario no tiene acceso a Forecast

Solución:

  • El administrador debe otorgar permisos de Forecast
  • Navegad a Configuración de Necta → Usuarios → [Vuestro usuario] → Permisos
  • Habilitar acceso al módulo "Forecast"

Los datos no se sincronizan desde Necta

Síntomas:

  • Las predicciones no se actualizan con los últimos datos de ventas de Necta
  • Importación histórica incompleta

Soluciones:

1. Verificar entrada de datos en Necta

Comprobar en Necta:

  • Navegad a Ventas → Informes diarios
  • Verificad que los datos de ventas están introducidos para las fechas recientes
  • Aseguraos de que todos los artículos del menú están registrados

2. Comprobar estado de sincronización

Contactad soporte de Eaternity:

Asunto: Problema de sincronización de datos de Necta

ID de cocina: [Vuestro ID de cocina]
ID de cuenta de Necta: [Vuestro ID de cuenta de Necta]
Última sincronización exitosa: [Comprobad en el panel de control de Forecast]
Fechas faltantes: [Listad las fechas sin sincronización]

3. Reconectar la integración

A través del panel de control de Necta:

  1. Navegad a Integraciones → Eaternity Forecast
  2. Haced clic en "Desconectar"
  3. Haced clic en "Reconectar"
  4. Otorgad permisos de nuevo

Problemas con ganchos web

Los ganchos web no se entregan

Síntomas:

  • Sin notificaciones de ganchos web recibidas
  • El punto de acceso del gancho web nunca se llama

Soluciones:

1. Verificar configuración del gancho web

GET /v1/forecast/webhooks

# Comprobar configuración
{
"webhooks": [
{
"webhook_id": "wh_123",
"url": "https://your-system.com/webhooks/forecast",
"events": ["predictions.generated"],
"status": "active",
"last_delivery": "2024-01-20T03:16:00Z"
}
]
}

Si status: "failed": Comprobad los registros de errores

2. Comprobar accesibilidad del punto de acceso

Probar desde servicio externo:

# Usad webhook.site o similar para probar
curl -X POST "https://your-system.com/webhooks/forecast" \
-H "Content-Type: application/json" \
-d '{"test": "webhook"}'

Problemas comunes:

  • Cortafuegos bloqueando IPs de Forecast
  • Certificado HTTPS inválido
  • El punto de acceso devuelve código de estado que no es 2xx

Solución: Añadir IPs de Forecast a la lista blanca (contactad soporte para la lista)

3. Verificar validación de firma

Problema: Rechazar ganchos web debido a fallo en verificación de firma

Depurar validación de firma:

import hmac
import hashlib

def verify_webhook(payload, signature, secret):
# Calcular firma esperada
expected = hmac.new(
secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()

# Salida de depuración
print(f"Firma recibida: {signature}")
print(f"Firma esperada: {expected}")
print(f"Coincidencia: {hmac.compare_digest(signature, expected)}")

return hmac.compare_digest(signature, expected)

Retrasos en la entrega de ganchos web

Síntomas:

  • Los ganchos web llegan tarde (>5 minutos después del evento)
  • Tiempos de entrega inconsistentes

Causas:

  • Vuestro punto de acceso tarda en responder
  • Congestión de red
  • Retrasos de reintento después de fallos

Soluciones:

1. Optimizar tiempo de respuesta del punto de acceso

// Incorrecto: El procesamiento lento bloquea la respuesta
app.post('/webhooks/forecast', async (req, res) => {
await processWebhook(req.body); // Operación lenta
res.status(200).send('OK');
});

// Correcto: Responder inmediatamente, procesar de forma asíncrona
app.post('/webhooks/forecast', async (req, res) => {
res.status(200).send('OK'); // Responder inmediatamente

// Procesar de forma asíncrona
processWebhookAsync(req.body).catch(err => {
console.error('Error de procesamiento de gancho web:', err);
});
});

2. Monitorear entrega de ganchos web

GET /v1/forecast/webhooks/wh_123/deliveries?limit=50

# Comprobar entregas recientes
{
"deliveries": [
{
"delivery_id": "del_abc123",
"event": "predictions.generated",
"timestamp": "2024-01-20T03:15:42Z",
"response_code": 200,
"response_time_ms": 350,
"status": "success"
}
]
}

Problemas de rendimiento

Respuestas lentas de la interfaz de programación de aplicaciones

Síntomas:

  • Solicitudes que tardan >5 segundos
  • Tiempos de respuesta inconsistentes

Pasos de diagnóstico:

1. Identificar puntos de acceso lentos

# Añadir tiempo a las solicitudes
time curl -X GET "https://api.eaternity.org/v1/forecast/predictions?date=2024-01-20" \
-H "Authorization: Bearer your_api_key"

2. Optimizar parámetros de solicitud

Lento (solicitando todos los artículos):

GET /v1/forecast/predictions?date=2024-01-20&end_date=2024-01-27
# Devuelve 65 artículos × 7 días = 455 predicciones

Rápido (solo artículos específicos):

GET /v1/forecast/predictions?date=2024-01-20&items=pasta_carbonara,grilled_salmon
# Devuelve 2 artículos × 1 día = 2 predicciones

3. Usar caché

import time
from functools import lru_cache

@lru_cache(maxsize=100)
def get_predictions_cached(date):
return get_predictions(date)

# La caché expira después de 1 hora
def get_predictions_with_expiry(date):
cache_key = f"{date}_{int(time.time() // 3600)}"
return get_predictions_cached(cache_key)

Problemas de calidad de datos

Puntuación de calidad de datos baja

Síntomas:

  • Puntuación de calidad de datos inferior al 80%
  • Advertencias en el panel de control
  • Predicciones con baja confianza

Pasos de mejora:

1. Ejecutar informe de calidad de datos

GET /v1/forecast/analytics/data-quality

# Informe detallado
{
"overall_score": 72,
"components": {
"completeness": 85, # Faltan algunas fechas
"consistency": 65, # Problemas de nomenclatura
"accuracy": 80, # Algunos valores atípicos
"timeliness": 70 # Envíos retrasados
},
"issues": [...]
}

2. Corregir problemas específicos

Fechas faltantes:

# Enviar datos faltantes
POST /v1/forecast/sales
{
"date": "2024-01-15",
"items": [...]
}

Nomenclatura inconsistente:

# Estandarizar nombres de artículos
POST /v1/forecast/items/standardize
{
"standardizations": [
{
"variants": ["pasta carbonara", "Pasta Carbonara", "PASTA_CARBONARA"],
"standard": "pasta_carbonara"
}
]
}

Valores atípicos:

# Marcar y explicar valores atípicos
POST /v1/forecast/sales/2024-01-15/annotate
{
"item_id": "grilled_salmon",
"note": "Evento festivo, volumen 2x normal esperado",
"type": "special_event"
}

Obtener ayuda

Canales de soporte

Tipo de problemaContactoTiempo de respuesta
Crítico (Producción caída)forecast-api@eaternity.org + Teléfono4 horas
Alto (Integración rota)forecast-api@eaternity.org24 horas
Medio (Preguntas de precisión)forecast@eaternity.org48 horas
Bajo (Preguntas generales)Documentación o correo electrónico1 semana

Información a incluir

En todas las solicitudes de soporte:

  • ID de cocina
  • Tipo de integración (Necta, interfaz de programación de aplicaciones personalizada, manual)
  • Descripción del problema
  • Pasos para reproducir
  • Mensajes de error (si los hay)
  • Capturas de pantalla (si es relevante)
  • Ejemplo de solicitud/respuesta (para problemas de interfaz de programación de aplicaciones)

Recursos de autoservicio

Ved también