Conversation
Walkthrough입고(Receipt) 삭제 기능을 추가했습니다: 새로운 DELETE 엔드포인트, 서비스의 삭제 로직, 응답 DTO와 성공 메시지 열거형 상수, 및 관련 컨트롤러·서비스 단위/통합 테스트가 도입되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant Controller as ReceiptController
participant Service as ReceiptService
participant Repo as Repository / DB
Client->>Controller: DELETE /api/v1/receipt/{receiptId} (Auth)
Note right of Controller `#dff0d8`: CustomUserPrincipal에서 userId 추출
Controller->>Service: deleteReceipt(receiptId, userId)
Service->>Repo: findUserById(userId)
Repo-->>Service: User
Service->>Repo: findReceiptByIdAndValidateAccess(receiptId, user.storeId)
alt 접근 허용
Repo-->>Service: Receipt
Service->>Repo: receipt.deactivate() / save()
Repo->>DB: UPDATE receipt (activated=false, status=CANCELED)
DB-->>Repo: OK
Repo-->>Service: updated Receipt
Service-->>Controller: DeleteReceiptResponse(true)
else 접근 거부 / 미존재
Repo-->>Service: 예외(BaseException)
Service-->>Controller: 예외 전파
end
Controller->>Client: ApiResponse(code=200, message="입고 삭제 성공", data=DeleteReceiptResponse)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 분 추가 주의 포인트:
권장 문서: Spring Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🧠 Learnings (1)📚 Learning: 2025-11-22T18:12:13.161ZApplied to files:
🔇 Additional comments (2)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/test/java/com/almang/inventory/receipt/service/ReceiptServiceTest.java (1)
896-924: 반환값 검증을 추가하세요.테스트가 삭제 후 엔티티 상태(
activated가 false,status가 CANCELED)를 잘 검증하고 있습니다. 하지만deleteReceipt의 반환값(DeleteReceiptResponse)도 검증하는 것이 좋습니다.다음과 같이 개선할 수 있습니다:
// when -receiptService.deleteReceipt(receipt.getId(), user.getId()); +DeleteReceiptResponse response = receiptService.deleteReceipt(receipt.getId(), user.getId()); // then +assertThat(response).isNotNull(); +assertThat(response.success()).isTrue(); Receipt deleted = receiptRepository.findById(receipt.getId()).orElseThrow(); assertThat(deleted.isActivated()).isFalse(); assertThat(deleted.getStatus()).isEqualTo(ReceiptStatus.CANCELED);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/main/java/com/almang/inventory/global/api/SuccessMessage.java(1 hunks)src/main/java/com/almang/inventory/receipt/controller/ReceiptController.java(3 hunks)src/main/java/com/almang/inventory/receipt/dto/response/DeleteReceiptResponse.java(1 hunks)src/main/java/com/almang/inventory/receipt/service/ReceiptService.java(2 hunks)src/test/java/com/almang/inventory/receipt/controller/ReceiptControllerTest.java(3 hunks)src/test/java/com/almang/inventory/receipt/service/ReceiptServiceTest.java(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-22T18:12:13.161Z
Learnt from: JoonKyoLee
Repo: almang2/inventory-server PR: 66
File: src/main/java/com/almang/inventory/order/domain/OrderItem.java:41-53
Timestamp: 2025-11-22T18:12:13.161Z
Learning: In the almang2/inventory-server repository, OrderItem entity update methods (updateQuantity, updatePrice in src/main/java/com/almang/inventory/order/domain/OrderItem.java) do not require null checks because OrderService will validate parameters before calling these update methods, following the same pattern as Product entity updates.
<!--
Applied to files:
src/test/java/com/almang/inventory/receipt/controller/ReceiptControllerTest.javasrc/main/java/com/almang/inventory/receipt/service/ReceiptService.java
🔇 Additional comments (9)
src/main/java/com/almang/inventory/global/api/SuccessMessage.java (1)
56-56: 잘 구현되었습니다! 👍성공 메시지가 기존 패턴과 일관되게 추가되었고, 적절한 섹션(RECEIPT)에 배치되었습니다.
src/test/java/com/almang/inventory/receipt/service/ReceiptServiceTest.java (1)
926-979: 예외 케이스 테스트가 잘 구현되었습니다!세 가지 예외 시나리오(사용자 없음, 입고 없음, 교차 상점 접근)가 모두 적절히 테스트되었습니다. 특히 라인 952-979의 교차 상점 접근 테스트는 보안 관점에서 중요한 검증입니다.
src/test/java/com/almang/inventory/receipt/controller/ReceiptControllerTest.java (2)
7-7: 필요한 임포트가 올바르게 추가되었습니다.새로운 삭제 기능을 위한 임포트가 적절히 추가되었습니다.
Also applies to: 22-22
714-780: 컨트롤러 테스트가 체계적으로 구현되었습니다!DELETE 엔드포인트에 대한 4가지 시나리오(성공, 사용자 없음, 입고 없음, 접근 거부)가 모두 테스트되었습니다. 각 테스트는 적절한 HTTP 상태 코드와 응답 구조를 검증하고 있습니다.
src/main/java/com/almang/inventory/receipt/service/ReceiptService.java (2)
16-16: 임포트가 적절히 추가되었습니다.새로운 응답 DTO를 위한 임포트입니다.
141-141: 현재 구현은 RESTful DELETE의 멱등성 원칙을 올바르게 따르고 있습니다.검증 결과:
Receipt.deactivate(): 멱등적 설계 (activated=false, status=CANCELED로 단순 설정)deleteReceipt(): 이미 삭제된 입고도 접근 가능하면 성공 처리- 현재 동작이 바로 리뷰 코멘트에서 "일반적"이라고 언급한 멱등성 패턴입니다
RESTful API 설계 관례상, DELETE 요청은 멱등성을 가져야 하므로 이미 삭제된 리소스에 대한 재삭제 요청도 성공으로 처리하는 것이 표준입니다. 추가 검증이나 명시적 에러 코드는 불필요하며, 현재 구현이 권장 사항을 충족하고 있습니다.
src/main/java/com/almang/inventory/receipt/controller/ReceiptController.java (2)
9-9: 필요한 임포트가 올바르게 추가되었습니다.새로운 삭제 엔드포인트를 위한 임포트가 적절히 추가되었습니다.
Also applies to: 20-20
122-135: 삭제 엔드포인트가 잘 구현되었습니다!엔드포인트 구현이 기존 컨트롤러의 패턴과 일관되게 작성되었습니다:
- 적절한 인증 처리
- 일관된 로깅
- 표준 응답 구조 사용
참고: 현재는 200 OK를 반환하고 있지만, REST API 관례상 DELETE 요청이 성공하면 204 No Content를 반환하는 것도 고려해볼 수 있습니다. 다만 프로젝트 전체의 일관성을 위해 현재 패턴을 유지하는 것도 합리적인 선택입니다.
src/main/java/com/almang/inventory/receipt/dto/response/DeleteReceiptResponse.java (1)
3-5: 프로젝트 전체 삭제 응답 설계의 재검토가 필요합니다.검증 결과, DeleteReceiptResponse는 고립된 문제가 아니라 프로젝트 전체의 일관된 패턴입니다. DeleteOrderResponse, DeleteUserResponse도 동일한
boolean success구조를 사용하고 있습니다.당신의 우려는 타당합니다:
- 모든 삭제 작업은
new DeleteXxxResponse(true)를 반환합니다- 실패 시 예외가 발생하므로 success boolean은 실질적으로 항상
true입니다- 응답에 삭제된 리소스의 식별 정보가 없어 클라이언트가 어떤 리소스가 삭제되었는지 명시적으로 확인할 수 없습니다
권장 개선 방안 (프로젝트 전체에 일관되게 적용):
삭제 ID 반환 (권장):
public record DeleteReceiptResponse( Long receiptId // 또는 timestamp도 함께 ) {}
- 클라이언트가 멱등성(idempotence) 처리 시 유용합니다
- 작업 추적성을 명확히 합니다
204 No Content 상태 코드:
- 응답 본문 없이 성공 여부를 상태 코드로만 전달
- REST 모범 사례와 더 부합합니다
현재 설계는
ApiResponse<DeleteReceiptResponse>래퍼로 인해 비용이 증가하는 반면 정보 가치가 낮습니다. DeleteOrderResponse, DeleteUserResponse와 함께 리팩토링하시기 바랍니다.참고 자료: RFC 7231 - DELETE 메서드, REST API 설계 가이드
✨ 작업 내용
📝 적용 범위
/receipt📌 참고 사항
Summary by CodeRabbit
New Features
Tests
✏️ Tip: You can customize this high-level summary in your review settings.