Zum Hauptinhalt springen

Integrations-Fehlerbehebung

Dieser Leitfaden hilft Ihnen, häufige Integrationsprobleme mit Eaternity Forecast zu diagnostizieren und zu beheben.

Authentifizierungsprobleme

API-Schlüssel funktioniert nicht

Symptome:

  • 401 Unauthorized-Antworten
  • "Authentication failed"-Fehler

Häufige Ursachen und Lösungen:

1. Falsches API-Schlüssel-Format

Problem: Zusätzliche Leerzeichen oder Zeichen im API-Schlüssel

Lösung:

# Falsch (nachgestelltes Leerzeichen)
API_KEY="sk_live_abc123 "

# Richtig (keine zusaetzlichen Leerzeichen)
API_KEY="sk_live_abc123"

# Authentifizierung testen
curl -X GET "https://api.eaternity.org/v1/forecast/ping" \
-H "Authorization: Bearer $API_KEY"

2. Sandbox-Schlüssel in Produktion verwenden

Problem: Versuch, Sandbox-API-Schlüssel mit Produktions-URL zu verwenden

Lösung:

# Sandbox-Schluessel (beginnt mit sk_sandbox_)
sk_sandbox_abc123 → Verwenden mit https://sandbox-api.eaternity.org

# Produktions-Schluessel (beginnt mit sk_live_)
sk_live_abc123 → Verwenden mit https://api.eaternity.org

3. Abgelaufener API-Schlüssel

Problem: API-Schlüssel wurde rotiert oder ist abgelaufen

Lösung:

  1. Ins Forecast-Dashboard einloggen
  2. Zu Einstellungen → API-Schlüssel navigieren
  3. Neuen API-Schlüssel generieren
  4. Integration mit neuem Schlüssel aktualisieren

4. Fehlender Authorization-Header

Problem: Authentifizierungs-Header nicht mitgesendet

Lösung:

# Falsch (keine Auth)
curl -X GET "https://api.eaternity.org/v1/forecast/predictions?date=2024-01-20"

# Richtig (mit Auth)
curl -X GET "https://api.eaternity.org/v1/forecast/predictions?date=2024-01-20" \
-H "Authorization: Bearer your_api_key"

OAuth-Token-Probleme

Symptome:

  • Token abgelaufen-Fehler
  • Ungültiges Token-Antworten

Lösungen:

Token-Aktualisierung implementieren

async function getValidToken() {
// Pruefen ob Token existiert und noch gueltig ist
if (accessToken && tokenExpiresAt > Date.now()) {
return accessToken;
}

// Token aktualisieren
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;
}

Dateneinreichungsprobleme

Historischer Datenimport schlägt fehl

Symptome:

  • Import bleibt im "processing"-Status hängen
  • Import schlägt mit Validierungsfehlern fehl
  • Einige Datensätze übersprungen

Häufige Ursachen und Lösungen:

1. Datumsformat falsch

Problem: Falsches Datumsformat verwendet

Falsche Formate:

{
"date": "20-01-2024", // ❌ Falsche Reihenfolge
"date": "2024/01/20", // ❌ Schraegstriche statt Bindestriche
"date": "2024-1-20", // ❌ Nicht nullgefuellt
"date": "Jan 20, 2024" // ❌ Textformat
}

Richtiges Format:

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

2. Fehlende Pflichtfelder

Problem: Erforderliche Datenfelder weggelassen

Lösung:

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

3. Inkonsistente Artikel-IDs

Problem: Artikel-IDs ändern sich zwischen Einreichungen

Falsch:

// Tag 1
{"item_id": "pasta_carbonara", "quantity_sold": 52}

// Tag 2
{"item_id": "Pasta_Carbonara", "quantity_sold": 48} // ❌ Andere Schreibweise

// Tag 3
{"item_id": "pasta-carbonara", "quantity_sold": 55} // ❌ Anderes Format

Richtig:

// Alle Tage gleiche ID verwenden
{"item_id": "pasta_carbonara", "quantity_sold": 52}
{"item_id": "pasta_carbonara", "quantity_sold": 48}
{"item_id": "pasta_carbonara", "quantity_sold": 55}

Inkonsistente Daten bereinigen:

# Artikel-ID-Mapping-Aktualisierung anfordern
POST /v1/forecast/items/map
{
"kitchen_id": "your_kitchen_id",
"mappings": [
{
"variants": ["pasta_carbonara", "Pasta_Carbonara", "pasta-carbonara"],
"canonical_id": "pasta_carbonara"
}
]
}

4. Doppelte Dateneinreichungen

Problem: Gleiches Datum mehrfach einreichen

Lösung:

# Erste Einreichung (Tag 1)
POST /v1/forecast/sales
{"date": "2024-01-20", "items": [...]}

# Spaetere Korrektur erforderlich
# PATCH statt POST verwenden
PATCH /v1/forecast/sales/2024-01-20
{"items": [{"item_id": "pasta_carbonara", "quantity_sold": 54}]}

5. Daten zu gross

Problem: Anfragengrössen-Limits überschritten

Lösung:

# Falsch: Alle Daten in einer Anfrage
bulk_import(sales_data_90_days) # Koennte Limit ueberschreiten

# Richtig: In Bloecke aufteilen
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) # Ratenlimits vermeiden

Tägliche Verkaufseinreichung schlägt fehl

Symptome:

  • 422 Validierungsfehler
  • Verkaufsdaten erscheinen nicht im Dashboard
  • Prognosen aktualisieren sich nicht

Lösungen:

Datenqualität prüfen

Validierungs-Endpunkt:

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

# Antwort zeigt Validierungsprobleme
{
"valid": false,
"errors": [
{
"field": "items[2].quantity_sold",
"value": -5,
"issue": "Quantity cannot be negative"
}
]
}

Häufige Validierungsfehler

FehlerUrsacheLösung
Quantity cannot be negativeNegativer Mengenwert0 für nicht verkaufte Artikel verwenden
Item ID contains invalid charactersSonderzeichen in IDNur alphanumerisch, Unterstrich, Bindestrich verwenden
Date in futureDatum noch nicht eingetretenNur historische Daten einreichen
Price exceeds maximumPreis > 999,99Support kontaktieren wenn legitim

Prognoseabruf-Probleme

Prognosen nicht verfügbar

Symptome:

  • 404 Not Found bei Prognoseanfragen
  • Leeres Prognose-Array
  • "No predictions generated"-Meldung

Häufige Ursachen und Lösungen:

1. Ungenügend Trainingsdaten

Problem: Modell hat Training noch nicht abgeschlossen

Trainingsstatus prüfen:

GET /v1/forecast/training/status

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

Lösung: Warten bis Training abgeschlossen (typischerweise 1-2 Wochen)

2. Keine aktuellen Verkaufsdaten

Problem: Kürzlich keine Verkaufsdaten eingereicht

Letzte Dateneinreichung prüfen:

GET /v1/forecast/sales/last

# Antwort
{
"last_submission": "2024-01-15",
"days_ago": 5,
"warning": "No data submitted in 5 days. Prediction accuracy may decline."
}

Lösung: Fehlende Verkaufsdaten einreichen

3. Zukünftiges Datum ausserhalb Reichweite angefragt

Problem: Prognosen zu weit im Voraus angefragt

Falsch:

# Heute ist 2024-01-20
GET /v1/forecast/predictions?date=2024-02-15 # 26 Tage voraus ❌

Richtig:

# Maximum 14 Tage voraus
GET /v1/forecast/predictions?date=2024-02-03 # 14 Tage voraus ✅

4. Artikel eingestellt

Problem: Prognosen für entfernten Menüpunkt angefragt

Artikelstatus prüfen:

GET /v1/forecast/items/pasta_carbonara

# Antwort
{
"item_id": "pasta_carbonara",
"status": "discontinued",
"last_sold": "2024-01-10",
"reason": "Zero sales for 10 consecutive days"
}

Lösung: Artikel reaktivieren oder aus Prognoseanfragen entfernen

Prognosegenauigkeits-Probleme

Symptome:

  • Prognosen konstant zu hoch oder zu niedrig
  • Breite Konfidenzintervalle
  • MAPE > 20%

Diagnoseschritte:

1. Datenqualitätswert prüfen

GET /v1/forecast/analytics/data-quality

# Antwort
{
"overall_score": 65, # ⚠️ Unter 80%
"issues": [
{
"type": "missing_dates",
"severity": "high",
"details": "Missing sales data for 12 days in last 30 days"
},
{
"type": "inconsistent_naming",
"severity": "medium",
"details": "15 items with name variations"
}
],
"recommendations": [
"Submit missing sales data for: 2024-01-05, 2024-01-08, ..."
]
}

Lösung: Identifizierte Datenqualitätsprobleme beheben

2. Aktuelle Änderungen verifizieren

Problem: Menüänderungen, betriebliche Änderungen nicht reflektiert

Änderungsprotokoll prüfen:

GET /v1/forecast/changelog

# Antwort
{
"recent_changes": [
{
"date": "2024-01-15",
"type": "menu_change",
"details": "5 new items added, 3 items removed"
}
]
}

Lösung:

  • 2-3 Wochen nach grossen Menüänderungen warten
  • Während Übergangszeit manuelle Überschreibungen bereitstellen
  • Feedback zu Abweichungsgründen einreichen

3. Systematische Fehler identifizieren

Abweichungsmuster analysieren:

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

# Antwort zeigt Muster
{
"patterns": [
{
"pattern": "consistently_over_predicting",
"items_affected": ["salad_items"],
"magnitude": "+15%",
"possible_cause": "Seasonal decline not yet learned"
}
]
}

Lösung: Modell lernt über Zeit, oder externe Faktordaten bereitstellen (Wetter, Ereignisse)

Netzwerk- und Konnektivitätsprobleme

Timeout-Fehler

Symptome:

  • Anfrage-Timeout nach 30 Sekunden
  • 504 Gateway Timeout-Fehler

Lösungen:

1. Client-Timeout erhöhen

import requests

# Falsch: Standard-Timeout zu kurz
response = requests.get(url)

# Richtig: Timeout angeben
response = requests.get(url, timeout=60) # 60 Sekunden

2. Async für Massenoperationen verwenden

// Falsch: Sequentielle Anfragen (langsam)
for (const date of dates) {
await submitSales(date);
}

// Richtig: Parallele Anfragen (schnell)
await Promise.all(dates.map(date => submitSales(date)));

Ratenlimit-Fehler

Symptome:

  • 429 Too Many Requests
  • "Rate limit exceeded"-Meldung

Lösungen:

1. Retry-After-Header respektieren

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"Ratenlimitiert. Warte {retry_after} Sekunden...")
time.sleep(retry_after)
return make_request(url) # Wiederholen

return response

2. Anfragewarteschlange implementieren

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()

# Anfragen aelter als 1 Minute entfernen
while self.request_times and self.request_times[0] < now - 60:
self.request_times.popleft()

# Pruefen ob am Limit
if len(self.request_times) >= self.requests_per_minute:
sleep_time = 60 - (now - self.request_times[0])
sleep(sleep_time)

# Anfrage ausfuehren
response = requests.get(url)
self.request_times.append(time.time())
return response

3. Ratenlimiterhöhanfrage stellen

Für Hochvolumen-Integrationen:

Necta-Integrationsprobleme

Forecast-Modul erscheint nicht

Symptome:

  • Kein "Forecast"-Tab im Necta-Planungsmodul
  • Aktivierung bestätigt aber Oberfläche unverändert

Lösungen:

1. Browser-Cache leeren

1. Necta vollstaendig schliessen
2. Browser-Cache leeren:
- Chrome: Einstellungen → Datenschutz → Browserdaten loeschen
- Firefox: Einstellungen → Datenschutz → Daten loeschen
3. Browser neu starten
4. Erneut bei Necta anmelden

2. Aktivierungsstatus verifizieren

Necta-Support kontaktieren:

Betreff: Forecast Modul Aktivierungsstatus

Konto-ID: [Ihre Necta Konto-ID]
Problem: Forecast-Modul nach Aktivierung nicht sichtbar
Aktivierungsdatum: [Datum an dem Aktivierung mitgeteilt wurde]

3. Benutzerberechtigungen prüfen

Problem: Benutzerrolle hat keinen Forecast-Zugriff

Lösung:

  • Admin muss Forecast-Berechtigungen erteilen
  • Zu Necta Einstellungen → Benutzer → [Ihr Benutzer] → Berechtigungen navigieren
  • "Forecast"-Modulzugriff aktivieren

Daten synchronisieren nicht aus Necta

Symptome:

  • Prognosen aktualisieren sich nicht mit neuesten Necta-Verkaufsdaten
  • Historischer Import unvollständig

Lösungen:

1. Necta-Dateneingabe verifizieren

In Necta prüfen:

  • Zu Verkäufe → Tagesberichte navigieren
  • Verifizieren dass Verkaufsdaten für aktuelle Daten eingegeben sind
  • Sicherstellen dass alle Menüpunkte erfasst sind

2. Synchronisationsstatus prüfen

Eaternity-Support kontaktieren:

Betreff: Necta Datensynchronisations-Problem

Kitchen-ID: [Ihre Kitchen-ID]
Necta Konto-ID: [Ihre Necta Konto-ID]
Letzte erfolgreiche Synchronisation: [In Forecast-Dashboard pruefen]
Fehlende Daten: [Daten ohne Synchronisation auflisten]

3. Integration neu verbinden

Über Necta-Dashboard:

  1. Zu Integrationen → Eaternity Forecast navigieren
  2. "Trennen" klicken
  3. "Neu verbinden" klicken
  4. Berechtigungen erneut erteilen

Webhook-Probleme

Webhooks werden nicht zugestellt

Symptome:

  • Keine Webhook-Benachrichtigungen erhalten
  • Webhook-Endpunkt wird nie aufgerufen

Lösungen:

1. Webhook-Konfiguration verifizieren

GET /v1/forecast/webhooks

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

Wenn status: "failed": Fehlerprotokolle prüfen

2. Endpunkt-Erreichbarkeit prüfen

Von externem Dienst testen:

# webhook.site oder aehnlich zum Testen verwenden
curl -X POST "https://your-system.com/webhooks/forecast" \
-H "Content-Type: application/json" \
-d '{"test": "webhook"}'

Häufige Probleme:

  • Firewall blockiert Forecast-IPs
  • HTTPS-Zertifikat ungültig
  • Endpunkt gibt nicht-2xx Statuscode zurück

Lösung: Forecast-IPs whitelisten (Support für Liste kontaktieren)

3. Signaturvalidierung verifizieren

Problem: Webhooks ablehnen wegen fehlgeschlagener Signaturprüfung

Signaturvalidierung debuggen:

import hmac
import hashlib

def verify_webhook(payload, signature, secret):
# Erwartete Signatur berechnen
expected = hmac.new(
secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()

# Debug-Ausgabe
print(f"Empfangene Signatur: {signature}")
print(f"Erwartete Signatur: {expected}")
print(f"Uebereinstimmung: {hmac.compare_digest(signature, expected)}")

return hmac.compare_digest(signature, expected)

Webhook-Zustellungsverzögerungen

Symptome:

  • Webhooks kommen spät an (>5 Minuten nach Ereignis)
  • Inkonsistente Zustellzeiten

Ursachen:

  • Ihr Endpunkt reagiert langsam
  • Netzwerkkongestion
  • Wiederholungsverzögerungen nach Fehlern

Lösungen:

1. Endpunkt-Antwortzeit optimieren

// Falsch: Langsame Verarbeitung blockiert Antwort
app.post('/webhooks/forecast', async (req, res) => {
await processWebhook(req.body); // Langsame Operation
res.status(200).send('OK');
});

// Richtig: Sofort bestaetigen, asynchron verarbeiten
app.post('/webhooks/forecast', async (req, res) => {
res.status(200).send('OK'); // Sofort antworten

// Asynchron verarbeiten
processWebhookAsync(req.body).catch(err => {
console.error('Webhook processing error:', err);
});
});

2. Webhook-Zustellung überwachen

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

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

Leistungsprobleme

Langsame API-Antworten

Symptome:

  • Anfragen dauern >5 Sekunden
  • Inkonsistente Antwortzeiten

Diagnoseschritte:

1. Langsame Endpunkte identifizieren

# Zeitmessung zu Anfragen hinzufuegen
time curl -X GET "https://api.eaternity.org/v1/forecast/predictions?date=2024-01-20" \
-H "Authorization: Bearer your_api_key"

2. Anfrageparameter optimieren

Langsam (alle Artikel anfordern):

GET /v1/forecast/predictions?date=2024-01-20&end_date=2024-01-27
# Gibt 65 Artikel × 7 Tage = 455 Prognosen zurueck

Schnell (nur bestimmte Artikel):

GET /v1/forecast/predictions?date=2024-01-20&items=pasta_carbonara,grilled_salmon
# Gibt 2 Artikel × 1 Tag = 2 Prognosen zurueck

3. Caching verwenden

import time
from functools import lru_cache

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

# Cache laeuft nach 1 Stunde ab
def get_predictions_with_expiry(date):
cache_key = f"{date}_{int(time.time() // 3600)}"
return get_predictions_cached(cache_key)

Datenqualitätsprobleme

Niedriger Datenqualitätswert

Symptome:

  • Datenqualitätswert unter 80%
  • Warnungen im Dashboard
  • Prognosen mit niedriger Konfidenz

Verbesserungsschritte:

1. Datenqualitätsbericht ausführen

GET /v1/forecast/analytics/data-quality

# Detaillierter Bericht
{
"overall_score": 72,
"components": {
"completeness": 85, # Einige Daten fehlen
"consistency": 65, # Benennungsprobleme
"accuracy": 80, # Einige Ausreisser
"timeliness": 70 # Verspaetete Einreichungen
},
"issues": [...]
}

2. Spezifische Probleme beheben

Fehlende Daten:

# Fehlende Daten einreichen
POST /v1/forecast/sales
{
"date": "2024-01-15",
"items": [...]
}

Inkonsistente Benennung:

# Artikelnamen standardisieren
POST /v1/forecast/items/standardize
{
"standardizations": [
{
"variants": ["pasta carbonara", "Pasta Carbonara", "PASTA_CARBONARA"],
"standard": "pasta_carbonara"
}
]
}

Ausreisser:

# Ausreisser markieren und erklaeren
POST /v1/forecast/sales/2024-01-15/annotate
{
"item_id": "grilled_salmon",
"note": "Holiday event, 2x normal volume expected",
"type": "special_event"
}

Hilfe erhalten

Support-Kanäle

ProblemtypKontaktAntwortzeit
Kritisch (Produktion ausgefallen)forecast-api@eaternity.org + Telefon4 Stunden
Hoch (Integration kaputt)forecast-api@eaternity.org24 Stunden
Mittel (Genauigkeitsfragen)forecast@eaternity.org48 Stunden
Niedrig (Allgemeine Fragen)Dokumentation oder E-Mail1 Woche

Anzugebende Informationen

In allen Support-Anfragen:

  • Kitchen-ID
  • Integrationstyp (Necta, Benutzerdefinierte API, Manuell)
  • Problembeschreibung
  • Schritte zur Reproduktion
  • Fehlermeldungen (falls vorhanden)
  • Screenshots (falls relevant)
  • Beispiel-Anfrage/Antwort (bei API-Problemen)

Selbsthilfe-Ressourcen

Siehe auch