Remove service interfaces — use concrete classes directly

Each domain had a single-implementation interface (e.g. AdminService
interface + AdminServiceImpl). Merged implementation into the service
class and deleted the redundant interfaces per KISS principle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-02 11:04:41 +02:00
parent 03b96e8584
commit 9713412d42
21 changed files with 1171 additions and 1595 deletions

View File

@@ -1,17 +1,98 @@
package com.recipeapp.pantry;
import com.recipeapp.common.ResourceNotFoundException;
import com.recipeapp.common.ValidationException;
import com.recipeapp.household.HouseholdRepository;
import com.recipeapp.household.entity.Household;
import com.recipeapp.pantry.dto.*;
import com.recipeapp.pantry.entity.PantryItem;
import com.recipeapp.recipe.IngredientRepository;
import com.recipeapp.recipe.dto.RecipeDetailResponse.CategoryRef;
import com.recipeapp.recipe.entity.Ingredient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.UUID;
public interface PantryService {
@Service
@Transactional
public class PantryService {
List<PantryItemResponse> listItems(UUID householdId);
private final PantryItemRepository pantryItemRepository;
private final HouseholdRepository householdRepository;
private final IngredientRepository ingredientRepository;
PantryItemResponse createItem(UUID householdId, CreatePantryItemRequest request);
public PantryService(PantryItemRepository pantryItemRepository,
HouseholdRepository householdRepository,
IngredientRepository ingredientRepository) {
this.pantryItemRepository = pantryItemRepository;
this.householdRepository = householdRepository;
this.ingredientRepository = ingredientRepository;
}
PantryItemResponse updateItem(UUID householdId, UUID itemId, UpdatePantryItemRequest request);
void deleteItem(UUID householdId, UUID itemId);
@Transactional(readOnly = true)
public List<PantryItemResponse> listItems(UUID householdId) {
return pantryItemRepository.findByHouseholdIdOrderByBestBeforeAscNullsLast(householdId)
.stream()
.map(this::toResponse)
.toList();
}
public PantryItemResponse createItem(UUID householdId, CreatePantryItemRequest request) {
Household household = householdRepository.findById(householdId)
.orElseThrow(() -> new ResourceNotFoundException("Household not found"));
Ingredient ingredient = null;
if (request.ingredientId() != null) {
ingredient = ingredientRepository.findById(request.ingredientId())
.orElseThrow(() -> new ResourceNotFoundException("Ingredient not found"));
}
if (request.ingredientId() == null && (request.customName() == null || request.customName().isBlank())) {
throw new ValidationException("Either ingredientId or customName must be provided");
}
PantryItem item = new PantryItem(household, ingredient, request.customName(),
request.quantity(), request.unit(), request.bestBefore(), request.openedOn());
item = pantryItemRepository.save(item);
return toResponse(item);
}
public PantryItemResponse updateItem(UUID householdId, UUID itemId, UpdatePantryItemRequest request) {
PantryItem item = pantryItemRepository.findByIdAndHouseholdId(itemId, householdId)
.orElseThrow(() -> new ResourceNotFoundException("Pantry item not found"));
if (request.quantity() != null) item.setQuantity(request.quantity());
if (request.unit() != null) item.setUnit(request.unit());
if (request.bestBefore() != null) item.setBestBefore(request.bestBefore());
if (request.openedOn() != null) item.setOpenedOn(request.openedOn());
item = pantryItemRepository.save(item);
return toResponse(item);
}
public void deleteItem(UUID householdId, UUID itemId) {
PantryItem item = pantryItemRepository.findByIdAndHouseholdId(itemId, householdId)
.orElseThrow(() -> new ResourceNotFoundException("Pantry item not found"));
pantryItemRepository.delete(item);
}
private PantryItemResponse toResponse(PantryItem item) {
UUID ingredientId = item.getIngredient() != null ? item.getIngredient().getId() : null;
String name = item.getIngredient() != null ? item.getIngredient().getName() : item.getCustomName();
CategoryRef category = null;
if (item.getIngredient() != null && item.getIngredient().getCategory() != null) {
category = new CategoryRef(
item.getIngredient().getCategory().getId(),
item.getIngredient().getCategory().getName());
}
return new PantryItemResponse(
item.getId(), ingredientId, name, category,
item.getQuantity(), item.getUnit(), item.getBestBefore(), item.getOpenedOn());
}
}

View File

@@ -1,98 +0,0 @@
package com.recipeapp.pantry;
import com.recipeapp.common.ResourceNotFoundException;
import com.recipeapp.common.ValidationException;
import com.recipeapp.household.HouseholdRepository;
import com.recipeapp.household.entity.Household;
import com.recipeapp.pantry.dto.*;
import com.recipeapp.pantry.entity.PantryItem;
import com.recipeapp.recipe.IngredientRepository;
import com.recipeapp.recipe.dto.RecipeDetailResponse.CategoryRef;
import com.recipeapp.recipe.entity.Ingredient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.UUID;
@Service
@Transactional
public class PantryServiceImpl implements PantryService {
private final PantryItemRepository pantryItemRepository;
private final HouseholdRepository householdRepository;
private final IngredientRepository ingredientRepository;
public PantryServiceImpl(PantryItemRepository pantryItemRepository,
HouseholdRepository householdRepository,
IngredientRepository ingredientRepository) {
this.pantryItemRepository = pantryItemRepository;
this.householdRepository = householdRepository;
this.ingredientRepository = ingredientRepository;
}
@Override
@Transactional(readOnly = true)
public List<PantryItemResponse> listItems(UUID householdId) {
return pantryItemRepository.findByHouseholdIdOrderByBestBeforeAscNullsLast(householdId)
.stream()
.map(this::toResponse)
.toList();
}
@Override
public PantryItemResponse createItem(UUID householdId, CreatePantryItemRequest request) {
Household household = householdRepository.findById(householdId)
.orElseThrow(() -> new ResourceNotFoundException("Household not found"));
Ingredient ingredient = null;
if (request.ingredientId() != null) {
ingredient = ingredientRepository.findById(request.ingredientId())
.orElseThrow(() -> new ResourceNotFoundException("Ingredient not found"));
}
if (request.ingredientId() == null && (request.customName() == null || request.customName().isBlank())) {
throw new ValidationException("Either ingredientId or customName must be provided");
}
PantryItem item = new PantryItem(household, ingredient, request.customName(),
request.quantity(), request.unit(), request.bestBefore(), request.openedOn());
item = pantryItemRepository.save(item);
return toResponse(item);
}
@Override
public PantryItemResponse updateItem(UUID householdId, UUID itemId, UpdatePantryItemRequest request) {
PantryItem item = pantryItemRepository.findByIdAndHouseholdId(itemId, householdId)
.orElseThrow(() -> new ResourceNotFoundException("Pantry item not found"));
if (request.quantity() != null) item.setQuantity(request.quantity());
if (request.unit() != null) item.setUnit(request.unit());
if (request.bestBefore() != null) item.setBestBefore(request.bestBefore());
if (request.openedOn() != null) item.setOpenedOn(request.openedOn());
item = pantryItemRepository.save(item);
return toResponse(item);
}
@Override
public void deleteItem(UUID householdId, UUID itemId) {
PantryItem item = pantryItemRepository.findByIdAndHouseholdId(itemId, householdId)
.orElseThrow(() -> new ResourceNotFoundException("Pantry item not found"));
pantryItemRepository.delete(item);
}
private PantryItemResponse toResponse(PantryItem item) {
UUID ingredientId = item.getIngredient() != null ? item.getIngredient().getId() : null;
String name = item.getIngredient() != null ? item.getIngredient().getName() : item.getCustomName();
CategoryRef category = null;
if (item.getIngredient() != null && item.getIngredient().getCategory() != null) {
category = new CategoryRef(
item.getIngredient().getCategory().getId(),
item.getIngredient().getCategory().getName());
}
return new PantryItemResponse(
item.getId(), ingredientId, name, category,
item.getQuantity(), item.getUnit(), item.getBestBefore(), item.getOpenedOn());
}
}