Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-validation")

implementation("org.mongodb:mongodb-driver-core:5.2.0")
implementation("org.mongodb:mongodb-driver-sync:5.2.0")

Comment on lines +22 to +24
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

🛠️ Refactor suggestion

Spring Boot 의존성 관리와 MongoDB 드라이버 버전 불일치 발견

Spring Boot 3.3.4는 MongoDB 드라이버 5.0.1 버전을 관리하고 있는데, 프로젝트에서는 5.2.0 버전을 직접 지정하고 있습니다. 이는 다음과 같은 문제를 일으킬 수 있습니다:

  • Spring Boot가 테스트한 MongoDB 드라이버 버전(5.0.1)과 다른 버전을 사용함으로써 예기치 않은 호환성 문제 발생 가능
  • Spring Boot의 의존성 관리 기능을 활용하지 못해 의존성 관리가 복잡해짐

수정 방법:

  • MongoDB 드라이버 버전을 명시적으로 지정하지 말고 Spring Boot의 의존성 관리를 사용하세요
implementation("org.mongodb:mongodb-driver-core")
implementation("org.mongodb:mongodb-driver-sync")

만약 반드시 최신 버전의 MongoDB 드라이버가 필요하다면, 전체 프로젝트의 MongoDB 관련 의존성에 대해 버전을 일괄적으로 오버라이드하는 것을 권장합니다:

ext["mongodb.version"] = "5.2.0"
🔗 Analysis chain

의존성 버전 관리 개선이 필요합니다

Spring Boot의 의존성 관리 기능을 활용하지 않고 MongoDB 드라이버 버전을 직접 지정하고 있습니다. 이는 잠재적인 호환성 문제를 일으킬 수 있습니다.

버전을 명시적으로 지정하지 말고 Spring Boot의 의존성 관리를 활용하세요:

-implementation("org.mongodb:mongodb-driver-core:5.2.0")
-implementation("org.mongodb:mongodb-driver-sync:5.2.0")
+implementation("org.mongodb:mongodb-driver-core")
+implementation("org.mongodb:mongodb-driver-sync")

MongoDB 드라이버와 Spring Boot 버전의 호환성을 확인하기 위해 다음 스크립트를 실행하세요:


Let me gather more information about the Spring Boot version being used in the project.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check Spring Boot's managed versions for MongoDB drivers

# Get Spring Boot's managed version for MongoDB drivers
curl -s https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/3.3.4/spring-boot-dependencies-3.3.4.pom | grep -A 2 "mongodb.version"

Length of output: 831


Script:

#!/bin/bash
# Check Spring Boot version in build.gradle.kts
cat build.gradle.kts | grep -A 5 "org.springframework.boot"

Length of output: 696

developmentOnly("org.springframework.boot:spring-boot-devtools")

testImplementation("org.springframework.boot:spring-boot-starter-test")
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/com/example/demo/Application.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
package com.example.demo;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoDatabase;
import org.springframework.beans.factory.annotation.Value;
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(
@Value("${mongodb.url}") String url
) {
return MongoClients.create(url);
}

@Bean
public MongoDatabase mongoDatabase(
MongoClient mongoClient,
@Value("${mongodb.database}") String database
) {
return mongoClient.getDatabase(database);
}
}
60 changes: 60 additions & 0 deletions src/main/java/com/example/demo/application/CartService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.example.demo.application;

import com.example.demo.infrastructure.LineItemDAO;
import com.example.demo.infrastructure.ProductDAO;
import com.example.demo.models.Cart;
import com.example.demo.models.LineItem;
import com.example.demo.models.Product;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CartService {


private final LineItemDAO lineItemDAO;
private final ProductDAO productDAO;

public CartService(
LineItemDAO lineItemDAO,
ProductDAO productDAO
) {
this.lineItemDAO = lineItemDAO;
this.productDAO = productDAO;
}

public Cart getCart() {
List<LineItem> lineItems = lineItemDAO.findAll();

lineItems.forEach(lineItem -> {
String productId = lineItem.getProductId();
Product product = productDAO.find(productId);


lineItem.setProduct(product);
});


return new Cart(lineItems);
}

public void addProduct(String productId, int quantity) {
List<LineItem> lineItems = lineItemDAO.findAll();

LineItem lineItem = lineItems.stream()
.filter(i -> i.getProductId().equals(productId))
.findFirst()
.orElse(null);

if (lineItem == null) {
lineItem = new LineItem(productId, quantity);
lineItemDAO.add(lineItem);
return;
}

lineItem.addQuantity(quantity);

lineItemDAO.update(lineItem);
}
}
32 changes: 30 additions & 2 deletions src/main/java/com/example/demo/controllers/CartController.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,42 @@
package com.example.demo.controllers;

import com.example.demo.application.CartService;
import com.example.demo.controllers.dtos.CartDto;
import com.example.demo.models.Cart;
import com.example.demo.models.LineItem;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/cart")
public class CartController {
private final CartService cartService;

public CartController(CartService cartService) {
this.cartService = cartService;
}


@GetMapping
String detail() {
return "";
CartDto detail() {
Cart cart = cartService.getCart();

return new CartDto(
cart.getLineItems().stream().map(this::mapToDto).toList(),
cart.getTotalPrice()
);
}

private CartDto.LineItemDto mapToDto(LineItem lineItem) {
return new CartDto.LineItemDto(
lineItem.getId(),
lineItem.getProductId(),
lineItem.getProductName(),
lineItem.getUnitPrice(),
lineItem.getQuantity(),
lineItem.getTotalPrice()
);
}

}
19 changes: 17 additions & 2 deletions src/main/java/com/example/demo/controllers/LineItemController.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
package com.example.demo.controllers;

import com.example.demo.application.CartService;
import com.example.demo.controllers.dtos.AddProductToCartDto;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/cart/line-items")
public class LineItemController {
private final CartService cartService;

public LineItemController(CartService cartService) {
this.cartService = cartService;
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
void create() {
//
void create(
@Valid @RequestBody AddProductToCartDto addProductToCartDto
) {
cartService.addProduct(
addProductToCartDto.productId(),
addProductToCartDto.quantity()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.demo.controllers.dtos;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Positive;

public record AddProductToCartDto(
@NotBlank
String productId,

@Positive
int quantity
) {

}
18 changes: 18 additions & 0 deletions src/main/java/com/example/demo/controllers/dtos/CartDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.example.demo.controllers.dtos;

import java.util.List;

public record CartDto(
List<LineItemDto> lineItems,
int totalPrice
) {
public record LineItemDto(
String id,
String productId,
String productName,
int unitPrice,
int quantity,
int totalPrice
) {
}
}
60 changes: 60 additions & 0 deletions src/main/java/com/example/demo/infrastructure/LineItemDAO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.example.demo.infrastructure;

import com.example.demo.models.LineItem;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class LineItemDAO {
private final MongoCollection<Document> collection;

public LineItemDAO(MongoDatabase mongoDatabase) {
this.collection = mongoDatabase.getCollection("line_items");
}

public List<LineItem> findAll() {

List<Document> documents = new ArrayList<>();

collection.find().into(documents);
return documents.stream()
.map(this::mapToModel)
.toList();
}

private LineItem mapToModel(Document document) {
return new LineItem(
document.getObjectId("_id").toString(),
document.getString("product_id"),
document.getInteger("quantity")
);
}

public void add(LineItem lineItem) {
Document document = new Document()
.append("product_id", lineItem.getProductId())
.append("quantity", lineItem.getQuantity());

collection.insertOne(document);
}


public void update(LineItem lineItem) {
collection.updateOne(
Filters.eq("_id", new ObjectId(lineItem.getId())),
Updates.combine(
Updates.set("product_id", lineItem.getProductId()),
Updates.set("quantity", lineItem.getQuantity())
)
);
}

}
35 changes: 35 additions & 0 deletions src/main/java/com/example/demo/infrastructure/ProductDAO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.example.demo.infrastructure;

import com.example.demo.models.Product;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.stereotype.Component;

@Component
public class ProductDAO {
private final MongoCollection<Document> collection;

public ProductDAO(MongoDatabase mongoDatabase) {
this.collection = mongoDatabase.getCollection("line_items");
}


public Product find(String productId) {
Document document = collection.find(
Filters.eq("_id", new ObjectId(productId))
).first();

if (document == null) {
return null;
}

return new Product(
document.getObjectId("_id").toString(),
document.getString("name"),
document.getInteger("price")
);
}
}
22 changes: 22 additions & 0 deletions src/main/java/com/example/demo/models/Cart.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.demo.models;

import java.util.Collections;
import java.util.List;

public class Cart {
private List<LineItem> lineItems;

public Cart(List<LineItem> lineItems) {
this.lineItems = lineItems;
}

public List<LineItem> getLineItems() {
return Collections.unmodifiableList(lineItems);
}

public int getTotalPrice() {
return lineItems.stream()
.mapToInt(LineItem::getTotalPrice)
.sum();
}
}
58 changes: 58 additions & 0 deletions src/main/java/com/example/demo/models/LineItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.example.demo.models;

public class LineItem {
//Similar to DB schema
private String id = null;
private String productId;
private int quantity;

private String productName;
private int unitPrice;
private int totalPrice;

public LineItem(String productId, int quantity) {
this.productId = productId;
this.quantity = quantity;
}

public LineItem(String id, String productId, int quantity) {
this.id = id;
this.productId = productId;
this.quantity = quantity;
}

public String getId() {
return id;
}

public String getProductId() {
return productId;
}

public int getQuantity() {
return quantity;
}

public String getProductName() {
return productName;
}

public int getUnitPrice() {
return unitPrice;
}

//business logic

public void addQuantity(int quantity) {
this.quantity += quantity;
}

public int getTotalPrice() {
return unitPrice * quantity;
}

public void setProduct(Product product) {
this.productName = product.getName();
this.unitPrice = product.getPrice();
}
}
Loading