diff --git a/src/main/java/group/goforward/battlbuilder/controllers/MerchantCategoryMappingController.java b/src/main/java/group/goforward/battlbuilder/controllers/MerchantCategoryMappingController.java deleted file mode 100644 index 20fc6f6..0000000 --- a/src/main/java/group/goforward/battlbuilder/controllers/MerchantCategoryMappingController.java +++ /dev/null @@ -1,65 +0,0 @@ -package group.goforward.battlbuilder.controllers; - -import group.goforward.battlbuilder.model.Merchant; -import group.goforward.battlbuilder.model.MerchantCategoryMapping; -import group.goforward.battlbuilder.repos.MerchantRepository; -import group.goforward.battlbuilder.services.MerchantCategoryMappingService; -import group.goforward.battlbuilder.web.dto.MerchantCategoryMappingDto; -import group.goforward.battlbuilder.web.dto.UpsertMerchantCategoryMappingRequest; -import java.util.List; -import java.util.stream.Collectors; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequestMapping("/api/admin/merchant-category-mappings") -@CrossOrigin -public class MerchantCategoryMappingController { - - private final MerchantCategoryMappingService mappingService; - private final MerchantRepository merchantRepository; - - public MerchantCategoryMappingController( - MerchantCategoryMappingService mappingService, - MerchantRepository merchantRepository - ) { - this.mappingService = mappingService; - this.merchantRepository = merchantRepository; - } - - @GetMapping - public List listMappings( - @RequestParam("merchantId") Integer merchantId - ) { - List mappings = mappingService.findByMerchant(merchantId); - return mappings.stream() - .map(this::toDto) - .collect(Collectors.toList()); - } - - @PostMapping - public MerchantCategoryMappingDto upsertMapping( - @RequestBody UpsertMerchantCategoryMappingRequest request - ) { - Merchant merchant = merchantRepository - .findById(request.getMerchantId()) - .orElseThrow(() -> new IllegalArgumentException("Merchant not found: " + request.getMerchantId())); - - MerchantCategoryMapping mapping = mappingService.upsertMapping( - merchant, - request.getRawCategory(), - request.getMappedPartRole() - ); - - return toDto(mapping); - } - - private MerchantCategoryMappingDto toDto(MerchantCategoryMapping mapping) { - MerchantCategoryMappingDto dto = new MerchantCategoryMappingDto(); - dto.setId(mapping.getId()); - dto.setMerchantId(mapping.getMerchant().getId()); - dto.setMerchantName(mapping.getMerchant().getName()); - dto.setRawCategory(mapping.getRawCategory()); - dto.setMappedPartRole(mapping.getMappedPartRole()); - return dto; - } -} \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminCategoryMappingController.java b/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminCategoryMappingController.java deleted file mode 100644 index 4e335ea..0000000 --- a/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminCategoryMappingController.java +++ /dev/null @@ -1,104 +0,0 @@ -package group.goforward.battlbuilder.controllers.admin; - -import group.goforward.battlbuilder.model.CategoryMapping; -import group.goforward.battlbuilder.model.Merchant; -import group.goforward.battlbuilder.model.PartCategory; -import group.goforward.battlbuilder.repos.CategoryMappingRepository; -import group.goforward.battlbuilder.repos.PartCategoryRepository; -import group.goforward.battlbuilder.web.dto.admin.MerchantCategoryMappingDto; -import group.goforward.battlbuilder.web.dto.admin.SimpleMerchantDto; -import group.goforward.battlbuilder.web.dto.admin.UpdateMerchantCategoryMappingRequest; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.server.ResponseStatusException; - -import java.util.List; - -@RestController -@RequestMapping("/api/admin/category-mappings") -@CrossOrigin // tighten later -public class AdminCategoryMappingController { - - private final CategoryMappingRepository categoryMappingRepository; - private final PartCategoryRepository partCategoryRepository; - - public AdminCategoryMappingController( - CategoryMappingRepository categoryMappingRepository, - PartCategoryRepository partCategoryRepository - ) { - this.categoryMappingRepository = categoryMappingRepository; - this.partCategoryRepository = partCategoryRepository; - } - - /** - * Merchants that have at least one category_mappings row. - * Used for the "All Merchants" dropdown in the UI. - */ - @GetMapping("/merchants") - public List listMerchantsWithMappings() { - List merchants = categoryMappingRepository.findDistinctMerchantsWithMappings(); - return merchants.stream() - .map(m -> new SimpleMerchantDto(m.getId(), m.getName())) - .toList(); - } - - /** - * List mappings for a specific merchant, or all mappings if no merchantId is provided. - * GET /api/admin/category-mappings?merchantId=1 - */ - @GetMapping - public List listByMerchant( - @RequestParam(name = "merchantId", required = false) Integer merchantId - ) { - List mappings; - - if (merchantId != null) { - mappings = categoryMappingRepository.findByMerchantIdOrderByRawCategoryPathAsc(merchantId); - } else { - mappings = categoryMappingRepository.findAll(); - } - - return mappings.stream() - .map(cm -> new MerchantCategoryMappingDto( - cm.getId(), - cm.getMerchant().getId(), - cm.getMerchant().getName(), - cm.getRawCategoryPath(), - cm.getPartCategory() != null ? cm.getPartCategory().getId() : null, - cm.getPartCategory() != null ? cm.getPartCategory().getName() : null - )) - .toList(); - } - - /** - * Update a single mapping's part_category. - * PUT /api/admin/category-mappings/{id} - * Body: { "partCategoryId": 24 } - */ - @PutMapping("/{id}") - public MerchantCategoryMappingDto updateMapping( - @PathVariable Integer id, - @RequestBody UpdateMerchantCategoryMappingRequest request - ) { - CategoryMapping mapping = categoryMappingRepository.findById(id) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Mapping not found")); - - PartCategory partCategory = null; - if (request.partCategoryId() != null) { - partCategory = partCategoryRepository.findById(request.partCategoryId()) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST, "Part category not found")); - } - - mapping.setPartCategory(partCategory); - mapping = categoryMappingRepository.save(mapping); - - return new MerchantCategoryMappingDto( - mapping.getId(), - mapping.getMerchant().getId(), - mapping.getMerchant().getName(), - mapping.getRawCategoryPath(), - mapping.getPartCategory() != null ? mapping.getPartCategory().getId() : null, - mapping.getPartCategory() != null ? mapping.getPartCategory().getName() : null - ); - } -} \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminDashboardController.java b/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminDashboardController.java index b85ca3c..384add2 100644 --- a/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminDashboardController.java +++ b/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminDashboardController.java @@ -1,6 +1,6 @@ -package group.goforward.battlbuilder.web; +package group.goforward.battlbuilder.controllers.admin; -import group.goforward.battlbuilder.services.AdminDashboardService; +import group.goforward.battlbuilder.services.admin.impl.AdminDashboardService; import group.goforward.battlbuilder.web.dto.AdminDashboardOverviewDto; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; diff --git a/src/main/java/group/goforward/battlbuilder/model/MerchantCategoryMap.java b/src/main/java/group/goforward/battlbuilder/model/MerchantCategoryMap.java index fa6cc5d..60a82ba 100644 --- a/src/main/java/group/goforward/battlbuilder/model/MerchantCategoryMap.java +++ b/src/main/java/group/goforward/battlbuilder/model/MerchantCategoryMap.java @@ -18,7 +18,7 @@ import java.time.OffsetDateTime; */ @Entity -@Table(name = "merchant_category_mappings") +@Table(name = "merchant_category_map") public class MerchantCategoryMap { @Id @@ -36,11 +36,11 @@ public class MerchantCategoryMap { @Column(name = "raw_category", nullable = false, length = Integer.MAX_VALUE) private String rawCategory; - @Column(name = "mapped_part_role", length = Integer.MAX_VALUE) - private String mappedPartRole; + @Column(name = "part_role", length = 255) + private String partRole; - @Column(name = "mapped_configuration", length = Integer.MAX_VALUE) - private String mappedConfiguration; +// @Column(name = "mapped_configuration", length = Integer.MAX_VALUE) +// private String mappedConfiguration; @NotNull @Column(name = "created_at", nullable = false) @@ -62,11 +62,11 @@ public class MerchantCategoryMap { public String getRawCategory() { return rawCategory; } public void setRawCategory(String rawCategory) { this.rawCategory = rawCategory; } - public String getMappedPartRole() { return mappedPartRole; } - public void setMappedPartRole(String mappedPartRole) { this.mappedPartRole = mappedPartRole; } + public String getPartRole() { return partRole; } + public void setPartRole(String partRole) { this.partRole = partRole; } - public String getMappedConfiguration() { return mappedConfiguration; } - public void setMappedConfiguration(String mappedConfiguration) { this.mappedConfiguration = mappedConfiguration; } +// public String getMappedConfiguration() { return mappedConfiguration; } +// public void setMappedConfiguration(String mappedConfiguration) { this.mappedConfiguration = mappedConfiguration; } public OffsetDateTime getCreatedAt() { return createdAt; } public void setCreatedAt(OffsetDateTime createdAt) { this.createdAt = createdAt; } diff --git a/src/main/java/group/goforward/battlbuilder/model/MerchantCategoryMapping.java b/src/main/java/group/goforward/battlbuilder/model/MerchantCategoryMapping.java deleted file mode 100644 index 86d4b44..0000000 --- a/src/main/java/group/goforward/battlbuilder/model/MerchantCategoryMapping.java +++ /dev/null @@ -1,103 +0,0 @@ -package group.goforward.battlbuilder.model; - -import jakarta.persistence.*; -import java.time.OffsetDateTime; - -@Entity -@Table( - name = "merchant_category_mappings", - uniqueConstraints = @UniqueConstraint( - name = "uq_merchant_category", - columnNames = { "merchant_id", "raw_category" } - ) -) -public class MerchantCategoryMapping { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) // SERIAL - @Column(name = "id", nullable = false) - private Integer id; - - @ManyToOne(fetch = FetchType.LAZY, optional = false) - @JoinColumn(name = "merchant_id", nullable = false) - private Merchant merchant; - - @Column(name = "raw_category", nullable = false, length = 512) - private String rawCategory; - - @Column(name = "mapped_part_role", length = 128) - private String mappedPartRole; // e.g. "upper-receiver", "barrel" - - @Column(name = "mapped_configuration") - @Enumerated(EnumType.STRING) - private ProductConfiguration mappedConfiguration; - - @Column(name = "created_at", nullable = false) - private OffsetDateTime createdAt = OffsetDateTime.now(); - - @Column(name = "updated_at", nullable = false) - private OffsetDateTime updatedAt = OffsetDateTime.now(); - - @PreUpdate - public void onUpdate() { - this.updatedAt = OffsetDateTime.now(); - } - - // getters & setters - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public Merchant getMerchant() { - return merchant; - } - - public void setMerchant(Merchant merchant) { - this.merchant = merchant; - } - - public String getRawCategory() { - return rawCategory; - } - - public void setRawCategory(String rawCategory) { - this.rawCategory = rawCategory; - } - - public String getMappedPartRole() { - return mappedPartRole; - } - - public void setMappedPartRole(String mappedPartRole) { - this.mappedPartRole = mappedPartRole; - } - - public ProductConfiguration getMappedConfiguration() { - return mappedConfiguration; - } - - public void setMappedConfiguration(ProductConfiguration mappedConfiguration) { - this.mappedConfiguration = mappedConfiguration; - } - - public OffsetDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(OffsetDateTime createdAt) { - this.createdAt = createdAt; - } - - public OffsetDateTime getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(OffsetDateTime updatedAt) { - this.updatedAt = updatedAt; - } -} \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/repos/MerchantCategoryMapRepository.java b/src/main/java/group/goforward/battlbuilder/repos/MerchantCategoryMapRepository.java index 2fc17a1..d856819 100644 --- a/src/main/java/group/goforward/battlbuilder/repos/MerchantCategoryMapRepository.java +++ b/src/main/java/group/goforward/battlbuilder/repos/MerchantCategoryMapRepository.java @@ -1,6 +1,8 @@ package group.goforward.battlbuilder.repos; import group.goforward.battlbuilder.model.MerchantCategoryMap; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -13,4 +15,9 @@ public interface MerchantCategoryMapRepository extends JpaRepository findFirstByMerchant_IdAndRawCategoryAndDeletedAtIsNull( + Integer merchantId, + String rawCategory + ); } \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/repos/MerchantCategoryMappingRepository.java b/src/main/java/group/goforward/battlbuilder/repos/MerchantCategoryMappingRepository.java deleted file mode 100644 index 27ec803..0000000 --- a/src/main/java/group/goforward/battlbuilder/repos/MerchantCategoryMappingRepository.java +++ /dev/null @@ -1,28 +0,0 @@ -package group.goforward.battlbuilder.repos; - -import group.goforward.battlbuilder.model.Merchant; -import group.goforward.battlbuilder.model.MerchantCategoryMapping; -import java.util.List; -import java.util.Optional; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface MerchantCategoryMappingRepository - extends JpaRepository { - - Optional findByMerchantIdAndRawCategoryIgnoreCase( - Integer merchantId, - String rawCategory - ); - - Optional findByMerchantIdAndRawCategory( - Integer merchantId, - String rawCategory - ); - - List findByMerchantIdOrderByRawCategoryAsc(Integer merchantId); - - Optional findByMerchantAndRawCategoryIgnoreCase( - Merchant merchant, - String rawCategory - ); -} \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/repos/ProductRepository.java b/src/main/java/group/goforward/battlbuilder/repos/ProductRepository.java index d1dcca2..6cfeb64 100644 --- a/src/main/java/group/goforward/battlbuilder/repos/ProductRepository.java +++ b/src/main/java/group/goforward/battlbuilder/repos/ProductRepository.java @@ -1,6 +1,5 @@ package group.goforward.battlbuilder.repos; -import aj.org.objectweb.asm.commons.Remapper; import group.goforward.battlbuilder.model.ImportStatus; import group.goforward.battlbuilder.model.Brand; import group.goforward.battlbuilder.model.Product; @@ -87,7 +86,7 @@ public interface ProductRepository extends JpaRepository { AND p.deletedAt IS NULL ORDER BY p.id """) - List findTop5ByPlatformWithBrand(@Param("platform") String platform); + List findByPlatformWithBrandOrdered(@Param("platform") String platform); // ------------------------------------------------- // Used by GunbuilderProductService (builder UI) @@ -178,45 +177,46 @@ public interface ProductRepository extends JpaRepository { // Mapping admin – pending buckets (all merchants) // ------------------------------------------------- @Query(""" - SELECT m.id AS merchantId, - m.name AS merchantName, - p.rawCategoryKey AS rawCategoryKey, - mcm.mappedPartRole AS mappedPartRole, - COUNT(DISTINCT p.id) AS productCount - FROM Product p - JOIN p.offers o - JOIN o.merchant m - LEFT JOIN MerchantCategoryMapping mcm - ON mcm.merchant.id = m.id - AND mcm.rawCategory = p.rawCategoryKey - WHERE p.importStatus = :status - GROUP BY m.id, m.name, p.rawCategoryKey, mcm.mappedPartRole - ORDER BY productCount DESC - """) - List findPendingMappingBuckets( - @Param("status") ImportStatus status - ); + SELECT m.id AS merchantId, + m.name AS merchantName, + p.rawCategoryKey AS rawCategoryKey, + mcm.partRole AS mappedPartRole, + COUNT(DISTINCT p.id) AS productCount + FROM Product p + JOIN p.offers o + JOIN o.merchant m + LEFT JOIN MerchantCategoryMap mcm + ON mcm.merchant.id = m.id + AND mcm.rawCategory = p.rawCategoryKey + AND mcm.deletedAt IS NULL + WHERE p.importStatus = :status + GROUP BY m.id, m.name, p.rawCategoryKey, mcm.partRole + ORDER BY productCount DESC + """) + List findPendingMappingBuckets(@Param("status") ImportStatus status); + // ------------------------------------------------- // Mapping admin – pending buckets for a single merchant // ------------------------------------------------- @Query(""" - SELECT m.id AS merchantId, - m.name AS merchantName, - p.rawCategoryKey AS rawCategoryKey, - mcm.mappedPartRole AS mappedPartRole, - COUNT(DISTINCT p.id) AS productCount - FROM Product p - JOIN p.offers o - JOIN o.merchant m - LEFT JOIN MerchantCategoryMapping mcm - ON mcm.merchant.id = m.id - AND mcm.rawCategory = p.rawCategoryKey - WHERE p.importStatus = :status - AND m.id = :merchantId - GROUP BY m.id, m.name, p.rawCategoryKey, mcm.mappedPartRole - ORDER BY productCount DESC - """) + SELECT m.id AS merchantId, + m.name AS merchantName, + p.rawCategoryKey AS rawCategoryKey, + mcm.partRole AS mappedPartRole, + COUNT(DISTINCT p.id) AS productCount + FROM Product p + JOIN p.offers o + JOIN o.merchant m + LEFT JOIN MerchantCategoryMap mcm + ON mcm.merchant.id = m.id + AND mcm.rawCategory = p.rawCategoryKey + AND mcm.deletedAt IS NULL + WHERE p.importStatus = :status + AND m.id = :merchantId + GROUP BY m.id, m.name, p.rawCategoryKey, mcm.partRole + ORDER BY productCount DESC + """) List findPendingMappingBucketsForMerchant( @Param("merchantId") Integer merchantId, @Param("status") ImportStatus status diff --git a/src/main/java/group/goforward/battlbuilder/services/MappingAdminService.java b/src/main/java/group/goforward/battlbuilder/services/MappingAdminService.java index 6c07a3b..a0a191d 100644 --- a/src/main/java/group/goforward/battlbuilder/services/MappingAdminService.java +++ b/src/main/java/group/goforward/battlbuilder/services/MappingAdminService.java @@ -2,8 +2,8 @@ package group.goforward.battlbuilder.services; import group.goforward.battlbuilder.model.ImportStatus; import group.goforward.battlbuilder.model.Merchant; -import group.goforward.battlbuilder.model.MerchantCategoryMapping; -import group.goforward.battlbuilder.repos.MerchantCategoryMappingRepository; +import group.goforward.battlbuilder.model.MerchantCategoryMap; +import group.goforward.battlbuilder.repos.MerchantCategoryMapRepository; import group.goforward.battlbuilder.repos.MerchantRepository; import group.goforward.battlbuilder.repos.ProductRepository; import group.goforward.battlbuilder.web.dto.PendingMappingBucketDto; @@ -16,28 +16,19 @@ import java.util.List; public class MappingAdminService { private final ProductRepository productRepository; - private final MerchantCategoryMappingRepository merchantCategoryMappingRepository; + private final MerchantCategoryMapRepository merchantCategoryMapRepository; private final MerchantRepository merchantRepository; public MappingAdminService( ProductRepository productRepository, - MerchantCategoryMappingRepository merchantCategoryMappingRepository, + MerchantCategoryMapRepository merchantCategoryMapRepository, MerchantRepository merchantRepository ) { this.productRepository = productRepository; - this.merchantCategoryMappingRepository = merchantCategoryMappingRepository; + this.merchantCategoryMapRepository = merchantCategoryMapRepository; this.merchantRepository = merchantRepository; } - /** - * Returns all pending mapping buckets across all merchants. - * Each row is: - * [0] merchantId (Integer) - * [1] merchantName (String) - * [2] rawCategoryKey (String) - * [3] mappedPartRole (String, currently null from query) - * [4] productCount (Long) - */ @Transactional(readOnly = true) public List listPendingBuckets() { List rows = productRepository.findPendingMappingBuckets( @@ -63,10 +54,6 @@ public class MappingAdminService { .toList(); } - /** - * Applies or updates a mapping for (merchant, rawCategoryKey) to a given partRole. - * Does NOT retroactively update Product rows; they will be updated on the next import. - */ @Transactional public void applyMapping(Integer merchantId, String rawCategoryKey, String mappedPartRole) { if (merchantId == null || rawCategoryKey == null || mappedPartRole == null || mappedPartRole.isBlank()) { @@ -76,18 +63,22 @@ public class MappingAdminService { Merchant merchant = merchantRepository.findById(merchantId) .orElseThrow(() -> new IllegalArgumentException("Merchant not found: " + merchantId)); - MerchantCategoryMapping mapping = merchantCategoryMappingRepository - .findByMerchantIdAndRawCategory(merchantId, rawCategoryKey) - .orElseGet(() -> { - MerchantCategoryMapping m = new MerchantCategoryMapping(); - m.setMerchant(merchant); - m.setRawCategory(rawCategoryKey); - return m; - }); + List existing = + merchantCategoryMapRepository.findAllByMerchant_IdAndRawCategoryAndDeletedAtIsNull( + merchantId, + rawCategoryKey + ); - mapping.setMappedPartRole(mappedPartRole.trim()); - merchantCategoryMappingRepository.save(mapping); + MerchantCategoryMap mapping = existing.isEmpty() + ? new MerchantCategoryMap() + : existing.get(0); - // Products will pick up this mapping on the next merchant import run. + if (mapping.getId() == null) { + mapping.setMerchant(merchant); + mapping.setRawCategory(rawCategoryKey); + } + + mapping.setPartRole(mappedPartRole.trim()); + merchantCategoryMapRepository.save(mapping); } } \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/services/MerchantCategoryMappingService.java b/src/main/java/group/goforward/battlbuilder/services/MerchantCategoryMappingService.java deleted file mode 100644 index 5c6d570..0000000 --- a/src/main/java/group/goforward/battlbuilder/services/MerchantCategoryMappingService.java +++ /dev/null @@ -1,95 +0,0 @@ -package group.goforward.battlbuilder.services; - -import group.goforward.battlbuilder.model.Merchant; -import group.goforward.battlbuilder.model.MerchantCategoryMapping; -import group.goforward.battlbuilder.model.ProductConfiguration; -import group.goforward.battlbuilder.repos.MerchantCategoryMappingRepository; -import jakarta.transaction.Transactional; -import java.util.List; -import org.springframework.stereotype.Service; - -@Service -public class MerchantCategoryMappingService { - - private final MerchantCategoryMappingRepository mappingRepository; - - public MerchantCategoryMappingService(MerchantCategoryMappingRepository mappingRepository) { - this.mappingRepository = mappingRepository; - } - - public List findByMerchant(Integer merchantId) { - return mappingRepository.findByMerchantIdOrderByRawCategoryAsc(merchantId); - } - - /** - * Resolve (or create) a mapping row for this merchant + raw category. - * - If it exists, returns it (with whatever mappedPartRole / mappedConfiguration are set). - * - If it doesn't exist, creates a placeholder row with null mappings and returns it. - * - * The importer can then: - * - skip rows where mappedPartRole is still null - * - use mappedConfiguration if present - */ - @Transactional - public MerchantCategoryMapping resolveMapping(Merchant merchant, String rawCategory) { - if (rawCategory == null || rawCategory.isBlank()) { - return null; - } - - String trimmed = rawCategory.trim(); - - return mappingRepository - .findByMerchantIdAndRawCategoryIgnoreCase(merchant.getId(), trimmed) - .orElseGet(() -> { - MerchantCategoryMapping mapping = new MerchantCategoryMapping(); - mapping.setMerchant(merchant); - mapping.setRawCategory(trimmed); - mapping.setMappedPartRole(null); - mapping.setMappedConfiguration(null); - return mappingRepository.save(mapping); - }); - } - - /** - * Upsert mapping (admin UI). - */ - @Transactional - public MerchantCategoryMapping upsertMapping( - Merchant merchant, - String rawCategory, - String mappedPartRole, - ProductConfiguration mappedConfiguration - ) { - String trimmed = rawCategory.trim(); - - MerchantCategoryMapping mapping = mappingRepository - .findByMerchantIdAndRawCategoryIgnoreCase(merchant.getId(), trimmed) - .orElseGet(() -> { - MerchantCategoryMapping m = new MerchantCategoryMapping(); - m.setMerchant(merchant); - m.setRawCategory(trimmed); - return m; - }); - - mapping.setMappedPartRole( - (mappedPartRole == null || mappedPartRole.isBlank()) ? null : mappedPartRole.trim() - ); - - mapping.setMappedConfiguration(mappedConfiguration); - - return mappingRepository.save(mapping); - } - /** - * Backwards-compatible overload for existing callers (e.g. controller) - * that don’t care about productConfiguration yet. - */ - @Transactional - public MerchantCategoryMapping upsertMapping( - Merchant merchant, - String rawCategory, - String mappedPartRole - ) { - // Delegate to the new method with `null` configuration - return upsertMapping(merchant, rawCategory, mappedPartRole, null); - } -} \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/services/admin/impl/AdminDashboardService.java b/src/main/java/group/goforward/battlbuilder/services/admin/impl/AdminDashboardService.java index 66c494b..d6f7f37 100644 --- a/src/main/java/group/goforward/battlbuilder/services/admin/impl/AdminDashboardService.java +++ b/src/main/java/group/goforward/battlbuilder/services/admin/impl/AdminDashboardService.java @@ -1,7 +1,7 @@ -package group.goforward.battlbuilder.services; +package group.goforward.battlbuilder.services.admin.impl; import group.goforward.battlbuilder.model.ImportStatus; -import group.goforward.battlbuilder.repos.MerchantCategoryMappingRepository; +import group.goforward.battlbuilder.repos.MerchantCategoryMapRepository; import group.goforward.battlbuilder.repos.MerchantRepository; import group.goforward.battlbuilder.repos.ProductRepository; import group.goforward.battlbuilder.web.dto.AdminDashboardOverviewDto; @@ -13,16 +13,16 @@ public class AdminDashboardService { private final ProductRepository productRepository; private final MerchantRepository merchantRepository; - private final MerchantCategoryMappingRepository merchantCategoryMappingRepository; + private final MerchantCategoryMapRepository merchantCategoryMapRepository; public AdminDashboardService( ProductRepository productRepository, MerchantRepository merchantRepository, - MerchantCategoryMappingRepository merchantCategoryMappingRepository + MerchantCategoryMapRepository merchantCategoryMapRepository ) { this.productRepository = productRepository; this.merchantRepository = merchantRepository; - this.merchantCategoryMappingRepository = merchantCategoryMappingRepository; + this.merchantCategoryMapRepository = merchantCategoryMapRepository; } @Transactional(readOnly = true) @@ -32,7 +32,7 @@ public class AdminDashboardService { long mappedProducts = totalProducts - unmappedProducts; long merchantCount = merchantRepository.count(); - long categoryMappings = merchantCategoryMappingRepository.count(); + long categoryMappings = merchantCategoryMapRepository.count(); return new AdminDashboardOverviewDto( totalProducts, diff --git a/src/main/java/group/goforward/battlbuilder/services/impl/CategoryClassificationServiceImpl.java b/src/main/java/group/goforward/battlbuilder/services/impl/CategoryClassificationServiceImpl.java index 58828fb..fa41c6b 100644 --- a/src/main/java/group/goforward/battlbuilder/services/impl/CategoryClassificationServiceImpl.java +++ b/src/main/java/group/goforward/battlbuilder/services/impl/CategoryClassificationServiceImpl.java @@ -65,7 +65,7 @@ public class CategoryClassificationServiceImpl implements CategoryClassification ); return mappings.stream() - .map(MerchantCategoryMap::getMappedPartRole) + .map(MerchantCategoryMap::getPartRole) .filter(r -> r != null && !r.isBlank()) .findFirst(); } diff --git a/src/main/java/group/goforward/battlbuilder/services/impl/ReclassificationServiceImpl.java b/src/main/java/group/goforward/battlbuilder/services/impl/ReclassificationServiceImpl.java index 541835e..ac22f1e 100644 --- a/src/main/java/group/goforward/battlbuilder/services/impl/ReclassificationServiceImpl.java +++ b/src/main/java/group/goforward/battlbuilder/services/impl/ReclassificationServiceImpl.java @@ -78,7 +78,7 @@ public class ReclassificationServiceImpl implements ReclassificationService { ); return mappings.stream() - .map(MerchantCategoryMap::getMappedPartRole) + .map(MerchantCategoryMap::getPartRole) .filter(v -> v != null && !v.isBlank()) .findFirst(); } diff --git a/src/main/java/group/goforward/battlbuilder/web/admin/AdminMappingController.java b/src/main/java/group/goforward/battlbuilder/web/admin/AdminMappingController.java index 12454d5..0345e4f 100644 --- a/src/main/java/group/goforward/battlbuilder/web/admin/AdminMappingController.java +++ b/src/main/java/group/goforward/battlbuilder/web/admin/AdminMappingController.java @@ -1,7 +1,8 @@ package group.goforward.battlbuilder.web.admin; -import group.goforward.battlbuilder.services.MappingAdminService; import group.goforward.battlbuilder.web.dto.PendingMappingBucketDto; +import group.goforward.battlbuilder.services.MappingAdminService; + import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; diff --git a/src/main/java/group/goforward/battlbuilder/web/admin/CategoryMappingAdminController.java b/src/main/java/group/goforward/battlbuilder/web/admin/CategoryMappingAdminController.java index d5e914f..61681f1 100644 --- a/src/main/java/group/goforward/battlbuilder/web/admin/CategoryMappingAdminController.java +++ b/src/main/java/group/goforward/battlbuilder/web/admin/CategoryMappingAdminController.java @@ -1,7 +1,7 @@ package group.goforward.battlbuilder.web.admin; -import group.goforward.battlbuilder.services.MappingAdminService; import group.goforward.battlbuilder.web.dto.PendingMappingBucketDto; +import group.goforward.battlbuilder.services.MappingAdminService; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*;