From 677959e3e6b83c0d006db6bfe719009b66034b4a Mon Sep 17 00:00:00 2001 From: Harkamal Randhawa Date: Tue, 14 Apr 2026 19:29:43 -0600 Subject: [PATCH] Fix backend issues --- .../com/petshop/backend/controller/RefundController.java | 4 ++-- .../com/petshop/backend/controller/SaleController.java | 2 +- .../backend/exception/GlobalExceptionHandler.java | 3 ++- .../petshop/backend/repository/ProductRepository.java | 4 ++++ .../java/com/petshop/backend/service/ProductService.java | 9 +++++++++ backend/src/main/resources/application.yml | 2 ++ 6 files changed, 20 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/com/petshop/backend/controller/RefundController.java b/backend/src/main/java/com/petshop/backend/controller/RefundController.java index 0001df1e..92fd22b3 100644 --- a/backend/src/main/java/com/petshop/backend/controller/RefundController.java +++ b/backend/src/main/java/com/petshop/backend/controller/RefundController.java @@ -30,7 +30,7 @@ public class RefundController { } @PostMapping - @PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')") + @PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF')") public ResponseEntity createRefund(@Valid @RequestBody RefundRequest request) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String role = authentication.getAuthorities().stream() @@ -85,7 +85,7 @@ public class RefundController { } @PutMapping("/{id}") - @PreAuthorize("hasAnyRole('STAFF', 'ADMIN')") + @PreAuthorize("hasRole('STAFF')") public ResponseEntity updateRefund(@PathVariable Long id, @Valid @RequestBody RefundUpdateRequest request) { return ResponseEntity.ok(refundService.updateRefundStatus(id, request.getStatus())); } diff --git a/backend/src/main/java/com/petshop/backend/controller/SaleController.java b/backend/src/main/java/com/petshop/backend/controller/SaleController.java index dffa63e4..cdb64c78 100644 --- a/backend/src/main/java/com/petshop/backend/controller/SaleController.java +++ b/backend/src/main/java/com/petshop/backend/controller/SaleController.java @@ -40,7 +40,7 @@ public class SaleController { } @PostMapping - @PreAuthorize("hasAnyRole('STAFF', 'ADMIN')") + @PreAuthorize("hasRole('STAFF')") public ResponseEntity createSale(@Valid @RequestBody SaleRequest request) { return ResponseEntity.status(HttpStatus.CREATED).body(saleService.createSale(request)); } diff --git a/backend/src/main/java/com/petshop/backend/exception/GlobalExceptionHandler.java b/backend/src/main/java/com/petshop/backend/exception/GlobalExceptionHandler.java index 1f9434a5..7c2b475f 100644 --- a/backend/src/main/java/com/petshop/backend/exception/GlobalExceptionHandler.java +++ b/backend/src/main/java/com/petshop/backend/exception/GlobalExceptionHandler.java @@ -42,9 +42,10 @@ public class GlobalExceptionHandler { errors.put(fieldName, errorMessage); }); + String firstMessage = errors.values().stream().findFirst().orElse("Validation failed"); Map response = new HashMap<>(); response.put("status", HttpStatus.BAD_REQUEST.value()); - response.put("message", "Validation failed"); + response.put("message", firstMessage); response.put("errors", errors); response.put("details", buildDetails(ex)); response.put("path", request.getRequestURI()); diff --git a/backend/src/main/java/com/petshop/backend/repository/ProductRepository.java b/backend/src/main/java/com/petshop/backend/repository/ProductRepository.java index 7122e6ea..140031d0 100644 --- a/backend/src/main/java/com/petshop/backend/repository/ProductRepository.java +++ b/backend/src/main/java/com/petshop/backend/repository/ProductRepository.java @@ -11,6 +11,10 @@ import org.springframework.stereotype.Repository; @Repository public interface ProductRepository extends JpaRepository { + boolean existsByProdNameIgnoreCase(String prodName); + + boolean existsByProdNameIgnoreCaseAndProdIdNot(String prodName, Long prodId); + @Query("SELECT p FROM Product p WHERE " + "(:q IS NULL OR LOWER(p.prodName) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(COALESCE(p.prodDesc, '')) LIKE LOWER(CONCAT('%', :q, '%'))) AND " + "(:categoryId IS NULL OR p.category.categoryId = :categoryId)") diff --git a/backend/src/main/java/com/petshop/backend/service/ProductService.java b/backend/src/main/java/com/petshop/backend/service/ProductService.java index d18890d5..38f30e84 100644 --- a/backend/src/main/java/com/petshop/backend/service/ProductService.java +++ b/backend/src/main/java/com/petshop/backend/service/ProductService.java @@ -5,6 +5,7 @@ import com.petshop.backend.dto.product.ProductRequest; import com.petshop.backend.dto.product.ProductResponse; import com.petshop.backend.entity.Category; import com.petshop.backend.entity.Product; +import com.petshop.backend.exception.BusinessException; import com.petshop.backend.exception.ResourceNotFoundException; import com.petshop.backend.repository.CategoryRepository; import com.petshop.backend.repository.ProductRepository; @@ -45,6 +46,10 @@ public class ProductService { @Transactional public ProductResponse createProduct(ProductRequest request) { + if (productRepository.existsByProdNameIgnoreCase(request.getProdName())) { + throw new BusinessException("A product with this name already exists"); + } + Category category = categoryRepository.findById(request.getCategoryId()) .orElseThrow(() -> new ResourceNotFoundException("Category not found with id: " + request.getCategoryId())); @@ -63,6 +68,10 @@ public class ProductService { Product product = productRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("Product not found with id: " + id)); + if (productRepository.existsByProdNameIgnoreCaseAndProdIdNot(request.getProdName(), id)) { + throw new BusinessException("A product with this name already exists"); + } + Category category = categoryRepository.findById(request.getCategoryId()) .orElseThrow(() -> new ResourceNotFoundException("Category not found with id: " + request.getCategoryId())); diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 4f424b93..f65764c0 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -68,6 +68,8 @@ openrouter: model: ${OPENROUTER_MODEL:openrouter/free} logging: + file: + name: ${LOG_FILE:log.txt} level: com.petshop: ${LOG_LEVEL:INFO} org.springframework.security: ${LOG_LEVEL_SECURITY:WARN}