diff --git a/build.gradle b/build.gradle index d97cdb9..ddc6399 100644 --- a/build.gradle +++ b/build.gradle @@ -29,6 +29,10 @@ sourceSets { } configurations { + compileOnly { + extendsFrom annotationProcessor + } + testFixturesImplementation { extendsFrom implementation } @@ -60,6 +64,8 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' // flyway implementation 'org.flywaydb:flyway-core' diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e644113..f8e1ee3 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeRepositoryTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeRepositoryTests.java index 00a6ee9..3829ee1 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeRepositoryTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeRepositoryTests.java @@ -37,57 +37,57 @@ public class RecipeRepositoryTests { @Test public void findsAllPublicRecipes() { - final RecipeEntity publicRecipe = new RecipeEntity(); + final Recipe publicRecipe = new Recipe(); publicRecipe.setCreated(OffsetDateTime.now()); publicRecipe.setSlug(UUID.randomUUID().toString()); - publicRecipe.setPublic(true); + publicRecipe.setIsPublic(true); publicRecipe.setOwner(this.seedUser()); publicRecipe.setTitle("Public Recipe"); publicRecipe.setRawText("Hello, World!"); - final RecipeEntity savedRecipe = this.recipeRepository.save(publicRecipe); + final Recipe savedRecipe = this.recipeRepository.save(publicRecipe); - final List publicRecipes = this.recipeRepository.findAllByIsPublicIsTrue(); + final List publicRecipes = this.recipeRepository.findAllByIsPublicIsTrue(); assertThat(publicRecipes).anyMatch(recipeEntity -> recipeEntity.getId().equals(savedRecipe.getId())); } @Test public void doesNotFindNonPublicRecipe() { - final RecipeEntity nonPublicRecipe = new RecipeEntity(); + final Recipe nonPublicRecipe = new Recipe(); nonPublicRecipe.setCreated(OffsetDateTime.now()); nonPublicRecipe.setSlug(UUID.randomUUID().toString()); nonPublicRecipe.setOwner(this.seedUser()); nonPublicRecipe.setTitle("Non-Public Recipe"); nonPublicRecipe.setRawText("Hello, World!"); - final RecipeEntity savedRecipe = this.recipeRepository.save(nonPublicRecipe); + final Recipe savedRecipe = this.recipeRepository.save(nonPublicRecipe); - final List publicRecipes = this.recipeRepository.findAllByIsPublicIsTrue(); + final List publicRecipes = this.recipeRepository.findAllByIsPublicIsTrue(); assertThat(publicRecipes).noneMatch(recipeEntity -> recipeEntity.getId().equals(savedRecipe.getId())); } @Test public void findsAllForViewer() { - final RecipeEntity recipe = new RecipeEntity(); + final Recipe recipe = new Recipe(); recipe.setCreated(OffsetDateTime.now()); recipe.setSlug(UUID.randomUUID().toString()); recipe.setOwner(this.seedUser()); recipe.setTitle("Test Recipe"); recipe.setRawText("Hello, World!"); - final RecipeEntity saved = this.recipeRepository.save(recipe); + final Recipe saved = this.recipeRepository.save(recipe); final UserEntity viewer = this.seedUser(); - final Set viewers = new HashSet<>(recipe.getViewerEntities()); + final Set viewers = new HashSet<>(recipe.getViewers()); viewers.add(viewer); saved.setViewers(viewers); this.recipeRepository.save(saved); - final List viewable = this.recipeRepository.findAllByViewersContaining(viewer); + final List viewable = this.recipeRepository.findAllByViewersContaining(viewer); assertThat(viewable.size()).isEqualTo(1); } @Test public void doesNotIncludeNonViewable() { - final RecipeEntity recipe = new RecipeEntity(); + final Recipe recipe = new Recipe(); recipe.setCreated(OffsetDateTime.now()); recipe.setSlug(UUID.randomUUID().toString()); recipe.setOwner(this.seedUser()); @@ -96,7 +96,7 @@ public class RecipeRepositoryTests { this.recipeRepository.save(recipe); final UserEntity viewer = this.seedUser(); - final List viewable = this.recipeRepository.findAllByViewersContaining(viewer); + final List viewable = this.recipeRepository.findAllByViewersContaining(viewer); assertThat(viewable.size()).isEqualTo(0); } diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeServiceTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeServiceTests.java index d761d09..76d6d61 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeServiceTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeServiceTests.java @@ -100,7 +100,7 @@ public class RecipeServiceTests { assertThat(byId.getSlug(), is(recipe.getSlug())); assertThat(byId.getTitle(), is("My Recipe")); assertThat(byId.getRawText(), is("Hello!")); - assertThat(byId.isPublic(), is(true)); + assertThat(byId.getIsPublic(), is(true)); } @Test diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepositoryTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepositoryTests.java index 3ea19bf..ad9f95e 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepositoryTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepositoryTests.java @@ -1,7 +1,7 @@ package app.mealsmadeeasy.api.recipe.star; import app.mealsmadeeasy.api.IntegrationTestsExtension; -import app.mealsmadeeasy.api.recipe.RecipeEntity; +import app.mealsmadeeasy.api.recipe.Recipe; import app.mealsmadeeasy.api.recipe.RecipeRepository; import app.mealsmadeeasy.api.user.UserEntity; import app.mealsmadeeasy.api.user.UserRepository; @@ -38,8 +38,8 @@ public class RecipeStarRepositoryTests { return this.userRepository.save(draft); } - private RecipeEntity getTestRecipe(UserEntity owner) { - final RecipeEntity recipeDraft = new RecipeEntity(); + private Recipe getTestRecipe(UserEntity owner) { + final Recipe recipeDraft = new Recipe(); recipeDraft.setCreated(OffsetDateTime.now()); recipeDraft.setSlug(UUID.randomUUID().toString()); recipeDraft.setOwner(owner); @@ -51,9 +51,9 @@ public class RecipeStarRepositoryTests { @Test public void returnsTrueIfStarer() { final UserEntity owner = this.seedUser(); - final RecipeEntity recipe = this.getTestRecipe(owner); + final Recipe recipe = this.getTestRecipe(owner); - final RecipeStarEntity starDraft = new RecipeStarEntity(); + final RecipeStar starDraft = new RecipeStar(); final RecipeStarId starId = new RecipeStarId(); starId.setRecipeId(recipe.getId()); starId.getOwnerId(owner.getId()); @@ -73,7 +73,7 @@ public class RecipeStarRepositoryTests { @Test public void returnsFalseIfNotStarer() { final UserEntity owner = this.seedUser(); - final RecipeEntity recipe = this.getTestRecipe(owner); + final Recipe recipe = this.getTestRecipe(owner); assertThat( this.recipeStarRepository.isStarer( recipe.getOwner().getUsername(), diff --git a/src/main/java/app/mealsmadeeasy/api/BackfillRecipeEmbeddings.java b/src/main/java/app/mealsmadeeasy/api/BackfillRecipeEmbeddings.java index f278da3..72c1027 100644 --- a/src/main/java/app/mealsmadeeasy/api/BackfillRecipeEmbeddings.java +++ b/src/main/java/app/mealsmadeeasy/api/BackfillRecipeEmbeddings.java @@ -1,7 +1,7 @@ package app.mealsmadeeasy.api; +import app.mealsmadeeasy.api.recipe.Recipe; import app.mealsmadeeasy.api.recipe.RecipeEmbeddingEntity; -import app.mealsmadeeasy.api.recipe.RecipeEntity; import app.mealsmadeeasy.api.recipe.RecipeRepository; import app.mealsmadeeasy.api.recipe.RecipeService; import org.slf4j.Logger; @@ -37,20 +37,20 @@ public class BackfillRecipeEmbeddings implements ApplicationRunner { @Override public void run(ApplicationArguments args) { - final List recipeEntities = this.recipeRepository.findAllByEmbeddingIsNull(); - for (final RecipeEntity recipeEntity : recipeEntities) { - logger.info("Calculating embedding for {}", recipeEntity); - final String renderedMarkdown = this.recipeService.getRenderedMarkdown(recipeEntity); - final String toEmbed = "

" + recipeEntity.getTitle() + "

" + renderedMarkdown; + final List recipeEntities = this.recipeRepository.findAllByEmbeddingIsNull(); + for (final Recipe recipe : recipeEntities) { + logger.info("Calculating embedding for {}", recipe); + final String renderedMarkdown = this.recipeService.getRenderedMarkdown(recipe); + final String toEmbed = "

" + recipe.getTitle() + "

" + renderedMarkdown; final float[] embedding = this.embeddingModel.embed(toEmbed); final RecipeEmbeddingEntity recipeEmbedding = new RecipeEmbeddingEntity(); - recipeEmbedding.setRecipe(recipeEntity); + recipeEmbedding.setRecipe(recipe); recipeEmbedding.setEmbedding(embedding); recipeEmbedding.setTimestamp(OffsetDateTime.now()); - recipeEntity.setEmbedding(recipeEmbedding); + recipe.setEmbedding(recipeEmbedding); - this.recipeRepository.save(recipeEntity); + this.recipeRepository.save(recipe); } this.recipeRepository.flush(); } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/Recipe.java b/src/main/java/app/mealsmadeeasy/api/recipe/Recipe.java index 248be5b..65e75e3 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/Recipe.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/Recipe.java @@ -1,28 +1,83 @@ package app.mealsmadeeasy.api.recipe; -import app.mealsmadeeasy.api.image.Image; +import app.mealsmadeeasy.api.image.S3ImageEntity; import app.mealsmadeeasy.api.recipe.comment.RecipeComment; import app.mealsmadeeasy.api.recipe.star.RecipeStar; -import app.mealsmadeeasy.api.user.User; +import app.mealsmadeeasy.api.user.UserEntity; +import jakarta.persistence.*; +import lombok.Data; import org.jetbrains.annotations.Nullable; import java.time.OffsetDateTime; +import java.util.HashSet; import java.util.Set; -public interface Recipe { - Integer getId(); - OffsetDateTime getCreated(); - @Nullable OffsetDateTime getModified(); - String getSlug(); - String getTitle(); - @Nullable Integer getPreparationTime(); - @Nullable Integer getCookingTime(); - @Nullable Integer getTotalTime(); - String getRawText(); - User getOwner(); - Set getStars(); - boolean isPublic(); - Set getViewers(); - Set getComments(); - @Nullable Image getMainImage(); +@Entity(name = "Recipe") +@Data +public final class Recipe { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false, updatable = false) + private Integer id; + + @Column(nullable = false) + private OffsetDateTime created; + + private OffsetDateTime modified; + + @Column(nullable = false, unique = true) + private String slug; + + @Column(nullable = false) + private String title; + + @Nullable + private Integer preparationTime; + + @Nullable + private Integer cookingTime; + + @Nullable + private Integer totalTime; + + @Lob + @Column(name = "raw_text", columnDefinition = "TEXT", nullable = false) + @Basic(fetch = FetchType.LAZY) + private String rawText; + + @Lob + @Column(name = "cached_rendered_text", columnDefinition = "TEXT") + @Basic(fetch = FetchType.LAZY) + private String cachedRenderedText; + + @ManyToOne(optional = false) + @JoinColumn(name = "owner_id", nullable = false) + private UserEntity owner; + + @OneToMany + @JoinColumn(name = "recipe_id") + private Set stars = new HashSet<>(); + + @OneToMany(mappedBy = "recipe") + private Set comments = new HashSet<>(); + + @Column(nullable = false) + private Boolean isPublic = false; + + @ManyToMany + @JoinTable( + name = "recipe_viewer", + joinColumns = @JoinColumn(name = "recipe_id"), + inverseJoinColumns = @JoinColumn(name = "viewer_id") + ) + private Set viewers = new HashSet<>(); + + @ManyToOne + @JoinColumn(name = "main_image_id") + private S3ImageEntity mainImage; + + @OneToOne(mappedBy = "recipe", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) + private RecipeEmbeddingEntity embedding; + } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEmbeddingEntity.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEmbeddingEntity.java index bc961e8..a447df0 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEmbeddingEntity.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEmbeddingEntity.java @@ -18,7 +18,7 @@ public class RecipeEmbeddingEntity { @OneToOne(fetch = FetchType.LAZY, optional = false) @MapsId @JoinColumn(name = "recipe_id") - private RecipeEntity recipe; + private Recipe recipe; @JdbcTypeCode(SqlTypes.VECTOR) @Array(length = 1024) @@ -36,11 +36,11 @@ public class RecipeEmbeddingEntity { this.id = id; } - public RecipeEntity getRecipe() { + public Recipe getRecipe() { return this.recipe; } - public void setRecipe(RecipeEntity recipe) { + public void setRecipe(Recipe recipe) { this.recipe = recipe; } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEntity.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEntity.java deleted file mode 100644 index 564c8e6..0000000 --- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEntity.java +++ /dev/null @@ -1,252 +0,0 @@ -package app.mealsmadeeasy.api.recipe; - -import app.mealsmadeeasy.api.image.S3ImageEntity; -import app.mealsmadeeasy.api.recipe.comment.RecipeComment; -import app.mealsmadeeasy.api.recipe.comment.RecipeCommentEntity; -import app.mealsmadeeasy.api.recipe.star.RecipeStar; -import app.mealsmadeeasy.api.recipe.star.RecipeStarEntity; -import app.mealsmadeeasy.api.user.User; -import app.mealsmadeeasy.api.user.UserEntity; -import jakarta.persistence.*; -import org.jetbrains.annotations.Nullable; - -import java.time.OffsetDateTime; -import java.util.HashSet; -import java.util.Set; - -@Entity(name = "Recipe") -public final class RecipeEntity implements Recipe { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(nullable = false, updatable = false) - private Integer id; - - @Column(nullable = false) - private OffsetDateTime created; - - private OffsetDateTime modified; - - @Column(nullable = false, unique = true) - private String slug; - - @Column(nullable = false) - private String title; - - @Nullable - private Integer preparationTime; - - @Nullable - private Integer cookingTime; - - @Nullable - private Integer totalTime; - - @Lob - @Column(name = "raw_text", columnDefinition = "TEXT", nullable = false) - @Basic(fetch = FetchType.LAZY) - private String rawText; - - @Lob - @Column(name = "cached_rendered_text", columnDefinition = "TEXT") - @Basic(fetch = FetchType.LAZY) - private String cachedRenderedText; - - @ManyToOne(optional = false) - @JoinColumn(name = "owner_id", nullable = false) - private UserEntity owner; - - @OneToMany - @JoinColumn(name = "recipe_id") - private Set stars = new HashSet<>(); - - @OneToMany(mappedBy = "recipe") - private Set comments = new HashSet<>(); - - @Column(nullable = false) - private Boolean isPublic = false; - - @ManyToMany - @JoinTable( - name = "recipe_viewer", - joinColumns = @JoinColumn(name = "recipe_id"), - inverseJoinColumns = @JoinColumn(name = "viewer_id") - ) - private Set viewers = new HashSet<>(); - - @ManyToOne - @JoinColumn(name = "main_image_id") - private S3ImageEntity mainImage; - - @OneToOne(mappedBy = "recipe", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) - private RecipeEmbeddingEntity embedding; - - @Override - public Integer getId() { - return this.id; - } - - public void setId(Integer id) { - this.id = id; - } - - @Override - public OffsetDateTime getCreated() { - return this.created; - } - - public void setCreated(OffsetDateTime created) { - this.created = created; - } - - @Override - public @Nullable OffsetDateTime getModified() { - return this.modified; - } - - public void setModified(@Nullable OffsetDateTime modified) { - this.modified = modified; - } - - @Override - public String getSlug() { - return this.slug; - } - - public void setSlug(String slug) { - this.slug = slug; - } - - @Override - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - @Override - public @Nullable Integer getPreparationTime() { - return this.preparationTime; - } - - public void setPreparationTime(@Nullable Integer preparationTime) { - this.preparationTime = preparationTime; - } - - @Override - public @Nullable Integer getCookingTime() { - return this.cookingTime; - } - - public void setCookingTime(@Nullable Integer cookingTime) { - this.cookingTime = cookingTime; - } - - @Override - public @Nullable Integer getTotalTime() { - return this.totalTime; - } - - public void setTotalTime(@Nullable Integer totalTime) { - this.totalTime = totalTime; - } - - @Override - public String getRawText() { - return this.rawText; - } - - public void setRawText(String rawText) { - this.rawText = rawText; - } - - public @Nullable String getCachedRenderedText() { - return this.cachedRenderedText; - } - - public void setCachedRenderedText(@Nullable String cachedRenderedText) { - this.cachedRenderedText = cachedRenderedText; - } - - @Override - public UserEntity getOwner() { - return this.owner; - } - - public void setOwner(UserEntity owner) { - this.owner = owner; - } - - @Override - public boolean isPublic() { - return this.isPublic; - } - - public void setPublic(Boolean isPublic) { - this.isPublic = isPublic; - } - - @Override - public Set getViewers() { - return Set.copyOf(this.viewers); - } - - public Set getViewerEntities() { - return this.viewers; - } - - public void setViewers(Set viewers) { - this.viewers = viewers; - } - - @Override - public Set getStars() { - return Set.copyOf(this.stars); - } - - public Set getStarEntities() { - return this.stars; - } - - public void setStarEntities(Set starGazers) { - this.stars = starGazers; - } - - @Override - public Set getComments() { - return Set.copyOf(this.comments); - } - - public Set getCommentEntities() { - return this.comments; - } - - public void setComments(Set comments) { - this.comments = comments; - } - - @Override - public String toString() { - return "RecipeEntity(" + this.id + ", " + this.title + ")"; - } - - @Override - public @Nullable S3ImageEntity getMainImage() { - return this.mainImage; - } - - public void setMainImage(@Nullable S3ImageEntity image) { - this.mainImage = image; - } - - public RecipeEmbeddingEntity getEmbedding() { - return this.embedding; - } - - public void setEmbedding(RecipeEmbeddingEntity embedding) { - this.embedding = embedding; - } - -} diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeRepository.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeRepository.java index 8ab6ad5..6bdebfb 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeRepository.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeRepository.java @@ -10,27 +10,27 @@ import org.springframework.data.jpa.repository.Query; import java.util.List; import java.util.Optional; -public interface RecipeRepository extends JpaRepository { +public interface RecipeRepository extends JpaRepository { - List findAllByIsPublicIsTrue(); + List findAllByIsPublicIsTrue(); - List findAllByViewersContaining(UserEntity viewer); + List findAllByViewersContaining(UserEntity viewer); - List findAllByOwner(UserEntity owner); + List findAllByOwner(UserEntity owner); @Query("SELECT r from Recipe r WHERE r.owner.username = ?1 AND r.slug = ?2") - Optional findByOwnerUsernameAndSlug(String ownerUsername, String slug); + Optional findByOwnerUsernameAndSlug(String ownerUsername, String slug); @Query("SELECT r FROM Recipe r WHERE size(r.stars) >= ?1 AND (r.isPublic OR ?2 MEMBER OF r.viewers)") - List findAllViewableByStarsGreaterThanEqual(long stars, UserEntity viewer); + List findAllViewableByStarsGreaterThanEqual(long stars, UserEntity viewer); @Query("SELECT r FROM Recipe r WHERE r.id = ?1") @EntityGraph(attributePaths = { "viewers" }) - Optional findByIdWithViewers(long id); + Optional findByIdWithViewers(long id); @Query("SELECT r FROM Recipe r WHERE r.id = ?1") @EntityGraph(attributePaths = { "stars" }) - Optional findByIdWithStars(long id); + Optional findByIdWithStars(long id); @Query("SELECT size(r.stars) FROM Recipe r WHERE r.id = ?1") int getStarCount(long recipeId); @@ -39,9 +39,9 @@ public interface RecipeRepository extends JpaRepository { int getViewerCount(long recipeId); @Query("SELECT r FROM Recipe r WHERE r.isPublic OR r.owner = ?1 OR ?1 MEMBER OF r.viewers") - Slice findAllViewableBy(UserEntity viewer, Pageable pageable); + Slice findAllViewableBy(UserEntity viewer, Pageable pageable); - List findAllByEmbeddingIsNull(); + List findAllByEmbeddingIsNull(); @Query( nativeQuery = true, @@ -57,7 +57,7 @@ public interface RecipeRepository extends JpaRepository { ORDER BY d.distance; """ ) - List searchByEmbeddingAndViewableBy(float[] queryEmbedding, float similarity, Integer viewerId); + List searchByEmbeddingAndViewableBy(float[] queryEmbedding, float similarity, Integer viewerId); @Query( nativeQuery = true, @@ -69,6 +69,6 @@ public interface RecipeRepository extends JpaRepository { ORDER BY d.distance; """ ) - List searchByEmbeddingAndIsPublic(float[] queryEmbedding, float similarity); + List searchByEmbeddingAndIsPublic(float[] queryEmbedding, float similarity); } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeSecurityImpl.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeSecurityImpl.java index 03af8d1..540a33a 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeSecurityImpl.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeSecurityImpl.java @@ -42,7 +42,7 @@ public class RecipeSecurityImpl implements RecipeSecurity { @Override public boolean isViewableBy(Recipe recipe, @Nullable User user) throws RecipeException { - if (recipe.isPublic()) { + if (recipe.getIsPublic()) { // public recipe return true; } else if (user == null) { @@ -53,7 +53,7 @@ public class RecipeSecurityImpl implements RecipeSecurity { return true; } else { // check if viewer - final RecipeEntity withViewers = this.recipeRepository.findByIdWithViewers(recipe.getId()) + final Recipe withViewers = this.recipeRepository.findByIdWithViewers(recipe.getId()) .orElseThrow(() -> new RecipeException( RecipeException.Type.INVALID_ID, "No such Recipe with id: " + recipe.getId() )); diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeService.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeService.java index 71992a9..466d6f3 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeService.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeService.java @@ -58,6 +58,6 @@ public interface RecipeService { @Nullable Boolean isOwner(String username, String slug, @Nullable User viewer); @ApiStatus.Internal - String getRenderedMarkdown(RecipeEntity entity); + String getRenderedMarkdown(Recipe entity); } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeServiceImpl.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeServiceImpl.java index 0102f6d..77936de 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeServiceImpl.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeServiceImpl.java @@ -58,18 +58,18 @@ public class RecipeServiceImpl implements RecipeService { if (owner == null) { throw new AccessDeniedException("Must be logged in."); } - final RecipeEntity draft = new RecipeEntity(); + final Recipe draft = new Recipe(); draft.setCreated(OffsetDateTime.now()); draft.setOwner((UserEntity) owner); draft.setSlug(spec.getSlug()); draft.setTitle(spec.getTitle()); draft.setRawText(spec.getRawText()); draft.setMainImage((S3ImageEntity) spec.getMainImage()); - draft.setPublic(spec.isPublic()); + draft.setIsPublic(spec.isPublic()); return this.recipeRepository.save(draft); } - private RecipeEntity findRecipeEntity(long id) throws RecipeException { + private Recipe findRecipeEntity(long id) throws RecipeException { return this.recipeRepository.findById(id).orElseThrow(() -> new RecipeException( RecipeException.Type.INVALID_ID, "No such Recipe with id: " + id )); @@ -101,7 +101,7 @@ public class RecipeServiceImpl implements RecipeService { @Override @ApiStatus.Internal - public String getRenderedMarkdown(RecipeEntity entity) { + public String getRenderedMarkdown(Recipe entity) { if (entity.getCachedRenderedText() == null) { entity.setCachedRenderedText(this.markdownService.renderAndCleanMarkdown(entity.getRawText())); entity = this.recipeRepository.save(entity); @@ -126,7 +126,7 @@ public class RecipeServiceImpl implements RecipeService { } } - private FullRecipeView getFullView(RecipeEntity recipe, boolean includeRawText, @Nullable User viewer) { + private FullRecipeView getFullView(Recipe recipe, boolean includeRawText, @Nullable User viewer) { return FullRecipeView.from( recipe, this.getRenderedMarkdown(recipe), @@ -137,7 +137,7 @@ public class RecipeServiceImpl implements RecipeService { ); } - private RecipeInfoView getInfoView(RecipeEntity recipe, @Nullable User viewer) { + private RecipeInfoView getInfoView(Recipe recipe, @Nullable User viewer) { return RecipeInfoView.from( recipe, this.getStarCount(recipe), @@ -148,7 +148,7 @@ public class RecipeServiceImpl implements RecipeService { @Override @PreAuthorize("@recipeSecurity.isViewableBy(#id, #viewer)") public FullRecipeView getFullViewById(long id, @Nullable User viewer) throws RecipeException { - final RecipeEntity recipe = this.recipeRepository.findById(id).orElseThrow(() -> new RecipeException( + final Recipe recipe = this.recipeRepository.findById(id).orElseThrow(() -> new RecipeException( RecipeException.Type.INVALID_ID, "No such Recipe for id: " + id )); return this.getFullView(recipe, false, viewer); @@ -162,7 +162,7 @@ public class RecipeServiceImpl implements RecipeService { boolean includeRawText, @Nullable User viewer ) throws RecipeException { - final RecipeEntity recipe = this.recipeRepository.findByOwnerUsernameAndSlug(username, slug) + final Recipe recipe = this.recipeRepository.findByOwnerUsernameAndSlug(username, slug) .orElseThrow(() -> new RecipeException( RecipeException.Type.INVALID_USERNAME_OR_SLUG, "No such Recipe for username " + username + " and slug: " + slug @@ -202,7 +202,7 @@ public class RecipeServiceImpl implements RecipeService { @Override public List aiSearch(RecipeAiSearchSpec searchSpec, @Nullable User viewer) { final float[] queryEmbedding = this.embeddingModel.embed(searchSpec.getPrompt()); - final List results; + final List results; if (viewer == null) { results = this.recipeRepository.searchByEmbeddingAndIsPublic(queryEmbedding, 0.5f); } else { @@ -217,7 +217,7 @@ public class RecipeServiceImpl implements RecipeService { @PreAuthorize("@recipeSecurity.isOwner(#username, #slug, #modifier)") public Recipe update(String username, String slug, RecipeUpdateSpec spec, User modifier) throws RecipeException, ImageException { - final RecipeEntity recipe = this.recipeRepository.findByOwnerUsernameAndSlug(username, slug).orElseThrow(() -> + final Recipe recipe = this.recipeRepository.findByOwnerUsernameAndSlug(username, slug).orElseThrow(() -> new RecipeException( RecipeException.Type.INVALID_USERNAME_OR_SLUG, "No such Recipe for username " + username + " and slug: " + slug @@ -230,7 +230,7 @@ public class RecipeServiceImpl implements RecipeService { recipe.setTotalTime(spec.getTotalTime()); recipe.setRawText(spec.getRawText()); recipe.setCachedRenderedText(null); - recipe.setPublic(spec.getIsPublic()); + recipe.setIsPublic(spec.getIsPublic()); final S3ImageEntity mainImage; if (spec.getMainImage() == null) { @@ -251,10 +251,10 @@ public class RecipeServiceImpl implements RecipeService { @Override @PreAuthorize("@recipeSecurity.isOwner(#id, #modifier)") public Recipe addViewer(long id, User modifier, User viewer) throws RecipeException { - final RecipeEntity entity = this.recipeRepository.findByIdWithViewers(id).orElseThrow(() -> new RecipeException( + final Recipe entity = this.recipeRepository.findByIdWithViewers(id).orElseThrow(() -> new RecipeException( RecipeException.Type.INVALID_ID, "No such Recipe with id: " + id )); - final Set viewers = new HashSet<>(entity.getViewerEntities()); + final Set viewers = new HashSet<>(entity.getViewers()); viewers.add((UserEntity) viewer); entity.setViewers(viewers); return this.recipeRepository.save(entity); @@ -263,8 +263,8 @@ public class RecipeServiceImpl implements RecipeService { @Override @PreAuthorize("@recipeSecurity.isOwner(#id, #modifier)") public Recipe removeViewer(long id, User modifier, User viewer) throws RecipeException { - final RecipeEntity entity = this.findRecipeEntity(id); - final Set viewers = new HashSet<>(entity.getViewerEntities()); + final Recipe entity = this.findRecipeEntity(id); + final Set viewers = new HashSet<>(entity.getViewers()); viewers.remove((UserEntity) viewer); entity.setViewers(viewers); return this.recipeRepository.save(entity); @@ -273,7 +273,7 @@ public class RecipeServiceImpl implements RecipeService { @Override @PreAuthorize("@recipeSecurity.isOwner(#id, #modifier)") public Recipe clearAllViewers(long id, User modifier) throws RecipeException { - final RecipeEntity entity = this.findRecipeEntity(id); + final Recipe entity = this.findRecipeEntity(id); entity.setViewers(new HashSet<>()); return this.recipeRepository.save(entity); } @@ -286,12 +286,12 @@ public class RecipeServiceImpl implements RecipeService { @Override public FullRecipeView toFullRecipeView(Recipe recipe, boolean includeRawText, @Nullable User viewer) { - return this.getFullView((RecipeEntity) recipe, includeRawText, viewer); + return this.getFullView((Recipe) recipe, includeRawText, viewer); } @Override public RecipeInfoView toRecipeInfoView(Recipe recipe, @Nullable User viewer) { - return this.getInfoView((RecipeEntity) recipe, viewer); + return this.getInfoView((Recipe) recipe, viewer); } @Override diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeComment.java b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeComment.java index 8640143..969e81c 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeComment.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeComment.java @@ -1,16 +1,40 @@ package app.mealsmadeeasy.api.recipe.comment; import app.mealsmadeeasy.api.recipe.Recipe; -import app.mealsmadeeasy.api.user.User; -import org.jetbrains.annotations.Nullable; +import app.mealsmadeeasy.api.user.UserEntity; +import jakarta.persistence.*; +import lombok.Data; import java.time.OffsetDateTime; -public interface RecipeComment { - Integer getId(); - OffsetDateTime getCreated(); - @Nullable OffsetDateTime getModified(); - String getRawText(); - User getOwner(); - Recipe getRecipe(); +@Entity +@Data +public final class RecipeComment { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false) + private Integer id; + + @Column(nullable = false, updatable = false) + private OffsetDateTime created = OffsetDateTime.now(); + + private OffsetDateTime modified; + + @Lob + @Basic(fetch = FetchType.LAZY) + private String rawText; + + @Lob + @Basic(fetch = FetchType.LAZY) + private String cachedRenderedText; + + @ManyToOne + @JoinColumn(name = "owner_id", nullable = false, updatable = false) + private UserEntity owner; + + @ManyToOne + @JoinColumn(name = "recipe_id", nullable = false, updatable = false) + private Recipe recipe; + } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentEntity.java b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentEntity.java deleted file mode 100644 index 7ad4741..0000000 --- a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentEntity.java +++ /dev/null @@ -1,100 +0,0 @@ -package app.mealsmadeeasy.api.recipe.comment; - -import app.mealsmadeeasy.api.recipe.RecipeEntity; -import app.mealsmadeeasy.api.user.UserEntity; -import jakarta.persistence.*; - -import java.time.OffsetDateTime; - -@Entity(name = "RecipeComment") -@Table(name = "recipe_comment") -public final class RecipeCommentEntity implements RecipeComment { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(nullable = false) - private Integer id; - - @Column(nullable = false, updatable = false) - private OffsetDateTime created = OffsetDateTime.now(); - - private OffsetDateTime modified; - - @Lob - @Basic(fetch = FetchType.LAZY) - private String rawText; - - @Lob - @Basic(fetch = FetchType.LAZY) - private String cachedRenderedText; - - @ManyToOne - @JoinColumn(name = "owner_id", nullable = false, updatable = false) - private UserEntity owner; - - @ManyToOne - @JoinColumn(name = "recipe_id", nullable = false, updatable = false) - private RecipeEntity recipe; - - public Integer getId() { - return this.id; - } - - public void setId(Integer id) { - this.id = id; - } - - @Override - public OffsetDateTime getCreated() { - return this.created; - } - - public void setCreated(OffsetDateTime created) { - this.created = created; - } - - @Override - public OffsetDateTime getModified() { - return this.modified; - } - - public void setModified(OffsetDateTime modified) { - this.modified = modified; - } - - @Override - public String getRawText() { - return this.rawText; - } - - public void setRawText(String rawText) { - this.rawText = rawText; - } - - public String getCachedRenderedText() { - return this.cachedRenderedText; - } - - public void setCachedRenderedText(String cachedRenderedText) { - this.cachedRenderedText = cachedRenderedText; - } - - @Override - public UserEntity getOwner() { - return this.owner; - } - - public void setOwner(UserEntity owner) { - this.owner = owner; - } - - @Override - public RecipeEntity getRecipe() { - return this.recipe; - } - - public void setRecipe(RecipeEntity recipe) { - this.recipe = recipe; - } - -} diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentRepository.java b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentRepository.java index d0bc09e..edf7ae4 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentRepository.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentRepository.java @@ -1,11 +1,11 @@ package app.mealsmadeeasy.api.recipe.comment; -import app.mealsmadeeasy.api.recipe.RecipeEntity; +import app.mealsmadeeasy.api.recipe.Recipe; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jpa.repository.JpaRepository; -public interface RecipeCommentRepository extends JpaRepository { - void deleteAllByRecipe(RecipeEntity recipe); - Slice findAllByRecipe(RecipeEntity recipe, Pageable pageable); +public interface RecipeCommentRepository extends JpaRepository { + void deleteAllByRecipe(Recipe recipe); + Slice findAllByRecipe(Recipe recipe, Pageable pageable); } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentServiceImpl.java b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentServiceImpl.java index a4ad726..1642d75 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentServiceImpl.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentServiceImpl.java @@ -1,7 +1,7 @@ package app.mealsmadeeasy.api.recipe.comment; import app.mealsmadeeasy.api.markdown.MarkdownService; -import app.mealsmadeeasy.api.recipe.RecipeEntity; +import app.mealsmadeeasy.api.recipe.Recipe; import app.mealsmadeeasy.api.recipe.RecipeException; import app.mealsmadeeasy.api.recipe.RecipeRepository; import app.mealsmadeeasy.api.user.User; @@ -42,12 +42,12 @@ public class RecipeCommentServiceImpl implements RecipeCommentService { RecipeCommentCreateBody body ) throws RecipeException { requireNonNull(commenter); - final RecipeCommentEntity draft = new RecipeCommentEntity(); + final RecipeComment draft = new RecipeComment(); draft.setCreated(OffsetDateTime.now()); draft.setRawText(body.getText()); draft.setCachedRenderedText(this.markdownService.renderAndCleanMarkdown(body.getText())); draft.setOwner((UserEntity) commenter); - final RecipeEntity recipe = this.recipeRepository.findByOwnerUsernameAndSlug(recipeUsername, recipeSlug) + final Recipe recipe = this.recipeRepository.findByOwnerUsernameAndSlug(recipeUsername, recipeSlug) .orElseThrow(() -> new RecipeException( RecipeException.Type.INVALID_USERNAME_OR_SLUG, "Invalid username or slug: " + recipeUsername + "/" + recipeSlug @@ -57,7 +57,7 @@ public class RecipeCommentServiceImpl implements RecipeCommentService { } @PostAuthorize("@recipeSecurity.isViewableBy(returnObject.recipe, #viewer)") - private RecipeCommentEntity loadCommentEntity(long commentId, User viewer) throws RecipeException { + private RecipeComment loadCommentEntity(long commentId, User viewer) throws RecipeException { return this.recipeCommentRepository.findById(commentId).orElseThrow(() -> new RecipeException( RecipeException.Type.INVALID_COMMENT_ID, "No such RecipeComment for id: " + commentId )); @@ -71,13 +71,13 @@ public class RecipeCommentServiceImpl implements RecipeCommentService { @Override @PreAuthorize("@recipeSecurity.isViewableBy(#recipeUsername, #recipeSlug, #viewer)") public Slice getComments(String recipeUsername, String recipeSlug, Pageable pageable, User viewer) throws RecipeException { - final RecipeEntity recipe = this.recipeRepository.findByOwnerUsernameAndSlug(recipeUsername, recipeSlug).orElseThrow( + final Recipe recipe = this.recipeRepository.findByOwnerUsernameAndSlug(recipeUsername, recipeSlug).orElseThrow( () -> new RecipeException( RecipeException.Type.INVALID_USERNAME_OR_SLUG, "No such Recipe for username/slug: " + recipeUsername + "/" + recipeSlug ) ); - final Slice commentEntities = this.recipeCommentRepository.findAllByRecipe(recipe, pageable); + final Slice commentEntities = this.recipeCommentRepository.findAllByRecipe(recipe, pageable); return commentEntities.map(commentEntity -> RecipeCommentView.from( commentEntity, false @@ -86,13 +86,13 @@ public class RecipeCommentServiceImpl implements RecipeCommentService { @Override public RecipeComment update(long commentId, User viewer, RecipeCommentUpdateSpec spec) throws RecipeException { - final RecipeCommentEntity entity = this.loadCommentEntity(commentId, viewer); + final RecipeComment entity = this.loadCommentEntity(commentId, viewer); entity.setRawText(spec.getRawText()); return this.recipeCommentRepository.save(entity); } @PostAuthorize("@recipeSecurity.isOwner(returnObject.recipe, #modifier)") - private RecipeCommentEntity loadForDelete(long commentId, User modifier) throws RecipeException { + private RecipeComment loadForDelete(long commentId, User modifier) throws RecipeException { return this.recipeCommentRepository.findById(commentId).orElseThrow(() -> new RecipeException( RecipeException.Type.INVALID_COMMENT_ID, "No such RecipeComment for id: " + commentId )); @@ -100,7 +100,7 @@ public class RecipeCommentServiceImpl implements RecipeCommentService { @Override public void delete(long commentId, User modifier) throws RecipeException { - final RecipeCommentEntity entityToDelete = this.loadForDelete(commentId, modifier); + final RecipeComment entityToDelete = this.loadForDelete(commentId, modifier); this.recipeCommentRepository.delete(entityToDelete); } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentView.java b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentView.java index 371c4ac..1559193 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentView.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentView.java @@ -12,7 +12,7 @@ public class RecipeCommentView { view.setId(comment.getId()); view.setCreated(comment.getCreated()); view.setModified(comment.getModified()); - view.setText(((RecipeCommentEntity) comment).getCachedRenderedText()); + view.setText(((RecipeComment) comment).getCachedRenderedText()); if (includeRawText) { view.setRawText(comment.getRawText()); } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/spec/RecipeUpdateSpec.java b/src/main/java/app/mealsmadeeasy/api/recipe/spec/RecipeUpdateSpec.java index 4ba0727..d511f1f 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/spec/RecipeUpdateSpec.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/spec/RecipeUpdateSpec.java @@ -53,7 +53,7 @@ public class RecipeUpdateSpec { this.cookingTime = recipe.getCookingTime(); this.totalTime = recipe.getTotalTime(); this.rawText = recipe.getRawText(); - this.isPublic = recipe.isPublic(); + this.isPublic = recipe.getIsPublic(); final @Nullable Image mainImage = recipe.getMainImage(); if (mainImage != null) { this.mainImage = new MainImageUpdateSpec(); diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStar.java b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStar.java index cad0ab2..2437a97 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStar.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStar.java @@ -1,7 +1,22 @@ package app.mealsmadeeasy.api.recipe.star; +import jakarta.persistence.Column; +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; + import java.time.OffsetDateTime; -public interface RecipeStar { - OffsetDateTime getTimestamp(); +@Entity(name = "RecipeStar") +@Table(name = "recipe_star") +@Data +public final class RecipeStar { + + @EmbeddedId + private RecipeStarId id; + + @Column(nullable = false, updatable = false) + private OffsetDateTime timestamp = OffsetDateTime.now(); + } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarEntity.java b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarEntity.java deleted file mode 100644 index c496991..0000000 --- a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarEntity.java +++ /dev/null @@ -1,41 +0,0 @@ -package app.mealsmadeeasy.api.recipe.star; - -import jakarta.persistence.Column; -import jakarta.persistence.EmbeddedId; -import jakarta.persistence.Entity; -import jakarta.persistence.Table; - -import java.time.OffsetDateTime; - -@Entity(name = "RecipeStar") -@Table(name = "recipe_star") -public final class RecipeStarEntity implements RecipeStar { - - @EmbeddedId - private RecipeStarId id; - - @Column(nullable = false, updatable = false) - private OffsetDateTime timestamp = OffsetDateTime.now(); - - public RecipeStarId getId() { - return this.id; - } - - public void setId(RecipeStarId id) { - this.id = id; - } - - public OffsetDateTime getTimestamp() { - return this.timestamp; - } - - public void setTimestamp(OffsetDateTime date) { - this.timestamp = date; - } - - @Override - public String toString() { - return "RecipeStarEntity(" + this.id + ")"; - } - -} diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepository.java b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepository.java index 25ba365..cf09917 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepository.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepository.java @@ -7,10 +7,10 @@ import org.springframework.data.jpa.repository.Query; import java.util.Optional; -public interface RecipeStarRepository extends JpaRepository { +public interface RecipeStarRepository extends JpaRepository { @Query("SELECT star FROM RecipeStar star WHERE star.id.recipeId = ?1 AND star.id.ownerId = ?2") - Optional findByRecipeIdAndOwnerId(Integer recipeId, Integer ownerId); + Optional findByRecipeIdAndOwnerId(Integer recipeId, Integer ownerId); @Query("SELECT count(rs) > 0 FROM RecipeStar rs, Recipe r WHERE r.owner.username = ?1 AND r.slug = ?2 AND r.id = rs.id.recipeId AND rs.id.ownerId = ?3") boolean isStarer(String ownerUsername, String slug, Integer viewerId); diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarServiceImpl.java b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarServiceImpl.java index da2d563..6f9d441 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarServiceImpl.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarServiceImpl.java @@ -22,7 +22,7 @@ public class RecipeStarServiceImpl implements RecipeStarService { @Override public RecipeStar create(Integer recipeId, Integer ownerId) { - final RecipeStarEntity draft = new RecipeStarEntity(); + final RecipeStar draft = new RecipeStar(); final RecipeStarId id = new RecipeStarId(); id.setRecipeId(recipeId); id.getOwnerId(ownerId); @@ -34,7 +34,7 @@ public class RecipeStarServiceImpl implements RecipeStarService { @Override public RecipeStar create(String recipeOwnerUsername, String recipeSlug, User starer) throws RecipeException { final Recipe recipe = this.recipeService.getByUsernameAndSlug(recipeOwnerUsername, recipeSlug, starer); - final Optional existing = this.recipeStarRepository.findByRecipeIdAndOwnerId( + final Optional existing = this.recipeStarRepository.findByRecipeIdAndOwnerId( recipe.getId(), starer.getId() ); @@ -47,8 +47,7 @@ public class RecipeStarServiceImpl implements RecipeStarService { @Override public Optional find(String recipeOwnerUsername, String recipeSlug, User starer) throws RecipeException { final Recipe recipe = this.recipeService.getByUsernameAndSlug(recipeOwnerUsername, recipeSlug, starer); - return this.recipeStarRepository.findByRecipeIdAndOwnerId(recipe.getId(), starer.getId()) - .map(RecipeStar.class::cast); + return this.recipeStarRepository.findByRecipeIdAndOwnerId(recipe.getId(), starer.getId()); } @Override diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/view/FullRecipeView.java b/src/main/java/app/mealsmadeeasy/api/recipe/view/FullRecipeView.java index 4db3021..d389411 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/view/FullRecipeView.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/view/FullRecipeView.java @@ -36,7 +36,7 @@ public class FullRecipeView { view.setStarCount(starCount); view.setViewerCount(viewerCount); view.setMainImage(mainImage); - view.setIsPublic(recipe.isPublic()); + view.setIsPublic(recipe.getIsPublic()); return view; } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/view/RecipeInfoView.java b/src/main/java/app/mealsmadeeasy/api/recipe/view/RecipeInfoView.java index e1ea529..2f2e2e7 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/view/RecipeInfoView.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/view/RecipeInfoView.java @@ -3,11 +3,13 @@ package app.mealsmadeeasy.api.recipe.view; import app.mealsmadeeasy.api.image.view.ImageView; import app.mealsmadeeasy.api.recipe.Recipe; import app.mealsmadeeasy.api.user.view.UserInfoView; +import lombok.Data; import org.jetbrains.annotations.Nullable; import java.time.OffsetDateTime; -public final class RecipeInfoView { +@Data +public class RecipeInfoView { public static RecipeInfoView from(Recipe recipe, int starCount, @Nullable ImageView mainImage) { final RecipeInfoView view = new RecipeInfoView(); @@ -20,7 +22,7 @@ public final class RecipeInfoView { view.setCookingTime(recipe.getCookingTime()); view.setTotalTime(recipe.getTotalTime()); view.setOwner(UserInfoView.from(recipe.getOwner())); - view.setIsPublic(recipe.isPublic()); + view.setPublic(recipe.getIsPublic()); view.setStarCount(starCount); view.setMainImage(mainImage); return view; @@ -39,100 +41,4 @@ public final class RecipeInfoView { private int starCount; private @Nullable ImageView mainImage; - public Integer getId() { - return this.id; - } - - public void setId(Integer id) { - this.id = id; - } - - public OffsetDateTime getCreated() { - return this.created; - } - - public void setCreated(OffsetDateTime created) { - this.created = created; - } - - public OffsetDateTime getModified() { - return this.modified; - } - - public void setModified(OffsetDateTime modified) { - this.modified = modified; - } - - public String getSlug() { - return this.slug; - } - - public void setSlug(String slug) { - this.slug = slug; - } - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public @Nullable Integer getPreparationTime() { - return this.preparationTime; - } - - public void setPreparationTime(@Nullable Integer preparationTime) { - this.preparationTime = preparationTime; - } - - public @Nullable Integer getCookingTime() { - return this.cookingTime; - } - - public void setCookingTime(@Nullable Integer cookingTime) { - this.cookingTime = cookingTime; - } - - public @Nullable Integer getTotalTime() { - return this.totalTime; - } - - public void setTotalTime(@Nullable Integer totalTime) { - this.totalTime = totalTime; - } - - public UserInfoView getOwner() { - return this.owner; - } - - public void setOwner(UserInfoView owner) { - this.owner = owner; - } - - public boolean getIsPublic() { - return this.isPublic; - } - - public void setIsPublic(boolean isPublic) { - this.isPublic = isPublic; - } - - public int getStarCount() { - return this.starCount; - } - - public void setStarCount(int starCount) { - this.starCount = starCount; - } - - public @Nullable ImageView getMainImage() { - return this.mainImage; - } - - public void setMainImage(@Nullable ImageView mainImage) { - this.mainImage = mainImage; - } - } diff --git a/src/testFixtures/java/app/mealsmadeeasy/api/recipe/ContainsRecipeStarsMatcher.java b/src/testFixtures/java/app/mealsmadeeasy/api/recipe/ContainsRecipeStarsMatcher.java index e940aff..cf1452d 100644 --- a/src/testFixtures/java/app/mealsmadeeasy/api/recipe/ContainsRecipeStarsMatcher.java +++ b/src/testFixtures/java/app/mealsmadeeasy/api/recipe/ContainsRecipeStarsMatcher.java @@ -2,7 +2,6 @@ package app.mealsmadeeasy.api.recipe; import app.mealsmadeeasy.api.matchers.ContainsItemsMatcher; import app.mealsmadeeasy.api.recipe.star.RecipeStar; -import app.mealsmadeeasy.api.recipe.star.RecipeStarEntity; import app.mealsmadeeasy.api.recipe.star.RecipeStarId; import java.util.List; @@ -18,8 +17,8 @@ public class ContainsRecipeStarsMatcher extends ContainsItemsMatcher o instanceof RecipeStar, - recipeStar -> ((RecipeStarEntity) recipeStar).getId(), - recipeStar -> ((RecipeStarEntity) recipeStar).getId(), + recipeStar -> ((RecipeStar) recipeStar).getId(), + recipeStar -> ((RecipeStar) recipeStar).getId(), (id0, id1) -> Objects.equals(id0.getRecipeId(), id1.getRecipeId()) && Objects.equals(id0.getOwnerId(), id1.getOwnerId()) );