Skip to content

Commit

Permalink
feat: product finder
Browse files Browse the repository at this point in the history
  • Loading branch information
waltercrdz committed Jan 13, 2025
1 parent d603526 commit 07eb4d3
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 12 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
# BlueJ files
*.ctxt

# Environment Variables
.env

# Mobile Tools for Java (J2ME)
.mtj.tmp/

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import dev.waltercrdz.api.ecommerce.shared.domain.exception.ErrorCode;
import dev.waltercrdz.api.ecommerce.shared.domain.exception.NotEnoughStockException;
import dev.waltercrdz.api.ecommerce.shared.domain.exception.ProductNotFoundException;
import dev.waltercrdz.api.ecommerce.shared.infrastructure.in.error.ApiError;

@ControllerAdvice
public class ErrorHandler {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package dev.waltercrdz.api.ecommerce.products.application;

import java.util.List;
import java.util.UUID;

import org.springframework.stereotype.Service;

import dev.waltercrdz.api.ecommerce.products.domain.model.Product;
import dev.waltercrdz.api.ecommerce.products.domain.repository.ProductQueryRepository;
import dev.waltercrdz.api.ecommerce.shared.domain.exception.ProductNotFoundException;

@Service
public class ProductFinder {

private final ProductQueryRepository reader;

public ProductFinder(ProductQueryRepository reader) {
this.reader = reader;
}

public Product find(UUID id) {
return reader.findById(id).orElseThrow(() -> new ProductNotFoundException("Product not found", id));
}

public List<Product> findAll() {
return reader.findAll();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
import org.springframework.stereotype.Service;

import dev.waltercrdz.api.ecommerce.products.domain.repository.ProductCommandRepository;
import dev.waltercrdz.api.ecommerce.shared.domain.exception.ProductNotFoundException;

@Service
public class ProductStockUpdater {

private final ProductFinder finder;
private final ProductCommandRepository writer;

public ProductStockUpdater(ProductCommandRepository writer) {
public ProductStockUpdater(ProductFinder finder, ProductCommandRepository writer) {
this.finder = finder;
this.writer = writer;
}

public void updateStock(UUID productId, Integer quantity) {
final var product = this.writer.findById(productId)
.orElseThrow(() -> new ProductNotFoundException("Product not found", productId));
final var product = finder.find(productId);
product.decreaseStock(quantity);
this.writer.save(product);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
package dev.waltercrdz.api.ecommerce.products.domain.repository;

import java.util.Optional;
import java.util.UUID;

import dev.waltercrdz.api.ecommerce.products.domain.model.Product;

public interface ProductCommandRepository {

void save(Product product);

Optional<Product> findById(UUID id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package dev.waltercrdz.api.ecommerce.products.domain.repository;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

import dev.waltercrdz.api.ecommerce.products.domain.model.Product;

public interface ProductQueryRepository {

Optional<Product> findById(UUID id);
List<Product> findAll();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package dev.waltercrdz.api.ecommerce.products.infrastructure.in.controller;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import dev.waltercrdz.api.ecommerce.products.application.ProductFinder;
import dev.waltercrdz.api.ecommerce.products.infrastructure.in.dto.ProductResponse;
import dev.waltercrdz.api.ecommerce.products.infrastructure.in.mapper.ProductMapper;

@RestController
@RequestMapping("/products")
public class ProductController {

private final ProductFinder finder;

public ProductController(ProductFinder finder) {
this.finder = finder;
}

@GetMapping("/{id}")
public ProductResponse getProduct(UUID id) {
final var product = this.finder.find(id);
return ProductMapper.toResponse(product);
}

@GetMapping
public List<ProductResponse> getProducts() {
final var products = this.finder.findAll();
return products.stream()
.map(ProductMapper::toResponse)
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package dev.waltercrdz.api.ecommerce.products.infrastructure.in.dto;

import java.math.BigDecimal;
import java.util.UUID;

public record ProductResponse(
UUID id,
String name,
String description,
BigDecimal price,
Integer stock) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package dev.waltercrdz.api.ecommerce.products.infrastructure.in.mapper;

import dev.waltercrdz.api.ecommerce.products.domain.model.Product;
import dev.waltercrdz.api.ecommerce.products.infrastructure.in.dto.ProductResponse;

public class ProductMapper {

public static ProductResponse toResponse(Product product) {
return new ProductResponse(
product.getId(),
product.getName(),
product.getDescription(),
product.getPrice(),
product.getStock());
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package dev.waltercrdz.api.ecommerce.products.infrastructure.out.persistence.repository;

import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

import org.springframework.stereotype.Repository;

import dev.waltercrdz.api.ecommerce.products.domain.model.Product;
import dev.waltercrdz.api.ecommerce.products.domain.repository.ProductCommandRepository;
import dev.waltercrdz.api.ecommerce.products.domain.repository.ProductQueryRepository;
import dev.waltercrdz.api.ecommerce.products.infrastructure.out.persistence.mapper.ProductMapper;

@Repository
public class ProductRepositoryDefault implements ProductCommandRepository {
public class ProductRepositoryDefault implements ProductCommandRepository, ProductQueryRepository {

private final ProductPostgresRepository productPostgresRepository;

Expand All @@ -24,6 +27,13 @@ public Optional<Product> findById(UUID product_id) {
.map(ProductMapper::toDomain);
}

public List<Product> findAll() {
return this.productPostgresRepository.findAll()
.stream()
.map(ProductMapper::toDomain)
.collect(Collectors.toList());
}

@Override
public void save(Product product) {
this.productPostgresRepository.save(ProductMapper.toEntity(product));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.waltercrdz.api.ecommerce.orders.infrastructure.in.error;
package dev.waltercrdz.api.ecommerce.shared.infrastructure.in.error;

import dev.waltercrdz.api.ecommerce.shared.domain.exception.DomainException;
import dev.waltercrdz.api.ecommerce.shared.domain.exception.ErrorCode;
Expand Down

0 comments on commit 07eb4d3

Please sign in to comment.