Init
This commit is contained in:
120
Prefab.Web/Gateway/Products.cs
Normal file
120
Prefab.Web/Gateway/Products.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System.Net;
|
||||
using FluentValidation;
|
||||
using Prefab.Domain.Exceptions;
|
||||
using Prefab.Endpoints;
|
||||
using Prefab.Shared.Catalog;
|
||||
using Prefab.Shared.Catalog.Products;
|
||||
using Prefab.Web.Client.Models.Catalog;
|
||||
using Prefab.Web.Client.Models.Shared;
|
||||
using Prefab.Web.Client.ViewModels.Catalog;
|
||||
using Prefab.Web.Client.Services;
|
||||
using UrlBuilder = Prefab.Web.UrlPolicy.UrlPolicy;
|
||||
|
||||
namespace Prefab.Web.Gateway;
|
||||
|
||||
public static class Products
|
||||
{
|
||||
public sealed class Endpoints : IEndpointRegistrar
|
||||
{
|
||||
public void MapEndpoints(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
endpoints.MapGet(
|
||||
"/bff/catalog/categories/{slug}/models",
|
||||
async (ListingService service, string slug, CancellationToken cancellationToken) =>
|
||||
{
|
||||
var result = await service.GetCategoryProducts(slug, cancellationToken);
|
||||
var status = result.Problem?.StatusCode ?? (result.IsSuccess
|
||||
? StatusCodes.Status200OK
|
||||
: StatusCodes.Status500InternalServerError);
|
||||
return Results.Json(result, statusCode: status);
|
||||
})
|
||||
.WithTags(nameof(Products));
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ListingService(IModuleClient moduleClient) : IProductListingService
|
||||
{
|
||||
public async Task<Result<ProductListingModel>> GetCategoryProducts(string categorySlug, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(categorySlug);
|
||||
|
||||
try
|
||||
{
|
||||
var response = await moduleClient.Product.GetCategoryModels(
|
||||
categorySlug.Trim(),
|
||||
page: null,
|
||||
pageSize: null,
|
||||
sort: null,
|
||||
direction: null,
|
||||
cancellationToken);
|
||||
|
||||
var listing = MapListing(response.Result);
|
||||
return Result<ProductListingModel>.Success(listing);
|
||||
}
|
||||
catch (ValidationException validationException)
|
||||
{
|
||||
var problem = ResultProblem.FromValidation(validationException);
|
||||
return Result<ProductListingModel>.Failure(problem);
|
||||
}
|
||||
catch (DomainException domainException)
|
||||
{
|
||||
var problem = ResultProblem.Unexpected(domainException.Message, domainException, HttpStatusCode.UnprocessableEntity);
|
||||
return Result<ProductListingModel>.Failure(problem);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var problem = ResultProblem.Unexpected("Failed to retrieve category products.", exception);
|
||||
return Result<ProductListingModel>.Failure(problem);
|
||||
}
|
||||
}
|
||||
|
||||
private static ProductListingModel MapListing(GetCategoryModels.CategoryProductsResponse payload)
|
||||
{
|
||||
var category = payload.Category;
|
||||
var categoryModel = new ProductCategoryModel
|
||||
{
|
||||
Id = category.Id,
|
||||
Name = category.Name,
|
||||
Slug = category.Slug,
|
||||
Description = category.Description,
|
||||
HeroImageUrl = category.HeroImageUrl,
|
||||
Icon = category.Icon
|
||||
};
|
||||
|
||||
var cards = payload.Products
|
||||
.Select(product => new ProductCardModel
|
||||
{
|
||||
Id = product.Id,
|
||||
Title = product.Name,
|
||||
Url = UrlBuilder.BrowseProduct(product.Slug),
|
||||
Slug = product.Slug,
|
||||
PrimaryImageUrl = product.PrimaryImageUrl,
|
||||
CategoryName = category.Name,
|
||||
CategoryUrl = UrlBuilder.BrowseCategory(category.Slug),
|
||||
FromPrice = product.FromPrice.HasValue
|
||||
? new MoneyModel
|
||||
{
|
||||
Amount = product.FromPrice.Value
|
||||
}
|
||||
: null,
|
||||
IsPriced = product.FromPrice.HasValue,
|
||||
OldPrice = null,
|
||||
IsOnSale = false,
|
||||
Rating = 0,
|
||||
ReviewCount = 0,
|
||||
Badges = new List<string>(),
|
||||
LastModifiedOn = product.LastModifiedOn
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return new ProductListingModel
|
||||
{
|
||||
Category = categoryModel,
|
||||
Products = cards,
|
||||
Total = payload.Total,
|
||||
Page = payload.Page,
|
||||
PageSize = payload.PageSize
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user