Szukasz wersji kodu, do ktorej odnosimy sie w kursie? Zajrzyj na branch kurs.
GroupFlights to projekt systemu realizujacego obsluge grupowych biletow lotniczych. To repozytorium przedstawia wynik calego proces wytwarzania oprogramowania w oparciu o Domain-Driven Design uwzgledniajac:
- discovery stanu AS-IS
- discovery stanu TO-BE
- destylacje subdomen
- projektowanie bounded contextow
- projektowanie integracji bounded contextow
- taktyke, tj, implementacje w oparciu o decyzje podjete na poziomie strategicznym
Suplementem do tego repozytorium jest publiczny board na Miro:
Z samym procesem "od A do Z" mozesz zapoznac sie w ramach naszego kursu Domain-Driven Design "Pragmatycznie: https://domain-driven-design.net/
Uruchamiamy wymagana infrastrukture:
docker-compose up -d
Nastepnie uruchamiamy bramke platnosci:
dotnet run --project src/_ExternalSystems/FakePaymentGateway/FakePaymentGateway.csproj
I w koncu nasza glowna aplikacje:
dotnet run --project src/Api/GroupFlights.Api/GroupFlights.Api.csproj
Na starcie aplikacji zostana uruchomione migracje, ktore zaloza wszystkie wymagane struktury w bazie danych.
Jesli zajdzie potrzeba, mozesz usunac wszystkie informacje z bazy danych bez potrzeby jej przegenerowywania uzywajac skryptu: truncate-everything.sql
By lepiej zrozumiec droge, jaka nalezy przejsc w ramach czesci strategicznej Domain-Driven Design warto zapoznac sie z n/w mapa procesu wytworczego:
Inspiracja: https://github.com/ddd-crew/ddd-starter-modelling-process
- Na architekture wdrozeniowa wybrano modularny monolit
- Jako baze danych wybrano Postgres
- Separacja modelu danych poszczegolnych modeli opiera sie o oddzielne schematy w ramach jednej bazy danych
- Zaleznosci pomiedzy modulami realizowane sa przy uzyciu tzw. shared contracts; wiecej o tym w ADR:
- W zaleznosci od poziomu skomplikowania oraz klasy rozwiazywanych problemow, architektura aplikacyjna to:
- CRUD,
- Clean Architecture
- CRUD+rich domain model
- Nie implementujemy uwierzytelnienia ani autoryzacji; naiwna "imitacja" tych funkcjonalnosci opiera sie o naglowki
X-UserId
iX-CashierId
, ktore zderzane sa z deklaracja w definicji endpointu: NaiveAccessControl - System nie korzysta z zadnego zewnetrznego brokera wiadomosci. Elementy asynchronicznosci realizowane sa poprzez in-memory message dispatchera (ktory celowo z opoznieniem i poza transakcja dispatchuje zebrane zdarzenia): EventDispatcher
- Projekt zawiera tylko przykladowe testy jednostkowe, tak by zaprezentowac roznice pomiedzy testowaniem modelu z publicznymi getterami w OfferDraftTests oraz modelu w pelni zenkapsulowanego, bez dostepu do pol i wlasciwosci ReservationChangeRequestTests
- Na potrzeby dydaktyczne projekt implementuje trzy podejscia do persystencji:
- serializacje agregatu do JSONa (OfferRepository),
- klasyczny model relacyjny (DeadlineConfiguration)
- model relacyjny oparty o w pelni zenkapsulowany model dziedziny (ReservationChangeRequestConfig)
- System nie implementuje bramki e-mail ani notyfikacji, a jedynie przyklad wysylki e-mail poprzez zapis komunikatu do konsoli
- System nie implementuje integracji z zadnym systemem platnosci; zamiast tego opracowano sztuczna bramke imitujaca takie zachowanie wraz z "auto-platnosci" po 5s
Dla uproszczenia przechodzenia przez poszczegolne kroki procesu biznesowego udostepnilismy pliki .http
.
Do ich uruchomienie niezbedne jest IDE takie jak: VSCode lub JetBrains Rider.
Scenariusze nalezy wykonac w nastepujacej kolejnosci:
- Dodanie zgloszenia przez potencjalnego klienta: add-inquiry.http
- Akceptacje zgloszenia przez kasjera: accept-inquiry.http
- Dodanie wariantu lotu przez kasjera: add-variant.http
- Potwierdzenie wariantu lotu wraz z jego kosztem przez kasjera: confirm-variant.http
- Prezentacje oferty klientowi przez kasjera: reveal-offer-draft.http
- Akceptacje oferty przez klienta: accept-offer.http
- Przegladanie rezerwacji: browse-reservations.http
- Pobranie wygenerowanej umowy przez klienta(1): download-contract.http
- Podpisanie wygenerowanej umowy przez klienta(1): upload-contract.http
- Podanie naziwsk pasazerow przez klienta(2): set-passengers-for-flight.http
- Dodanie platnika przez klienta: add-payer.http
- Ustalenie platnosci po zatwierdzeniu rezerwacji przez kasjera: setup-reservation-payment.http
- Deklaracje zmiany rezerwacji przez klienta(2): request-travel-change.http
- Ustawienie "robialnosci" zmiany przez kasjera: set-change-feasibility.httpp
(1) Identyfikator umowy znajduje sie na rezerwacji, ktora wyszukasz uzywajac browse-reservations.http
(2) Identyfikator rezerwacji znajduje sie na rezerwacji, ktora wyszukasz uzywajac browse-reservations.http