mirror of
https://gitea.gofwd.group/Forward_Group/ballistic-builder-spring.git
synced 2026-01-20 16:51:03 -05:00
new admin dashboard controllers for mappings
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
package group.goforward.ballistic.web;
|
||||
|
||||
import group.goforward.ballistic.services.AdminDashboardService;
|
||||
import group.goforward.ballistic.web.dto.AdminDashboardOverviewDto;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/admin/dashboard")
|
||||
public class AdminDashboardController {
|
||||
|
||||
private final AdminDashboardService adminDashboardService;
|
||||
|
||||
public AdminDashboardController(AdminDashboardService adminDashboardService) {
|
||||
this.adminDashboardService = adminDashboardService;
|
||||
}
|
||||
|
||||
@GetMapping("/overview")
|
||||
public ResponseEntity<AdminDashboardOverviewDto> getOverview() {
|
||||
AdminDashboardOverviewDto dto = adminDashboardService.getOverview();
|
||||
return ResponseEntity.ok(dto);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
package group.goforward.ballistic.repos;
|
||||
|
||||
import group.goforward.ballistic.model.Brand;
|
||||
import group.goforward.ballistic.model.ImportStatus;
|
||||
import group.goforward.ballistic.model.Merchant;
|
||||
import group.goforward.ballistic.model.MerchantCategoryMapping;
|
||||
import group.goforward.ballistic.model.Brand;
|
||||
import group.goforward.ballistic.model.Product;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -21,6 +24,8 @@ public interface ProductRepository extends JpaRepository<Product, Integer> {
|
||||
|
||||
List<Product> findAllByBrandAndUpc(Brand brand, String upc);
|
||||
|
||||
long countByImportStatus(ImportStatus importStatus);
|
||||
|
||||
boolean existsBySlug(String slug);
|
||||
|
||||
// -------------------------------------------------
|
||||
@@ -28,12 +33,12 @@ public interface ProductRepository extends JpaRepository<Product, Integer> {
|
||||
// -------------------------------------------------
|
||||
|
||||
@Query("""
|
||||
SELECT p
|
||||
FROM Product p
|
||||
JOIN FETCH p.brand b
|
||||
WHERE p.platform = :platform
|
||||
AND p.deletedAt IS NULL
|
||||
""")
|
||||
SELECT p
|
||||
FROM Product p
|
||||
JOIN FETCH p.brand b
|
||||
WHERE p.platform = :platform
|
||||
AND p.deletedAt IS NULL
|
||||
""")
|
||||
List<Product> findByPlatformWithBrand(@Param("platform") String platform);
|
||||
|
||||
@Query(name = "Products.findByPlatformWithBrand")
|
||||
@@ -57,13 +62,13 @@ public interface ProductRepository extends JpaRepository<Product, Integer> {
|
||||
// -------------------------------------------------
|
||||
|
||||
@Query("""
|
||||
SELECT p
|
||||
FROM Product p
|
||||
JOIN FETCH p.brand b
|
||||
WHERE p.platform = :platform
|
||||
AND p.deletedAt IS NULL
|
||||
ORDER BY p.id
|
||||
""")
|
||||
SELECT p
|
||||
FROM Product p
|
||||
JOIN FETCH p.brand b
|
||||
WHERE p.platform = :platform
|
||||
AND p.deletedAt IS NULL
|
||||
ORDER BY p.id
|
||||
""")
|
||||
List<Product> findTop5ByPlatformWithBrand(@Param("platform") String platform);
|
||||
|
||||
// -------------------------------------------------
|
||||
@@ -72,15 +77,15 @@ public interface ProductRepository extends JpaRepository<Product, Integer> {
|
||||
// -------------------------------------------------
|
||||
|
||||
@Query("""
|
||||
SELECT DISTINCT p
|
||||
FROM Product p
|
||||
LEFT JOIN FETCH p.brand b
|
||||
LEFT JOIN FETCH p.offers o
|
||||
WHERE p.platform = :platform
|
||||
AND p.partRole IN :partRoles
|
||||
AND p.importStatus = :status
|
||||
AND p.deletedAt IS NULL
|
||||
""")
|
||||
SELECT DISTINCT p
|
||||
FROM Product p
|
||||
LEFT JOIN FETCH p.brand b
|
||||
LEFT JOIN FETCH p.offers o
|
||||
WHERE p.platform = :platform
|
||||
AND p.partRole IN :partRoles
|
||||
AND p.importStatus = :status
|
||||
AND p.deletedAt IS NULL
|
||||
""")
|
||||
List<Product> findForGunbuilderByPlatformAndPartRoles(
|
||||
@Param("platform") String platform,
|
||||
@Param("partRoles") Collection<String> partRoles,
|
||||
@@ -91,85 +96,111 @@ public interface ProductRepository extends JpaRepository<Product, Integer> {
|
||||
// Admin import-status dashboard (summary)
|
||||
// -------------------------------------------------
|
||||
@Query("""
|
||||
SELECT p.importStatus AS status, COUNT(p) AS count
|
||||
FROM Product p
|
||||
WHERE p.deletedAt IS NULL
|
||||
GROUP BY p.importStatus
|
||||
""")
|
||||
SELECT p.importStatus AS status, COUNT(p) AS count
|
||||
FROM Product p
|
||||
WHERE p.deletedAt IS NULL
|
||||
GROUP BY p.importStatus
|
||||
""")
|
||||
List<Map<String, Object>> aggregateByImportStatus();
|
||||
|
||||
// -------------------------------------------------
|
||||
// Admin import-status dashboard (by merchant)
|
||||
// -------------------------------------------------
|
||||
@Query("""
|
||||
SELECT m.name AS merchantName,
|
||||
p.platform AS platform,
|
||||
p.importStatus AS status,
|
||||
COUNT(p) AS count
|
||||
FROM Product p
|
||||
JOIN p.offers o
|
||||
JOIN o.merchant m
|
||||
WHERE p.deletedAt IS NULL
|
||||
GROUP BY m.name, p.platform, p.importStatus
|
||||
""")
|
||||
SELECT m.id AS merchantId,
|
||||
m.name AS merchantName,
|
||||
p.platform AS platform,
|
||||
p.importStatus AS status,
|
||||
COUNT(p) AS count
|
||||
FROM Product p
|
||||
JOIN p.offers o
|
||||
JOIN o.merchant m
|
||||
WHERE p.deletedAt IS NULL
|
||||
GROUP BY m.id, m.name, p.platform, p.importStatus
|
||||
ORDER BY m.name ASC, p.platform ASC, p.importStatus ASC
|
||||
""")
|
||||
List<Map<String, Object>> aggregateByMerchantAndStatus();
|
||||
|
||||
// -------------------------------------------------
|
||||
// Admin: Unmapped category clusters
|
||||
// -------------------------------------------------
|
||||
@Query("""
|
||||
SELECT p.rawCategoryKey AS rawCategoryKey,
|
||||
m.name AS merchantName,
|
||||
COUNT(DISTINCT p.id) AS productCount
|
||||
FROM Product p
|
||||
JOIN p.offers o
|
||||
JOIN o.merchant m
|
||||
WHERE p.deletedAt IS NULL
|
||||
AND (p.importStatus = group.goforward.ballistic.model.ImportStatus.PENDING_MAPPING
|
||||
OR p.partRole IS NULL
|
||||
OR LOWER(p.partRole) = 'unknown')
|
||||
AND p.rawCategoryKey IS NOT NULL
|
||||
GROUP BY p.rawCategoryKey, m.name
|
||||
ORDER BY productCount DESC
|
||||
""")
|
||||
SELECT p.rawCategoryKey AS rawCategoryKey,
|
||||
m.name AS merchantName,
|
||||
COUNT(DISTINCT p.id) AS productCount
|
||||
FROM Product p
|
||||
JOIN p.offers o
|
||||
JOIN o.merchant m
|
||||
WHERE p.deletedAt IS NULL
|
||||
AND (p.importStatus = group.goforward.ballistic.model.ImportStatus.PENDING_MAPPING
|
||||
OR p.partRole IS NULL
|
||||
OR LOWER(p.partRole) = 'unknown')
|
||||
AND p.rawCategoryKey IS NOT NULL
|
||||
GROUP BY p.rawCategoryKey, m.name
|
||||
ORDER BY productCount DESC
|
||||
""")
|
||||
List<Map<String, Object>> findUnmappedCategoryGroups();
|
||||
|
||||
@Query("""
|
||||
SELECT p
|
||||
FROM Product p
|
||||
JOIN p.offers o
|
||||
JOIN o.merchant m
|
||||
WHERE p.deletedAt IS NULL
|
||||
AND m.name = :merchantName
|
||||
AND p.rawCategoryKey = :rawCategoryKey
|
||||
ORDER BY p.id
|
||||
""")
|
||||
SELECT p
|
||||
FROM Product p
|
||||
JOIN p.offers o
|
||||
JOIN o.merchant m
|
||||
WHERE p.deletedAt IS NULL
|
||||
AND m.name = :merchantName
|
||||
AND p.rawCategoryKey = :rawCategoryKey
|
||||
ORDER BY p.id
|
||||
""")
|
||||
List<Product> findExamplesForCategoryGroup(
|
||||
@Param("merchantName") String merchantName,
|
||||
@Param("rawCategoryKey") String rawCategoryKey
|
||||
);
|
||||
|
||||
// -------------------------------------------------
|
||||
// Admin Bulk Mapper: Merchant + rawCategoryKey buckets
|
||||
// Mapping admin – pending buckets (all merchants)
|
||||
// -------------------------------------------------
|
||||
@Query("""
|
||||
SELECT m.id,
|
||||
m.name,
|
||||
p.rawCategoryKey,
|
||||
COALESCE(mcm.mappedPartRole, '') AS mappedPartRole,
|
||||
COUNT(DISTINCT p.id)
|
||||
FROM Product p
|
||||
JOIN p.offers o
|
||||
JOIN o.merchant m
|
||||
LEFT JOIN MerchantCategoryMapping mcm
|
||||
ON mcm.merchant = m
|
||||
AND mcm.rawCategory = p.rawCategoryKey
|
||||
WHERE p.importStatus = :status
|
||||
AND p.deletedAt IS NULL
|
||||
GROUP BY m.id, m.name, p.rawCategoryKey, mcm.mappedPartRole
|
||||
ORDER BY COUNT(DISTINCT p.id) DESC
|
||||
""")
|
||||
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<Object[]> 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
|
||||
""")
|
||||
List<Object[]> findPendingMappingBucketsForMerchant(
|
||||
@Param("merchantId") Integer merchantId,
|
||||
@Param("status") ImportStatus status
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package group.goforward.ballistic.services;
|
||||
|
||||
import group.goforward.ballistic.model.ImportStatus;
|
||||
import group.goforward.ballistic.repos.MerchantCategoryMappingRepository;
|
||||
import group.goforward.ballistic.repos.MerchantRepository;
|
||||
import group.goforward.ballistic.repos.ProductRepository;
|
||||
import group.goforward.ballistic.web.dto.AdminDashboardOverviewDto;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class AdminDashboardService {
|
||||
|
||||
private final ProductRepository productRepository;
|
||||
private final MerchantRepository merchantRepository;
|
||||
private final MerchantCategoryMappingRepository merchantCategoryMappingRepository;
|
||||
|
||||
public AdminDashboardService(
|
||||
ProductRepository productRepository,
|
||||
MerchantRepository merchantRepository,
|
||||
MerchantCategoryMappingRepository merchantCategoryMappingRepository
|
||||
) {
|
||||
this.productRepository = productRepository;
|
||||
this.merchantRepository = merchantRepository;
|
||||
this.merchantCategoryMappingRepository = merchantCategoryMappingRepository;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public AdminDashboardOverviewDto getOverview() {
|
||||
long totalProducts = productRepository.count();
|
||||
long unmappedProducts = productRepository.countByImportStatus(ImportStatus.PENDING_MAPPING);
|
||||
long mappedProducts = totalProducts - unmappedProducts;
|
||||
|
||||
long merchantCount = merchantRepository.count();
|
||||
long categoryMappings = merchantCategoryMappingRepository.count();
|
||||
|
||||
return new AdminDashboardOverviewDto(
|
||||
totalProducts,
|
||||
mappedProducts,
|
||||
unmappedProducts,
|
||||
merchantCount,
|
||||
categoryMappings
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -29,19 +29,28 @@ public class MappingAdminService {
|
||||
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(
|
||||
ImportStatus.PENDING_MAPPING // use top-level enum
|
||||
ImportStatus.PENDING_MAPPING
|
||||
);
|
||||
|
||||
return rows.stream()
|
||||
.map(row -> {
|
||||
Integer merchantId = (Integer) row[0];
|
||||
String merchantName = (String) row[1];
|
||||
String rawCategoryKey = (String) row[2];
|
||||
String mappedPartRole = (String) row[3];
|
||||
Long count = (Long) row[4];
|
||||
Integer merchantId = (Integer) row[0];
|
||||
String merchantName = (String) row[1];
|
||||
String rawCategoryKey = (String) row[2];
|
||||
String mappedPartRole = (String) row[3];
|
||||
Long count = (Long) row[4];
|
||||
|
||||
return new PendingMappingBucketDto(
|
||||
merchantId,
|
||||
@@ -54,6 +63,10 @@ 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()) {
|
||||
@@ -75,9 +88,6 @@ public class MappingAdminService {
|
||||
mapping.setMappedPartRole(mappedPartRole.trim());
|
||||
merchantCategoryMappingRepository.save(mapping);
|
||||
|
||||
// NOTE:
|
||||
// We're not touching existing Product rows here.
|
||||
// They will pick up this mapping on the next merchant import,
|
||||
// which keeps this endpoint fast and side-effect simple.
|
||||
// Products will pick up this mapping on the next merchant import run.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package group.goforward.ballistic.web.admin;
|
||||
|
||||
import group.goforward.ballistic.model.ImportStatus;
|
||||
import group.goforward.ballistic.repos.ProductRepository;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/admin/import-status")
|
||||
public class AdminImportStatusController {
|
||||
|
||||
private final ProductRepository productRepository;
|
||||
|
||||
public AdminImportStatusController(ProductRepository productRepository) {
|
||||
this.productRepository = productRepository;
|
||||
}
|
||||
|
||||
public record ImportSummaryDto(
|
||||
long totalProducts,
|
||||
long mappedProducts,
|
||||
long pendingProducts
|
||||
) {}
|
||||
|
||||
public record ByMerchantRowDto(
|
||||
Integer merchantId,
|
||||
String merchantName,
|
||||
String platform,
|
||||
ImportStatus status,
|
||||
long count
|
||||
) {}
|
||||
|
||||
@GetMapping("/summary")
|
||||
public ImportSummaryDto summary() {
|
||||
List<Map<String, Object>> rows = productRepository.aggregateByImportStatus();
|
||||
|
||||
long total = 0L;
|
||||
long mapped = 0L;
|
||||
long pending = 0L;
|
||||
|
||||
for (Map<String, Object> row : rows) {
|
||||
ImportStatus status = (ImportStatus) row.get("status");
|
||||
long count = ((Number) row.get("count")).longValue();
|
||||
total += count;
|
||||
|
||||
if (status == ImportStatus.MAPPED) {
|
||||
mapped += count;
|
||||
} else if (status == ImportStatus.PENDING_MAPPING) {
|
||||
pending += count;
|
||||
}
|
||||
}
|
||||
|
||||
return new ImportSummaryDto(total, mapped, pending);
|
||||
}
|
||||
|
||||
@GetMapping("/by-merchant")
|
||||
public List<ByMerchantRowDto> byMerchant() {
|
||||
List<Map<String, Object>> rows = productRepository.aggregateByMerchantAndStatus();
|
||||
|
||||
return rows.stream()
|
||||
.map(row -> new ByMerchantRowDto(
|
||||
(Integer) row.get("merchantId"),
|
||||
(String) row.get("merchantName"),
|
||||
(String) row.get("platform"),
|
||||
(ImportStatus) row.get("status"),
|
||||
((Number) row.get("count")).longValue()
|
||||
))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
@@ -20,16 +20,26 @@ public class AdminMappingController {
|
||||
|
||||
@GetMapping("/pending-buckets")
|
||||
public List<PendingMappingBucketDto> listPendingBuckets() {
|
||||
// Simple: just delegate to service
|
||||
return mappingAdminService.listPendingBuckets();
|
||||
}
|
||||
|
||||
@PostMapping("/apply")
|
||||
public ResponseEntity<?> applyMapping(@RequestBody Map<String, Object> body) {
|
||||
Integer merchantId = (Integer) body.get("merchantId");
|
||||
String rawCategoryKey = (String) body.get("rawCategoryKey");
|
||||
String mappedPartRole = (String) body.get("mappedPartRole");
|
||||
public record ApplyMappingRequest(
|
||||
Integer merchantId,
|
||||
String rawCategoryKey,
|
||||
String mappedPartRole
|
||||
) {}
|
||||
|
||||
@PostMapping("/apply")
|
||||
public ResponseEntity<Map<String, Object>> applyMapping(
|
||||
@RequestBody ApplyMappingRequest request
|
||||
) {
|
||||
mappingAdminService.applyMapping(
|
||||
request.merchantId(),
|
||||
request.rawCategoryKey(),
|
||||
request.mappedPartRole()
|
||||
);
|
||||
|
||||
mappingAdminService.applyMapping(merchantId, rawCategoryKey, mappedPartRole);
|
||||
return ResponseEntity.ok(Map.of("ok", true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package group.goforward.ballistic.web.admin;
|
||||
|
||||
import group.goforward.ballistic.services.MerchantFeedImportService;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/admin/merchants")
|
||||
public class AdminMerchantController {
|
||||
|
||||
private final MerchantFeedImportService merchantFeedImportService;
|
||||
|
||||
public AdminMerchantController(MerchantFeedImportService merchantFeedImportService) {
|
||||
this.merchantFeedImportService = merchantFeedImportService;
|
||||
}
|
||||
|
||||
@PostMapping("/{merchantId}/import")
|
||||
public ResponseEntity<Map<String, Object>> triggerFullImport(
|
||||
@PathVariable Integer merchantId
|
||||
) {
|
||||
// Fire off the full import for this merchant.
|
||||
// (Right now this is synchronous; later we can push to a queue if needed.)
|
||||
merchantFeedImportService.importMerchantFeed(merchantId);
|
||||
|
||||
return ResponseEntity.accepted().body(
|
||||
Map.of(
|
||||
"ok", true,
|
||||
"merchantId", merchantId,
|
||||
"message", "Import triggered"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/admin/mappings")
|
||||
@@ -37,4 +38,30 @@ public class CategoryMappingAdminController {
|
||||
);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
// @RestController
|
||||
// @RequestMapping("/api/admin/mapping")
|
||||
// public static class AdminMappingController {
|
||||
//
|
||||
// private final MappingAdminService mappingAdminService;
|
||||
//
|
||||
// public AdminMappingController(MappingAdminService mappingAdminService) {
|
||||
// this.mappingAdminService = mappingAdminService;
|
||||
// }
|
||||
//
|
||||
// @GetMapping("/pending-buckets")
|
||||
// public List<PendingMappingBucketDto> listPendingBuckets() {
|
||||
// return mappingAdminService.listPendingBuckets();
|
||||
// }
|
||||
//
|
||||
// @PostMapping("/apply")
|
||||
// public ResponseEntity<?> applyMapping(@RequestBody Map<String, Object> body) {
|
||||
// Integer merchantId = (Integer) body.get("merchantId");
|
||||
// String rawCategoryKey = (String) body.get("rawCategoryKey");
|
||||
// String mappedPartRole = (String) body.get("mappedPartRole");
|
||||
//
|
||||
// mappingAdminService.applyMapping(merchantId, rawCategoryKey, mappedPartRole);
|
||||
// return ResponseEntity.ok(Map.of("ok", true));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// src/main/java/group/goforward/ballistic/web/admin/ImportStatusAdminController.java
|
||||
package group.goforward.ballistic.web.admin;
|
||||
|
||||
import group.goforward.ballistic.services.ImportStatusAdminService;
|
||||
import group.goforward.ballistic.web.dto.ImportStatusByMerchantDto;
|
||||
import group.goforward.ballistic.web.dto.ImportStatusSummaryDto;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/admin/import-status")
|
||||
public class ImportStatusAdminController {
|
||||
|
||||
private final ImportStatusAdminService service;
|
||||
|
||||
public ImportStatusAdminController(ImportStatusAdminService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@GetMapping("/summary")
|
||||
public List<ImportStatusSummaryDto> summary() {
|
||||
return service.summarizeByStatus();
|
||||
}
|
||||
|
||||
@GetMapping("/by-merchant")
|
||||
public List<ImportStatusByMerchantDto> byMerchant() {
|
||||
return service.summarizeByMerchant();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package group.goforward.ballistic.web.dto;
|
||||
|
||||
public class AdminDashboardOverviewDto {
|
||||
|
||||
private long totalProducts;
|
||||
private long mappedProducts;
|
||||
private long unmappedProducts;
|
||||
private long merchantCount;
|
||||
private long categoryMappingCount;
|
||||
|
||||
public AdminDashboardOverviewDto(
|
||||
long totalProducts,
|
||||
long mappedProducts,
|
||||
long unmappedProducts,
|
||||
long merchantCount,
|
||||
long categoryMappingCount
|
||||
) {
|
||||
this.totalProducts = totalProducts;
|
||||
this.mappedProducts = mappedProducts;
|
||||
this.unmappedProducts = unmappedProducts;
|
||||
this.merchantCount = merchantCount;
|
||||
this.categoryMappingCount = categoryMappingCount;
|
||||
}
|
||||
|
||||
public long getTotalProducts() {
|
||||
return totalProducts;
|
||||
}
|
||||
|
||||
public long getMappedProducts() {
|
||||
return mappedProducts;
|
||||
}
|
||||
|
||||
public long getUnmappedProducts() {
|
||||
return unmappedProducts;
|
||||
}
|
||||
|
||||
public long getMerchantCount() {
|
||||
return merchantCount;
|
||||
}
|
||||
|
||||
public long getCategoryMappingCount() {
|
||||
return categoryMappingCount;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user