[volume-3] 도메인 모델링 및 구현 - 홍창모#80
Closed
HongChangMo wants to merge 28 commits intoLoopers-dev-lab:mainfrom
Closed
Conversation
- 회원 ID 값을 받아 회원 정보 조회 통합 테스트 작성
- 회원 ID 값을 받아 회원 포인트 정보 조회 통합, E2E 테스트 작성 완료
- 회원 ID 값과 충전할 포인트를 받아 회원 포인트 충전 단위, 통합, E2E 테스트 작성 완료
- 컨트롤러 코드 가독성 및 유지보수성 향상 - Gender 필드의 null 검증 버그 수정 - 메서드명 오타 수정
- 유저 시나리오를 기반으로한 요구사항 명세서 작성
- 요구사항 명세서 기반 Sequence Diagram 작성
- 요구사항 명세서 기반 Class Diagram 작성
- 01-requirements.md : 부분 실패 시나리오 명확화 - 02-sequence-diagrams.md : 외부 시스템 연동 시 오류 처리 시나리오 추가 - 04-erd.md : 불필요 컬럼 삭제
- UserModel -> User
- UserModel -> User
- Product 도메인 생성 및 단위 테스트 작성 - ProductLike 도메인 생성 및 User, Product 연관관계 설정 - Brand 도메인 생성
- 상품 등록 validation 로직 추가 - 상품 등록 unit test 코드 작성
- 도메인 validation 체크 기능 추가 - class diagram 수정
- 포인트 자료형 변경 Integer -> BigDecimal - 자료형 변경에 따른 User 도메인, 통합, E2E 테스트 코드 수정
- 재고 입력값 검증 로직 구현 - 상품 목록 조회 기능 구현(sorting) - SortType 관리를 위한 ProductSortType.java 생성 - 단위, 통합 테스트 코드 작성
- 주문 도메인 작성 - 주문 생성 단위 테스트 작성 - OrderStatus Enum class 활용, 주문 상태 관리
- 브랜드 사용/ 미사용 기능 구현 - 브랜드 생성 기능 구현 - 단위 테스트 작성
- 주문 생성 협력 관계 도메인 대상 로직 추가 - Product 도메인 : 상품 재고 감소 기능 추가 - User 도메인 : 사용자 포인트 사용 기능 추가 - 단위, 통합 테스트 작성 완료
- 재고(Stock) VO 객체로 분리 - 금액(Money) VO 객체로 분리 - VO 객체 분리로 인한 로직 수정 및 테스트 코드 수정
- 상품 좋아요 등록, 취소, 중복 방지 기능 구현 - 중복 좋아요 방지를 위한 멱등성 처리
- 주문 총 합계 금액 컬럼 불필요해보여 메서드로 수정
- BaseEntity 상속 제외 처리
- 클래스 다이어그램 제어 동작 상세화 - ERD 컬럼 설명 추가 및 개선
|
Caution Review failedThe pull request is closed. 코드 리뷰 분석Walkthrough이 PR은 전자상거래 플랫폼의 핵심 도메인 모델과 API를 구현합니다. 사용자, 상품, 브랜드, 주문, 상품 좋아요 기능을 위한 도메인 엔티티, 저장소, 서비스, 애플리케이션 파사드 및 REST 컨트롤러를 추가합니다. 또한 가치 객체(Money, Stock), 테스트 및 설계 문서를 포함합니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant UserV1Controller
participant UserFacade
participant UserService
participant UserRepository
participant Database
Client->>UserV1Controller: POST /api/v1/users/new<br/>UserRequest(userId, email, birthdate, gender)
activate UserV1Controller
UserV1Controller->>UserFacade: accountUser(userId, email,<br/>birthdate, gender)
activate UserFacade
UserFacade->>UserService: accountUser(...)
activate UserService
rect rgb(200, 220, 255)
Note over UserService: 중복 체크
UserService->>UserRepository: existsByUserId(userId)
activate UserRepository
UserRepository->>Database: SELECT * FROM users<br/>WHERE user_id = ?
Database-->>UserRepository: 결과
deactivate UserRepository
end
alt 존재하는 경우
UserService-->>UserService: throw CoreException<br/>(BAD_REQUEST)
else 존재하지 않는 경우
UserService->>UserService: User.createUser(...)
UserService->>UserRepository: save(user)
activate UserRepository
UserRepository->>Database: INSERT INTO users ...
Database-->>UserRepository: user entity
deactivate UserRepository
UserService-->>UserFacade: User
end
deactivate UserService
UserFacade->>UserFacade: UserInfo.from(user)
UserFacade-->>UserV1Controller: UserInfo
deactivate UserFacade
UserV1Controller->>UserV1Controller: UserV1DTO.UserResponse.from(userInfo)
UserV1Controller-->>Client: 200 OK<br/>ApiResponse<UserResponse>
deactivate UserV1Controller
sequenceDiagram
participant Client
participant OrderService as OrderService<br/>(Transactional)
participant OrderRepository
participant ProductRepository
participant UserRepository
participant Database
Client->>OrderService: createOrder(user,<br/>productQuantities)
activate OrderService
rect rgb(200, 220, 255)
Note over OrderService: Order 생성 및 검증
OrderService->>OrderService: Order.createOrder(user,<br/>productQuantities)
Note over OrderService: - 재고 검증<br/>- 포인트 검증<br/>- 총액 계산
end
rect rgb(200, 255, 220)
Note over OrderService: 각 상품별 재고 차감
loop for each product in productQuantities
OrderService->>ProductRepository: findProduct(...)
activate ProductRepository
ProductRepository->>Database: SELECT...
Database-->>ProductRepository: product
deactivate ProductRepository
OrderService->>OrderService: product.decreaseStock(qty)
end
end
rect rgb(255, 220, 220)
Note over OrderService: 사용자 포인트 사용
OrderService->>UserRepository: findUser(user.getId())
activate UserRepository
UserRepository->>Database: SELECT...
Database-->>UserRepository: user
deactivate UserRepository
OrderService->>OrderService: user.usePoint(order.totalPrice)
end
rect rgb(220, 240, 255)
Note over OrderService: Order 저장
OrderService->>OrderRepository: save(order)
activate OrderRepository
OrderRepository->>Database: INSERT INTO orders...
Database-->>OrderRepository: order
deactivate OrderRepository
end
OrderService-->>Client: Order 생성 완료
deactivate OrderService
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes 주의가 필요한 영역:
Possibly related PRs
Poem
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (47)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📌 Summary
상품, 브랜드, 좋아요, 주문 기능의 도메인 모델 및 도메인 서비스 구현
💬 Review Points
Order단위 테스트 작성 중주문 생성 시 포인트가 부족하면 예외가 발생한다에 관한 테스트 코드를 작성 중 궁금한 사항이 생겨 질문드립니다.단위 테스트는 단일 도메인에 대한 테스트를 진행해야 한다고 알고있습니다.
하지만 해당 테스트를 진행하면서
Order가 생성되지 않기 때문에포인트가 부족하더라도Order자체가 생성이 안되어야 하기때문에Order댠위 테스트에 테스트를 진행하였는데, 이런 경우는도메인 간 협력 로직이기 때문에 도메인 서비스 테스트로 올려야하는 건지 궁금합니다만약 위와같이 코드를 작성해도 괜찮다면,
다른 도메인의 변경에 영향을 받지 않도록 해당 부분을 Mockito 를 활용해 테스트를 진행했는데,
위의 코드의 경우 다른 도메인의 변경에 영향을 받지 않고
Order도메인에 대한 예외가 발생하기 때문에 단위 테스트라고 생각해서 테스트 코드를 작성했는데, 단위 테스트로 볼 수 있는 테스트 코드인지 궁금합니다.✅ Checklist
상품 정보 객체는 브랜드 정보, 좋아요 수를 포함한다.
상품의 정렬 조건(
latest,price_asc,likes_desc) 을 고려한 조회 기능을 설계했다상품은 재고를 가지고 있고, 주문 시 차감할 수 있어야 한다
재고는 감소만 가능하며 음수 방지는 도메인 레벨에서 처리된다
좋아요는 유저와 상품 간의 관계로 별도 도메인으로 분리했다
중복 좋아요 방지를 위한 멱등성 처리가 구현되었다
상품의 좋아요 수는 상품 상세/목록 조회에서 함께 제공된다
단위 테스트에서 좋아요 등록/취소/중복 방지 흐름을 검증했다
주문은 여러 상품을 포함할 수 있으며, 각 상품의 수량을 명시한다
주문 시 상품의 재고 차감, 유저 포인트 차감 등을 수행한다
재고 부족, 포인트 부족 등 예외 흐름을 고려해 설계되었다
단위 테스트에서 정상 주문 / 예외 주문 흐름을 모두 검증했다
도메인 간 협력 로직은 Domain Service에 위치시켰다
상품 상세 조회 시 Product + Brand 정보 조합은 도메인 서비스에서 처리했다
복합 유스케이스는 Application Layer에 존재하고, 도메인 로직은 위임되었다
도메인 서비스는 상태 없이, 도메인 객체의 협력 중심으로 설계되었다
전체 프로젝트의 구성은 아래 아키텍처를 기반으로 구성되었다
Application Layer는 도메인 객체를 조합해 흐름을 orchestration 했다
핵심 비즈니스 로직은 Entity, VO, Domain Service 에 위치한다
Repository Interface는 Domain Layer 에 정의되고, 구현체는 Infra에 위치한다
패키지는 계층 + 도메인 기준으로 구성되었다 (
/domain/order,/application/like등)테스트는 외부 의존성을 분리하고, Fake/Stub 등을 사용해 단위 테스트가 가능하게 구성되었다
Summary by CodeRabbit
릴리스 노트
새로운 기능
문서