From efc44bd9fa1dd6f85345f41cd560b35a9c789fd6 Mon Sep 17 00:00:00 2001 From: chodak166 Date: Sat, 9 Aug 2025 15:27:07 +0200 Subject: [PATCH] WIP: cpp17 --- cpp17/doc/add-item-sequence.md | 33 +++++++++++++++++ cpp17/doc/request-sequence.md | 25 +++++++++++++ .../lib/src/application/commands/AddItem.cpp | 20 ++++++++--- cpp17/lib/src/application/commands/AddItem.h | 9 ++++- cpp17/lib/src/application/interfaces/IClock.h | 14 ++++++++ .../application/interfaces/IOrderService.h | 14 ++++++++ .../src/domain/polices/ItemExpirationPolicy.h | 18 ++++++++++ .../adapters/HttpOrderService.cpp | 36 +++++++++++++++++++ .../adapters/HttpOrderService.h | 20 +++++++++++ .../src/infrastructure/adapters/SystemClock.h | 17 +++++++++ 10 files changed, 201 insertions(+), 5 deletions(-) create mode 100644 cpp17/doc/add-item-sequence.md create mode 100644 cpp17/doc/request-sequence.md create mode 100644 cpp17/lib/src/application/interfaces/IClock.h create mode 100644 cpp17/lib/src/application/interfaces/IOrderService.h create mode 100644 cpp17/lib/src/domain/polices/ItemExpirationPolicy.h create mode 100644 cpp17/lib/src/infrastructure/adapters/HttpOrderService.cpp create mode 100644 cpp17/lib/src/infrastructure/adapters/HttpOrderService.h create mode 100644 cpp17/lib/src/infrastructure/adapters/SystemClock.h diff --git a/cpp17/doc/add-item-sequence.md b/cpp17/doc/add-item-sequence.md new file mode 100644 index 0000000..1fb5e71 --- /dev/null +++ b/cpp17/doc/add-item-sequence.md @@ -0,0 +1,33 @@ +# Add item sequence + +```mermaid +sequenceDiagram + participant Controller as StoreController + participant UseCase as AddItem Use Case + participant Clock as IClock + participant Policy as ExpirationPolicy + participant OrderService as OrderingService + participant HttpClient as HttpClient + participant Repo as IItemRepository + + Controller->>UseCase: execute(item) + + UseCase->>Clock: getCurrentTime() + Clock-->>UseCase: DateTime + + UseCase->>Policy: IsExpired(item, currentTime) + Policy-->>UseCase: boolean + + alt Item is expired + UseCase->>OrderService: orderItem(item) + OrderService->>HttpClient: POST to order URL + HttpClient-->>OrderService: Response + OrderService-->>UseCase: OrderResult + end + + UseCase->>Repo: save(item) + Repo->>Repo: Persist to storage + Repo-->>UseCase: Saved Item ID + + UseCase-->>Controller: Result (success/error) +``` diff --git a/cpp17/doc/request-sequence.md b/cpp17/doc/request-sequence.md new file mode 100644 index 0000000..a38295f --- /dev/null +++ b/cpp17/doc/request-sequence.md @@ -0,0 +1,25 @@ +# General request sequence with authentication + +```mermaid +sequenceDiagram + participant Client as HTTP Client + participant Router as Request Router + participant Auth as JwtMiddleware + participant Controller as Controller + participant UseCase as Use Case + + Client->>Router: POST /api/items (with JWT) + Router->>Auth: Forward request + + alt Authentication successful + Auth->>Auth: Validate JWT + Auth->>Controller: Forward authenticated request + Controller->>Controller: Parse request body to DTO + Controller->>UseCase: execute() + UseCase-->>Controller: Result (success/error) + Controller->>Controller: Convert result to HTTP response + Controller-->>Client: HTTP Response (2xx) + else Authentication fails + Auth-->>Client: 401 Unauthorized + end +``` diff --git a/cpp17/lib/src/application/commands/AddItem.cpp b/cpp17/lib/src/application/commands/AddItem.cpp index 94a0162..dfbac25 100644 --- a/cpp17/lib/src/application/commands/AddItem.cpp +++ b/cpp17/lib/src/application/commands/AddItem.cpp @@ -1,15 +1,27 @@ #include "AddItem.h" -#include "domain/polices/ItemExpirationPolicy.h" +#include namespace nxl::autostore::application { -AddItem::AddItem(IItemRepository& itemRepository) - : itemRepository(itemRepository) +AddItem::AddItem(IItemRepository& itemRepository, IClock& clock, + IOrderService& orderService) + : itemRepository(itemRepository), clock(clock), orderService(orderService) {} void AddItem::execute(domain::Item&& item, const IntPresenter& presenter) { - // TODO + try { + const auto currentTime = clock.getCurrentTime(); + + if (expirationPolicy.isExpired(item, currentTime)) { + orderService.orderItem(item); + } + + itemRepository.save(item); + presenter(1); // Success + } catch (const std::exception& e) { + presenter(0); // Failure + } } } // namespace nxl::autostore::application \ No newline at end of file diff --git a/cpp17/lib/src/application/commands/AddItem.h b/cpp17/lib/src/application/commands/AddItem.h index 8296677..6ccad2b 100644 --- a/cpp17/lib/src/application/commands/AddItem.h +++ b/cpp17/lib/src/application/commands/AddItem.h @@ -1,7 +1,10 @@ #pragma once #include "domain/entities/Item.h" +#include "domain/polices/ItemExpirationPolicy.h" #include "application/interfaces/IItemRepository.h" +#include "application/interfaces/IClock.h" +#include "application/interfaces/IOrderService.h" #include "application/presenters/GenericPresenters.h" namespace nxl { @@ -13,11 +16,15 @@ class AddItem public: virtual ~AddItem() = default; - AddItem(IItemRepository& itemRepository); + AddItem(IItemRepository& itemRepository, IClock& clock, + IOrderService& orderService); void execute(domain::Item&& item, const IntPresenter& presenter); private: IItemRepository& itemRepository; + IClock& clock; + IOrderService& orderService; + domain::ItemExpirationPolicy expirationPolicy; }; } // namespace application diff --git a/cpp17/lib/src/application/interfaces/IClock.h b/cpp17/lib/src/application/interfaces/IClock.h new file mode 100644 index 0000000..21b51c1 --- /dev/null +++ b/cpp17/lib/src/application/interfaces/IClock.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +namespace nxl::autostore::application { + +class IClock +{ +public: + virtual ~IClock() = default; + virtual std::chrono::system_clock::time_point getCurrentTime() const = 0; +}; + +} // namespace nxl::autostore::application \ No newline at end of file diff --git a/cpp17/lib/src/application/interfaces/IOrderService.h b/cpp17/lib/src/application/interfaces/IOrderService.h new file mode 100644 index 0000000..2cc907a --- /dev/null +++ b/cpp17/lib/src/application/interfaces/IOrderService.h @@ -0,0 +1,14 @@ +#pragma once + +#include "domain/entities/Item.h" + +namespace nxl::autostore::application { + +class IOrderService +{ +public: + virtual ~IOrderService() = default; + virtual void orderItem(const domain::Item& item) = 0; +}; + +} // namespace nxl::autostore::application \ No newline at end of file diff --git a/cpp17/lib/src/domain/polices/ItemExpirationPolicy.h b/cpp17/lib/src/domain/polices/ItemExpirationPolicy.h new file mode 100644 index 0000000..5a39570 --- /dev/null +++ b/cpp17/lib/src/domain/polices/ItemExpirationPolicy.h @@ -0,0 +1,18 @@ +#pragma once + +#include "domain/entities/Item.h" +#include + +namespace nxl::autostore::domain { + +class ItemExpirationPolicy +{ +public: + bool isExpired(const Item& item, + const std::chrono::system_clock::time_point& currentTime) const + { + return item.expirationDate <= currentTime; + } +}; + +} // namespace nxl::autostore::domain \ No newline at end of file diff --git a/cpp17/lib/src/infrastructure/adapters/HttpOrderService.cpp b/cpp17/lib/src/infrastructure/adapters/HttpOrderService.cpp new file mode 100644 index 0000000..6f27dd9 --- /dev/null +++ b/cpp17/lib/src/infrastructure/adapters/HttpOrderService.cpp @@ -0,0 +1,36 @@ +#include "HttpOrderService.h" +#include +#include + +namespace nxl::autostore::infrastructure { + +HttpOrderService::HttpOrderService(const std::string& baseUrl) + : baseUrl(baseUrl) +{} + +void HttpOrderService::orderItem(const domain::Item& item) +{ + if (item.orderUrl.empty()) { + throw std::runtime_error("Order URL is empty for item: " + item.name); + } + + std::string payload = + R"({"itemName": ")" + item.name + R"(", "itemId": ")" + item.id + "\"}"; + sendPostRequest(item.orderUrl, payload); +} + +void HttpOrderService::sendPostRequest(const std::string& url, + const std::string& payload) +{ + // In a real implementation, this would use an HTTP client library + // For now, we'll simulate the HTTP call + std::cout << "POST request to: " << url << std::endl; + std::cout << "Payload: " << payload << std::endl; + + // Simulate HTTP error handling + if (url.find("error") != std::string::npos) { + throw std::runtime_error("Failed to send order request to: " + url); + } +} + +} // namespace nxl::autostore::infrastructure \ No newline at end of file diff --git a/cpp17/lib/src/infrastructure/adapters/HttpOrderService.h b/cpp17/lib/src/infrastructure/adapters/HttpOrderService.h new file mode 100644 index 0000000..ab7b194 --- /dev/null +++ b/cpp17/lib/src/infrastructure/adapters/HttpOrderService.h @@ -0,0 +1,20 @@ +#pragma once + +#include "application/interfaces/IOrderService.h" +#include "domain/entities/Item.h" +#include + +namespace nxl::autostore::infrastructure { + +class HttpOrderService : public application::IOrderService +{ +public: + explicit HttpOrderService(const std::string& baseUrl = ""); + void orderItem(const domain::Item& item) override; + +private: + std::string baseUrl; + void sendPostRequest(const std::string& url, const std::string& payload); +}; + +} // namespace nxl::autostore::infrastructure \ No newline at end of file diff --git a/cpp17/lib/src/infrastructure/adapters/SystemClock.h b/cpp17/lib/src/infrastructure/adapters/SystemClock.h new file mode 100644 index 0000000..22d8cdb --- /dev/null +++ b/cpp17/lib/src/infrastructure/adapters/SystemClock.h @@ -0,0 +1,17 @@ +#pragma once + +#include "application/interfaces/IClock.h" +#include + +namespace nxl::autostore::infrastructure { + +class SystemClock : public application::IClock +{ +public: + std::chrono::system_clock::time_point getCurrentTime() const override + { + return std::chrono::system_clock::now(); + } +}; + +} // namespace nxl::autostore::infrastructure \ No newline at end of file