diff --git a/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminPlatformController.java b/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminPlatformController.java index 307ef24..96491a5 100644 --- a/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminPlatformController.java +++ b/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminPlatformController.java @@ -1,4 +1,4 @@ -package group.goforward.battlbuilder.controllers; +package group.goforward.battlbuilder.controllers.admin; import group.goforward.battlbuilder.model.Platform; import group.goforward.battlbuilder.repos.PlatformRepository; @@ -36,21 +36,70 @@ public class AdminPlatformController { .toList(); } - @PostMapping("/add") - public ResponseEntity createPlatform(@RequestBody Platform platform) { + /** + * Create new platform (RESTful) + * POST /api/platforms + */ + @PostMapping + public ResponseEntity create(@RequestBody Platform platform) { + // Normalize key so we don’t end up with Ak47 / ak47 / AK-47 variants + if (platform.getKey() != null) { + platform.setKey(platform.getKey().trim().toUpperCase()); + } + + // Optional: if label empty, default to key + if (platform.getLabel() == null || platform.getLabel().trim().isEmpty()) { + platform.setLabel(platform.getKey()); + } + + // Default active = true if omitted + if (platform.getIsActive() == null) { + platform.setIsActive(true); + } + platform.setCreatedAt(OffsetDateTime.now()); platform.setUpdatedAt(OffsetDateTime.now()); + Platform created = platformRepository.save(platform); - return ResponseEntity.status(HttpStatus.CREATED).body(created); + + return ResponseEntity.status(HttpStatus.CREATED).body( + new PlatformDto( + created.getId(), + created.getKey(), + created.getLabel(), + created.getCreatedAt(), + created.getUpdatedAt(), + created.getIsActive() + ) + ); } - @DeleteMapping("/delete/{id}") - public ResponseEntity deletePlatform(@PathVariable Integer id) { - return platformRepository.findById(id) - .map(platform -> { - platformRepository.deleteById(id); - return ResponseEntity.noContent().build(); - }) - .orElse(ResponseEntity.notFound().build()); + /** + * (Optional) keep old endpoint temporarily so nothing breaks + */ + @PostMapping("/add") + public ResponseEntity createViaAdd(@RequestBody Platform platform) { + return create(platform); } -} + + /** + * Delete platform (RESTful) + * DELETE /api/platforms/{id} + */ + @DeleteMapping("/{id}") + public ResponseEntity delete(@PathVariable Integer id) { + if (!platformRepository.existsById(id)) { + return ResponseEntity.notFound().build(); + } + platformRepository.deleteById(id); + return ResponseEntity.noContent().build(); + } + + /** + * (Optional) keep old delete route temporarily + */ + @DeleteMapping("/delete/{id}") + public ResponseEntity deleteLegacy(@PathVariable Integer id) { + return delete(id); + } +} \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/services/admin/AdminProductService.java b/src/main/java/group/goforward/battlbuilder/services/admin/AdminProductService.java index 9cbf4c7..8158670 100644 --- a/src/main/java/group/goforward/battlbuilder/services/admin/AdminProductService.java +++ b/src/main/java/group/goforward/battlbuilder/services/admin/AdminProductService.java @@ -3,16 +3,13 @@ package group.goforward.battlbuilder.services.admin; import group.goforward.battlbuilder.web.dto.admin.AdminProductSearchRequest; import group.goforward.battlbuilder.web.dto.admin.ProductAdminRowDto; import group.goforward.battlbuilder.web.dto.admin.ProductBulkUpdateRequest; +import group.goforward.battlbuilder.web.dto.admin.BulkUpdateResult; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; public interface AdminProductService { + Page search(AdminProductSearchRequest request, Pageable pageable); - Page search( - AdminProductSearchRequest request, - Pageable pageable - ); - - int bulkUpdate(ProductBulkUpdateRequest request); + BulkUpdateResult bulkUpdate(ProductBulkUpdateRequest request); } \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/services/admin/impl/AdminProductServiceImpl.java b/src/main/java/group/goforward/battlbuilder/services/admin/impl/AdminProductServiceImpl.java index 1f242aa..3d24752 100644 --- a/src/main/java/group/goforward/battlbuilder/services/admin/impl/AdminProductServiceImpl.java +++ b/src/main/java/group/goforward/battlbuilder/services/admin/impl/AdminProductServiceImpl.java @@ -5,6 +5,7 @@ import group.goforward.battlbuilder.repos.ProductRepository; import group.goforward.battlbuilder.services.admin.AdminProductService; import group.goforward.battlbuilder.specs.ProductSpecifications; import group.goforward.battlbuilder.web.dto.admin.AdminProductSearchRequest; +import group.goforward.battlbuilder.web.dto.admin.BulkUpdateResult; import group.goforward.battlbuilder.web.dto.admin.ProductAdminRowDto; import group.goforward.battlbuilder.web.dto.admin.ProductBulkUpdateRequest; @@ -38,28 +39,75 @@ public class AdminProductServiceImpl implements AdminProductService { } @Override - public int bulkUpdate(ProductBulkUpdateRequest request) { + public BulkUpdateResult bulkUpdate(ProductBulkUpdateRequest request) { var products = productRepository.findAllById(request.getProductIds()); - products.forEach(p -> { + int updated = 0; + int skippedLocked = 0; + + for (var p : products) { + boolean changed = false; + + // --- straightforward fields --- if (request.getVisibility() != null) { p.setVisibility(request.getVisibility()); + changed = true; } if (request.getStatus() != null) { p.setStatus(request.getStatus()); + changed = true; } if (request.getBuilderEligible() != null) { p.setBuilderEligible(request.getBuilderEligible()); + changed = true; } if (request.getAdminLocked() != null) { p.setAdminLocked(request.getAdminLocked()); + changed = true; } if (request.getAdminNote() != null) { p.setAdminNote(request.getAdminNote()); + changed = true; } - }); + + // --- platform update with lock semantics --- + if (request.getPlatform() != null) { + boolean isLocked = Boolean.TRUE.equals(p.getPlatformLocked()); + boolean override = Boolean.TRUE.equals(request.getPlatformLocked()); // request says "I'm allowed to touch locked ones" + + if (isLocked && !override) { + skippedLocked++; + } else { + if (!request.getPlatform().equals(p.getPlatform())) { + p.setPlatform(request.getPlatform()); + changed = true; + } + } + } + + // --- apply platformLocked toggle (even if platform isn't being changed) --- + if (request.getPlatformLocked() != null) { + if (!request.getPlatformLocked().equals(p.getPlatformLocked())) { + p.setPlatformLocked(request.getPlatformLocked()); + changed = true; + } + } + + if (changed) updated++; + } productRepository.saveAll(products); - return products.size(); + productRepository.flush(); // ✅ ensures UPDATEs are executed now + + var check = productRepository.findAllById(request.getProductIds()); + for (var p : check) { + System.out.println( + "AFTER FLUSH id=" + p.getId() + + " platform=" + p.getPlatform() + + " platformLocked=" + p.getPlatformLocked() + ); + } + + return new BulkUpdateResult(updated, skippedLocked); } } \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/web/admin/AdminProductController.java b/src/main/java/group/goforward/battlbuilder/web/admin/AdminProductController.java index df5e539..568b888 100644 --- a/src/main/java/group/goforward/battlbuilder/web/admin/AdminProductController.java +++ b/src/main/java/group/goforward/battlbuilder/web/admin/AdminProductController.java @@ -3,6 +3,7 @@ package group.goforward.battlbuilder.web.admin; import group.goforward.battlbuilder.services.admin.AdminProductService; import group.goforward.battlbuilder.web.dto.admin.AdminProductSearchRequest; import group.goforward.battlbuilder.web.dto.admin.ProductBulkUpdateRequest; +import group.goforward.battlbuilder.web.dto.admin.BulkUpdateResult; import group.goforward.battlbuilder.web.dto.admin.ProductAdminRowDto; import org.springframework.data.domain.Page; @@ -36,10 +37,11 @@ public class AdminProductController { * Bulk admin actions (disable, hide, lock, etc.) */ @PatchMapping("/bulk") - public Map bulkUpdate( - @RequestBody ProductBulkUpdateRequest request - ) { - int updated = adminProductService.bulkUpdate(request); - return Map.of("updatedCount", updated); + public Map bulkUpdate(@RequestBody ProductBulkUpdateRequest request) { + BulkUpdateResult result = adminProductService.bulkUpdate(request); + return Map.of( + "updatedCount", result.updatedCount(), + "skippedLockedCount", result.skippedLockedCount() + ); } } \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/web/dto/admin/BulkUpdateResult.java b/src/main/java/group/goforward/battlbuilder/web/dto/admin/BulkUpdateResult.java new file mode 100644 index 0000000..076d878 --- /dev/null +++ b/src/main/java/group/goforward/battlbuilder/web/dto/admin/BulkUpdateResult.java @@ -0,0 +1,6 @@ +package group.goforward.battlbuilder.web.dto.admin; + +public record BulkUpdateResult( + int updatedCount, + int skippedLockedCount +) {} diff --git a/src/main/java/group/goforward/battlbuilder/web/dto/admin/PlatformCreateRequest.java b/src/main/java/group/goforward/battlbuilder/web/dto/admin/PlatformCreateRequest.java new file mode 100644 index 0000000..e4569f3 --- /dev/null +++ b/src/main/java/group/goforward/battlbuilder/web/dto/admin/PlatformCreateRequest.java @@ -0,0 +1,16 @@ +package group.goforward.battlbuilder.web.dto.admin; + +public class PlatformCreateRequest { + private String key; + private String label; + private Boolean isActive; + + public String getKey() { return key; } + public void setKey(String key) { this.key = key; } + + public String getLabel() { return label; } + public void setLabel(String label) { this.label = label; } + + public Boolean getIsActive() { return isActive; } + public void setIsActive(Boolean isActive) { this.isActive = isActive; } +} diff --git a/src/main/java/group/goforward/battlbuilder/web/dto/admin/ProductBulkUpdateRequest.java b/src/main/java/group/goforward/battlbuilder/web/dto/admin/ProductBulkUpdateRequest.java index e235657..4098c38 100644 --- a/src/main/java/group/goforward/battlbuilder/web/dto/admin/ProductBulkUpdateRequest.java +++ b/src/main/java/group/goforward/battlbuilder/web/dto/admin/ProductBulkUpdateRequest.java @@ -8,7 +8,8 @@ import java.util.Set; public class ProductBulkUpdateRequest { private Set productIds; - + private String platform; + private Boolean platformLocked; private ProductVisibility visibility; private ProductStatus status; @@ -36,4 +37,10 @@ public class ProductBulkUpdateRequest { public String getAdminNote() { return adminNote; } public void setAdminNote(String adminNote) { this.adminNote = adminNote; } + + public String getPlatform() { return platform; } + public void setPlatform(String platform) { this.platform = platform; } + + public Boolean getPlatformLocked() { return platformLocked; } + public void setPlatformLocked(Boolean platformLocked) { this.platformLocked = platformLocked; } } \ No newline at end of file