Proces zamówienia | Event Storming

Poniżej przygotowałem rozpisany krok po kroku Event Storming

Wyobraź sobie, że naklejamy karteczki na wielkiej ścianie (zachowałem tradycyjne kolory karteczek dla ułatwienia wizualizacji).


Krok 1: Zdarzenia domenowe (🟧 Pomarańczowe karteczki)

Zdarzenia to fakty, które wystąpiły w systemie (zawsze w czasie przeszłym dokonanym). Układamy je chronologicznie od lewej do prawej.

  1. Zamówienie klienta wpłynęło
  2. Reguły terminu wysyłki zostały zdefiniowane (np. “od wpłaty” / “od rysunków”)
  3. Wstępne potwierdzenie zamówienia zostało wysłane (z proformą)
  4. Wpłata została zaksięgowana
  5. Rysunki techniczne zostały zaakceptowane
  6. Warunki brzegowe zamówienia zostały spełnione (np. wpłata + rysunki)
  7. Powiadomienie o gotowości do akceptacji zostało wyświetlone (dla Handlowca)
  8. Bramka walidacyjna (Okno Modalne) została otwarta
  9. Komentarz operacyjny dla CUW został dodany
  10. Zamówienie zostało zaakceptowane do realizacji
  11. Ostateczna data wysyłki została wyliczona
  12. Końcowe potwierdzenie zamówienia zostało wysłane (do klienta)
  13. Zlecenie realizacji trafiło do panelu CUW
  14. Braki magazynowe zostały wykryte
  15. Ostrzeżenie o minimum logistycznym (MOQ) zostało wyświetlone
  16. Zamówienie do dostawcy zewnętrznego zostało złożone

Krok 2: Komendy (🟦 Niebieskie karteczki)

Komendy to intencje/akcje, które wywołują powyższe zdarzenia (tryb rozkazujący).

  • Zarejestruj zamówienie (wywołuje zdarzenia 1, 2 i 3)
  • Zaksięguj wpłatę (wywołuje zdarzenie 4)
  • Zatwierdź rysunki (wywołuje zdarzenie 5)
  • Sprawdź warunki uruchomienia (wywołuje zdarzenie 6 i 7)
  • Otwórz podsumowanie / Okno Modalne (wywołuje zdarzenie 8)
  • Zatwierdź zlecenie dla CUW (wywołuje zdarzenia 9, 10, 11 i 12)
  • Weryfikuj stany magazynowe (wywołuje zdarzenia 13 i 14)
  • Oblicz zapotrzebowanie u dostawcy (wywołuje zdarzenie 15)
  • Zamów brakujący towar (wywołuje zdarzenie 16)

Krok 3: Aktorzy (🟨 Małe żółte karteczki)

Kto lub co wykonuje komendy? Przypinamy ich do niebieskich karteczek.

  • Klient (Inicjuje proces wysyłając zamówienie, dokonując wpłaty, akceptując rysunki)
  • Handlowiec (Rejestruje zamówienie, otwiera Okno Modalne, zatwierdza zlecenie dla CUW)
  • Księgowość / System Enova (Księguje wpłatę)
  • Pracownik CUW (Weryfikuje stany, zamawia braki z uwzględnieniem MOQ)
  • System GoNet / Automatyzacja (Wysyła powiadomienia, wylicza datę wysyłki na podstawie dni roboczych, weryfikuje warunki brzegowe)

Krok 4: Agregaty (🟨 Duże bladożółte karteczki)

Agregat to “serce” logiki biznesowej. To obiekt (rzeczownik), który pilnuje reguł i zmienia swój stan pod wpływem komend.

  1. Zamówienie Sprzedaży (Sales Order)
    • Pilnuje: Cen, ilości, danych klienta, warunków dostawy (Incoterms).
    • Stany: Nowe ➔ Oczekujące na warunki ➔ Zaakceptowane.
  2. Kalkulator Terminu (Delivery Schedule / Trigger Engine)
    • Pilnuje: Reguł wyliczania czasu (dni/tygodnie), sprawdzania czy wpłata zeszła i czy rysunki są gotowe. Wylicza dokładną datę kalendarzową.
  3. Zlecenie Realizacji (Fulfillment Order)
    • Pilnuje: Danych dla CUW. To tu zapisuje się ten “Komentarz” z okna modalnego i tu znikają zbędne dla magazynu informacje finansowe.
  4. Polityka Dostawcy (Supplier Policy / MOQ Rule)
    • Pilnuje: Minimów logistycznych (np. Techline = 40 sztuk), czasów produkcji (3-5 tyg.) oraz kalkulacji dopłat (np. dopłata 30% za małe zamówienie).

Krok 5: Bounded Context (⭕ Czerwone okręgi / Strefy na tablicy)

Dzielimy nasz proces na niezależne moduły (konteksty). Każdy kontekst to może być osobny kawałek kodu / inna zakładka w systemie.

🟢 Kontekst Ofertowania i Sprzedaży (Sales Context)

  • Co tu się dzieje: Handlowiec buduje ofertę, dogaduje się z klientem, przyjmuje zamówienie, ustala z czego wyniknie termin dostawy.
  • Główny bohater: Oferta/Zamówienie.

🔵 Kontekst Finansowo-Zdarzeniowy (Billing & Trigger Context) -> Punkt styku Enova/GoNet

  • Co tu się dzieje: System nasłuchuje zdarzeń ze świata (przyszła wpłata z Enovy, inżynier odklikał rysunki). Jeśli warunki są spełnione, budzi handlowca powiadomieniem.

🟣 Kontekst Walidacji – “Bramka Handlowca” (Validation Context)

  • Co tu się dzieje: Tu żyje Okno Modalne. Zebranie ostatecznych danych, dodanie komentarza, odcięcie klienta i przygotowanie czystej paczki danych operacyjnych, wyliczenie ostatecznej daty na dokumencie PDF.

🟠 Kontekst Realizacji i Zaopatrzenia (CUW Fulfillment Context)

  • Co tu się dzieje: Pracownik CUW widzi zlecenia z datą. Kontekst ten ignoruje już negocjacje handlowe. Skupia się na magazynie (Enova), a w przypadku braków odpala logikę zaopatrzenia (agregat Polityki Dostawcy – podpowiedzi o MOQ i czasie z Chin).

Jak to wykorzystać?

Jeśli wyślecie taki “Event Storming” do programistów (lub pokażecie go na spotkaniu), oni będą wniebowzięci. Zamiast domyślać się, co autor miał na myśli, mają gotową architekturę mikrousług/modułów. Dokładnie wiedzą:

  • Kiedy wysłać maila (Zdarzenia 3 i 12).
  • Kiedy wyświetlić popup (Komenda: Otwórz bramkę walidacyjną).
  • Skąd brać dane o MOQ (Agregat: Polityka Dostawcy w Kontekście Zaopatrzenia).
flowchart LR

%% =======================
%% SALES CONTEXT
%% =======================
subgraph SALES["Kontekst Ofertowania i Sprzedaży"]
A1["Zamówienie klienta wpłynęło"]
A2["Rejestracja zamówienia (Handlowiec)"]
A3["Definicja warunków terminu (dni + trigger)"]
A4["Wstępne potwierdzenie (proforma)"]

A1 --> A2 --> A3 --> A4
end

%% =======================
%% BILLING & TRIGGERS
%% =======================
subgraph BILLING["Kontekst Finansowo-Zdarzeniowy (Enova + GoNet)"]
B1["Wpłata zaksięgowana"]
B2["Rysunki zaakceptowane"]
B3["Warunki spełnione"]
B4["Powiadomienie dla handlowca"]

B1 --> B3
B2 --> B3
B3 --> B4
end

A4 --> B1
A4 --> B2

%% =======================
%% VALIDATION (MODAL)
%% =======================
subgraph VALIDATION["Bramka walidacyjna (Okno modalne)"]
C1["Klik 'Zatwierdź zamówienie'"]
C2["Okno modalne - podsumowanie"]
C3["Komentarz operacyjny"]
C4["Akceptacja zamówienia"]

C1 --> C2 --> C3 --> C4
end

B4 --> C1

%% =======================
%% DELIVERY CALCULATION
%% =======================
subgraph DELIVERY["Kalkulator terminu"]
D1["Wyliczenie ostatecznej daty"]
end

C4 --> D1

%% =======================
%% CUSTOMER OUTPUT
%% =======================
subgraph CUSTOMER["Komunikacja z klientem"]
E1["Końcowe potwierdzenie (PDF)"]
end

D1 --> E1

%% =======================
%% FULFILLMENT (CUW)
%% =======================
subgraph CUW["Realizacja i zaopatrzenie (CUW)"]
F1["Zlecenie trafia do CUW"]
F2["Weryfikacja magazynu"]
F3["Braki wykryte"]
F4["MOQ / Lead time - podpowiedź"]
F5["Zamówienie do dostawcy"]

F1 --> F2
F2 -->|Brak towaru| F3 --> F4 --> F5
end

C4 --> F1

%% =======================
%% OPTIONAL PATHS
%% =======================
F2 -->|Towar dostępny| F6["Rezerwacja / realizacja"]