using CMSMicroservice.Protobuf.Protos.BlogCategory; using CMSMicroservice.WebApi.Common.Services; using CMSMicroservice.Application.BlogCategoryCQ.Commands.CreateBlogCategory; using CMSMicroservice.Application.BlogCategoryCQ.Commands.UpdateBlogCategory; using CMSMicroservice.Application.BlogCategoryCQ.Commands.DeleteBlogCategory; using CMSMicroservice.Application.BlogCategoryCQ.Queries.GetBlogCategory; using CMSMicroservice.Application.BlogCategoryCQ.Queries.GetAllBlogCategories; using CMSMicroservice.Application.BlogCategoryCQ.Queries.GetActiveBlogCategories; using Google.Protobuf.WellKnownTypes; using Grpc.Core; using Mapster; using MediatR; using AppModels = CMSMicroservice.Application.Common.Models; using ProtoMetaData = CMSMicroservice.Protobuf.Protos.MetaData; namespace CMSMicroservice.WebApi.Services; public class BlogCategoryService : BlogCategoryContract.BlogCategoryContractBase { private readonly ISender _sender; private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS; public BlogCategoryService(ISender sender, IDispatchRequestToCQRS dispatchRequestToCQRS) { _sender = sender; _dispatchRequestToCQRS = dispatchRequestToCQRS; } public override async Task CreateBlogCategory(CreateBlogCategoryRequest request, ServerCallContext context) { return await _dispatchRequestToCQRS.Handle(request, context); } public override async Task UpdateBlogCategory(UpdateBlogCategoryRequest request, ServerCallContext context) { return await _dispatchRequestToCQRS.Handle(request, context); } public override async Task DeleteBlogCategory(DeleteBlogCategoryRequest request, ServerCallContext context) { return await _dispatchRequestToCQRS.Handle(request, context); } public override async Task GetBlogCategory(GetBlogCategoryRequest request, ServerCallContext context) { var query = new GetBlogCategoryQuery { Id = request.Id }; var result = await _sender.Send(query, context.CancellationToken); return MapCategoryToResponse(result); } public override async Task GetAllBlogCategories(GetAllBlogCategoriesRequest request, ServerCallContext context) { var query = new GetAllBlogCategoriesQuery { PageNumber = request.PaginationState?.PageNumber ?? 1, PageSize = request.PaginationState?.PageSize ?? 20, SearchTerm = request.SortBy }; var result = await _sender.Send(query, context.CancellationToken); var response = new GetAllBlogCategoriesResponse { MetaData = result.MetaData.Adapt() }; foreach (var item in result.Models) response.Models.Add(MapToListItem(item)); return response; } public override async Task GetActiveBlogCategories(GetActiveBlogCategoriesRequest request, ServerCallContext context) { var query = new GetActiveBlogCategoriesQuery(); var result = await _sender.Send(query, context.CancellationToken); var response = new GetActiveBlogCategoriesResponse(); foreach (var item in result) response.Categories.Add(MapToListItem(item)); return response; } // ── Private Mapping Helpers ── private static GetBlogCategoryResponse MapCategoryToResponse(BlogCategoryDto dto) { return new GetBlogCategoryResponse { Id = dto.Id, Title = dto.Title ?? string.Empty, Slug = dto.Slug ?? string.Empty, Description = dto.Description, IconName = dto.IconName, SortOrder = dto.SortOrder, IsActive = dto.IsActive, PostCount = dto.PostCount, Created = dto.Created != default ? Timestamp.FromDateTime(DateTime.SpecifyKind(dto.Created, DateTimeKind.Utc)) : null }; } private static BlogCategoryListItem MapToListItem(BlogCategoryDto dto) { return new BlogCategoryListItem { Id = dto.Id, Title = dto.Title ?? string.Empty, Slug = dto.Slug ?? string.Empty, Description = dto.Description, IconName = dto.IconName, SortOrder = dto.SortOrder, IsActive = dto.IsActive, PostCount = dto.PostCount }; } }