diff --git a/Directory.Build.props b/Directory.Build.props
index 9e7f627..a66f618 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -5,7 +5,7 @@
enable
true
enable
- 0.15.0-beta.4
+ 0.15.0-beta.10
https://github.com/erikshafer/event-sourcing-ecommerce
https://event-sourcing.dev/
MIT
diff --git a/src/Catalog/Catalog.Api/Catalog.Api.csproj b/src/Catalog/Catalog.Api/Catalog.Api.csproj
index 5341711..419355a 100644
--- a/src/Catalog/Catalog.Api/Catalog.Api.csproj
+++ b/src/Catalog/Catalog.Api/Catalog.Api.csproj
@@ -8,6 +8,7 @@
+
diff --git a/src/Catalog/Catalog.Api/Catalog.Api.http b/src/Catalog/Catalog.Api/Catalog.Api.http
index 57cc883..65e9cdb 100644
--- a/src/Catalog/Catalog.Api/Catalog.Api.http
+++ b/src/Catalog/Catalog.Api/Catalog.Api.http
@@ -2,7 +2,7 @@
###
-GET {{Inventory.Api_HostAddress}}/swagger/
+GET {{Inventory.Api_HostAddress}}/api/
Accept: application/json
###
diff --git a/src/Catalog/Catalog.Api/Registrations.cs b/src/Catalog/Catalog.Api/Registrations.cs
index f864d72..3316528 100644
--- a/src/Catalog/Catalog.Api/Registrations.cs
+++ b/src/Catalog/Catalog.Api/Registrations.cs
@@ -31,6 +31,9 @@ public static void AddEventuous(this IServiceCollection services, IConfiguration
)
);
+ // register known event types (e.g. using [EventType] annotation)
+ TypeMap.RegisterKnownEventTypes();
+
// event store (core)
services.AddEventStoreClient(configuration["EventStore:ConnectionString"]!);
services.AddAggregateStore();
diff --git a/src/Inventory/Inventory.Api/Inventory.Api.csproj b/src/Inventory/Inventory.Api/Inventory.Api.csproj
index 5b5f7f5..065a89f 100644
--- a/src/Inventory/Inventory.Api/Inventory.Api.csproj
+++ b/src/Inventory/Inventory.Api/Inventory.Api.csproj
@@ -7,9 +7,7 @@
-
-
diff --git a/src/Retail/ShoppingCart.Api/HttpApi/CommandApi.cs b/src/Retail/ShoppingCart.Api/HttpApi/CommandApi.cs
index 7a2b3dc..162b4d4 100644
--- a/src/Retail/ShoppingCart.Api/HttpApi/CommandApi.cs
+++ b/src/Retail/ShoppingCart.Api/HttpApi/CommandApi.cs
@@ -1,25 +1,25 @@
using Eventuous;
+using Eventuous.AspNetCore.Web;
using Microsoft.AspNetCore.Mvc;
using static ShoppingCart.CartCommands.V1;
namespace ShoppingCart.Api.HttpApi;
[Route("/cart")]
-public class CommandApi(IFuncCommandService service) : ControllerBase
+public class CommandApi : CommandHttpApiBaseFunc
{
- [HttpPost]
- [Route("open")]
- public async Task> OpenCart([FromBody] OpenCart cmd, CancellationToken ct)
+ private readonly IFuncCommandService _service;
+
+ public CommandApi(IFuncCommandService service) : base(service)
{
- var result = await service.Handle(cmd, ct);
- return Ok(result);
+ _service = service;
}
[HttpPost]
- [Route("open-with-id")]
- public async Task> OpenCart([FromBody] OpenCartWithProvidedId cmd, CancellationToken ct)
+ [Route("open")]
+ public async Task> OpenCart([FromBody] OpenCart cmd, CancellationToken ct)
{
- var result = await service.Handle(cmd, ct);
+ var result = await _service.Handle(cmd, ct);
return Ok(result);
}
@@ -27,7 +27,7 @@ public async Task> OpenCart([FromBody] OpenCartWithProvided
[Route("add-product")]
public async Task> OpenCart([FromBody] AddProductToCart cmd, CancellationToken ct)
{
- var result = await service.Handle(cmd, ct);
+ var result = await _service.Handle(cmd, ct);
return Ok(result);
}
@@ -35,7 +35,15 @@ public async Task> OpenCart([FromBody] AddProductToCart cmd
[Route("remove-product")]
public async Task> OpenCart([FromBody] RemoveProductFromCart cmd, CancellationToken ct)
{
- var result = await service.Handle(cmd, ct);
+ var result = await _service.Handle(cmd, ct);
+ return Ok(result);
+ }
+
+ [HttpPost]
+ [Route("prepare-checkout")]
+ public async Task> PrepareForCheckout([FromBody] PrepareCartForCheckout cmd, CancellationToken ct)
+ {
+ var result = await _service.Handle(cmd, ct);
return Ok(result);
}
@@ -43,7 +51,7 @@ public async Task> OpenCart([FromBody] RemoveProductFromCar
[Route("confirm")]
public async Task> OpenCart([FromBody] ConfirmCart cmd, CancellationToken ct)
{
- var result = await service.Handle(cmd, ct);
+ var result = await _service.Handle(cmd, ct);
return Ok(result);
}
}
diff --git a/src/Retail/ShoppingCart.Api/Program.cs b/src/Retail/ShoppingCart.Api/Program.cs
index fb211d4..d67411d 100644
--- a/src/Retail/ShoppingCart.Api/Program.cs
+++ b/src/Retail/ShoppingCart.Api/Program.cs
@@ -3,6 +3,7 @@
using NodaTime;
using NodaTime.Serialization.SystemTextJson;
using Serilog;
+using ShoppingCart;
using ShoppingCart.Api;
using ShoppingCart.Api.Infrastructure;
diff --git a/src/Retail/ShoppingCart.Api/Registrations.cs b/src/Retail/ShoppingCart.Api/Registrations.cs
index 2bd6d90..182633b 100644
--- a/src/Retail/ShoppingCart.Api/Registrations.cs
+++ b/src/Retail/ShoppingCart.Api/Registrations.cs
@@ -25,6 +25,9 @@ public static void AddEventuous(this IServiceCollection services, IConfiguration
)
);
+ // register known event types (e.g. using [EventType] annotation)
+ TypeMap.RegisterKnownEventTypes();
+
// event store (core)
services.AddEventStoreClient(configuration["EventStore:ConnectionString"]!);
services.AddAggregateStore();
diff --git a/src/Retail/ShoppingCart.Api/ShoppingCart.Api.csproj b/src/Retail/ShoppingCart.Api/ShoppingCart.Api.csproj
index 61985dc..edea4fd 100644
--- a/src/Retail/ShoppingCart.Api/ShoppingCart.Api.csproj
+++ b/src/Retail/ShoppingCart.Api/ShoppingCart.Api.csproj
@@ -8,6 +8,7 @@
+
diff --git a/src/Retail/ShoppingCart/CartCommands.cs b/src/Retail/ShoppingCart/CartCommands.cs
index 86d60fe..f22b5a4 100644
--- a/src/Retail/ShoppingCart/CartCommands.cs
+++ b/src/Retail/ShoppingCart/CartCommands.cs
@@ -8,11 +8,6 @@ public record OpenCart(
string CustomerId
);
- public record OpenCartWithProvidedId(
- string CartId,
- string CustomerId
- );
-
public record AddProductToCart(
string CartId,
string ProductId,
@@ -25,6 +20,10 @@ public record RemoveProductFromCart(
int Quantity
);
+ public record PrepareCartForCheckout(
+ string CartId
+ );
+
public record ConfirmCart(
string CartId
);
diff --git a/src/Retail/ShoppingCart/CartEvents.cs b/src/Retail/ShoppingCart/CartEvents.cs
index 677fcc4..ccbfb4c 100644
--- a/src/Retail/ShoppingCart/CartEvents.cs
+++ b/src/Retail/ShoppingCart/CartEvents.cs
@@ -30,5 +30,10 @@ int Quantity
public record CartConfirmed(
string CartId
);
+
+ [EventType("V1.EmptyCartDetected")]
+ public record EmptyCartDetected(
+ string CartId
+ );
}
}
diff --git a/src/Retail/ShoppingCart/CartFuncService.cs b/src/Retail/ShoppingCart/CartFuncService.cs
index cc76c32..04ab406 100644
--- a/src/Retail/ShoppingCart/CartFuncService.cs
+++ b/src/Retail/ShoppingCart/CartFuncService.cs
@@ -14,41 +14,53 @@ public CartFuncService(
TypeMapper? typeMap = null)
: base(store, typeMap)
{
- var generatedId = idGenerator.New(); // TODO: leverage
+ var generatedId = idGenerator.New();
- // Register command handlers
OnNew(cmd => GetStream(generatedId), OpenCart);
- OnNew(cmd => GetStream(cmd.CartId), OpenCartCommandHasId);
- OnExisting(cmd => GetStream(cmd.CartId), AddItemToCart);
+ OnExisting(cmd => GetStream(cmd.CartId), AddProductToCart);
+ OnExisting(cmd => GetStream(cmd.CartId), RemoveProductFromCart);
+ OnExisting(cmd => GetStream(cmd.CartId), PrepareCartForCheckout);
- // Helper function to get the stream name from the command
static StreamName GetStream(string id) => new($"Cart-{id}");
- // When there's no stream to load, the function only receives the command. (CLOSURES)
IEnumerable