-
Notifications
You must be signed in to change notification settings - Fork 8
[4주차] 장바구니 만들기 #3
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
base: main
Are you sure you want to change the base?
Changes from 11 commits
df5f899
5f78898
c77924e
d6ef0b1
84d2fa5
5938641
fb97daf
ba09ba2
67f9704
0db46a1
741c0cf
98abcea
5dda26e
ec6dab0
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 |
|---|---|---|
| @@ -1,11 +1,19 @@ | ||
| package com.example.demo; | ||
|
|
||
| import com.mongodb.client.MongoClient; | ||
| import com.mongodb.client.MongoClients; | ||
| import org.springframework.boot.SpringApplication; | ||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
| import org.springframework.context.annotation.Bean; | ||
|
|
||
| @SpringBootApplication | ||
| public class Application { | ||
| public static void main(String[] args) { | ||
| SpringApplication.run(Application.class, args); | ||
| } | ||
| @Bean | ||
| public MongoClient mongoClient(){ | ||
| String mongoURL = "mongodb://localhost:27017"; | ||
| return MongoClients.create(mongoURL); | ||
| } | ||
|
Comment on lines
+14
to
+18
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. MongoDB 연결 구성의 개선이 필요합니다. 현재 구현에는 몇 가지 개선이 필요한 부분이 있습니다:
다음과 같이 개선하는 것을 추천드립니다: +@Configuration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
+ @Value("${spring.data.mongodb.uri}")
+ private String mongodbUri;
+
@Bean
public MongoClient mongoClient(){
- String mongoURL = "mongodb://localhost:27017";
- return MongoClients.create(mongoURL);
+ try {
+ return MongoClients.create(mongodbUri);
+ } catch (Exception e) {
+ throw new MongoConnectionException("MongoDB 연결 중 오류가 발생했습니다", e);
+ }
}
}그리고 spring.data.mongodb.uri=mongodb://localhost:27017💡 Codebase verification MongoDB 연결 설정의 보안 및 환경 설정 개선이 필요합니다 현재 MongoDB 연결 설정에 다음과 같은 문제점들이 발견되었습니다:
다음 사항들의 추가를 권장드립니다:
예시 설정: spring:
data:
mongodb:
uri: ${MONGODB_URI:mongodb://localhost:27017/demo}
connection-timeout: 5000
socket-timeout: 5000🔗 Analysis chainMongoDB 연결 설정 검증이 필요합니다. 현재 설정된 MongoDB 연결이 의도한 대로 작동하는지 확인이 필요합니다. 다음 스크립트를 실행하여 MongoDB 관련 설정을 확인해보세요: 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# MongoDB 관련 설정 파일 확인
echo "MongoDB 설정 파일 검색 중..."
fd -e properties -e yml | xargs rg "mongodb://"
# MongoDB 관련 환경 설정 클래스 검색
echo "MongoDB 설정 클래스 검색 중..."
rg -l "MongoProperties|MongoClientSettings"
Length of output: 201 Script: #!/bin/bash
# MongoDB 관련 설정 파일 검색 (확장자 추가)
echo "MongoDB 설정 파일 검색 중..."
fd -e properties -e yml -e yaml -e xml -e conf | xargs rg -i "mongo|mongodb"
# application.properties/yml 파일 직접 확인
echo "Application 설정 파일 확인 중..."
fd "application\.(properties|ya?ml)$"
# MongoDB 관련 Java 설정 클래스 검색
echo "MongoDB 설정 클래스 검색 중..."
rg -t java "import.*mongo" -A 5
# MongoDB 연결 관련 코드 검색
echo "MongoDB 연결 코드 검색 중..."
ast-grep --pattern 'mongoClient($$$) {
$$$
}'
Length of output: 2010 Script: #!/bin/bash
# application.yaml 파일의 내용 확인
echo "application.yaml 내용 확인:"
cat src/main/resources/application.yaml
# MongoDB 테스트 코드 확인
echo "MongoDB 테스트 코드 확인:"
cat src/test/java/com/example/demo/MongoDbTest.java
# MongoDB 관련 다른 설정이나 프로퍼티 검색
echo "추가 MongoDB 설정 검색:"
rg -g "!*.{class,jar}" -i "spring\.data\.mongodb|mongodb\."
Length of output: 2233 |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package com.example.demo.exceptions; | ||
|
|
||
| public class ExceedTotalQuantity extends RuntimeException { | ||
| public ExceedTotalQuantity(String message){ | ||
| super(message); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,80 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package com.example.demo.models; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.example.demo.exceptions.ExceedTotalQuantity; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.ArrayList; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.Optional; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public class Cart { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final List<CartItem> cartItems; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private int totalQuantity; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public Cart() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.cartItems = new ArrayList<>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.totalQuantity = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void checkTotalQuantity(int quantity) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (this.totalQuantity + quantity > 20) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw new ExceedTotalQuantity("장바구니 총 합계는 20을 넘길 수 없습니다."); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void addCartItem(ProductId productId, int quantity) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checkTotalQuantity(quantity); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Optional<CartItem> existingCartItem = findCartItem(productId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (existingCartItem.isPresent()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CartItem cartItem = existingCartItem.get(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cartItem.addQuantity(quantity); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| addNewCartItem(productId, quantity); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.totalQuantity += quantity; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+24
to
+38
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. 수량 검증 및 동시성 처리가 필요합니다
public void addCartItem(ProductId productId, int quantity) {
+ if (quantity <= 0) {
+ throw new IllegalArgumentException("수량은 0보다 커야 합니다.");
+ }
- checkTotalQuantity(quantity);
+ validateQuantityLimit(quantity);
Optional<CartItem> existingCartItem = findCartItem(productId);
- if (existingCartItem.isPresent()) {
- CartItem cartItem = existingCartItem.get();
- cartItem.addQuantity(quantity);
- } else {
- addNewCartItem(productId, quantity);
- }
+ synchronized(this) {
+ if (existingCartItem.isPresent()) {
+ CartItem cartItem = existingCartItem.get();
+ cartItem.addQuantity(quantity);
+ } else {
+ addNewCartItem(productId, quantity);
+ }
+ this.totalQuantity += quantity;
+ }
- this.totalQuantity += quantity;
}📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private void addNewCartItem(ProductId productId, int quantity) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (productId == null) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw new IllegalArgumentException("상품 ID는 null일 수 없습니다."); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CartItemId cartItemId = new CartItemId(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Product product = new Product(productId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CartItem newCartItem = new CartItem(cartItemId, product, quantity); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cartItems.add(newCartItem); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private Optional<CartItem> findCartItem(ProductId productId) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return cartItems.stream() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .filter(cartItem -> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Product product = cartItem.getProduct(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return product != null && | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| product.productId().equals(productId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .findFirst(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public List<CartItem> getCartList() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return cartItems; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void madeCartZero() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.totalQuantity = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.cartItems.clear(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public int getTotalQuantity() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return totalQuantity; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public String toString() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "Cart{" + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "cartItems=" + cartItems + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ", totalQuantity=" + totalQuantity + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '}'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,64 @@ | ||||||||||||||||||||||||||||||||||||
| package com.example.demo.models; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| import java.util.Objects; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public class CartItem { | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| private final CartItemId id; | ||||||||||||||||||||||||||||||||||||
| private final Product product; | ||||||||||||||||||||||||||||||||||||
| private int quantity; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
Comment on lines
+5
to
+10
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 필드 유효성 검증 추가 필요 필수 필드에 대한 유효성 검증이 누락되어 있습니다. 다음과 같은 개선사항을 제안드립니다:
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
public class CartItem {
- private final CartItemId id;
- private final Product product;
- private int quantity;
+ @NotNull
+ private final CartItemId id;
+ @NotNull
+ private final Product product;
+ @Min(value = 1, message = "수량은 1 이상이어야 합니다")
+ private int quantity;📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||
| public CartItem(CartItemId id, Product product, int quantity) { | ||||||||||||||||||||||||||||||||||||
| if (id == null) { | ||||||||||||||||||||||||||||||||||||
| throw new IllegalArgumentException("id는 null일 수 없습니다"); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| if (product == null) { | ||||||||||||||||||||||||||||||||||||
| throw new IllegalArgumentException("product는 null일 수 없습니다"); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| if (quantity < 1) { | ||||||||||||||||||||||||||||||||||||
| throw new IllegalArgumentException("수량은 1 이상이어야 합니다"); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| this.id = id; | ||||||||||||||||||||||||||||||||||||
| this.product = product; | ||||||||||||||||||||||||||||||||||||
| this.quantity = quantity; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public void addQuantity(int quantity) { | ||||||||||||||||||||||||||||||||||||
| if (quantity < 0) { | ||||||||||||||||||||||||||||||||||||
| throw new IllegalArgumentException("추가할 수량은 0 이상이어야 합니다"); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| this.quantity += quantity; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public Product getProduct() { | ||||||||||||||||||||||||||||||||||||
| return product; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| public int getQuantity() { | ||||||||||||||||||||||||||||||||||||
| return quantity; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||||||||||
| public boolean equals(Object o) { | ||||||||||||||||||||||||||||||||||||
| if (this == o) return true; | ||||||||||||||||||||||||||||||||||||
| if (o == null || getClass() != o.getClass()) return false; | ||||||||||||||||||||||||||||||||||||
| CartItem cartItem = (CartItem) o; | ||||||||||||||||||||||||||||||||||||
| return id.equals(cartItem.id); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||||||||||
| public int hashCode() { | ||||||||||||||||||||||||||||||||||||
| return Objects.hash(id); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||||||||||
| public String toString() { | ||||||||||||||||||||||||||||||||||||
| return "CartItem{" | ||||||||||||||||||||||||||||||||||||
| + "id=" | ||||||||||||||||||||||||||||||||||||
| + id | ||||||||||||||||||||||||||||||||||||
| + ", product=" | ||||||||||||||||||||||||||||||||||||
| + product | ||||||||||||||||||||||||||||||||||||
| + ", quantity=" | ||||||||||||||||||||||||||||||||||||
| + quantity + "}"; | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package com.example.demo.models; | ||
|
|
||
| public record CartItemId( | ||
| String id | ||
| ) { | ||
| public CartItemId(){ | ||
| this(new GenerateId().id()); | ||
| } | ||
|
Comment on lines
+6
to
+8
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. 💡 Codebase verification 🛠️ Refactor suggestion ID 생성 로직 검증 완료 및 개선 권장 GenerateId와 IdGenerator 클래스의 구현을 확인한 결과, 다음과 같은 개선이 필요합니다:
수정 제안: public CartItemId(){
String generatedId = new GenerateId().id();
if (generatedId == null || generatedId.trim().isEmpty()) {
throw new IllegalStateException("장바구니 아이템 ID가 올바르게 생성되지 않았습니다.");
}
this(generatedId);
}🔗 Analysis chainGenerateId 클래스 사용 및 유효성 검사 확인이 필요합니다. 다음 사항들을 확인해 주시기 바랍니다:
다음과 같이 수정하는 것을 제안드립니다: public CartItemId(){
- this(new GenerateId().id());
+ String generatedId = new GenerateId().id();
+ if (generatedId == null || generatedId.trim().isEmpty()) {
+ throw new IllegalStateException("장바구니 아이템 ID가 올바르게 생성되지 않았습니다.");
+ }
+ this(generatedId);
}GenerateId 클래스 구현을 확인하기 위해 다음 스크립트를 실행합니다: Let me try a different search pattern to locate the GenerateId implementation. Let me check the implementation of IdGenerator to complete the verification. 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# GenerateId 클래스 구현 확인
echo "Searching for GenerateId class implementation..."
rg -l "class GenerateId"
# ID 생성 메서드 구현 확인
echo "Checking ID generation implementation..."
ast-grep --pattern 'class GenerateId {
$$$
$_ id() {
$$$
}
$$$
}'
Length of output: 304 Script: #!/bin/bash
# Search for GenerateId class with broader pattern
echo "Searching for GenerateId class with broader pattern..."
rg -A 5 "GenerateId"
# Search for files containing 'id' method
echo "Searching for files with id method..."
rg -A 3 "id\(\)"
Length of output: 2460 Script: #!/bin/bash
# Check IdGenerator implementation
echo "Checking IdGenerator implementation..."
rg -A 10 "class IdGenerator"
# Check if there are any existing null checks
echo "Checking for null checks in related files..."
rg -A 3 "null|isEmpty|isBlank" src/main/java/com/example/demo/models/
Length of output: 1250 |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package com.example.demo.models; | ||
|
|
||
| import java.time.LocalDateTime; | ||
| import java.time.format.DateTimeFormatter; | ||
| import java.util.UUID; | ||
|
|
||
| public record GenerateId( | ||
| String id | ||
| ) { | ||
|
|
||
| public GenerateId() { | ||
| this(new IdGenerator().generateId()); | ||
| } | ||
| } | ||
|
|
||
| class IdGenerator { | ||
|
|
||
| public String generateId() { | ||
| LocalDateTime now = LocalDateTime.now(); | ||
| DateTimeFormatter formatter = | ||
| DateTimeFormatter.ofPattern("yyyyMMddHHmm"); | ||
| String dateTime = now.format(formatter); | ||
| String shortUUID = UUID.randomUUID().toString().substring(0, 4); | ||
|
|
||
| return dateTime + shortUUID; | ||
| } | ||
| } | ||
|
Comment on lines
+16
to
+27
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. 💡 Codebase verification ID 생성기 개선 제안이 적절합니다 코드베이스 분석 결과, ProductId와 CartItemId에서 ID 생성기를 사용하고 있으며, 현재는 동시성 테스트나 대량 생성 시나리오가 구현되어 있지 않습니다. 하지만 제안된 개선사항들은 다음과 같은 이유로 여전히 유효합니다:
🔗 Analysis chainID 생성 로직의 개선이 필요합니다. 현재 구현에는 다음과 같은 잠재적인 문제가 있습니다:
다음과 같은 개선을 제안합니다: class IdGenerator {
+ private static final Object lock = new Object();
public String generateId() {
- LocalDateTime now = LocalDateTime.now();
- DateTimeFormatter formatter =
- DateTimeFormatter.ofPattern("yyyyMMddHHmm");
- String dateTime = now.format(formatter);
- String shortUUID = UUID.randomUUID().toString().substring(0, 4);
+ synchronized (lock) {
+ LocalDateTime now = LocalDateTime.now();
+ DateTimeFormatter formatter =
+ DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
+ String dateTime = now.format(formatter);
+ String uuid = UUID.randomUUID().toString().replace("-", "");
- return dateTime + shortUUID;
+ return dateTime + uuid;
+ }
}
}다음 스크립트로 ID 생성 로직의 사용처를 확인해보겠습니다: Let's check the usage of the ID generator in those files. Let's check if there are any concurrent operations or batch processes that might create multiple IDs simultaneously. Let's check the test files to see how the IDs are being tested, which might give us insight into the requirements for uniqueness and concurrency. 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# ID 생성 로직을 사용하는 다른 클래스들을 검색
rg -l "new GenerateId\(\)"
Length of output: 135 Script: #!/bin/bash
# Check the content of files using the ID generator
rg -A 10 "new GenerateId\(\)" src/main/java/com/example/demo/models/CartItemId.java src/main/java/com/example/demo/models/ProductId.java
Length of output: 546 Script: #!/bin/bash
# Search for any concurrent operations or batch processes
rg -l "CompletableFuture|ExecutorService|@Async|@Scheduled|parallel|Stream.parallel|newFixedThreadPool|newCachedThreadPool"
# Also check for any repository or service methods that might create products or cart items
rg -l "save.*Product|create.*Product|save.*CartItem|create.*CartItem"
Length of output: 312 Script: #!/bin/bash
# Check the content of test files
rg -A 10 "class.*Test" src/test/java/com/example/demo/models/CartItemIdTest.java src/test/java/com/example/demo/models/ProductIdTest.java
Length of output: 1508 |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package com.example.demo.models; | ||
|
|
||
| import java.util.Objects; | ||
|
|
||
| public record Product ( | ||
| ProductId productId | ||
| ){ | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return "{" + productId + "}"; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object obj) { | ||
| if (this == obj) return true; | ||
| if (obj == null || getClass() != obj.getClass()) return false; | ||
| Product product = (Product) obj; | ||
| return productId.equals(product.productId); | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return productId.hashCode(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package com.example.demo.models; | ||
|
|
||
| public record ProductId( | ||
| String id | ||
| ) { | ||
|
|
||
| public ProductId() { | ||
| this(new GenerateId().id()); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,50 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package com.example.demo; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.mongodb.client.MongoClient; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.mongodb.client.MongoClients; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.mongodb.client.MongoCollection; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.mongodb.client.MongoDatabase; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.bson.Document; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.junit.jupiter.api.Test; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.ArrayList; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @SpringBootTest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public class MongoDbTest { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Autowired | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private MongoClient mongoClient; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+17
to
+21
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 테스트 구성 개선 필요 MongoDB 테스트를 위해 더 가벼운 다음과 같이 변경을 제안합니다: -@SpringBootTest
+@DataMongoTest
+@TestPropertySource(properties = {
+ "spring.data.mongodb.uri=mongodb://localhost:27017/test-db"
+})
public class MongoDbTest {
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Test | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void testMongoClientBean() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // MongoClient 빈이 주입되었는지 확인 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assertThat(mongoClient).isNotNull(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Test | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void readProducts() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 1. DB 서버 접속 간단확인 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String mongoDatabase = "demo"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 2. 데이터 베이스 선택 -> demo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MongoDatabase database = mongoClient.getDatabase(mongoDatabase); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 3. collection에서 목록 열기 -> products | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MongoCollection<Document> collection = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| database.getCollection("products"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<Document> documents = new ArrayList<>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| collection.find().into(documents); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| documents.forEach(document -> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| System.out.println(document.getString("name")); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| System.out.println(document.getInteger("price")); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+29
to
+47
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. 테스트 메소드 개선 필요 현재 구현에는 몇 가지 개선이 필요한 부분이 있습니다:
다음과 같이 개선을 제안합니다: +@Value("${spring.data.mongodb.database}")
+private String databaseName;
+
+@BeforeEach
+void setUp() {
+ // 테스트 데이터 설정
+ MongoDatabase database = mongoClient.getDatabase(databaseName);
+ MongoCollection<Document> collection = database.getCollection("products");
+ collection.insertMany(Arrays.asList(
+ new Document("name", "테스트 상품1").append("price", 1000),
+ new Document("name", "테스트 상품2").append("price", 2000)
+ ));
+}
+
+@AfterEach
+void tearDown() {
+ // 테스트 데이터 정리
+ mongoClient.getDatabase(databaseName)
+ .getCollection("products")
+ .drop();
+}
+
@Test
-void readProducts() {
- // 1. DB 서버 접속 간단확인
- String mongoDatabase = "demo";
-
- // 2. 데이터 베이스 선택 -> demo
- MongoDatabase database = mongoClient.getDatabase(mongoDatabase);
-
- // 3. collection에서 목록 열기 -> products
- MongoCollection<Document> collection =
- database.getCollection("products");
-
- List<Document> documents = new ArrayList<>();
- collection.find().into(documents);
-
- documents.forEach(document -> {
- System.out.println(document.getString("name"));
- System.out.println(document.getInteger("price"));
- });
+void readProducts() throws Exception {
+ // given
+ MongoCollection<Document> collection = mongoClient
+ .getDatabase(databaseName)
+ .getCollection("products");
+
+ // when
+ List<Document> documents = collection.find()
+ .into(new ArrayList<>());
+
+ // then
+ assertThat(documents).hasSize(2);
+ assertThat(documents.get(0))
+ .extracting("name", "price")
+ .containsExactly("테스트 상품1", 1000);
}📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package com.example.demo.models; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.*; | ||
|
|
||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| class CartItemIdTest { | ||
| @Test | ||
| void createCartItemId(){ | ||
| CartItemId id = new CartItemId(); | ||
| System.out.println("Generated ID: " + id.id()); | ||
| assertNotNull(id.id(), "ID should not be null"); | ||
| } | ||
|
Comment on lines
+8
to
+13
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 테스트 케이스 보완이 필요합니다. 현재 테스트는 ID가 null이 아닌지만 확인하고 있습니다. ID의 고유성이나 형식에 대한 추가 검증이 필요할 수 있습니다. 다음과 같은 추가 테스트 케이스를 제안합니다: @Test
void createMultipleCartItemIds_ShouldGenerateUniqueIds() {
CartItemId id1 = new CartItemId();
CartItemId id2 = new CartItemId();
assertNotEquals(id1.id(), id2.id(), "Generated IDs should be unique");
}
@Test
void generatedId_ShouldFollowExpectedFormat() {
CartItemId id = new CartItemId();
String generatedId = id.id();
// ID 형식이 예상된 패턴을 따르는지 확인
assertTrue(generatedId.matches("^[a-zA-Z0-9-]+$"), "ID should match expected format");
} |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| package com.example.demo.models; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.*; | ||
|
|
||
| import java.util.ArrayList; | ||
| import org.junit.jupiter.api.BeforeEach; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| class CartItemTest { | ||
|
|
||
| private CartItem cartItem; | ||
| private CartItemId cartItemId; | ||
| private Product product; | ||
| private ProductId productId; | ||
| private ArrayList<Product> products; | ||
|
|
||
| @BeforeEach | ||
| void setUp() { | ||
| productId = new ProductId(); | ||
| product = new Product(productId); | ||
|
|
||
| cartItemId = new CartItemId(); | ||
| cartItem = new CartItem(cartItemId, product, 1); | ||
| } | ||
|
|
||
| @Test | ||
| void addQuantity() { | ||
| cartItem.addQuantity(1); | ||
| assertEquals(2, cartItem.getQuantity()); | ||
| } | ||
|
Comment on lines
+26
to
+30
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 중복된 테스트 케이스 통합 필요
- @Test
- void addQuantity() {
- cartItem.addQuantity(1);
- assertEquals(2, cartItem.getQuantity());
- }Also applies to: 32-35 |
||
| @Test | ||
| void addQuantity_WhenAddingPositiveNumber_ShouldIncreaseQuantity() { | ||
| cartItem.addQuantity(1); | ||
| assertEquals(2, cartItem.getQuantity()); | ||
| } | ||
|
|
||
| @Test | ||
| void addQuantity_WhenAddingNegativeNumber_ShouldThrowException() { | ||
| assertThrows(IllegalArgumentException.class, () -> cartItem.addQuantity(-1)); | ||
| } | ||
|
|
||
| @Test | ||
| void addQuantity_WhenAddingZero_ShouldNotChangeQuantity() { | ||
| cartItem.addQuantity(0); | ||
| assertEquals(1, cartItem.getQuantity()); | ||
| } | ||
| } | ||
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.
🛠️ Refactor suggestion
MongoDB 의존성 설정 개선이 필요합니다
Spring Boot 애플리케이션에서 MongoDB를 사용할 때는 직접 드라이버를 추가하는 것보다
spring-boot-starter-data-mongodb를 사용하는 것이 좋습니다. 이는 다음과 같은 이점이 있습니다:다음과 같이 수정하는 것을 추천드립니다:
📝 Committable suggestion