-
Notifications
You must be signed in to change notification settings - Fork 0
포인트 상점 탭 분리 기능 구현 #395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
포인트 상점 탭 분리 기능 구현 #395
Changes from all commits
fa84c06
a3575ba
275f228
b3c1227
7ee2567
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| package com.example.green.domain.pointshop.admin.controller; | ||
|
|
||
| import static com.example.green.domain.pointshop.admin.controller.message.PointShopAdminResponseMessage.*; | ||
|
|
||
| import org.springframework.web.bind.annotation.DeleteMapping; | ||
| import org.springframework.web.bind.annotation.PathVariable; | ||
| import org.springframework.web.bind.annotation.PostMapping; | ||
| import org.springframework.web.bind.annotation.PutMapping; | ||
| import org.springframework.web.bind.annotation.RequestBody; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| import com.example.green.domain.pointshop.admin.controller.docs.PointShopAdminControllerDocs; | ||
| import com.example.green.domain.pointshop.admin.dto.request.AdminCreatePointShopRequest; | ||
| import com.example.green.domain.pointshop.admin.dto.request.AdminUpdatePointShopRequest; | ||
| import com.example.green.domain.pointshop.admin.service.PointShopAdminService; | ||
| import com.example.green.global.api.ApiTemplate; | ||
| import com.example.green.global.api.NoContent; | ||
| import com.example.green.global.security.annotation.AdminApi; | ||
|
|
||
| import jakarta.validation.Valid; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| @RestController | ||
| @RequiredArgsConstructor | ||
| @RequestMapping("/api/admin/point-shop") | ||
| @AdminApi | ||
| public class PointShopAdminController implements PointShopAdminControllerDocs { | ||
|
|
||
| private final PointShopAdminService pointShopAdminService; | ||
|
|
||
| @PostMapping("/create") | ||
| public ApiTemplate<Long> create(@RequestBody @Valid AdminCreatePointShopRequest createPointShopRequest) { | ||
| Long result = pointShopAdminService.create(createPointShopRequest); | ||
| return ApiTemplate.ok(POINT_ITEM_CREATION_SUCCESS, result); | ||
| } | ||
|
|
||
| @PutMapping("/update/{id}") | ||
| public NoContent update( | ||
| @PathVariable Long id, | ||
| @RequestBody @Valid AdminUpdatePointShopRequest updatePointShopRequest | ||
| ) { | ||
| pointShopAdminService.update(updatePointShopRequest, id); | ||
| return NoContent.ok(POINT_ITEM_UPDATE_SUCCESS); | ||
| } | ||
|
|
||
| @DeleteMapping("/delete/{id}") | ||
| public NoContent delete(@PathVariable Long id) { | ||
| pointShopAdminService.delete(id); | ||
| return NoContent.ok(POINT_ITEM_DELETE_SUCCESS); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| package com.example.green.domain.pointshop.admin.controller.docs; | ||
|
|
||
| import com.example.green.domain.pointshop.admin.dto.request.AdminCreatePointShopRequest; | ||
| import com.example.green.domain.pointshop.admin.dto.request.AdminUpdatePointShopRequest; | ||
| import com.example.green.global.api.ApiTemplate; | ||
| import com.example.green.global.api.NoContent; | ||
| import com.example.green.global.error.dto.ExceptionResponse; | ||
|
|
||
| import io.swagger.v3.oas.annotations.Operation; | ||
| import io.swagger.v3.oas.annotations.media.Content; | ||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||
|
|
||
| @Tag(name = "포인트 상점 상품 / 아이템 어드민 API", description = "포인트 상점 상품 / 아이템 어드민 API 모음 입니다.") | ||
| public interface PointShopAdminControllerDocs { | ||
|
|
||
| @Operation(summary = "포인트 아이템 / 상품 생성 (관리자)", description = "포인트 아이템 / 상품 을 생성합니다.") | ||
| @ApiResponse(responseCode = "200", description = "포인트 아이템 / 상품 생성에 성공했습니다.") | ||
| @ApiResponse( | ||
| responseCode = "400", description = "포인트 아이템 / 상품 생성 시 잘못된 정보 기입하면 발생", | ||
| content = @Content(schema = @Schema(implementation = ExceptionResponse.class)) | ||
| ) | ||
| ApiTemplate<Long> create(AdminCreatePointShopRequest createPointShopRequest); | ||
|
|
||
| @Operation(summary = "포인트 상점 아이템 / 상품 수정(관리자)", description = "포인트 상점 아이템 / 상품 정보를 수정합니다.") | ||
| @ApiResponse(responseCode = "200", description = "포인트 상점 아이템 / 상품 수정에 성공했습니다") | ||
| @ApiResponse( | ||
| responseCode = "400", description = "중복된 코드 또는 잘못된 데이터", | ||
| content = @Content(schema = @Schema(implementation = ExceptionResponse.class)) | ||
| ) | ||
| @ApiResponse( | ||
| responseCode = "404", description = "아이템 / 상품 을 찾을 수 없습니다.", | ||
| content = @Content(schema = @Schema(implementation = ExceptionResponse.class)) | ||
| ) | ||
| NoContent update(Long id, AdminUpdatePointShopRequest updatePointShopRequest); | ||
|
|
||
| @Operation(summary = "포인트 상점 아이템 / 상품 삭제(관리자)", description = "포인트 상점 아이템 / 상품 을 삭제합니다.") | ||
| @ApiResponse(responseCode = "200", description = "아이템 / 상품 삭제에 성공했습니다") | ||
| @ApiResponse( | ||
| responseCode = "404", description = "아이템 / 상품 을 찾을 수 없습니다.", | ||
| content = @Content(schema = @Schema(implementation = ExceptionResponse.class)) | ||
| ) | ||
| NoContent delete(Long id); | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,17 @@ | ||||||||||
| package com.example.green.domain.pointshop.admin.controller.message; | ||||||||||
|
|
||||||||||
| import com.example.green.global.api.ResponseMessage; | ||||||||||
|
|
||||||||||
| import lombok.Getter; | ||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||
|
|
||||||||||
| @RequiredArgsConstructor | ||||||||||
| @Getter | ||||||||||
| public enum PointShopAdminResponseMessage implements ResponseMessage { | ||||||||||
|
|
||||||||||
| POINT_ITEM_CREATION_SUCCESS("포인트 상점 아이템 / 상품 생성에 성공했습니다."), | ||||||||||
| POINT_ITEM_UPDATE_SUCCESS("포인트 상점 아이템 / 상품 수정에 성공했습니다."), | ||||||||||
| POINT_ITEM_DELETE_SUCCESS("아이템 / 상품수정 삭제에 성공했습니다."); | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix typo in delete success message. The message contains "상품수정 삭제" where "수정" (modification) appears incorrectly. It should be "상품 삭제" (product deletion). Apply this diff to correct the message: POINT_ITEM_CREATION_SUCCESS("포인트 상점 아이템 / 상품 생성에 성공했습니다."),
POINT_ITEM_UPDATE_SUCCESS("포인트 상점 아이템 / 상품 수정에 성공했습니다."),
- POINT_ITEM_DELETE_SUCCESS("아이템 / 상품수정 삭제에 성공했습니다.");
+ POINT_ITEM_DELETE_SUCCESS("아이템 / 상품 삭제에 성공했습니다.");📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| private final String message; | ||||||||||
| } | ||||||||||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,44 @@ | ||||||||
| package com.example.green.domain.pointshop.admin.dto.request; | ||||||||
|
|
||||||||
| import java.math.BigDecimal; | ||||||||
|
|
||||||||
| import com.example.green.domain.pointshop.admin.service.PointShopType; | ||||||||
|
|
||||||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||||||
| import jakarta.validation.constraints.NotBlank; | ||||||||
| import jakarta.validation.constraints.NotNull; | ||||||||
| import jakarta.validation.constraints.Size; | ||||||||
| import lombok.Builder; | ||||||||
|
|
||||||||
| @Schema(description = "상품 생성 요청") | ||||||||
| @Builder | ||||||||
| public record AdminCreatePointShopRequest( | ||||||||
| PointShopType type, | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add The Apply this diff to add validation: public record AdminCreatePointShopRequest(
+ @NotNull(message = "상품 타입은 필수입니다.")
PointShopType type,📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||
|
|
||||||||
| @NotBlank(message = "상품 코드는 비어 있을 수 없습니다.") | ||||||||
| @Schema(description = "상품 코드", example = "ITM-AA-001") | ||||||||
| String code, | ||||||||
|
|
||||||||
| @NotBlank(message = "상품명은 비어있을 수 없습니다.") | ||||||||
| @Size(min = 2, max = 15, message = "상품명은 2글자 ~ 15글자 사이입니다.") | ||||||||
| @Schema(description = "상품명", example = "맑은 뭉게 구름") | ||||||||
| String name, | ||||||||
|
|
||||||||
| @NotNull(message = "상품 설명은 필수입니다.") | ||||||||
| @Size(max = 100, message = "상품 설명은 최대 100글자입니다.") | ||||||||
| @Schema(description = "상품 설명", example = "하늘에서 포근한 구름이 내려와 식물을 감싸요. 몽글몽글 기분 좋은 하루!") | ||||||||
| String description, | ||||||||
|
|
||||||||
| @NotBlank(message = "상품 썸네일 이미지는 비어있을 수 없습니다.") | ||||||||
| @Schema(description = "상품 썸네일", example = "https://example.com/image.png") | ||||||||
| String thumbnailUrl, | ||||||||
|
|
||||||||
| @NotNull(message = "상품 가격은 필수입니다.") | ||||||||
| @Schema(description = "상품 가격", example = "10000") | ||||||||
| BigDecimal price, | ||||||||
|
|
||||||||
| @Schema(description = "상품 재고", example = "10") | ||||||||
| Integer stock | ||||||||
| ) { | ||||||||
|
|
||||||||
| } | ||||||||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,43 @@ | ||||||||
| package com.example.green.domain.pointshop.admin.dto.request; | ||||||||
|
|
||||||||
| import java.math.BigDecimal; | ||||||||
|
|
||||||||
| import com.example.green.domain.pointshop.admin.service.PointShopType; | ||||||||
|
|
||||||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||||||
| import jakarta.validation.constraints.NotBlank; | ||||||||
| import jakarta.validation.constraints.NotNull; | ||||||||
| import jakarta.validation.constraints.Size; | ||||||||
| import lombok.Builder; | ||||||||
|
|
||||||||
| @Schema(description = "상품 수정 요청") | ||||||||
| @Builder | ||||||||
| public record AdminUpdatePointShopRequest( | ||||||||
| PointShopType type, | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add The Apply this diff to add validation: public record AdminUpdatePointShopRequest(
+ @NotNull(message = "상품 타입은 필수입니다.")
PointShopType type,📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||
|
|
||||||||
| @NotBlank(message = "상품 코드는 비어 있을 수 없습니다.") | ||||||||
| @Schema(description = "상품 코드", example = "ITM-AA-001") | ||||||||
| String code, | ||||||||
|
|
||||||||
| @NotBlank(message = "상품명은 비어있을 수 없습니다.") | ||||||||
| @Size(min = 2, max = 15, message = "상품명은 2글자 ~ 15글자 사이입니다.") | ||||||||
| @Schema(description = "상품명", example = "맑은 뭉게 구름") | ||||||||
| String name, | ||||||||
|
|
||||||||
| @NotNull(message = "상품 설명은 필수입니다.") | ||||||||
| @Size(max = 100, message = "상품 설명은 최대 100글자입니다.") | ||||||||
| @Schema(description = "상품 설명", example = "하늘에서 포근한 구름이 내려와 식물을 감싸요. 몽글몽글 기분 좋은 하루!") | ||||||||
| String description, | ||||||||
|
|
||||||||
| @NotBlank(message = "상품 썸네일 이미지는 비어있을 수 없습니다.") | ||||||||
| @Schema(description = "상품 썸네일", example = "https://example.com/image.png") | ||||||||
| String thumbnailUrl, | ||||||||
|
|
||||||||
| @NotNull(message = "상품 가격은 필수입니다.") | ||||||||
| @Schema(description = "상품 가격", example = "10000") | ||||||||
| BigDecimal price, | ||||||||
|
|
||||||||
| @Schema(description = "상품 재고", example = "10") | ||||||||
| Integer stock | ||||||||
| ) { | ||||||||
| } | ||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package com.example.green.domain.pointshop.admin.exception; | ||
|
|
||
| import com.example.green.global.error.exception.BusinessException; | ||
| import com.example.green.global.error.exception.ExceptionMessage; | ||
|
|
||
| public class PointShopAdminException extends BusinessException { | ||
|
|
||
| public PointShopAdminException(ExceptionMessage message) { | ||
| super(message); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,22 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| package com.example.green.domain.pointshop.admin.exception; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| import static org.springframework.http.HttpStatus.*; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.http.HttpStatus; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| import com.example.green.global.error.exception.ExceptionMessage; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| import lombok.Getter; | ||||||||||||||||||||||||||||||||||||||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| @RequiredArgsConstructor | ||||||||||||||||||||||||||||||||||||||||||||||
| @Getter | ||||||||||||||||||||||||||||||||||||||||||||||
| public enum PointShopAdminExceptionMessage implements ExceptionMessage { | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| NOT_FOUND_CATEGORY(NOT_FOUND, "카테고리를 찾을 수가 없습니다"), | ||||||||||||||||||||||||||||||||||||||||||||||
| NOT_FOUND_PRODUCT(NOT_FOUND, "등록된 상품 / 아이템을 찾을 수 없습니다"); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| private final HttpStatus httpStatus; | ||||||||||||||||||||||||||||||||||||||||||||||
| private final String message; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+12
to
+22
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Polish error message Korean phrasing for consistency
- NOT_FOUND_CATEGORY(NOT_FOUND, "카테고리를 찾을 수가 없습니다"),
+ NOT_FOUND_CATEGORY(NOT_FOUND, "카테고리를 찾을 수 없습니다"),📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| package com.example.green.domain.pointshop.admin.service; | ||
|
|
||
| import java.util.Optional; | ||
|
|
||
| import org.springframework.stereotype.Service; | ||
|
|
||
| import com.example.green.domain.pointshop.admin.dto.request.AdminCreatePointShopRequest; | ||
| import com.example.green.domain.pointshop.admin.dto.request.AdminUpdatePointShopRequest; | ||
| import com.example.green.domain.pointshop.admin.exception.PointShopAdminException; | ||
| import com.example.green.domain.pointshop.admin.exception.PointShopAdminExceptionMessage; | ||
| import com.example.green.domain.pointshop.item.entity.PointItem; | ||
| import com.example.green.domain.pointshop.item.entity.vo.Category; | ||
| import com.example.green.domain.pointshop.item.entity.vo.ItemBasicInfo; | ||
| import com.example.green.domain.pointshop.item.entity.vo.ItemCode; | ||
| import com.example.green.domain.pointshop.item.entity.vo.ItemMedia; | ||
| import com.example.green.domain.pointshop.item.entity.vo.ItemPrice; | ||
| import com.example.green.domain.pointshop.item.repository.PointItemRepository; | ||
| import com.example.green.domain.pointshop.item.service.PointItemService; | ||
| import com.example.green.domain.pointshop.item.service.command.PointItemCreateCommand; | ||
| import com.example.green.domain.pointshop.item.service.command.PointItemUpdateCommand; | ||
| import com.example.green.domain.pointshop.product.entity.PointProduct; | ||
| import com.example.green.domain.pointshop.product.entity.vo.BasicInfo; | ||
| import com.example.green.domain.pointshop.product.entity.vo.Code; | ||
| import com.example.green.domain.pointshop.product.entity.vo.Media; | ||
| import com.example.green.domain.pointshop.product.entity.vo.Price; | ||
| import com.example.green.domain.pointshop.product.entity.vo.Stock; | ||
| import com.example.green.domain.pointshop.product.repository.PointProductRepository; | ||
| import com.example.green.domain.pointshop.product.service.PointProductService; | ||
| import com.example.green.domain.pointshop.product.service.command.PointProductCreateCommand; | ||
| import com.example.green.domain.pointshop.product.service.command.PointProductUpdateCommand; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class PointShopAdminService { | ||
|
Comment on lines
+34
to
+36
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Missing Both +import org.springframework.transaction.annotation.Transactional;
+
@Service
@RequiredArgsConstructor
+@Transactional
public class PointShopAdminService {🤖 Prompt for AI Agents |
||
|
|
||
| private final PointItemService pointItemService; | ||
| private final PointProductService pointProductService; | ||
| private final PointItemRepository pointItemRepository; | ||
| private final PointProductRepository pointProductRepository; | ||
|
|
||
| //생성 | ||
| public Long create(AdminCreatePointShopRequest request) { | ||
|
|
||
| if (request.type() == PointShopType.ITEM) { | ||
| PointItemCreateCommand command = new PointItemCreateCommand( | ||
| new ItemCode(request.code()), | ||
| new ItemBasicInfo(request.name(), request.description()), | ||
| new ItemMedia(request.thumbnailUrl()), | ||
| new ItemPrice(request.price()), | ||
| Category.ITEM | ||
| ); | ||
| return pointItemService.create(command); | ||
| } | ||
|
|
||
| if (request.type() == PointShopType.PRODUCT) { | ||
| PointProductCreateCommand command = new PointProductCreateCommand( | ||
| new Code(request.code()), | ||
| new BasicInfo(request.name(), request.description()), | ||
| new Media(request.thumbnailUrl()), | ||
| new Price(request.price()), | ||
| new Stock(request.stock()) | ||
| ); | ||
| return pointProductService.create(command); | ||
| } | ||
|
|
||
| throw new PointShopAdminException(PointShopAdminExceptionMessage.NOT_FOUND_CATEGORY); | ||
| } | ||
|
|
||
| //수정 | ||
| public void update(AdminUpdatePointShopRequest request, Long productId) { | ||
| //item 먼저 찾기 | ||
| Optional<PointItem> pointItem = pointItemRepository.findById(productId); | ||
| if (pointItem.isPresent()) { | ||
| PointItemUpdateCommand command = new PointItemUpdateCommand( | ||
| new ItemCode(request.code()), | ||
| new ItemBasicInfo(request.name(), request.description()), | ||
| new ItemMedia(request.thumbnailUrl()), | ||
| new ItemPrice(request.price()), | ||
| Category.ITEM | ||
| ); | ||
| pointItemService.updatePointItem(command, productId); | ||
| return; | ||
| } | ||
| //product 찾기 | ||
| Optional<PointProduct> pointProduct = pointProductRepository.findById(productId); | ||
| if (pointProduct.isPresent()) { | ||
| PointProductUpdateCommand command = new PointProductUpdateCommand( | ||
| new Code(request.code()), | ||
| new BasicInfo(request.name(), request.description()), | ||
| new Media(request.thumbnailUrl()), | ||
| new Price(request.price()), | ||
| new Stock(request.stock()), | ||
| Category.PRODUCT | ||
| ); | ||
| pointProductService.update(command, productId); | ||
| return; | ||
| } | ||
| throw new PointShopAdminException(PointShopAdminExceptionMessage.NOT_FOUND_PRODUCT); | ||
|
Comment on lines
+72
to
+100
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ID collision risk: probing both repositories by ID is unreliable.
Unlike -public void update(AdminUpdatePointShopRequest request, Long productId) {
- Optional<PointItem> pointItem = pointItemRepository.findById(productId);
- if (pointItem.isPresent()) {
+public void update(AdminUpdatePointShopRequest request, Long productId) {
+ if (request.type() == PointShopType.ITEM) {
PointItemUpdateCommand command = new PointItemUpdateCommand(
...
);
pointItemService.updatePointItem(command, productId);
return;
}
- Optional<PointProduct> pointProduct = pointProductRepository.findById(productId);
- if (pointProduct.isPresent()) {
+ if (request.type() == PointShopType.PRODUCT) {
PointProductUpdateCommand command = new PointProductUpdateCommand(
...
);
pointProductService.update(command, productId);
return;
}
- throw new PointShopAdminException(PointShopAdminExceptionMessage.NOT_FOUND_PRODUCT);
+ throw new PointShopAdminException(PointShopAdminExceptionMessage.NOT_FOUND_CATEGORY);
}
🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| //삭제 | ||
| public void delete(Long productId) { | ||
| Optional<PointItem> pointItem = pointItemRepository.findById(productId); | ||
| if (pointItem.isPresent()) { | ||
| pointItemService.delete(productId); | ||
| return; | ||
| } | ||
| Optional<PointProduct> pointProduct = pointProductRepository.findById(productId); | ||
| if (pointProduct.isPresent()) { | ||
| pointProductService.delete(productId); | ||
| return; | ||
| } | ||
| throw new PointShopAdminException(PointShopAdminExceptionMessage.NOT_FOUND_PRODUCT); | ||
| } | ||
|
Comment on lines
+104
to
+116
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same ID collision issue as This method has the same problem: if both tables have an entity with the same ID, the Additionally, public void delete(Long productId) {
- Optional<PointItem> pointItem = pointItemRepository.findById(productId);
- if (pointItem.isPresent()) {
+ if (pointItemRepository.existsById(productId)) {
pointItemService.delete(productId);
return;
}
- Optional<PointProduct> pointProduct = pointProductRepository.findById(productId);
- if (pointProduct.isPresent()) {
+ if (pointProductRepository.existsById(productId)) {
pointProductService.delete(productId);
return;
}
throw new PointShopAdminException(PointShopAdminExceptionMessage.NOT_FOUND_PRODUCT);
}However, the preferred fix is to require a type discriminator like |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package com.example.green.domain.pointshop.admin.service; | ||
|
|
||
| public enum PointShopType { | ||
| ITEM, | ||
| PRODUCT | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use type-agnostic message constants or conditional messages.
The endpoint uses
POINT_ITEM_CREATION_SUCCESSfor all creations, but this controller handles both items and products. Consider either:POINT_SHOP_CREATION_SUCCESS)The same issue applies to lines 44 and 50 with
POINT_ITEM_UPDATE_SUCCESSandPOINT_ITEM_DELETE_SUCCESS.🤖 Prompt for AI Agents