fixed the duplicate mapping stuff.

This commit is contained in:
2025-12-22 11:55:45 -05:00
parent d41bcdb94c
commit 5527effba6
15 changed files with 85 additions and 481 deletions

View File

@@ -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<MerchantCategoryMappingDto> listMappings(
@RequestParam("merchantId") Integer merchantId
) {
List<MerchantCategoryMapping> 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;
}
}

View File

@@ -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<SimpleMerchantDto> listMerchantsWithMappings() {
List<Merchant> 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<MerchantCategoryMappingDto> listByMerchant(
@RequestParam(name = "merchantId", required = false) Integer merchantId
) {
List<CategoryMapping> 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
);
}
}

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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;
}
}

View File

@@ -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<MerchantCat
Integer merchantId,
String rawCategory
);
Optional<MerchantCategoryMap> findFirstByMerchant_IdAndRawCategoryAndDeletedAtIsNull(
Integer merchantId,
String rawCategory
);
}

View File

@@ -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<MerchantCategoryMapping, Integer> {
Optional<MerchantCategoryMapping> findByMerchantIdAndRawCategoryIgnoreCase(
Integer merchantId,
String rawCategory
);
Optional<MerchantCategoryMapping> findByMerchantIdAndRawCategory(
Integer merchantId,
String rawCategory
);
List<MerchantCategoryMapping> findByMerchantIdOrderByRawCategoryAsc(Integer merchantId);
Optional<MerchantCategoryMapping> findByMerchantAndRawCategoryIgnoreCase(
Merchant merchant,
String rawCategory
);
}

View File

@@ -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<Product, Integer> {
AND p.deletedAt IS NULL
ORDER BY p.id
""")
List<Product> findTop5ByPlatformWithBrand(@Param("platform") String platform);
List<Product> findByPlatformWithBrandOrdered(@Param("platform") String platform);
// -------------------------------------------------
// Used by GunbuilderProductService (builder UI)
@@ -181,21 +180,21 @@ public interface ProductRepository extends JpaRepository<Product, Integer> {
SELECT m.id AS merchantId,
m.name AS merchantName,
p.rawCategoryKey AS rawCategoryKey,
mcm.mappedPartRole AS mappedPartRole,
mcm.partRole AS mappedPartRole,
COUNT(DISTINCT p.id) AS productCount
FROM Product p
JOIN p.offers o
JOIN o.merchant m
LEFT JOIN MerchantCategoryMapping mcm
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.mappedPartRole
GROUP BY m.id, m.name, p.rawCategoryKey, mcm.partRole
ORDER BY productCount DESC
""")
List<Object[]> findPendingMappingBuckets(
@Param("status") ImportStatus status
);
List<Object[]> findPendingMappingBuckets(@Param("status") ImportStatus status);
// -------------------------------------------------
// Mapping admin pending buckets for a single merchant
@@ -204,17 +203,18 @@ public interface ProductRepository extends JpaRepository<Product, Integer> {
SELECT m.id AS merchantId,
m.name AS merchantName,
p.rawCategoryKey AS rawCategoryKey,
mcm.mappedPartRole AS mappedPartRole,
mcm.partRole AS mappedPartRole,
COUNT(DISTINCT p.id) AS productCount
FROM Product p
JOIN p.offers o
JOIN o.merchant m
LEFT JOIN MerchantCategoryMapping mcm
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.mappedPartRole
GROUP BY m.id, m.name, p.rawCategoryKey, mcm.partRole
ORDER BY productCount DESC
""")
List<Object[]> findPendingMappingBucketsForMerchant(

View File

@@ -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<PendingMappingBucketDto> listPendingBuckets() {
List<Object[]> 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<MerchantCategoryMap> 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);
}
}

View File

@@ -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<MerchantCategoryMapping> 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 dont 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);
}
}

View File

@@ -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,

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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.*;

View File

@@ -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.*;