Inventory Domain
Verfügbarkeit, Reservierung und Freigabe von Warenbeständen konsistent verwalten.
1. GeschäftsauftragGrundverständnis
Die Inventory Domain entscheidet, ob Ware verfügbar ist, reserviert Mengen für bestätigte Bestellungen und gibt Reservierungen bei Abbruch oder Timeout wieder frei.
2. Domänenmodell und AggregateDDD
Das zentrale Aggregate heißt StockReservation. Es schützt Invarianten innerhalb einer Transaktion. Externe Komponenten arbeiten über Commands, Queries und Events, nicht über interne Tabellen.
| Aspekt | Festlegung | Begründung |
|---|---|---|
| Aggregate | StockReservation | Konsistenzgrenze der Fachregeln |
| Entity-ID | stabil und global eindeutig | ermöglicht Idempotenz und Korrelation |
| Value Objects | fachliche Werte statt primitive Strings | Validierung wird Teil des Modells |
3. ZustandsmodellLifecycle
Nur definierte Übergänge sind erlaubt. Jeder Übergang benötigt einen fachlichen Auslöser, Vorbedingungen, ein Ergebnis und einen nachvollziehbaren Audit-Kontext.
Event Flow verständlich gelesen
Ein Event ist mit einem eingeschriebenen Brief vergleichbar: Der Producer schreibt eine Nachricht, Kafka ordnet sie einem Topic und einer Partition zu, und Consumer lesen sie in ihrer eigenen Geschwindigkeit. Offsets markieren, bis wohin ein Consumer gekommen ist.
Alltagstaugliche Ablaufbeschreibung
Dieser Abschnitt beschreibt den Ablauf ohne unnötige Fachsprache. Er dient als Brücke zwischen dem sichtbaren Ergebnis und der technischen Umsetzung.
- Producer erstellt Event
- Schema wird geprüft
- Broker speichert Event
- Partition bestimmt Reihenfolge
- Consumer Group verteilt Arbeit
- Consumer bestätigt Offset
- Telemetrie misst Lag und Fehler.
Fachlicher Ablauf
Ein fachliches Ereignis informiert andere Bereiche darüber, dass sich etwas Relevantes geändert hat. Der sendende Bereich bleibt verantwortlich für seine Aussage; empfangende Bereiche entscheiden selbst, wie sie darauf reagieren.
- Fachliches Ziel: Der Ablauf liefert ein fachlich eindeutiges und für Benutzer beziehungsweise Betrieb nachvollziehbares Ergebnis.
- Verantwortung: Jeder beteiligte Bereich entscheidet nur innerhalb seiner eigenen fachlichen Zuständigkeit.
- Sichtbares Ergebnis: Order, Inventory, Payment und Notification können unabhängig reagieren, ohne eng gekoppelte synchrone Aufrufketten.
Technischer Ablauf
Der Producer schreibt ein Event in ein Topic. Partitionierung bestimmt Reihenfolge und Parallelität, Consumer Groups verteilen Arbeit, Offsets dokumentieren den Verarbeitungsstand. Retry, Idempotenz und Dead Letter Queue schützen vor Doppelwirkung und dauerhaft fehlerhaften Nachrichten.
- Daten und Schnittstellen: Daten werden an jeder Grenze validiert und nur über definierte APIs, Ports oder Events weitergegeben.
- Fehlerbehandlung: Fehler werden dort behandelt, wo ausreichender Kontext und Verantwortung vorhanden sind; Wiederholungen müssen sicher und nachvollziehbar bleiben.
- Technischer Nachweis: Geprüft werden Producer-Erfolg, Topic/Partition, Consumer Lag, Offset-Fortschritt, Retry-Zahl und DLQ-Einträge.
Zusammenspiel: Der fachliche Ablauf erklärt, warum etwas geschieht und welches Ergebnis zählt. Der technische Ablauf erklärt, wie dieses Ergebnis zuverlässig, sicher und beobachtbar umgesetzt wird.
4. Use CasesAnwendung
- CheckAvailability: eigener Application Use Case mit Autorisierung, Validierung und idempotentem Ergebnis.
- ReserveStock: eigener Application Use Case mit Autorisierung, Validierung und idempotentem Ergebnis.
- CommitReservation: eigener Application Use Case mit Autorisierung, Validierung und idempotentem Ergebnis.
- ReleaseReservation: eigener Application Use Case mit Autorisierung, Validierung und idempotentem Ergebnis.
Use Cases orchestrieren das Aggregate und Ports. Sie enthalten keine HTTP-, SQL- oder Kafka-Details.
5. API-VertragIntegration
GET /api/inventory/{sku}/availability
POST /api/reservations
POST /api/reservations/{id}/commit
DELETE /api/reservations/{id}6. Event ContractsMessaging
StockReserved– unveränderliches vergangenes Ereignis mit eventId, occurredAt, aggregateId, schemaVersion und correlationId.StockRejected– unveränderliches vergangenes Ereignis mit eventId, occurredAt, aggregateId, schemaVersion und correlationId.StockCommitted– unveränderliches vergangenes Ereignis mit eventId, occurredAt, aggregateId, schemaVersion und correlationId.StockReleased– unveränderliches vergangenes Ereignis mit eventId, occurredAt, aggregateId, schemaVersion und correlationId.
Events werden versioniert. Consumer müssen doppelte Zustellung tolerieren und unbekannte optionale Felder ignorieren.
7. Datenverantwortung und KonsistenzDaten
Eigene Daten: Physischer Bestand, verfügbarer Bestand, Reservierungen, Ablaufzeit und Lagerort.
Andere Domänen erhalten benötigte Informationen über API oder Event. Gemeinsame Tabellen und domänenübergreifende SQL-Joins werden vermieden. Für verteilte Abläufe gilt meist Eventual Consistency; der aktuelle Prozessstatus wird explizit sichtbar gemacht.
8. Sicherheit und DatenschutzSecurity
Schreibzugriffe kommen nur von vertrauenswürdigen Service-Identitäten. Manuelle Bestandskorrekturen benötigen Vier-Augen-Prinzip und Audit-Log.
- Least Privilege für Benutzer und Services.
- Auditierbare Statusänderungen.
- Minimierung personenbezogener Daten.
- Secrets nie in Code, Events oder Logs.
9. SLOs und BetriebszieleSRE
99,95 % Verfügbarkeit der Reservierungsfunktion; p95 unter 250 ms; keine negativen Bestände.
| Signal | Messung | Reaktion |
|---|---|---|
| Erfolg | fachlich erfolgreiche Use Cases | Error Budget und Release-Risiko bewerten |
| Latenz | p50/p95/p99 pro Use Case | Abhängigkeit und Warteschlange lokalisieren |
| Korrektheit | Invarianten und Reconciliation | Geschäftsschaden begrenzen |
10. Typische FehlerbilderTroubleshooting
- gleichzeitige Reservierungen überbuchen Bestand
- abgelaufene Reservierung bleibt blockierend
- doppelte Event-Verarbeitung
- Bestandskorrektur ohne Audit-Spur
11. DiagnosewegBetrieb
- Betroffene Bestellung oder fachliche ID bestimmen.
- Correlation-ID über API, Event und Datenzustand verfolgen.
- Erwarteten und tatsächlichen Status vergleichen.
- Letzte erfolgreiche Transition und fehlgeschlagenen Schritt identifizieren.
- Idempotente, reversible Wiederherstellung wählen.
- Nach der Behebung Reconciliation und Benutzerwirkung prüfen.
12. Lernkontrolle und eigene NotizenSelbsttest
Erkläre die Verantwortung der Inventory Domain ohne technische Produktnamen. Benenne zwei Invarianten, einen erlaubten Zustandsübergang und ein SLO.
Bestand: vollständiger Zusammenhang
Inventory besitzt die Verantwortung für verfügbare, reservierte und freigegebene Mengen. Andere Domänen dürfen den Bestand nicht direkt in dessen Tabellen verändern. Reservierungen sind zeitlich begrenzt und müssen idempotent auf Ereignisse reagieren.
Wie funktioniert der Ablauf?Funktionsweise
Die Bestand-Domäne verarbeitet Befehle ausschließlich über ihre Anwendungsgrenze. Das Aggregat prüft Invarianten und erzeugt Events. Persistenz und Messaging sind Adapter. Andere Domänen kommunizieren über dokumentierte APIs oder Events und greifen nicht direkt auf interne Tabellen zu.
Konkretes CommerceOne-BeispielPraxis
Auf `OrderCreated` versucht Inventory jede Position zu reservieren. Gelingt eine Position nicht, wird die gesamte fachliche Reservierung abgelehnt und ein erklärendes Ereignis publiziert. Wiederholte Events ändern die Menge nicht erneut.
event: OrderCreated
handler: reserve-items
idempotency: event-id
result: InventoryReserved | InventoryRejectedSo liest du das Beispiel: Identitäten und Zustände werden ausdrücklich benannt. Wiederholung, Teilfehler und Beobachtbarkeit sind Teil des Designs. Das Beispiel ist zum Lesen und Anpassen gedacht; es wird nichts automatisch ausgeführt.
Entscheidungs- und DiagnosefragenReflexion
- Welches fachliche Ergebnis soll für den Benutzer entstehen?
- Welche Komponente besitzt die Verantwortung und welche Daten gehören ihr?
- Was passiert bei Timeout, Wiederholung oder Teilausfall?
- Welches Signal beweist, dass der Ablauf korrekt funktioniert?
- Welche einfachere Alternative wäre ausreichend?