Skip to content

Commit

Permalink
Catalog Extending Product Domain Model + Mini-Restructure (#35)
Browse files Browse the repository at this point in the history
* fixed; value object records, flattened namespace

* quick push with WIP code due to power outages + thunderstorm ⛈️⚡

* feat: handle for ProductTakeMeasurement event, measurement VO logic fix

* feat; handle logic for ProductRemoveMeasurement event

* fix; Measurements: init property, Array.Empty

* streamlined order of adjustment methods (description, then name)

* fix: inverted operator

* added commands and HTTP endpoints for measurements (WIP; bug found)

* fix; string comparison

* fix; string comparison (2)

* feat; Product's brand adjustment fleshed out

* fix; brand creation during domain model initialization

* chore; updated API http to include brand (still WIP)

* fixes; names, value assignment

* TODO comments -- need to update Measurements VO

* add Measurements to commands, projections, etc. WIP
  • Loading branch information
erikshafer authored May 31, 2024
1 parent 1b4fbd0 commit 0cab709
Show file tree
Hide file tree
Showing 23 changed files with 415 additions and 59 deletions.
56 changes: 52 additions & 4 deletions src/Catalog/Catalog.Api/Catalog.Api.http
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Accept: application/json
# "sku": "36606",
# "name": "Bubbletron",
# "description": "A magical machine that blows out bubbles! Woo!",
# "brand": "ADJ Products LLC",
# "createdBy": "Erik"
#}'
POST http://localhost:5252/product/draft-with-id
Expand All @@ -27,6 +28,7 @@ Content-Type: application/json
"sku": "36606",
"name": "Bubbletron",
"description": "A magical machine that blows out bubbles! Woo!",
"brand": "ADJ Products LLC",
"createdBy": "Erik"
}

Expand All @@ -40,6 +42,7 @@ Content-Type: application/json
# "sku": "36606",
# "name": "Bubbletron",
# "description": "A magical machine that blows out bubbles! Woo!",
# "brand": "ADJ Products LLC",
# "createdBy": "Erik"
#}'
POST http://localhost:5252/product/draft
Expand All @@ -50,6 +53,7 @@ Content-Type: application/json
"sku": "36606",
"name": "Bubbletron",
"description": "A magical machine that blows out bubbles! Woo!",
"brand": "ADJ Products LLC",
"createdBy": "Erik"
}

Expand Down Expand Up @@ -88,9 +92,9 @@ accept: text/plain
Content-Type: application/json

{
"productId": "36606-001",
"productId": "1243552823715561472",
"archivedBy": "Erik",
"reason": "oopsie daisy"
"reason": "Made in error."
}

###
Expand All @@ -111,7 +115,7 @@ Content-Type: application/json
{
"productId": "36606-001",
"cancelledBy": "Erik",
"reason": "not sure tbh frfr"
"reason": "not sure tbh frfr no cap"
}

###
Expand Down Expand Up @@ -152,7 +156,7 @@ Content-Type: application/json

{
"productId": "36606-001",
"description": "This is a new description and I sure hope it works! Oh, right. Bubbleszzz!",
"description": "This is a new description. Oh, right. Bubblesss! 🫧🫧🫧",
"adjustedBy": "Erik"
}

Expand All @@ -165,3 +169,47 @@ GET http://localhost:5252/products/36606-001
accept: text/plain

###
# curl -X 'POST'
# 'http://localhost:5252/product/adjust-brand'
# -H 'accept: text/plain'
# -H 'Content-Type: application/json'
# -d '{
# "productId": "36606-001",
# "brand": "ADJ Lighting",
# "adjustedBy": "Erik"
#}'
POST http://localhost:5252/product/adjust-brand
accept: text/plain
Content-Type: application/json

{
"productId": "36606-001",
"brand": "ADJ Lighting Inc",
"adjustedBy": "Erik"
}

###

# curl -X 'POST'
# 'http://localhost:5252/product/take-measurement'
# -H 'accept: text/plain'
# -H 'Content-Type: application/json'
# -d '{
# "productId": "36606-001",
# "type": "Dimension",
# "unit": "in",
# "value": "14.25 x 7.5 x 8.25"
#}'
POST http://localhost:5252/product/take-measurement
accept: text/plain
Content-Type: application/json

{
"productId": "36606-001",
"type": "Dimension",
"unit": "in",
"value": "14.25 x 7.5 x 8.25"
}

###

25 changes: 21 additions & 4 deletions src/Catalog/Catalog.Api/Commands/ProductCommandService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Catalog.Products;
using Ecommerce.Core.Identities;
using Eventuous;
using static Catalog.Api.Commands.ProductCommands;
Expand All @@ -24,6 +23,7 @@ public ProductCommandService(
cmd.Name,
cmd.Description,
cmd.Brand,
cmd.Measurements,
DateTimeOffset.Now,
cmd.CreatedBy,
isSkuAvailable,
Expand All @@ -37,6 +37,7 @@ public ProductCommandService(
cmd.Name,
cmd.Description,
cmd.Brand,
cmd.Measurements,
DateTimeOffset.Now,
cmd.CreatedBy,
isSkuAvailable,
Expand All @@ -59,16 +60,32 @@ public ProductCommandService(
cmd.CancelledBy,
cmd.Reason)));

OnExisting<AdjustDescription>(cmd => new ProductId(cmd.ProductId),
((product, cmd) => product.AdjustDescription(
cmd.Description,
DateTimeOffset.Now,
cmd.AdjustedBy)));

OnExisting<AdjustName>(cmd => new ProductId(cmd.ProductId),
((product, cmd) => product.AdjustName(
cmd.Name,
DateTimeOffset.Now,
cmd.AdjustedBy)));

OnExisting<AdjustDescription>(cmd => new ProductId(cmd.ProductId),
((product, cmd) => product.AdjustDescription(
cmd.Description,
OnExisting<AdjustBrand>(cmd => new ProductId(cmd.ProductId),
((product, cmd) => product.AdjustBrand(
cmd.Brand,
DateTimeOffset.Now,
cmd.AdjustedBy)));

OnExisting<TakeMeasurement>(cmd => new ProductId(cmd.ProductId),
((product, cmd) => product.TakeMeasurement(
Measurement.GetName(cmd.Type), // TODO evaluate if this is a good path to take
cmd.Unit,
cmd.Value)));

OnExisting<RemoveMeasurement>(cmd => new ProductId(cmd.ProductId),
((product, cmd) => product.RemoveMeasurement(
Measurement.GetName(cmd.Type)))); // TODO evaluate if this is a good path to take;
}
}
25 changes: 20 additions & 5 deletions src/Catalog/Catalog.Api/Commands/ProductCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public record DraftWithProvidedId(
string Name,
string Description,
string Brand,
string Measurements,
string CreatedBy
);

Expand All @@ -16,12 +17,14 @@ public record Draft(
string Name,
string Description,
string Brand,
string Measurements,
string CreatedBy
);

public record Activate(
string ProductId,
string ActivatedBy);
string ActivatedBy
);

public record Archive(
string ProductId,
Expand All @@ -35,15 +38,15 @@ public record Cancel(
string Reason
);

public record AdjustName(
public record AdjustDescription(
string ProductId,
string Name,
string Description,
string AdjustedBy
);

public record AdjustDescription(
public record AdjustName(
string ProductId,
string Description,
string Name,
string AdjustedBy
);

Expand All @@ -52,4 +55,16 @@ public record AdjustBrand(
string Brand,
string AdjustedBy
);

public record TakeMeasurement(
string ProductId,
string Type,
string Unit,
string Value
);

public record RemoveMeasurement(
string ProductId,
string Type
);
}
19 changes: 14 additions & 5 deletions src/Catalog/Catalog.Api/HttpApi/CommandApi.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Catalog.Products;
using Eventuous;
using Eventuous.AspNetCore.Web;
using Microsoft.AspNetCore.Mvc;
Expand Down Expand Up @@ -35,17 +34,27 @@ public Task<ActionResult<Result>> Cancel([FromBody] Cancel cmd, CancellationToke
=> Handle(cmd, ct);

[HttpPost]
[Route("adjust-name")]
public Task<ActionResult<Result>> AdjustName([FromBody] AdjustName cmd, CancellationToken ct)
[Route("adjust-description")]
public Task<ActionResult<Result>> AdjustDescription([FromBody] AdjustDescription cmd, CancellationToken ct)
=> Handle(cmd, ct);

[HttpPost]
[Route("adjust-description")]
public Task<ActionResult<Result>> AdjustDescription([FromBody] AdjustDescription cmd, CancellationToken ct)
[Route("adjust-name")]
public Task<ActionResult<Result>> AdjustName([FromBody] AdjustName cmd, CancellationToken ct)
=> Handle(cmd, ct);

[HttpPost]
[Route("adjust-brand")]
public Task<ActionResult<Result>> AdjustBrand([FromBody] AdjustBrand cmd, CancellationToken ct)
=> Handle(cmd, ct);

[HttpPost]
[Route("take-measurement")]
public Task<ActionResult<Result>> TakeMeasurement([FromBody] TakeMeasurement cmd, CancellationToken ct)
=> Handle(cmd, ct);

[HttpPost]
[Route("remove-measurement")]
public Task<ActionResult<Result>> RemoveMeasurement([FromBody] RemoveMeasurement cmd, CancellationToken ct)
=> Handle(cmd, ct);
}
1 change: 0 additions & 1 deletion src/Catalog/Catalog.Api/HttpApi/QueryApi.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Catalog.Products;
using Eventuous;
using Microsoft.AspNetCore.Mvc;

Expand Down
3 changes: 3 additions & 0 deletions src/Catalog/Catalog.Api/Queries/ProductDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ public ProductDocument(string Id) : base(Id)
public string Sku { get; set; } = null!;
public string Description { get; set; } = null!;
public string Brand { get; set; } = null!;

public string Measurements { get; set; } = null!;
// public string[] Measurements { get; set; } = null!; // TODO
}
54 changes: 36 additions & 18 deletions src/Catalog/Catalog.Api/Queries/ProductStateProjection.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using Catalog.Products;
using Eventuous.Projections.MongoDB;
using Eventuous.Subscriptions.Context;
using MongoDB.Driver;
using static Catalog.Products.ProductEvents;
using static Catalog.ProductEvents;

namespace Catalog.Api.Queries;

Expand All @@ -27,20 +26,21 @@ private static UpdateDefinition<ProductDocument> Handle(
var evt = ctx.Message;

return update.SetOnInsert(x => x.Id, ctx.Stream.GetId())
.Set(x => x.CreatedAt, evt.CreatedAt)
.Set(x => x.CreatedBy, evt.CreatedBy)
.Set(x => x.Status, nameof(ProductStatus.Drafted))
.Set(x => x.Name, evt.Name)
.Set(x => x.Sku, evt.Sku)
.Set(x => x.Description, evt.Description)
.Set(x => x.Brand, evt.Brand);
.Set(x => x.CreatedAt, evt.CreatedAt)
.Set(x => x.CreatedBy, evt.CreatedBy)
.Set(x => x.Status, nameof(ProductStatus.Drafted))
.Set(x => x.Name, evt.Name)
.Set(x => x.Sku, evt.Sku)
.Set(x => x.Description, evt.Description)
.Set(x => x.Brand, evt.Brand)
.Set(x => x.Measurements, evt.Measurements);
}

private static UpdateDefinition<ProductDocument> Handle(
IMessageConsumeContext<V1.ProductActivated> ctx,
UpdateDefinition<ProductDocument> update)
{
var evt = ctx.Message;
var @event = ctx.Message;

return update.Set(x => x.Status, nameof(ProductStatus.Activated));
}
Expand All @@ -49,7 +49,7 @@ private static UpdateDefinition<ProductDocument> Handle(
IMessageConsumeContext<V1.ProductArchived> ctx,
UpdateDefinition<ProductDocument> update)
{
var evt = ctx.Message;
var @event = ctx.Message;

return update.Set(x => x.Status, nameof(ProductStatus.Archived));
}
Expand All @@ -58,7 +58,7 @@ private static UpdateDefinition<ProductDocument> Handle(
IMessageConsumeContext<V1.ProductDraftCancelled> ctx,
UpdateDefinition<ProductDocument> update)
{
var evt = ctx.Message;
var @event = ctx.Message;

return update.Set(x => x.Status, nameof(ProductStatus.Cancelled));
}
Expand All @@ -67,26 +67,44 @@ private static UpdateDefinition<ProductDocument> Handle(
IMessageConsumeContext<V1.ProductNameAdjusted> ctx,
UpdateDefinition<ProductDocument> update)
{
var evt = ctx.Message;
var @event = ctx.Message;

return update.Set(x => x.Name, evt.Name);
return update.Set(x => x.Name, @event.Name);
}

private static UpdateDefinition<ProductDocument> Handle(
IMessageConsumeContext<V1.ProductDescriptionAdjusted> ctx,
UpdateDefinition<ProductDocument> update)
{
var evt = ctx.Message;
var @event = ctx.Message;

return update.Set(x => x.Description, evt.Description);
return update.Set(x => x.Description, @event.Description);
}

private static UpdateDefinition<ProductDocument> Handle(
IMessageConsumeContext<V1.ProductBrandAdjusted> ctx,
UpdateDefinition<ProductDocument> update)
{
var evt = ctx.Message;
var @event = ctx.Message;

return update.Set(x => x.Brand, @event.Brand);
}

private static UpdateDefinition<ProductDocument> Handle(
IMessageConsumeContext<V1.ProductTakeMeasurement> ctx,
UpdateDefinition<ProductDocument> update)
{
var @event = ctx.Message;

return update.Set(x => x.Measurements, @event.ToString());
}

private static UpdateDefinition<ProductDocument> Handle(
IMessageConsumeContext<V1.ProductRemoveMeasurement> ctx,
UpdateDefinition<ProductDocument> update)
{
var @event = ctx.Message;

return update.Set(x => x.Brand, evt.Brand);
return update.Set(x => x.Measurements, string.Empty);
}
}
1 change: 0 additions & 1 deletion src/Catalog/Catalog.Api/Registrations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Catalog.Api.Commands;
using Catalog.Api.Infrastructure;
using Catalog.Api.Queries;
using Catalog.Products;
using Ecommerce.Core.Identities;
using Eventuous;
using Eventuous.Diagnostics.OpenTelemetry;
Expand Down
Loading

0 comments on commit 0cab709

Please sign in to comment.