getIngredientUsage(@PathVariable Long id) {
+ if (ingredientService.findById(id).isEmpty()) {
+ return ResponseEntity.notFound().build();
+ }
+
+ // Server-side computation of how many recipes reference this ingredient
+ long usedInRecipes = ingredientService.countUsage(id);
+ return ResponseEntity.ok(new IngredientUsageResponse(id, usedInRecipes));
+ }
+
+
+
/**
* Update an existing ingredient by its ID.
* Maps to PATCH /api/ingredients/{id}
@@ -126,7 +141,7 @@ public class IngredientController {
updated.setId(id);
return ingredientService.update(id, updated)
.map(saved -> {
- messagingTemplate.convertAndSend(Topics.INGREDIENTS, new CreateIngredientMessage(saved));
+ messagingTemplate.convertAndSend(Topics.INGREDIENTS, new UpdateIngredientMessage(saved));
return ResponseEntity.ok(saved);
})
.orElseGet(() -> ResponseEntity.notFound().build());
@@ -139,7 +154,7 @@ public class IngredientController {
*
* If an ingredient with the same name already exists,
* returns 400 Bad Request.
- *
+ *
* If the ingredient is created successfully,
* returns the created ingredient with 200 OK.
*
@@ -157,7 +172,7 @@ public class IngredientController {
return ingredientService.create(ingredient)
.map(saved -> {
- messagingTemplate.convertAndSend(Topics.INGREDIENTS, new UpdateIngredientMessage(saved));
+ messagingTemplate.convertAndSend(Topics.INGREDIENTS, new CreateIngredientMessage(saved));
return ResponseEntity.ok(saved);
})
.orElseGet(() -> ResponseEntity.badRequest().build());
@@ -186,4 +201,6 @@ public class IngredientController {
messagingTemplate.convertAndSend(Topics.INGREDIENTS, new DeleteIngredientMessage(id));
return ResponseEntity.ok(true);
}
+
+ public record IngredientUsageResponse(Long ingredientId, long usedInRecipes){}
}
diff --git a/server/src/main/java/server/api/RecipeController.java b/server/src/main/java/server/api/RecipeController.java
index 1ba4edc..7021bdd 100644
--- a/server/src/main/java/server/api/RecipeController.java
+++ b/server/src/main/java/server/api/RecipeController.java
@@ -25,17 +25,21 @@ import server.service.RecipeService;
import java.util.List;
import java.util.Optional;
+import java.util.logging.Logger;
@RestController
@RequestMapping("/api")
public class RecipeController {
+
+ private static final Logger logger = Logger.getLogger(RecipeController.class.getName());
+ private SimpMessagingTemplate messagingTemplate;
+ private RecipeService recipeService;
private RecipeRepository recipeRepository;
- private final SimpMessagingTemplate messagingTemplate;
- private final RecipeService recipeService;
public RecipeController(RecipeService recipeService, SimpMessagingTemplate messagingTemplate) {
this.recipeService = recipeService;
this.messagingTemplate = messagingTemplate;
+ logger.info("Initialized controller.");
}
/**
@@ -48,6 +52,7 @@ public class RecipeController {
*/
@GetMapping("/recipe/{id}")
public ResponseEntity getRecipe(@PathVariable Long id) {
+ logger.info("GET /recipe/" + id + " called.");
return recipeService.findById(id)
.map(ResponseEntity::ok)
.orElseGet(() -> ResponseEntity.notFound().build());
@@ -62,6 +67,7 @@ public class RecipeController {
*/
@GetMapping("/recipes")
public ResponseEntity> getRecipes(@RequestParam Optional limit) {
+ logger.info("GET /recipes called.");
return ResponseEntity.ok(
// Choose the right overload. One has a limit, other doesn't.
limit.map(recipeService::findAll).orElseGet(recipeService::findAll)
@@ -78,6 +84,7 @@ public class RecipeController {
*/
@PostMapping("/recipe/{id}")
public ResponseEntity updateRecipe(@PathVariable Long id, @RequestBody Recipe recipe) {
+ logger.info("POST /recipe/" + id + " called.");
return recipeService.update(id, recipe)
.map(saved -> {
messagingTemplate.convertAndSend(Topics.RECIPES, new UpdateRecipeMessage(saved)); // Send to WS.
@@ -98,6 +105,7 @@ public class RecipeController {
*/
@PutMapping("/recipe/new")
public ResponseEntity createRecipe(@RequestBody Recipe recipe) {
+ logger.info("POST /recipe/new called.");
return recipeService.create(recipe)
.map(saved -> {
messagingTemplate.convertAndSend(Topics.RECIPES, new CreateRecipeMessage(saved)); // Send to WS.
@@ -116,6 +124,7 @@ public class RecipeController {
*/
@DeleteMapping("/recipe/{id}")
public ResponseEntity deleteRecipe(@PathVariable Long id) {
+ logger.info("DELETE /recipe/" + id + " called.");
if (!recipeService.delete(id)) {
return ResponseEntity.badRequest().build();
}
diff --git a/server/src/main/java/server/service/IngredientService.java b/server/src/main/java/server/service/IngredientService.java
index 8a79659..37cb76c 100644
--- a/server/src/main/java/server/service/IngredientService.java
+++ b/server/src/main/java/server/service/IngredientService.java
@@ -4,16 +4,21 @@ import commons.Ingredient;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import server.database.IngredientRepository;
+import server.database.RecipeIngredientRepository;
import java.util.List;
import java.util.Optional;
@Service
public class IngredientService {
- IngredientRepository ingredientRepository;
- public IngredientService(IngredientRepository ingredientRepository) {
+ private final IngredientRepository ingredientRepository;
+ private final RecipeIngredientRepository recipeIngredientRepository;
+
+ public IngredientService(IngredientRepository ingredientRepository,
+ RecipeIngredientRepository recipeIngredientRepository) {
this.ingredientRepository = ingredientRepository;
+ this.recipeIngredientRepository = recipeIngredientRepository;
}
public Optional findById(Long id) {
@@ -30,12 +35,16 @@ public class IngredientService {
/**
* Creates a new ingredient. Returns empty if the recipe with the same name or id already exists.
+ *
* @param ingredient Ingredient to be saved in the db.
* @return The created ingredient (the ingredient arg with a new assigned id) or empty if it already exists in db.
*/
public Optional create(Ingredient ingredient) {
- if (ingredientRepository.existsByName(ingredient.getName()) ||
- ingredientRepository.existsById(ingredient.getId())) {
+ if (ingredient == null || ingredient.getName() == null) {
+ return Optional.empty();
+ }
+
+ if (ingredientRepository.existsByName(ingredient.getName())) {
return Optional.empty();
}
@@ -44,7 +53,8 @@ public class IngredientService {
/**
* Updates an ingredient. The ingredient with the provided id will be replaced (in db) with the provided ingredient.
- * @param id id of the ingredient to update.
+ *
+ * @param id id of the ingredient to update.
* @param ingredient Ingredient to be saved in the db.
* @return The created ingredient (the ingredient arg with a new assigned id.)
*/
@@ -64,4 +74,10 @@ public class IngredientService {
return true;
}
+ //actually counting the amount used in recipes
+
+ public long countUsage(long ingredientId) {
+ return recipeIngredientRepository.countByIngredientId(ingredientId);
+
+ }
}