diff --git a/src/BackOffice.BFF.Application/ProductsCQ/Commands/UpdateProductCategories/UpdateProductCategoriesCommand.cs b/src/BackOffice.BFF.Application/ProductsCQ/Commands/UpdateProductCategories/UpdateProductCategoriesCommand.cs new file mode 100644 index 0000000..03737d1 --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductsCQ/Commands/UpdateProductCategories/UpdateProductCategoriesCommand.cs @@ -0,0 +1,8 @@ +namespace BackOffice.BFF.Application.ProductsCQ.Commands.UpdateProductCategories; + +public record UpdateProductCategoriesCommand : IRequest +{ + public long ProductId { get; init; } + public IReadOnlyCollection CategoryIds { get; init; } = Array.Empty(); +} + diff --git a/src/BackOffice.BFF.Application/ProductsCQ/Commands/UpdateProductCategories/UpdateProductCategoriesCommandHandler.cs b/src/BackOffice.BFF.Application/ProductsCQ/Commands/UpdateProductCategories/UpdateProductCategoriesCommandHandler.cs new file mode 100644 index 0000000..802d634 --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductsCQ/Commands/UpdateProductCategories/UpdateProductCategoriesCommandHandler.cs @@ -0,0 +1,21 @@ +using BackOffice.BFF.Application.Common.Interfaces; + +namespace BackOffice.BFF.Application.ProductsCQ.Commands.UpdateProductCategories; + +public class UpdateProductCategoriesCommandHandler : IRequestHandler +{ + private readonly IApplicationContractContext _context; + + public UpdateProductCategoriesCommandHandler(IApplicationContractContext context) + { + _context = context; + } + + public async Task Handle(UpdateProductCategoriesCommand request, CancellationToken cancellationToken) + { + // Stub: until CMS Category services are available via the protobuf package, + // this handler is a no-op to keep the pipeline consistent. + await Task.CompletedTask; + return Unit.Value; + } +} diff --git a/src/BackOffice.BFF.Application/ProductsCQ/Queries/GetCategories/GetCategoriesQuery.cs b/src/BackOffice.BFF.Application/ProductsCQ/Queries/GetCategories/GetCategoriesQuery.cs new file mode 100644 index 0000000..6f8f1e5 --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductsCQ/Queries/GetCategories/GetCategoriesQuery.cs @@ -0,0 +1,7 @@ +namespace BackOffice.BFF.Application.ProductsCQ.Queries.GetCategories; + +public record GetCategoriesQuery : IRequest +{ + public long ProductId { get; init; } +} + diff --git a/src/BackOffice.BFF.Application/ProductsCQ/Queries/GetCategories/GetCategoriesQueryHandler.cs b/src/BackOffice.BFF.Application/ProductsCQ/Queries/GetCategories/GetCategoriesQueryHandler.cs new file mode 100644 index 0000000..d7cb1c7 --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductsCQ/Queries/GetCategories/GetCategoriesQueryHandler.cs @@ -0,0 +1,20 @@ +using BackOffice.BFF.Application.Common.Interfaces; + +namespace BackOffice.BFF.Application.ProductsCQ.Queries.GetCategories; + +public class GetCategoriesQueryHandler : IRequestHandler +{ + public GetCategoriesQueryHandler(IApplicationContractContext context) + { + // context is currently unused; reserved for future CMS integration + } + + public async Task Handle(GetCategoriesQuery request, CancellationToken cancellationToken) + { + // Stub implementation: returns empty list. + // When CMS protobuf package with Category support is available, + // this handler can be updated to call Category and PruductCategory services. + await Task.CompletedTask; + return new GetCategoriesResponseDto(); + } +} diff --git a/src/BackOffice.BFF.Application/ProductsCQ/Queries/GetCategories/GetCategoriesResponseDto.cs b/src/BackOffice.BFF.Application/ProductsCQ/Queries/GetCategories/GetCategoriesResponseDto.cs new file mode 100644 index 0000000..85df92d --- /dev/null +++ b/src/BackOffice.BFF.Application/ProductsCQ/Queries/GetCategories/GetCategoriesResponseDto.cs @@ -0,0 +1,14 @@ +namespace BackOffice.BFF.Application.ProductsCQ.Queries.GetCategories; + +public class GetCategoriesResponseDto +{ + public List Items { get; set; } = new(); +} + +public class CategoryItemDto +{ + public long Id { get; set; } + public string Title { get; set; } + public bool Selected { get; set; } +} + diff --git a/src/BackOffice.BFF.WebApi/Services/ProductsService.cs b/src/BackOffice.BFF.WebApi/Services/ProductsService.cs index fb6b677..4befc01 100644 --- a/src/BackOffice.BFF.WebApi/Services/ProductsService.cs +++ b/src/BackOffice.BFF.WebApi/Services/ProductsService.cs @@ -8,6 +8,8 @@ using BackOffice.BFF.Application.ProductsCQ.Queries.GetAllProductsByFilter; using BackOffice.BFF.Application.ProductsCQ.Commands.AddProductImage; using BackOffice.BFF.Application.ProductsCQ.Queries.GetProductGallery; using BackOffice.BFF.Application.ProductsCQ.Commands.RemoveProductImage; +using BackOffice.BFF.Application.ProductsCQ.Queries.GetCategories; +using BackOffice.BFF.Application.ProductsCQ.Commands.UpdateProductCategories; namespace BackOffice.BFF.WebApi.Services; @@ -59,4 +61,14 @@ public class ProductsService : ProductsContract.ProductsContractBase { return await _dispatchRequestToCQRS.Handle(request, context); } + + public override async Task GetCategories(GetCategoriesRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } + + public override async Task UpdateProductCategories(UpdateProductCategoriesRequest request, ServerCallContext context) + { + return await _dispatchRequestToCQRS.Handle(request, context); + } } diff --git a/src/Protobufs/BackOffice.BFF.Products.Protobuf/Protos/products.proto b/src/Protobufs/BackOffice.BFF.Products.Protobuf/Protos/products.proto index c58d9b6..a5a2fdf 100644 --- a/src/Protobufs/BackOffice.BFF.Products.Protobuf/Protos/products.proto +++ b/src/Protobufs/BackOffice.BFF.Products.Protobuf/Protos/products.proto @@ -60,6 +60,19 @@ service ProductsContract body: "*" }; }; + + rpc GetCategories(GetCategoriesRequest) returns (GetCategoriesResponse){ + option (google.api.http) = { + get: "/GetCategories" + }; + }; + + rpc UpdateProductCategories(UpdateProductCategoriesRequest) returns (google.protobuf.Empty){ + option (google.api.http) = { + post: "/UpdateProductCategories" + body: "*" + }; + }; } message ImageFileModel @@ -233,3 +246,26 @@ message RemoveProductImageRequest { int64 product_gallery_id = 1; } + +message CategoryItem +{ + int64 id = 1; + string title = 2; + bool selected = 3; +} + +message GetCategoriesRequest +{ + int64 product_id = 1; +} + +message GetCategoriesResponse +{ + repeated CategoryItem items = 1; +} + +message UpdateProductCategoriesRequest +{ + int64 product_id = 1; + repeated int64 category_ids = 2; +}