Skip to content

feat: Implement product catalog features with batch update capabilities#26

Merged
zribktad merged 1 commit intomainfrom
feature/productcatalog-vsa-refactor
Apr 3, 2026
Merged

feat: Implement product catalog features with batch update capabilities#26
zribktad merged 1 commit intomainfrom
feature/productcatalog-vsa-refactor

Conversation

@zribktad
Copy link
Copy Markdown
Owner

@zribktad zribktad commented Apr 3, 2026

  • Add ProductDataResponse and its subtypes for polymorphic product data representation.
  • Introduce ProductMappings for EF Core projections from Product entities to ProductResponse DTOs.
  • Create ProductPriceFacetBucketResponse and ProductPriceFacetSpecification for price facet handling.
  • Establish ProductRequestValidatorBase for shared validation rules across product requests.
  • Define ProductResponse and ProductSearchFacetsResponse for API responses.
  • Implement ProductSortFields for sorting product queries.
  • Develop ProductValidationHelper for validating product references in batch operations.
  • Create specifications for loading products and categories with tenant context for soft deletes.
  • Implement TenantCascadeDeleteHandler for cascading soft deletes on tenant deletion.
  • Add UpdateCategories and UpdateProducts features with batch processing and validation.
  • Introduce controllers for handling update requests for categories and products.
  • Define request and response models for updating categories and products.
  • Implement validators for ensuring data integrity during updates.
  • Add IProductRepository interface for product-specific repository operations.

- Add ProductDataResponse and its subtypes for polymorphic product data representation.
- Introduce ProductMappings for EF Core projections from Product entities to ProductResponse DTOs.
- Create ProductPriceFacetBucketResponse and ProductPriceFacetSpecification for price facet handling.
- Establish ProductRequestValidatorBase for shared validation rules across product requests.
- Define ProductResponse and ProductSearchFacetsResponse for API responses.
- Implement ProductSortFields for sorting product queries.
- Develop ProductValidationHelper for validating product references in batch operations.
- Create specifications for loading products and categories with tenant context for soft deletes.
- Implement TenantCascadeDeleteHandler for cascading soft deletes on tenant deletion.
- Add UpdateCategories and UpdateProducts features with batch processing and validation.
- Introduce controllers for handling update requests for categories and products.
- Define request and response models for updating categories and products.
- Implement validators for ensuring data integrity during updates.
- Add IProductRepository interface for product-specific repository operations.
Copilot AI review requested due to automatic review settings April 3, 2026 21:24
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request performs a significant refactoring of the ProductCatalog module, transitioning from a controller-based organization to a feature-sliced architecture. Key changes include splitting monolithic controllers into feature-specific ones (e.g., CreateCategories, GetProducts), reorganizing DTOs, validators, and commands into corresponding feature folders, and updating namespaces to reflect this new structure. Additionally, a GlobalUsings file was introduced to streamline imports, and the module registration was updated to support the decentralized controller and validator setup. I have no feedback to provide as there are no review comments.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements and reorganizes ProductCatalog functionality into feature-focused endpoints and shared DTO/specification infrastructure, including batch create/update/delete operations and tenant soft-delete cascading.

Changes:

  • Split ProductCatalog HTTP endpoints into per-feature controllers/commands (get/create/update/delete for products, categories, product-data, plus examples like idempotent create and patch).
  • Introduce/relocate shared DTOs, mappings, facet specs, sort fields, and validation helpers under Features/Shared, and migrate repository contracts to ProductCatalog.Interfaces.
  • Consolidate ProductCatalog global usings into a single src/Modules/ProductCatalog/GlobalUsings.cs and move Errors/CacheTags under ProductCatalog.Common.*.

Reviewed changes

Copilot reviewed 120 out of 120 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
tests/APITemplate.Tests/Unit/Validators/UpdateProductRequestValidatorTests.cs Update validator test imports to new UpdateProducts feature namespace.
tests/APITemplate.Tests/Unit/Validators/CreateProductRequestValidatorTests.cs Update validator test imports to new CreateProducts feature namespace.
tests/APITemplate.Tests/Unit/ProductCatalog/ProductCatalogModuleTests.cs Update imports to new feature namespaces for batch rule registration tests.
tests/APITemplate.Tests/Unit/ProductCatalog/PatchProductCommandHandlerTests.cs Update imports to new namespaces (Common.Events, Interfaces, Features.Shared).
tests/APITemplate.Tests/Integration/Features/IdempotentControllerTests.cs Update imports to new IdempotentCreate feature namespace.
src/Modules/ProductCatalog/ValueObjects/Price.cs Update error namespace to ProductCatalog.Common.Errors.
src/Modules/ProductCatalog/Repositories/ProductRepository.cs Update repository contract alias and add GetProducts types usage.
src/Modules/ProductCatalog/ProductCatalogModule.cs Update validator assembly scanning marker, controller application part, and repository contract alias.
src/Modules/ProductCatalog/ProductCatalog.Infrastructure.GlobalUsings.cs Remove old infra global usings file (consolidation).
src/Modules/ProductCatalog/ProductCatalog.Domain.GlobalUsings.cs Remove old domain global usings file (consolidation).
src/Modules/ProductCatalog/ProductCatalog.Application.GlobalUsings.cs Remove old application global usings file (consolidation).
src/Modules/ProductCatalog/ProductCatalog.Api.GlobalUsings.cs Remove old API global usings file (consolidation).
src/Modules/ProductCatalog/Interfaces/IProductRepository.cs Move repository contract to ProductCatalog.Interfaces and update dependencies.
src/Modules/ProductCatalog/GraphQL/Queries/ProductQueries.cs Update query dependencies to new GetProductById/GetProducts features.
src/Modules/ProductCatalog/GraphQL/Queries/CategoryQueries.cs Update query dependencies to new GetCategoryById/GetCategories features.
src/Modules/ProductCatalog/GraphQL/Mutations/ProductMutations.cs Update mutation dependencies to new CreateProducts/DeleteProducts features.
src/Modules/ProductCatalog/GlobalUsings.cs Add consolidated module-wide global usings.
src/Modules/ProductCatalog/Features/ValidateProductExists/ValidateProductExistsQueryHandler.cs Move handler to ValidateProductExists feature and update repository injection type.
src/Modules/ProductCatalog/Features/UpdateProducts/UpdateProductsRequest.cs Move DTOs to UpdateProducts feature namespace.
src/Modules/ProductCatalog/Features/UpdateProducts/UpdateProductsController.cs New controller for batch product update.
src/Modules/ProductCatalog/Features/UpdateProducts/UpdateProductsCommand.cs Move batch update command/handler into UpdateProducts feature and update repository contract alias.
src/Modules/ProductCatalog/Features/UpdateProducts/UpdateProductRequestValidator.cs Move validator to UpdateProducts feature namespace.
src/Modules/ProductCatalog/Features/UpdateProducts/UpdateProductRequest.cs Move DTO to UpdateProducts feature namespace.
src/Modules/ProductCatalog/Features/UpdateProducts/UpdateProductItemValidator.cs Move validator to UpdateProducts feature namespace.
src/Modules/ProductCatalog/Features/UpdateCategories/UpdateCategoryRequest.cs Move DTO to UpdateCategories feature namespace.
src/Modules/ProductCatalog/Features/UpdateCategories/UpdateCategoryItemValidator.cs Move validator to UpdateCategories feature namespace.
src/Modules/ProductCatalog/Features/UpdateCategories/UpdateCategoriesRequest.cs Move batch DTO to UpdateCategories feature namespace.
src/Modules/ProductCatalog/Features/UpdateCategories/UpdateCategoriesController.cs New controller for batch category update.
src/Modules/ProductCatalog/Features/UpdateCategories/UpdateCategoriesCommand.cs Move batch update command/handler into UpdateCategories feature namespace.
src/Modules/ProductCatalog/Features/TenantCascadeDelete/TenantCascadeDeleteHandler.cs Move tenant cascade delete handler to TenantCascadeDelete feature namespace.
src/Modules/ProductCatalog/Features/TenantCascadeDelete/ProductsForTenantSoftDeleteSpecification.cs Move tenant soft-delete spec to TenantCascadeDelete feature namespace.
src/Modules/ProductCatalog/Features/TenantCascadeDelete/CategoriesForTenantSoftDeleteSpecification.cs Move tenant soft-delete spec to TenantCascadeDelete feature namespace.
src/Modules/ProductCatalog/Features/Shared/ProductValidationHelper.cs Move helper to Features.Shared and update spec usage.
src/Modules/ProductCatalog/Features/Shared/ProductsResponse.cs Move response DTO to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/ProductSortFields.cs Move sort field map to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/ProductSearchFacetsResponse.cs Move facets DTO to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/ProductsByIdsWithLinksSpecification.cs Move spec to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/ProductResponse.cs Move product response DTO to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/ProductRequestValidatorBase.cs Move shared validator base to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/ProductPriceFacetSpecification.cs Move facet spec to Features.Shared and update filter type dependency.
src/Modules/ProductCatalog/Features/Shared/ProductPriceFacetBucketResponse.cs Move bucket DTO to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/ProductMappings.cs Move EF Core projection/mapping helpers to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/ProductDataResponse.cs Move polymorphic product-data response DTOs to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/ProductDataMappings.cs Move product-data mapping helpers to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/ProductCategoryFacetValue.cs Move category facet DTO to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/ProductCategoryFacetSpecification.cs Move facet spec to Features.Shared and update filter type dependency.
src/Modules/ProductCatalog/Features/Shared/IProductRequest.cs Move shared product request contract to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/CategorySortFields.cs Move category sort fields to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/CategoryResponse.cs Move category response DTO to Features.Shared.
src/Modules/ProductCatalog/Features/Shared/CategoryMappings.cs Move category mapping helpers to Features.Shared (remove stats mapping).
src/Modules/ProductCatalog/Features/Shared/CategoriesByIdsSpecification.cs Move spec to Features.Shared.
src/Modules/ProductCatalog/Features/PatchProduct/PatchProductController.cs Move/rename patch controller under PatchProduct feature.
src/Modules/ProductCatalog/Features/PatchProduct/PatchProductCommand.cs Move patch command/handler under PatchProduct feature and update repository contract alias.
src/Modules/ProductCatalog/Features/PatchProduct/PatchableProductDtoValidator.cs Move patch DTO validator under PatchProduct feature.
src/Modules/ProductCatalog/Features/PatchProduct/PatchableProductDto.cs Move patch DTO under PatchProduct feature.
src/Modules/ProductCatalog/Features/IdempotentCreate/IdempotentCreateResponse.cs Move idempotent DTO under IdempotentCreate feature.
src/Modules/ProductCatalog/Features/IdempotentCreate/IdempotentCreateRequestValidator.cs Move idempotent validator under IdempotentCreate feature.
src/Modules/ProductCatalog/Features/IdempotentCreate/IdempotentCreateRequest.cs Move idempotent request under IdempotentCreate feature.
src/Modules/ProductCatalog/Features/IdempotentCreate/IdempotentCreateController.cs Move/rename idempotent controller under IdempotentCreate feature.
src/Modules/ProductCatalog/Features/IdempotentCreate/IdempotentCreateCommand.cs Move idempotent command/handler under IdempotentCreate feature and update repository alias.
src/Modules/ProductCatalog/Features/GetProducts/ProductSpecification.cs Move product query spec under GetProducts feature.
src/Modules/ProductCatalog/Features/GetProducts/ProductFilterValidator.cs Move filter validator under GetProducts feature.
src/Modules/ProductCatalog/Features/GetProducts/ProductFilterCriteria.cs Move filter criteria helper under GetProducts feature.
src/Modules/ProductCatalog/Features/GetProducts/ProductFilter.cs Move filter DTO under GetProducts feature.
src/Modules/ProductCatalog/Features/GetProducts/GetProductsQuery.cs Move query under GetProducts feature and update repository contract alias.
src/Modules/ProductCatalog/Features/GetProducts/GetProductsController.cs New controller for product list + facets.
src/Modules/ProductCatalog/Features/GetProductDataById/GetProductDataByIdQuery.cs Move query under GetProductDataById feature.
src/Modules/ProductCatalog/Features/GetProductDataById/GetProductDataByIdController.cs New controller for product-data get-by-id.
src/Modules/ProductCatalog/Features/GetProductData/GetProductDataQuery.cs Move query under GetProductData feature.
src/Modules/ProductCatalog/Features/GetProductData/GetProductDataController.cs New controller for product-data listing.
src/Modules/ProductCatalog/Features/GetProductById/ProductByIdWithLinksSpecification.cs Move spec under GetProductById feature.
src/Modules/ProductCatalog/Features/GetProductById/ProductByIdSpecification.cs Move spec under GetProductById feature.
src/Modules/ProductCatalog/Features/GetProductById/GetProductByIdQuery.cs Move query under GetProductById feature and update repository alias.
src/Modules/ProductCatalog/Features/GetProductById/GetProductByIdController.cs New controller for product get-by-id.
src/Modules/ProductCatalog/Features/GetCategoryStats/ProductCategoryStatsResponse.cs Move stats response DTO under GetCategoryStats feature.
src/Modules/ProductCatalog/Features/GetCategoryStats/GetCategoryStatsQuery.cs Move stats query under GetCategoryStats feature and inline mapping.
src/Modules/ProductCatalog/Features/GetCategoryStats/GetCategoryStatsController.cs New controller for category stats.
src/Modules/ProductCatalog/Features/GetCategoryById/GetCategoryByIdQuery.cs Move query under GetCategoryById feature.
src/Modules/ProductCatalog/Features/GetCategoryById/GetCategoryByIdController.cs New controller for category get-by-id.
src/Modules/ProductCatalog/Features/GetCategoryById/CategoryByIdSpecification.cs Move spec under GetCategoryById feature.
src/Modules/ProductCatalog/Features/GetCategories/GetCategoriesQuery.cs Move query under GetCategories feature.
src/Modules/ProductCatalog/Features/GetCategories/GetCategoriesController.cs New controller for category listing.
src/Modules/ProductCatalog/Features/GetCategories/CategorySpecification.cs Move spec under GetCategories feature.
src/Modules/ProductCatalog/Features/GetCategories/CategoryFilterValidator.cs Move filter validator under GetCategories feature.
src/Modules/ProductCatalog/Features/GetCategories/CategoryFilterCriteria.cs Move criteria helper under GetCategories feature.
src/Modules/ProductCatalog/Features/GetCategories/CategoryFilter.cs Move filter DTO under GetCategories feature.
src/Modules/ProductCatalog/Features/DeleteProducts/DeleteProductsController.cs New controller for batch product delete.
src/Modules/ProductCatalog/Features/DeleteProducts/DeleteProductsCommand.cs Move delete command/handler under DeleteProducts feature and update repository alias.
src/Modules/ProductCatalog/Features/DeleteProductData/ProductDataCascadeDeleteHandler.cs Move handler under DeleteProductData feature namespace.
src/Modules/ProductCatalog/Features/DeleteProductData/DeleteProductDataController.cs New controller for product-data delete.
src/Modules/ProductCatalog/Features/DeleteProductData/DeleteProductDataCommand.cs Move command/handler under DeleteProductData feature namespace.
src/Modules/ProductCatalog/Features/DeleteCategories/DeleteCategoriesController.cs New controller for batch category delete.
src/Modules/ProductCatalog/Features/DeleteCategories/DeleteCategoriesCommand.cs Move delete command/handler under DeleteCategories feature namespace.
src/Modules/ProductCatalog/Features/CreateVideoProductData/CreateVideoProductDataRequestValidator.cs Move validator under CreateVideoProductData feature namespace.
src/Modules/ProductCatalog/Features/CreateVideoProductData/CreateVideoProductDataRequest.cs Move request under CreateVideoProductData feature namespace.
src/Modules/ProductCatalog/Features/CreateVideoProductData/CreateVideoProductDataController.cs New controller for creating video product-data.
src/Modules/ProductCatalog/Features/CreateVideoProductData/CreateVideoProductDataCommand.cs Move command/handler under CreateVideoProductData feature namespace.
src/Modules/ProductCatalog/Features/CreateProducts/CreateProductsRequest.cs Move batch create request under CreateProducts feature namespace.
src/Modules/ProductCatalog/Features/CreateProducts/CreateProductsController.cs New controller for batch product create.
src/Modules/ProductCatalog/Features/CreateProducts/CreateProductsCommand.cs Move create command/handler under CreateProducts feature and update repository alias.
src/Modules/ProductCatalog/Features/CreateProducts/CreateProductRequestValidator.cs Move validator under CreateProducts feature namespace.
src/Modules/ProductCatalog/Features/CreateProducts/CreateProductRequest.cs Move request under CreateProducts feature namespace.
src/Modules/ProductCatalog/Features/CreateImageProductData/CreateImageProductDataRequestValidator.cs Move validator under CreateImageProductData feature namespace.
src/Modules/ProductCatalog/Features/CreateImageProductData/CreateImageProductDataRequest.cs Move request under CreateImageProductData feature namespace.
src/Modules/ProductCatalog/Features/CreateImageProductData/CreateImageProductDataController.cs New controller for creating image product-data.
src/Modules/ProductCatalog/Features/CreateImageProductData/CreateImageProductDataCommand.cs Move command/handler under CreateImageProductData feature namespace.
src/Modules/ProductCatalog/Features/CreateCategories/CreateCategoryRequestValidator.cs Move validator under CreateCategories feature namespace.
src/Modules/ProductCatalog/Features/CreateCategories/CreateCategoryRequest.cs Move request under CreateCategories feature namespace.
src/Modules/ProductCatalog/Features/CreateCategories/CreateCategoriesRequest.cs Move batch create request under CreateCategories feature namespace.
src/Modules/ProductCatalog/Features/CreateCategories/CreateCategoriesController.cs New controller for batch category create.
src/Modules/ProductCatalog/Features/CreateCategories/CreateCategoriesCommand.cs Move command/handler under CreateCategories feature namespace.
src/Modules/ProductCatalog/Controllers/V1/ProductsController.cs Remove old combined products controller (replaced by feature controllers).
src/Modules/ProductCatalog/Controllers/V1/ProductDataController.cs Remove old combined product-data controller (replaced by feature controllers).
src/Modules/ProductCatalog/Controllers/V1/CategoriesController.cs Remove old combined categories controller (replaced by feature controllers).
src/Modules/ProductCatalog/Common/Events/CacheTags.cs Move cache tags to ProductCatalog.Common.Events.
src/Modules/ProductCatalog/Common/Errors/ProductCatalogDomainErrors.cs Move domain errors to ProductCatalog.Common.Errors.
src/Modules/ProductCatalog/Common/Errors/ErrorCatalog.cs Move error catalog to ProductCatalog.Common.Errors.
src/Modules/ProductCatalog/Common/Errors/DomainErrors.cs Move domain errors to ProductCatalog.Common.Errors.
src/APITemplate/Api/Program.cs Update Wolverine discovery to include new ProductCatalog feature assembly anchor type.
src/APITemplate/Api/Extensions/ApiServiceCollectionExtensions.cs Update cache tag alias namespace to ProductCatalog.Common.Events.
Comments suppressed due to low confidence (4)

src/Modules/ProductCatalog/Features/IdempotentCreate/IdempotentCreateController.cs:22

  • This controller currently routes as POST /api/v1/IdempotentCreate (ApiControllerBase uses [controller]), but integration tests and existing API calls use POST /api/v1/idempotent. Add an explicit [Route("api/v{version:apiVersion}/idempotent")] to preserve the endpoint.
    src/Modules/ProductCatalog/Features/IdempotentCreate/IdempotentCreateController.cs:33
  • The action returns Ok(...) (HTTP 200), but integration tests expect 201 Created for the first idempotent request, and the XML docs describe create semantics. Return a 201 response (ideally with a Location header) so the idempotency filter can cache the correct status code.
    src/Modules/ProductCatalog/Features/PatchProduct/PatchProductController.cs:16
  • Without a controller-level [Route], this endpoint becomes /api/v1/PatchProduct/products/{id} (ApiControllerBase uses [controller]). Integration tests call /api/v1/patch/products/{id}. Add [Route("api/v{version:apiVersion}/patch")] (or adjust the action route) to match the expected URL.
    src/Modules/ProductCatalog/Features/PatchProduct/PatchProductController.cs:16
  • This endpoint patches products but is protected by Permission.Examples.Update. That grants access based on the examples permission set rather than product update permissions, which is likely incorrect for a product write operation. Consider switching to Permission.Products.Update to align authorization with the resource being modified.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +11 to +16
[ApiVersion(1.0)]
public sealed class GetProductsController(IMessageBus bus) : ApiControllerBase
{
/// <summary>Returns a filtered, paginated product list including search facets.</summary>
[HttpGet]
[RequirePermission(Permission.Products.Read)]
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ApiControllerBase uses route template api/v{version:apiVersion}/[controller]. With this controller name, the endpoint becomes /api/v1/GetProducts instead of the existing /api/v1/products used throughout integration tests and likely by clients. Add an explicit [Route("api/v{version:apiVersion}/products")] (or similar resource route) to preserve the public API path.

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +18
[ApiVersion(1.0)]
public sealed class GetProductByIdController(IMessageBus bus) : ApiControllerBase
{
/// <summary>Returns a single product by its identifier, or 404 if not found.</summary>
[HttpGet("{id:guid}")]
[RequirePermission(Permission.Products.Read)]
[OutputCache(PolicyName = CacheTags.Products)]
public async Task<ActionResult<ProductResponse>> GetById(Guid id, CancellationToken ct)
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ApiControllerBase routes by [controller], so this controller will map to /api/v1/GetProductById rather than /api/v1/products/{id}. Add an explicit controller-level route like [Route("api/v{version:apiVersion}/products")] so [HttpGet("{id:guid}")] matches the established endpoint shape.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +16
[ApiVersion(1.0)]
public sealed class CreateProductsController(IMessageBus bus) : ApiControllerBase
{
/// <summary>Creates multiple products in a single batch operation.</summary>
[HttpPost]
[RequirePermission(Permission.Products.Create)]
public async Task<ActionResult<BatchResponse>> Create(
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without an explicit [Route], this will be POST /api/v1/CreateProducts due to ApiControllerBase’s [controller] route. Existing API/tests use POST /api/v1/products. Add [Route("api/v{version:apiVersion}/products")] (same as the other product controllers) to avoid breaking the public API.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +16
[ApiVersion(1.0)]
public sealed class UpdateProductsController(IMessageBus bus) : ApiControllerBase
{
/// <summary>Updates multiple products in a single batch operation.</summary>
[HttpPut]
[RequirePermission(Permission.Products.Update)]
public async Task<ActionResult<BatchResponse>> Update(
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With ApiControllerBase’s [controller] route template, this endpoint becomes PUT /api/v1/UpdateProducts instead of PUT /api/v1/products. Add a controller-level [Route("api/v{version:apiVersion}/products")] to preserve the existing REST route.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +16
[ApiVersion(1.0)]
public sealed class DeleteProductsController(IMessageBus bus) : ApiControllerBase
{
/// <summary>Soft-deletes multiple products in a single batch operation.</summary>
[HttpDelete]
[RequirePermission(Permission.Products.Delete)]
public async Task<ActionResult<BatchResponse>> Delete(
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without an explicit controller route, this will be DELETE /api/v1/DeleteProducts rather than DELETE /api/v1/products (ApiControllerBase routes by [controller]). Add [Route("api/v{version:apiVersion}/products")] to avoid breaking clients/tests.

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +18
[ApiVersion(1.0)]
public sealed class GetCategoryByIdController(IMessageBus bus) : ApiControllerBase
{
/// <summary>Returns a single category by its identifier, or 404 if not found.</summary>
[HttpGet("{id:guid}")]
[RequirePermission(Permission.Categories.Read)]
[OutputCache(PolicyName = CacheTags.Categories)]
public async Task<ActionResult<CategoryResponse>> GetById(Guid id, CancellationToken ct)
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will route as /api/v1/GetCategoryById/{id} (ApiControllerBase uses [controller]) instead of /api/v1/categories/{id}. Add [Route("api/v{version:apiVersion}/categories")] so [HttpGet("{id:guid}")] matches the existing endpoint.

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +21
[ApiVersion(1.0)]
public sealed class GetCategoryStatsController(IMessageBus bus) : ApiControllerBase
{
/// <summary>
/// Returns aggregated statistics for a category by calling the
/// <c>get_product_category_stats(p_category_id)</c> stored procedure via EF Core FromSql.
/// </summary>
[HttpGet("{id:guid}/stats")]
[RequirePermission(Permission.Categories.Read)]
[OutputCache(PolicyName = CacheTags.Categories)]
public async Task<ActionResult<ProductCategoryStatsResponse>> GetStats(
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without a controller-level [Route], this maps to /api/v1/GetCategoryStats/{id}/stats instead of /api/v1/categories/{id}/stats used by tests/clients. Add [Route("api/v{version:apiVersion}/categories")] to preserve the existing REST route shape.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +16
[ApiVersion(1.0)]
public sealed class CreateCategoriesController(IMessageBus bus) : ApiControllerBase
{
/// <summary>Creates multiple categories in a single batch operation.</summary>
[HttpPost]
[RequirePermission(Permission.Categories.Create)]
public async Task<ActionResult<BatchResponse>> Create(
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ApiControllerBase routes by [controller], so this becomes POST /api/v1/CreateCategories rather than POST /api/v1/categories. Add [Route("api/v{version:apiVersion}/categories")] to preserve the established API path.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +16
[ApiVersion(1.0)]
public sealed class UpdateCategoriesController(IMessageBus bus) : ApiControllerBase
{
/// <summary>Updates multiple categories in a single batch operation.</summary>
[HttpPut]
[RequirePermission(Permission.Categories.Update)]
public async Task<ActionResult<BatchResponse>> Update(
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With ApiControllerBase’s [controller] route, this becomes PUT /api/v1/UpdateCategories instead of PUT /api/v1/categories. Add [Route("api/v{version:apiVersion}/categories")] to avoid a breaking route change.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +16
[ApiVersion(1.0)]
public sealed class DeleteCategoriesController(IMessageBus bus) : ApiControllerBase
{
/// <summary>Soft-deletes multiple categories in a single batch operation.</summary>
[HttpDelete]
[RequirePermission(Permission.Categories.Delete)]
public async Task<ActionResult<BatchResponse>> Delete(
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without an explicit route, this maps to DELETE /api/v1/DeleteCategories rather than DELETE /api/v1/categories due to ApiControllerBase’s [controller] routing. Add [Route("api/v{version:apiVersion}/categories")] to preserve the existing API endpoint.

Copilot uses AI. Check for mistakes.
@zribktad zribktad merged commit 2fbaf15 into main Apr 3, 2026
5 checks passed
@zribktad zribktad deleted the feature/productcatalog-vsa-refactor branch April 3, 2026 21:53
@zribktad zribktad restored the feature/productcatalog-vsa-refactor branch April 3, 2026 21:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants