From 5833ea59c576e62488ab0a48e816882506b13201 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 4 Jun 2026 16:14:11 +0000 Subject: [PATCH] Extract catalog stock validation service Co-authored-by: mattfromcursor --- src/Catalog.API/Extensions/Extensions.cs | 1 + .../CatalogStockValidationService.cs | 25 +++++++++++++++++++ ...aitingValidationIntegrationEventHandler.cs | 20 ++------------- .../ICatalogStockValidationService.cs | 6 +++++ 4 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 src/Catalog.API/IntegrationEvents/CatalogStockValidationService.cs create mode 100644 src/Catalog.API/IntegrationEvents/ICatalogStockValidationService.cs diff --git a/src/Catalog.API/Extensions/Extensions.cs b/src/Catalog.API/Extensions/Extensions.cs index bc04536..81c2227 100644 --- a/src/Catalog.API/Extensions/Extensions.cs +++ b/src/Catalog.API/Extensions/Extensions.cs @@ -27,6 +27,7 @@ public static void AddApplicationServices(this IHostApplicationBuilder builder) builder.Services.AddTransient>(); builder.Services.AddTransient(); + builder.Services.AddTransient(); builder.AddRabbitMqEventBus("eventbus") .AddSubscription() diff --git a/src/Catalog.API/IntegrationEvents/CatalogStockValidationService.cs b/src/Catalog.API/IntegrationEvents/CatalogStockValidationService.cs new file mode 100644 index 0000000..0286770 --- /dev/null +++ b/src/Catalog.API/IntegrationEvents/CatalogStockValidationService.cs @@ -0,0 +1,25 @@ +namespace eShop.Catalog.API.IntegrationEvents; + +public sealed class CatalogStockValidationService(CatalogContext catalogContext) : ICatalogStockValidationService +{ + public async Task ValidateStockAsync(int orderId, IEnumerable orderStockItems) + { + var confirmedOrderStockItems = new List(); + + foreach (var orderStockItem in orderStockItems) + { + var catalogItem = await catalogContext.CatalogItems.FindAsync(orderStockItem.ProductId); + if (catalogItem is not null) + { + var hasStock = catalogItem.AvailableStock >= orderStockItem.Units; + var confirmedOrderStockItem = new ConfirmedOrderStockItem(catalogItem.Id, hasStock); + + confirmedOrderStockItems.Add(confirmedOrderStockItem); + } + } + + return confirmedOrderStockItems.Any(c => !c.HasStock) + ? new OrderStockRejectedIntegrationEvent(orderId, confirmedOrderStockItems) + : new OrderStockConfirmedIntegrationEvent(orderId); + } +} diff --git a/src/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs b/src/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs index 9b0ea73..c36db23 100644 --- a/src/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs +++ b/src/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs @@ -1,7 +1,7 @@ namespace eShop.Catalog.API.IntegrationEvents.EventHandling; public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler( - CatalogContext catalogContext, + ICatalogStockValidationService stockValidationService, ICatalogIntegrationEventService catalogIntegrationEventService, ILogger logger) : IIntegrationEventHandler @@ -10,23 +10,7 @@ public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent { logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); - var confirmedOrderStockItems = new List(); - - foreach (var orderStockItem in @event.OrderStockItems) - { - var catalogItem = catalogContext.CatalogItems.Find(orderStockItem.ProductId); - if (catalogItem is not null) - { - var hasStock = catalogItem.AvailableStock >= orderStockItem.Units; - var confirmedOrderStockItem = new ConfirmedOrderStockItem(catalogItem.Id, hasStock); - - confirmedOrderStockItems.Add(confirmedOrderStockItem); - } - } - - var confirmedIntegrationEvent = confirmedOrderStockItems.Any(c => !c.HasStock) - ? (IntegrationEvent)new OrderStockRejectedIntegrationEvent(@event.OrderId, confirmedOrderStockItems) - : new OrderStockConfirmedIntegrationEvent(@event.OrderId); + var confirmedIntegrationEvent = await stockValidationService.ValidateStockAsync(@event.OrderId, @event.OrderStockItems); await catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(confirmedIntegrationEvent); await catalogIntegrationEventService.PublishThroughEventBusAsync(confirmedIntegrationEvent); diff --git a/src/Catalog.API/IntegrationEvents/ICatalogStockValidationService.cs b/src/Catalog.API/IntegrationEvents/ICatalogStockValidationService.cs new file mode 100644 index 0000000..2b27f8f --- /dev/null +++ b/src/Catalog.API/IntegrationEvents/ICatalogStockValidationService.cs @@ -0,0 +1,6 @@ +namespace eShop.Catalog.API.IntegrationEvents; + +public interface ICatalogStockValidationService +{ + Task ValidateStockAsync(int orderId, IEnumerable orderStockItems); +}