Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.cuoco.adapter.in.controller.model.ImageIngredientsResponse;
import com.cuoco.adapter.in.controller.model.IngredientResponse;
import com.cuoco.adapter.in.controller.model.MealPrepResponse;
import com.cuoco.adapter.in.controller.model.TextRequest;
import com.cuoco.adapter.in.controller.model.UnitResponse;
import com.cuoco.application.port.in.GetIngredientsFromAudioCommand;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,17 @@

import com.cuoco.adapter.in.controller.model.IngredientRequest;
import com.cuoco.adapter.in.controller.model.IngredientResponse;
import com.cuoco.adapter.in.controller.model.MealPrepConfigurationRequest;
import com.cuoco.adapter.in.controller.model.MealPrepFilterRequest;
import com.cuoco.adapter.in.controller.model.MealPrepRequest;
import com.cuoco.adapter.in.controller.model.MealPrepResponse;
import com.cuoco.adapter.in.controller.model.ParametricResponse;
import com.cuoco.adapter.in.controller.model.RecipeResponse;
import com.cuoco.adapter.in.controller.model.StepResponse;
import com.cuoco.adapter.in.controller.model.UnitResponse;
import com.cuoco.adapter.out.hibernate.CreateUserDatabaseRepositoryAdapter;
import com.cuoco.application.port.in.GetMealPrepByIdQuery;
import com.cuoco.application.port.in.GetMealPrepFromIngredientsCommand;
import com.cuoco.application.usecase.model.Ingredient;
import com.cuoco.application.usecase.model.MealPrep;
import com.cuoco.application.usecase.model.Recipe;
import com.cuoco.application.usecase.model.Step;
import com.cuoco.shared.GlobalExceptionHandler;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.ArraySchema;
Expand Down Expand Up @@ -76,7 +74,6 @@ public ResponseEntity<List<MealPrepResponse>> generate(@RequestBody MealPrepRequ
log.info("Executing GET mealPrep from ingredients with body {}", mealPrepRequest);

List<MealPrep> mealPreps = getMealPrepFromIngredientsCommand.execute(buildGenerateMealPrepCommand(mealPrepRequest));

List<MealPrepResponse> mealPrepsResponse = mealPreps.stream().map(this::buildResponse).toList();

log.info("Successfully generated recipes");
Expand Down Expand Up @@ -121,6 +118,10 @@ public ResponseEntity<MealPrepResponse> getById(@PathVariable Long id) {
}

private GetMealPrepFromIngredientsCommand.Command buildGenerateMealPrepCommand(MealPrepRequest mealPrepRequest) {

if(mealPrepRequest.getFilters() == null) mealPrepRequest.setFilters(new MealPrepFilterRequest());
if(mealPrepRequest.getConfiguration() == null) mealPrepRequest.setConfiguration(new MealPrepConfigurationRequest());

return GetMealPrepFromIngredientsCommand.Command.builder()
.ingredients(mealPrepRequest.getIngredients().stream().map(this::buildIngredient).toList())
.freeze(mealPrepRequest.getFilters().getFreeze())
Expand All @@ -131,6 +132,8 @@ private GetMealPrepFromIngredientsCommand.Command buildGenerateMealPrepCommand(M
.typeIds(mealPrepRequest.getFilters().getTypeIds())
.allergiesIds(mealPrepRequest.getFilters().getAllergiesIds())
.dietaryNeedsIds(mealPrepRequest.getFilters().getDietaryNeedsIds())
.size(mealPrepRequest.getConfiguration().getSize())
.notInclude(mealPrepRequest.getConfiguration().getNotInclude())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.cuoco.adapter.in.controller.model.IngredientRequest;
import com.cuoco.adapter.in.controller.model.IngredientResponse;
import com.cuoco.adapter.in.controller.model.ParametricResponse;
import com.cuoco.adapter.in.controller.model.RecipeConfiguration;
import com.cuoco.adapter.in.controller.model.RecipeConfigurationRequest;
import com.cuoco.adapter.in.controller.model.RecipeFilterRequest;
import com.cuoco.adapter.in.controller.model.RecipeRequest;
import com.cuoco.adapter.in.controller.model.RecipeResponse;
Expand Down Expand Up @@ -86,10 +86,10 @@ public RecipeControllerAdapter(
)
)
})
public ResponseEntity<RecipeResponse> getRecipe(@PathVariable(name = "id") Long recipeId) {
public ResponseEntity<RecipeResponse> getRecipe(@PathVariable(name = "id") Long recipeId, @RequestParam(required = false) Integer servings) {
log.info("Executing GET for find recipe with ID {}", recipeId);

Recipe recipe = getRecipeByIdQuery.execute(recipeId);
Recipe recipe = getRecipeByIdQuery.execute(recipeId, servings);

RecipeResponse recipeResponse = buildResponse(recipe);

Expand Down Expand Up @@ -208,7 +208,7 @@ private GetRecipesFromIngredientsCommand.Command buildGenerateRecipeCommand(Reci
recipeRequest.setFilters(new RecipeFilterRequest());
}

if(recipeRequest.getConfiguration() == null) recipeRequest.setConfiguration(new RecipeConfiguration());
if(recipeRequest.getConfiguration() == null) recipeRequest.setConfiguration(new RecipeConfigurationRequest());

return GetRecipesFromIngredientsCommand.Command.builder()
.filtersEnabled(filtersEnabled)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.cuoco.adapter.in.controller.model;

import com.cuoco.application.usecase.model.Calendar;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.cuoco.adapter.in.controller.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.Data;

import java.util.List;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@JsonIgnoreProperties(ignoreUnknown = true)
public class MealPrepConfigurationRequest {
private Integer size;
private List<Long> notInclude;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ public class MealPrepRequest {
@NotEmpty(message = "Es requerido un ingrediente como minimo")
private List<IngredientRequest> ingredients;
private MealPrepFilterRequest filters;
private MealPrepConfigurationRequest configuration;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@ public class MealPrepResponse {
private List<StepResponse> steps;
private List<RecipeResponse> recipes;
private List<IngredientResponse> ingredients;

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@JsonIgnoreProperties(ignoreUnknown = true)
public class RecipeConfiguration {
public class RecipeConfigurationRequest {
private Integer size;
private List<Long> notInclude;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ public class RecipeRequest {
@NotEmpty(message = "Es requerido un ingrediente como minimo")
private List<IngredientRequest> ingredients;
private RecipeFilterRequest filters;
private RecipeConfiguration configuration;
private RecipeConfigurationRequest configuration;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,13 @@
import com.cuoco.adapter.out.hibernate.model.RecipeHibernateModel;
import com.cuoco.adapter.out.hibernate.model.RecipeIngredientsHibernateModel;
import com.cuoco.adapter.out.hibernate.model.RecipeStepsHibernateModel;
import com.cuoco.adapter.out.hibernate.model.UnitHibernateModel;
import com.cuoco.adapter.out.hibernate.repository.CreateIngredientHibernateRepositoryAdapter;
import com.cuoco.adapter.out.hibernate.repository.CreateRecipeHibernateRepositoryAdapter;
import com.cuoco.adapter.out.hibernate.repository.CreateRecipeIngredientsHibernateRepositoryAdapter;
import com.cuoco.adapter.out.hibernate.repository.FindRecipeByNameHibernateRepositoryAdapter;
import com.cuoco.adapter.out.hibernate.repository.GetIngredientByNameHibernateRepositoryAdapter;
import com.cuoco.adapter.out.hibernate.repository.GetUnitBySymbolHibernateRepositoryAdapter;
import com.cuoco.application.port.out.CreateRecipeRepository;
import com.cuoco.application.usecase.model.Allergy;
import com.cuoco.application.usecase.model.DietaryNeed;
import com.cuoco.application.usecase.model.Ingredient;
import com.cuoco.application.usecase.model.MealType;
import com.cuoco.application.usecase.model.Recipe;
import com.cuoco.application.usecase.model.Step;
import jakarta.transaction.Transactional;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import com.cuoco.adapter.out.hibernate.repository.CreateAllUserRecipeCalendarsHibernateRepositoryAdapter;
import com.cuoco.application.port.out.CreateUserCalendarRepository;
import com.cuoco.application.usecase.model.Calendar;
import com.cuoco.application.usecase.model.CalendarRecipe;
import com.cuoco.application.usecase.model.MealType;
import com.cuoco.application.usecase.model.Recipe;
import com.cuoco.application.usecase.model.CalendarRecipe;
import com.cuoco.application.usecase.model.User;
import com.cuoco.application.usecase.model.UserCalendar;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
import com.cuoco.adapter.out.hibernate.repository.CreateUserHibernateRepositoryAdapter;
import com.cuoco.adapter.out.hibernate.repository.CreateUserPreferencesHibernateRepositoryAdapter;
import com.cuoco.application.port.out.CreateUserRepository;
import com.cuoco.application.usecase.model.Allergy;
import com.cuoco.application.usecase.model.DietaryNeed;
import com.cuoco.application.usecase.model.User;
import com.cuoco.application.usecase.model.UserPreferences;
import jakarta.transaction.Transactional;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import com.cuoco.application.port.out.DeleteUserCalendarRepository;
import com.cuoco.application.usecase.model.Calendar;
import com.cuoco.application.usecase.model.CalendarRecipe;
import com.cuoco.application.usecase.model.MealType;
import com.cuoco.application.usecase.model.Recipe;
import com.cuoco.application.usecase.model.User;
import com.cuoco.application.usecase.model.UserCalendar;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.cuoco.adapter.out.hibernate;

import com.cuoco.adapter.out.hibernate.model.RecipeHibernateModel;
import com.cuoco.adapter.out.hibernate.repository.CreateRecipeHibernateRepositoryAdapter;
import com.cuoco.adapter.out.hibernate.repository.FindRecipeByNameHibernateRepositoryAdapter;
import com.cuoco.application.port.out.FindRecipeByNameRepository;
import com.cuoco.application.usecase.model.Recipe;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.cuoco.adapter.out.hibernate;

import com.cuoco.adapter.out.hibernate.model.MealPrepHibernateModel;
import com.cuoco.adapter.out.hibernate.repository.GetAllMealPrepsByIdsHibernateRepositoryAdapter;
import com.cuoco.application.port.out.GetAllMealPrepsByIdsRepository;
import com.cuoco.application.usecase.model.MealPrep;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.util.List;

@Slf4j
@Repository
@RequiredArgsConstructor
public class GetAllMealPrepsByIdsDatabaseRepositoryAdapter implements GetAllMealPrepsByIdsRepository {

private final GetAllMealPrepsByIdsHibernateRepositoryAdapter getAllMealPrepsByIdsHibernateRepositoryAdapter;

@Override
public List<MealPrep> execute(List<Long> ids) {
log.info("Get all meal preps by ids: {}", ids);

List<MealPrepHibernateModel> recipes = getAllMealPrepsByIdsHibernateRepositoryAdapter.findAllById(ids);
return recipes.stream().map(MealPrepHibernateModel::toDomain).toList();
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
package com.cuoco.adapter.out.hibernate;

import com.cuoco.adapter.out.hibernate.model.*;
import com.cuoco.adapter.out.hibernate.repository.*;
import com.cuoco.application.exception.BadRequestException;
import com.cuoco.adapter.out.hibernate.model.AllergyHibernateModel;
import com.cuoco.adapter.out.hibernate.model.CookLevelHibernateModel;
import com.cuoco.adapter.out.hibernate.model.DietHibernateModel;
import com.cuoco.adapter.out.hibernate.model.DietaryNeedHibernateModel;
import com.cuoco.adapter.out.hibernate.model.PlanHibernateModel;
import com.cuoco.adapter.out.hibernate.model.UserHibernateModel;
import com.cuoco.adapter.out.hibernate.model.UserPreferencesHibernateModel;
import com.cuoco.adapter.out.hibernate.repository.CreateUserHibernateRepositoryAdapter;
import com.cuoco.adapter.out.hibernate.repository.CreateUserPreferencesHibernateRepositoryAdapter;
import com.cuoco.application.port.out.UpdateUserRepository;
import com.cuoco.application.usecase.model.Allergy;
import com.cuoco.application.usecase.model.CookLevel;
import com.cuoco.application.usecase.model.Diet;
import com.cuoco.application.usecase.model.DietaryNeed;
import com.cuoco.application.usecase.model.User;
import com.cuoco.application.usecase.model.UserPreferences;
import com.cuoco.shared.model.ErrorDescription;
import jakarta.transaction.Transactional;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Repository
@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
import com.cuoco.application.usecase.model.Ingredient;
import com.cuoco.application.usecase.model.Recipe;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.Lob;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.cuoco.adapter.out.hibernate.repository;

import com.cuoco.adapter.out.hibernate.model.MealPrepHibernateModel;
import org.springframework.data.jpa.repository.JpaRepository;

public interface GetAllMealPrepsByIdsHibernateRepositoryAdapter extends JpaRepository<MealPrepHibernateModel, Long> {}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.cuoco.adapter.exception.NotAvailableException;
import com.cuoco.adapter.exception.UnprocessableException;
import com.cuoco.adapter.out.rest.gemini.model.MealPrepResponseGeminiModel;
import com.cuoco.adapter.out.rest.gemini.model.RecipeRequestGeminiModel;
import com.cuoco.adapter.out.rest.gemini.model.wrapper.ContentGeminiRequestModel;
import com.cuoco.adapter.out.rest.gemini.model.wrapper.GeminiResponseModel;
import com.cuoco.adapter.out.rest.gemini.model.wrapper.GenerationConfigurationGeminiRequestModel;
Expand All @@ -11,7 +12,11 @@
import com.cuoco.adapter.out.rest.gemini.utils.Constants;
import com.cuoco.adapter.out.rest.gemini.utils.Utils;
import com.cuoco.application.port.out.GetMealPrepsFromIngredientsRepository;
import com.cuoco.application.usecase.model.Allergy;
import com.cuoco.application.usecase.model.DietaryNeed;
import com.cuoco.application.usecase.model.Ingredient;
import com.cuoco.application.usecase.model.MealPrep;
import com.cuoco.application.usecase.model.MealType;
import com.cuoco.application.usecase.model.Recipe;
import com.cuoco.shared.FileReader;
import com.cuoco.shared.model.ErrorDescription;
Expand Down Expand Up @@ -56,17 +61,13 @@ public List<MealPrep> execute(MealPrep mealPrep) {
try {
log.info("Executing meal prep generation from Gemini with ingredients: {}", mealPrep.getIngredients());

List<String> recipesJson = mealPrep.getRecipes().stream().map(value -> {
try {
return objectMapper.writeValueAsString(value);
} catch (JsonProcessingException e) {
throw new NotAvailableException(ErrorDescription.NOT_AVAILABLE.getValue());
}
}).toList();
String recipesJson = buildRecipesJson(mealPrep.getRecipes());
String mealPrepsToNotInclude = buildMealPrepsToNotInclude(mealPrep.getConfiguration().getNotInclude());

String basicPrompt = BASIC_PROMPT
.replace(Constants.RECIPES.getValue(), objectMapper.writeValueAsString(recipesJson))
.replace(Constants.MAX_MEAL_PREPS.getValue(), mealPrep.getFilters().getServings().toString())
.replace(Constants.RECIPES.getValue(), recipesJson)
.replace(Constants.NOT_INCLUDE.getValue(), mealPrepsToNotInclude)
.replace(Constants.MAX_MEAL_PREPS.getValue(), mealPrep.getConfiguration().getSize().toString())
.replace(Constants.FREEZE.getValue(), mealPrep.getFilters().getFreeze().toString());

PromptBodyGeminiRequestModel prompt = buildPromptBody(basicPrompt);
Expand Down Expand Up @@ -96,14 +97,40 @@ public List<MealPrep> execute(MealPrep mealPrep) {

return mealPreps;
} catch (JsonProcessingException e) {
log.error("Error generating meal preps from Gemini", e);
throw new NotAvailableException("Failed to generate meal preps");
log.error("Failed to convert JSON in meal preps gemini adapter. ", e);
throw new NotAvailableException(ErrorDescription.NOT_AVAILABLE.getValue());
} catch (Exception e) {
log.error("Error generating meal preps from Gemini", e);
throw new UnprocessableException("Failed to generate meal preps");
throw new NotAvailableException(ErrorDescription.NOT_AVAILABLE.getValue());
}
}

private String buildRecipesJson(List<Recipe> recipes) throws JsonProcessingException {
List<RecipeRequestGeminiModel> requests = recipes.stream().map(this::buildRecipeRequest).toList();
return objectMapper.writeValueAsString(requests);
}

private RecipeRequestGeminiModel buildRecipeRequest(Recipe recipe) {
return RecipeRequestGeminiModel.builder()
.id(recipe.getId())
.name(recipe.getName())
.subtitle(recipe.getSubtitle())
.description(recipe.getDescription())
.preparationTime(recipe.getPreparationTime().getDescription())
.cookLevelName(recipe.getCookLevel().getDescription())
.dietName(recipe.getDiet().getDescription())
.mealTypesNames(recipe.getMealTypes().stream().map(MealType::getDescription).toList())
.allergiesNames(recipe.getAllergies().stream().map(Allergy::getDescription).toList())
.dietaryNeedsNames(recipe.getDietaryNeeds().stream().map(DietaryNeed::getDescription).toList())
.ingredientNames(recipe.getIngredients().stream().map(Ingredient::getName).toList())
.build();
}

private String buildMealPrepsToNotInclude(List<MealPrep> mealPrepsToNotInclude) throws JsonProcessingException {
List<String> notInclude = mealPrepsToNotInclude.stream().map(MealPrep::getTitle).toList();
return objectMapper.writeValueAsString(notInclude);
}

private PromptBodyGeminiRequestModel buildPromptBody(String prompt) {
return PromptBodyGeminiRequestModel.builder()
.contents(List.of(ContentGeminiRequestModel.builder().parts(buildPartsRequest(prompt)).build()))
Expand Down
Loading