Zum Inhalt

Beispielarbeiten · KI & Automation

Fehlerfeste Automation: Bestellung, Rechnung, Lager, Mail ohne Doppelbuchung

Ein Ablauf von der Bestellung bis zur Mail wurde absichtlich gestört: Zeitüberschreitungen, Serverfehler, doppelte Zustellungen und harte Abstürze. Die gehärtete Fassung bucht nichts doppelt und verliert nichts still.

Musterarbeit (Demo), kein Kundenauftrag. Gebaut als Probeaufgabe mit erfundenen Beispieldaten; die Prüfzahlen unten stammen aus dem automatischen Prüflauf und sind nicht geschönt.

Was gebaut wurde

  • Jeder Schritt mit eigenem Schlüssel, damit eine Wiederholung nichts doppelt bucht
  • Wiederholungen mit wachsender Wartezeit; was dauerhaft scheitert, landet gemeldet in einer Dead-Letter-Liste
  • Nach einem Absturz geht es an der richtigen Stelle weiter

fehlerfeste-automation-demo.zip herunterladen

Genau einmal ausgeführt werden kann ein Schritt nur, wenn die Gegenseite einen Schlüssel annimmt oder einen Abgleich erlaubt. Eine verschickte Mail lässt sich nicht zurückholen.

Wie geprüft wurde

Automatischer Prüflauf vom 22.10.2026, aus dem Protokoll (Testdaten erfunden, Zahlen gemessen):

  • 40 Bestellungen, 46 Zustellungen (6 doppelt), 12 Stoerfolgen (Timeout nach/vor Ausfuehrung, 5xx 1-3x), 1 Dauerausfall, 2x 422, 3 harte Prozessabbrueche je Lauf. Ausgang: 10 doppelte Rechnungen, Lager um 15 Stueck falsch, 7 doppelte Mails

Grenzen

Was diese Probe nicht abdeckt, steht hier, damit niemand mehr erwartet:

  • Exactly-once gilt nur fuer Schritte, bei denen die Gegenseite einen Idempotenzschluessel annimmt oder einen Abgleich erlaubt (Suche nach Referenz/Schluessel/Message-ID); ohne beides bleibt nur …
  • Mails sind nach dem Versand nicht zurueckholbar: Versand ist deshalb der letzte, vorher markierte Schritt; ohne abfragbares Versandprotokoll kann ein Absturz genau zwischen Versand und Markierung …
  • Die Abgleich-Abfragen der Gegenseite gelten in der Probe als zuverlaessig; faellt auch die Suche aus, wird wiederholt bzw. das Ereignis in die Dead-Letter-Liste gelegt statt blind neu zu buchen
  • Echte Plattformen haben eigene Wiederhol-Semantik (n8n: Retry on Fail je Knoten, Error-Workflow; Make: Break-Handler/unvollstaendige Ausfuehrungen; Zapier: Autoreplay) - die Muster hier werden dort …
  • Dead-Letter heisst: sauber angehalten und gemeldet, nicht repariert - teilweise Ausfuehrungen (Rechnung da, Lager nicht gebucht) brauchen eine fachliche Entscheidung (Storno oder Nachbuchen)
  • Backoff ohne Zufallsstreuung (Jitter), damit es exakt pruefbar ist; bei vielen parallelen Arbeitern gehoert Jitter dazu. Ein Arbeiter, keine Nebenlaeufigkeit; Mehrfacharbeiter brauchen zusaetzlich …

Bericht

# Fehlerfeste Automation: Bestellung -> Rechnung -> Lager -> Mail

Samen 20261022; 40 Bestellungen, 46 Webhook-Zustellungen (6 doppelt), Stoerungen laut stoerplan.json, 3 harte Prozessabbrueche je Lauf.

| Kennzahl | Ausgang | Gehaertet | Gegenprobe (ohne Idempotenz) |
|---|---|---|---|
| Doppelte Rechnungen | 10 | 0 | 3 |
| Fehlende Rechnungen | 1 | 0 | 0 |
| Doppelte Lagerbuchungen | 9 | 0 | 3 |
| Fehlende Lagerbuchungen | 2 | 0 | 0 |
| Lagerabweichung (Stueck) | 15 | 0 | 5 |
| Doppelte Mails | 7 | 0 | 2 |
| Fehlende Mails | 3 | 0 | 0 |
| Still verlorene Ereignisse | 6 | 0 | 0 |
| Dead-Letter-Eintraege | 0 | 3 | 3 |
| Prozessstarts | 4 | 4 | 4 |
| Harte Abbrueche | 3 | 3 | 3 |

Gehaertet zusaetzlich: 15 Wiederholungen mit Backoff, 8 Abgleiche fanden eine schon ausgefuehrte Aktion, 6 Doppelzustellungen verworfen, 3 Alarmzeilen.

## Abweichungen vom Soll
- **ausgang**: 5
  - Rechnung: 11 Bestellungen nicht genau wie Soll (B-1001, B-1007, B-1009, B-1014, B-1019, B-1021)
  - Lagerbuchung: 10 Bestellungen nicht genau wie Soll (B-1001, B-1007, B-1009, B-1014, B-1015, B-1019)
  - Mail: 10 Bestellungen nicht genau wie Soll (B-1001, B-1007, B-1014, B-1019, B-1021, B-1022)
  - Lagerbestand {'TASSE-WEISS': 374, 'TASSE-BLAU': 283, 'TELLER-24': 228, 'SCHALE-12': 194, 'KANNE-1L': 105} statt {'TASSE-WEISS': 378, 'TASSE-BLAU': 286, 'TELLER-24': 231, 'SCHALE-12': 195, 'KANNE-1L': 109}
  - Dead-Letter {} statt {'evt-B-1010': 'rechnung', 'evt-B-1033': 'rechnung', 'evt-B-1023': 'lager'}
- **gehaertet**: 0
- **gegenprobe**: 4
  - Rechnung: 3 Bestellungen nicht genau wie Soll (B-1030, B-1036, B-1040)
  - Lagerbuchung: 3 Bestellungen nicht genau wie Soll (B-1009, B-1015, B-1019)
  - Mail: 2 Bestellungen nicht genau wie Soll (B-1022, B-1029)
  - Lagerbestand {'TASSE-WEISS': 373, 'TASSE-BLAU': 286, 'TELLER-24': 231, 'SCHALE-12': 195, 'KANNE-1L': 109} statt {'TASSE-WEISS': 378, 'TASSE-BLAU': 286, 'TELLER-24': 231, 'SCHALE-12': 195, 'KANNE-1L': 109}

## Haertung
- Idempotenzschluessel je Ereignis und Schritt (evt-B-xxxx:rechnung/lager/mail)
- Abgleich bei der Gegenseite vor jeder Wiederholung nach Timeout und nach Absturz
- Exponentielles Backoff 0.02 s * 2^n, Deckel 0.32 s, hoechstens 5 Versuche
- Dead-Letter-Tabelle + Alarmzeile fuer Dauerfehler (422, Dauerausfall)
- Fortschritt je Schritt und Eingangs-Cursor persistent in SQLite; Mail als letzter markierter Schritt

## Grenzen
- Exactly-once gilt nur fuer Schritte, bei denen die Gegenseite einen Idempotenzschluessel annimmt oder einen Abgleich erlaubt (Suche nach Referenz/Schluessel/Message-ID); ohne beides bleibt nur at-least-once (doppelt moeglich) oder at-most-once (verloren moeglich) - das wird je Schritt entschieden und benannt
- Mails sind nach dem Versand nicht zurueckholbar: Versand ist deshalb der letzte, vorher markierte Schritt; ohne abfragbares Versandprotokoll kann ein Absturz genau zwischen Versand und Markierung eine Mail doppelt oder gar nicht ausloesen - hier per Protokollabfrage geschlossen, bei reinem SMTP nicht
- Die Abgleich-Abfragen der Gegenseite gelten in der Probe als zuverlaessig; faellt auch die Suche aus, wird wiederholt bzw. das Ereignis in die Dead-Letter-Liste gelegt statt blind neu zu buchen
- Echte Plattformen haben eigene Wiederhol-Semantik (n8n: Retry on Fail je Knoten, Error-Workflow; Make: Break-Handler/unvollstaendige Ausfuehrungen; Zapier: Autoreplay) - die Muster hier werden dort mit deren Mitteln umgesetzt (Datenspeicher fuer Fortschritt, Schluessel im Header), nicht 1:1 als Python-Code
- Dead-Letter heisst: sauber angehalten und gemeldet, nicht repariert - teilweise Ausfuehrungen (Rechnung da, Lager nicht gebucht) brauchen eine fachliche Entscheidung (Storno oder Nachbuchen)
- Backoff ohne Zufallsstreuung (Jitter), damit es exakt pruefbar ist; bei vielen parallelen Arbeitern gehoert Jitter dazu. Ein Arbeiter, keine Nebenlaeufigkeit; Mehrfacharbeiter brauchen zusaetzlich Sperren

So etwas für deinen Betrieb?

Beschreib kurz, was du brauchst. Du bekommst einen Festpreis, bevor ich anfange; ohne dein Ja passiert nichts.

Zur Werkstatt