Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catalog - Offers initial (2024-06-21) #45

Merged
merged 6 commits into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions EventSourcingEcommerce.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=EventStoreDB/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Eventuous/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=MicroPlumberd/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=newegg/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Shopee/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Newegg/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Plumberd/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Nullo/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=otel/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
46 changes: 46 additions & 0 deletions src/Catalog/Catalog.Api/Catalog.Api.Offers.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# curl -X 'GET'
# 'http://localhost:5252/offers/0190421a-1466-4f1b-8261-a22a528aadae'
# -H 'accept: text/plain'
GET http://localhost:5252/offers/0190421a-1466-4f1b-8261-a22a528aadae
accept: text/plain

###

# curl -X 'POST'
# 'http://localhost:5252/offer/draft'
# -H 'accept: text/plain'
# -H 'Content-Type: application/json'
# -d '{
# "sku": "36606-001",
# "createdBy": "erik"
#}'
POST http://localhost:5252/offer/draft
accept: text/plain
Content-Type: application/json

{
"sku": "36606-001",
"createdBy": "erik"
}

###

# curl -X 'POST'
# 'http://localhost:5252/offer/activate'
# -H 'accept: text/plain'
# -H 'Content-Type: application/json'
# -d '{
# "offerId": "0190421a-1466-4f1b-8261-a22a528aada",
# "activatedBy": "erik"
#}'
POST http://localhost:5252/offer/activate
accept: text/plain
Content-Type: application/json

{
"offerId": "0190421a-1466-4f1b-8261-a22a528aadae",
"activatedBy": "erik"
}

###

33 changes: 33 additions & 0 deletions src/Catalog/Catalog.Api/Commands/Offers/OfferCommandService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Catalog.Offers;
using Ecommerce.Core.Identities;
using Eventuous;
using MongoDB.Bson.Serialization;

namespace Catalog.Api.Commands.Offers;

public class OfferCommandService : CommandService<Offer, OfferState, OfferId>
{
[Obsolete("Obsolete usage of OnNewAsync per Eventuous; use new API instead (TODO)")]
public OfferCommandService(
IAggregateStore store,
Services.IsSkuAvailable isSkuAvailable,
Services.IsUserAuthorized isUserAuthorized,
ICombIdGenerator idGenerator)
: base(store)
{
var generatedId = idGenerator.New();
OnNewAsync<OfferCommands.Draft>(cmd => new OfferId(generatedId),
((offer, cmd, _) => offer.Draft(
generatedId,
cmd.Sku,
DateTimeOffset.Now,
cmd.CreatedBy,
isSkuAvailable,
isUserAuthorized)));

OnExisting<OfferCommands.Activate>(cmd => new OfferId(cmd.OfferId),
((offer, cmd) => offer.Activate(
DateTimeOffset.Now,
cmd.ActivatedBy)));
}
}
14 changes: 14 additions & 0 deletions src/Catalog/Catalog.Api/Commands/Offers/OfferCommands.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Catalog.Api.Commands.Offers;

public class OfferCommands
{
public record Draft(
string Sku,
string CreatedBy
);

public record Activate(
string OfferId,
string ActivatedBy
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Ecommerce.Core.Identities;
using Eventuous;

namespace Catalog.Api.Commands;
namespace Catalog.Api.Commands.Prices;

public class PriceCommandService : CommandService<Price, PriceState, PriceId>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Catalog.Api.Commands;
namespace Catalog.Api.Commands.Prices;

public static class PriceCommands
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using Catalog.Products;
using Ecommerce.Core.Identities;
using Eventuous;
using static Catalog.Api.Commands.ProductCommands;

namespace Catalog.Api.Commands;
namespace Catalog.Api.Commands.Products;

public class ProductCommandService : CommandService<Product, ProductState, ProductId>
{
Expand All @@ -17,7 +16,7 @@ public ProductCommandService(
{
// On<InitializeProduct>(); // TODO use new API instead of obsolete versions

OnNewAsync<DraftWithProvidedId>(cmd => new ProductId(cmd.ProductId),
OnNewAsync<ProductCommands.DraftWithProvidedId>(cmd => new ProductId(cmd.ProductId),
((product, cmd, _) => product.Draft(
cmd.ProductId,
cmd.Sku,
Expand All @@ -31,7 +30,7 @@ public ProductCommandService(
isUserAuthorized)));

var generatedId = idGenerator.New();
OnNewAsync<Draft>(cmd => new ProductId(generatedId),
OnNewAsync<ProductCommands.Draft>(cmd => new ProductId(generatedId),
((product, cmd, _) => product.Draft(
generatedId,
cmd.Sku,
Expand All @@ -44,48 +43,48 @@ public ProductCommandService(
isSkuAvailable,
isUserAuthorized)));

OnExisting<Activate>(cmd => new ProductId(cmd.ProductId),
OnExisting<ProductCommands.Activate>(cmd => new ProductId(cmd.ProductId),
((product, cmd) => product.Activate(
DateTimeOffset.Now,
cmd.ActivatedBy)));

OnExisting<Archive>(cmd => new ProductId(cmd.ProductId),
OnExisting<ProductCommands.Archive>(cmd => new ProductId(cmd.ProductId),
((product, cmd) => product.Archive(
DateTimeOffset.Now,
cmd.ArchivedBy,
cmd.Reason)));

OnExisting<Cancel>(cmd => new ProductId(cmd.ProductId),
OnExisting<ProductCommands.Cancel>(cmd => new ProductId(cmd.ProductId),
((product, cmd) => product.CancelDraft(
DateTimeOffset.Now,
cmd.CancelledBy,
cmd.Reason)));

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

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

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

OnExisting<TakeMeasurement>(cmd => new ProductId(cmd.ProductId),
OnExisting<ProductCommands.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),
OnExisting<ProductCommands.RemoveMeasurement>(cmd => new ProductId(cmd.ProductId),
((product, cmd) => product.RemoveMeasurement(
Measurement.GetName(cmd.Type)))); // TODO evaluate if this is a good path to take;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Catalog.Api.Commands;
namespace Catalog.Api.Commands.Products;

public static class ProductCommands
{
Expand Down
21 changes: 21 additions & 0 deletions src/Catalog/Catalog.Api/HttpApi/Offers/OfferCommandApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Catalog.Api.Commands.Offers;
using Catalog.Offers;
using Eventuous;
using Eventuous.AspNetCore.Web;
using Microsoft.AspNetCore.Mvc;

namespace Catalog.Api.HttpApi.Offers;

[Route("/offer")]
public class OfferCommandApi(ICommandService<Offer> service) : CommandHttpApiBase<Offer>(service)
{
[HttpPost]
[Route("draft")]
public Task<ActionResult<Result>> Draft([FromBody] OfferCommands.Draft cmd, CancellationToken ct)
=> Handle(cmd, ct);

[HttpPost]
[Route("activate")]
public Task<ActionResult<Result>> Activate([FromBody] OfferCommands.Activate cmd, CancellationToken ct)
=> Handle(cmd, ct);
}
21 changes: 21 additions & 0 deletions src/Catalog/Catalog.Api/HttpApi/Offers/OfferQueryApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Catalog.Offers;
using Eventuous;
using Microsoft.AspNetCore.Mvc;

namespace Catalog.Api.HttpApi.Offers;

[Route("/offers")]
public class OfferQueryApi : ControllerBase
{
private readonly IAggregateStore _store;

public OfferQueryApi(IAggregateStore store) => _store = store;

[HttpGet]
[Route("{id}")]
public async Task<OfferState> GetProduct(string id, CancellationToken ct)
{
var product = await _store.Load<Offer>(StreamName.For<Offer>(id), ct);
return product.State;
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
using Catalog.Api.Commands.Prices;
using Catalog.Prices;
using Eventuous;
using Eventuous.AspNetCore.Web;
using Microsoft.AspNetCore.Mvc;
using static Catalog.Api.Commands.PriceCommands;

namespace Catalog.Api.HttpApi;
namespace Catalog.Api.HttpApi.Prices;

[Route("/price")]
public class PriceCommandApi(ICommandService<Price> service) : CommandHttpApiBase<Price>(service)
{
[HttpPost]
[Route("initialize")]
public Task<ActionResult<Result>> Draft([FromBody] Initialize cmd, CancellationToken ct)
public Task<ActionResult<Result>> Draft([FromBody] PriceCommands.Initialize cmd, CancellationToken ct)
=> Handle(cmd, ct);

[HttpPost]
[Route("activate")]
public Task<ActionResult<Result>> Activate([FromBody] Activate cmd, CancellationToken ct)
public Task<ActionResult<Result>> Activate([FromBody] PriceCommands.Activate cmd, CancellationToken ct)
=> Handle(cmd, ct);

[HttpPost]
[Route("deprecate")]
public Task<ActionResult<Result>> Deprecate([FromBody] Deprecate cmd, CancellationToken ct)
public Task<ActionResult<Result>> Deprecate([FromBody] PriceCommands.Deprecate cmd, CancellationToken ct)
=> Handle(cmd, ct);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Eventuous;
using Microsoft.AspNetCore.Mvc;

namespace Catalog.Api.HttpApi;
namespace Catalog.Api.HttpApi.Prices;

[Route("/prices")]
public class PriceQueryApi : ControllerBase
Expand Down
Original file line number Diff line number Diff line change
@@ -1,61 +1,61 @@
using Catalog.Api.Commands.Products;
using Catalog.Products;
using Eventuous;
using Eventuous.AspNetCore.Web;
using Microsoft.AspNetCore.Mvc;
using static Catalog.Api.Commands.ProductCommands;

namespace Catalog.Api.HttpApi;
namespace Catalog.Api.HttpApi.Products;

[Route("/product")]
public class ProductCommandApi(ICommandService<Product> service) : CommandHttpApiBase<Product>(service)
{
[HttpPost]
[Route("draft-with-id")]
public Task<ActionResult<Result>> Draft([FromBody] DraftWithProvidedId cmd, CancellationToken ct)
public Task<ActionResult<Result>> Draft([FromBody] ProductCommands.DraftWithProvidedId cmd, CancellationToken ct)
=> Handle(cmd, ct);

[HttpPost]
[Route("draft")]
public Task<ActionResult<Result>> Draft([FromBody] Draft cmd, CancellationToken ct)
public Task<ActionResult<Result>> Draft([FromBody] ProductCommands.Draft cmd, CancellationToken ct)
=> Handle(cmd, ct);

[HttpPost]
[Route("activate")]
public Task<ActionResult<Result>> Activate([FromBody] Activate cmd, CancellationToken ct)
public Task<ActionResult<Result>> Activate([FromBody] ProductCommands.Activate cmd, CancellationToken ct)
=> Handle(cmd, ct);

[HttpPost]
[Route("archive")]
public Task<ActionResult<Result>> Archive([FromBody] Archive cmd, CancellationToken ct)
public Task<ActionResult<Result>> Archive([FromBody] ProductCommands.Archive cmd, CancellationToken ct)
=> Handle(cmd, ct);

[HttpPost]
[Route("cancel")]
public Task<ActionResult<Result>> Cancel([FromBody] Cancel cmd, CancellationToken ct)
public Task<ActionResult<Result>> Cancel([FromBody] ProductCommands.Cancel cmd, CancellationToken ct)
=> Handle(cmd, ct);

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

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

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

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

[HttpPost]
[Route("remove-measurement")]
public Task<ActionResult<Result>> RemoveMeasurement([FromBody] RemoveMeasurement cmd, CancellationToken ct)
public Task<ActionResult<Result>> RemoveMeasurement([FromBody] ProductCommands.RemoveMeasurement cmd, CancellationToken ct)
=> Handle(cmd, ct);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Eventuous;
using Microsoft.AspNetCore.Mvc;

namespace Catalog.Api.HttpApi;
namespace Catalog.Api.HttpApi.Products;

[Route("/products")]
public class ProductQueryApi : ControllerBase
Expand Down
15 changes: 15 additions & 0 deletions src/Catalog/Catalog.Api/Queries/Offers/OfferDocument.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Eventuous.Projections.MongoDB.Tools;

namespace Catalog.Api.Queries.Offers;

public record OfferDocument : ProjectedDocument
{
public OfferDocument(string Id) : base(Id)
{
}

public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.MinValue;
public string CreatedBy { get; set; } = null!;
public string Sku { get; set; } = null!;
public string Status { get; set; } = null!;
}
Loading
Loading