Wiki
Angebotslebenszyklus und State Machine
Deep Dive in Statusübergänge von Angeboten, Validierungsregeln und Audit-Trail in QuoteNode.
Angebotslebenszyklus und State Machine
Jedes Angebot in QuoteNode durchläuft einen streng validierten Lebenszyklus. Das System erzwingt erlaubte Statusübergänge und blockiert jede unzulässige Änderung.
Statusdefinitionen
| Status | Beschreibung | Bearbeitbar | Terminal |
|---|---|---|---|
| DRAFT | Das Angebot wird vorbereitet. Der Kunde sieht es noch nicht. | Ja | Nein |
| SENT | Das Angebot wurde per E-Mail oder öffentlichem Link an den Kunden übermittelt. | Nein | Nein |
| OPENED | Der Kunde hat den öffentlichen Link mindestens einmal geöffnet. | Nein | Nein |
| NEGOTIATION | Der Kunde hat mit Rückfrage oder Gegenvorschlag geantwortet. | Nein | Nein |
| ACCEPTED | Der Kunde hat das Angebot bestätigt. | Nein | Ja |
| REJECTED | Der Kunde hat das Angebot abgelehnt. | Nein | Ja |
| EXPIRED | Die Gültigkeit ist ohne Entscheidung abgelaufen. | Nein | Ja |
| ARCHIVED | Das Angebot wurde manuell archiviert. | Nein | Ja |
Übergangsregeln
DRAFT ──────────► SENT
│ │
│ ▼
│ OPENED
│ │
│ ├──► NEGOTIATION
│ │ │
│ ├──► ACCEPTED (terminal)
│ ├──► REJECTED (terminal)
│ └──► EXPIRED (terminal)
│
└──► ARCHIVED (terminal)
Erlaubte Übergänge
- DRAFT → SENT — wenn der Vertriebsmitarbeiter das Angebot versendet oder einen öffentlichen Link erzeugt
- SENT → OPENED — wenn der Kunde den öffentlichen Link erstmals öffnet
- OPENED → NEGOTIATION — wenn der Kunde antwortet
- OPENED → ACCEPTED — wenn der Kunde auf der öffentlichen Seite „Accept“ wählt
- OPENED → REJECTED — wenn der Kunde auf „Decline“ klickt
- SENT/OPENED/NEGOTIATION → EXPIRED — wenn
valid_untilerreicht ist - DRAFT → ARCHIVED — wenn ein unversendeter Entwurf archiviert wird
- NEGOTIATION → ACCEPTED — wenn der Kunde nach einer Verhandlung annimmt
- NEGOTIATION → REJECTED — wenn der Kunde nach einer Verhandlung ablehnt
Nicht erlaubte Übergänge
- SENT → DRAFT
- ACCEPTED → irgendein anderer Status
- REJECTED → irgendein anderer Status
- EXPIRED → irgendein anderer Status
- ARCHIVED → irgendein anderer Status
Was bei wichtigen Übergängen passiert
DRAFT → SENT
- Das System prüft, ob das Angebot mindestens eine Position enthält.
- Ein unveränderlicher Snapshot des vollständigen Angebotszustands wird erzeugt.
- Beim E-Mail-Versand wird eine Nachricht mit PDF und/oder öffentlichem Link in die Queue gestellt.
- Bei Generierung eines öffentlichen Links entsteht ein zufälliger 256-Bit-Token; in der Datenbank wird nur dessen SHA-256-Hash gespeichert.
- Der Status wechselt zu SENT.
- Ein Ereignis wird in der Kundentimeline protokolliert.
- Ein Audit-Log-Eintrag wird geschrieben.
SENT → OPENED
- Der Kunde öffnet die URL des öffentlichen Links.
- Der Token-Hash wird gegen die Datenbank abgeglichen.
- Nur beim ersten Öffnen wechselt der Status auf OPENED.
- Ein Web-Ereignis mit Zeit, IP, User Agent und Land wird gespeichert.
- Der zuständige Vertriebsmitarbeiter kann benachrichtigt werden.
OPENED → ACCEPTED
- Der Kunde klickt auf der öffentlichen Seite auf „Accept“.
- Das System prüft Rate Limiting und Bot-Detection.
- Optional werden Bestellabsichts-Daten erfasst.
- Der Status wechselt auf ACCEPTED.
- Der Vertriebsmitarbeiter erhält eine sofortige Benachrichtigung.
- Die Kundentimeline wird ergänzt.
Snapshots
Ein Snapshot ist die vollständige, unveränderliche Aufzeichnung des Angebots zum Zeitpunkt des Versands. Er enthält unter anderem:
- Kundendaten,
- alle Positionen,
- berechnete Summen, Rabatte, MwSt. und Versand,
- verwendeten FX-Kurs,
- Branding,
- Template-Einstellungen und sichtbare Spalten.
Snapshots werden nie verändert. Wenn ein Angebot nach Änderungen erneut versendet wird, entsteht eine neue Snapshot-Version mit erhöhter Versionsnummer.
PDFs werden immer aus Snapshots und nie aus Live-Daten erzeugt. So bleibt das Dokument exakt deckungsgleich mit dem, was dem Kunden gezeigt wurde.
Audit-Trail
Jeder Statusübergang erzeugt einen unveränderlichen Audit-Eintrag mit:
- Benutzer-ID und Rolle oder einem System-Akteur,
- Ursprungs-IP,
- vorherigem und neuem Status,
- serverseitigem Zeitstempel,
- optionalem Kommentar, z. B. Ablehnungsgrund.
Das Audit-Log ist append-only. Einträge können selbst von Administratoren nicht bearbeitet, gelöscht oder gekürzt werden.
Operationen nach terminalen Zuständen
Angebote in terminalen Zuständen bleiben unveränderbar, können aber als Basis für neue Angebote dienen:
- Clone — erzeugt einen neuen DRAFT mit denselben Positionen und Preisen
- Extend Validity — klont das Angebot mit neuer Gültigkeitsdauer
- Update Prices — klont und berechnet Preise aus aktuellem Katalog und FX-Kontext neu
- Use as Template — klont ohne Kundenbezug oder Preise als Ausgangspunkt
Diese Operationen erzeugen immer eine neue Angebots-ID im Status DRAFT. Das Original bleibt unverändert.