From a7c897c667d4f722de8d41842ccc141f5587a634 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:25:27 +0000 Subject: [PATCH 1/3] Initial plan From 7af1b89a39f9631f7aebcf8822549d507be9fb68 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:32:59 +0000 Subject: [PATCH 2/3] Fix referential integrity issues for catalog-basket-order Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com> --- ...ChangedToAwaitingValidationIntegrationEventHandler.cs | 9 +++++++++ src/WebApp/Services/BasketState.cs | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs b/src/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs index 9b0ea73c9..71bcc6546 100644 --- a/src/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs +++ b/src/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs @@ -22,6 +22,15 @@ public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent confirmedOrderStockItems.Add(confirmedOrderStockItem); } + else + { + // Product no longer exists in catalog (may have been deleted) + // Treat as out of stock to reject the order + logger.LogWarning("Product with id {ProductId} in order {OrderId} not found in catalog", + orderStockItem.ProductId, @event.OrderId); + var confirmedOrderStockItem = new ConfirmedOrderStockItem(orderStockItem.ProductId, false); + confirmedOrderStockItems.Add(confirmedOrderStockItem); + } } var confirmedIntegrationEvent = confirmedOrderStockItems.Any(c => !c.HasStock) diff --git a/src/WebApp/Services/BasketState.cs b/src/WebApp/Services/BasketState.cs index e03b37730..6331f3795 100644 --- a/src/WebApp/Services/BasketState.cs +++ b/src/WebApp/Services/BasketState.cs @@ -132,7 +132,12 @@ async Task> FetchCoreAsync() var catalogItems = (await catalogService.GetCatalogItems(productIds)).ToDictionary(k => k.Id, v => v); foreach (var item in quantities) { - var catalogItem = catalogItems[item.ProductId]; + // Skip items that no longer exist in the catalog (may have been deleted) + if (!catalogItems.TryGetValue(item.ProductId, out var catalogItem)) + { + continue; + } + var orderItem = new BasketItem { Id = Guid.NewGuid().ToString(), // TODO: this value is meaningless, use ProductId instead. From 3bf357c65927ce176545f4ce83ff06e28ec27c70 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:37:21 +0000 Subject: [PATCH 3/3] Add logging for basket items with missing catalog products Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com> --- src/WebApp/Services/BasketState.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/WebApp/Services/BasketState.cs b/src/WebApp/Services/BasketState.cs index 6331f3795..fcaa9f619 100644 --- a/src/WebApp/Services/BasketState.cs +++ b/src/WebApp/Services/BasketState.cs @@ -10,7 +10,8 @@ public class BasketState( BasketService basketService, CatalogService catalogService, OrderingService orderingService, - AuthenticationStateProvider authenticationStateProvider) : IBasketState + AuthenticationStateProvider authenticationStateProvider, + ILogger logger) : IBasketState { private Task>? _cachedBasket; private HashSet _changeSubscriptions = new(); @@ -135,6 +136,7 @@ async Task> FetchCoreAsync() // Skip items that no longer exist in the catalog (may have been deleted) if (!catalogItems.TryGetValue(item.ProductId, out var catalogItem)) { + logger.LogWarning("Basket item with ProductId {ProductId} not found in catalog and will be skipped", item.ProductId); continue; }