From 1fefeaa1da48381df7ed925502addab14eae7f08 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Fri, 26 Dec 2025 13:45:27 -0600 Subject: [PATCH] Change to flyway migrations, many SQL/entity updates. --- build.gradle | 5 + .../star/RecipeStarRepositoryTests.java | 10 +- .../api/auth/AuthController.java | 11 +- .../mealsmadeeasy/api/auth/AuthService.java | 6 +- .../api/auth/AuthServiceImpl.java | 14 +-- .../mealsmadeeasy/api/auth/LoginDetails.java | 6 +- .../mealsmadeeasy/api/auth/RefreshToken.java | 12 +- .../api/auth/RefreshTokenEntity.java | 44 +++---- .../api/auth/RefreshTokenRepository.java | 3 +- .../app/mealsmadeeasy/api/image/Image.java | 8 +- .../api/image/S3ImageEntity.java | 28 +++-- .../api/image/S3ImageService.java | 4 +- .../api/image/view/ImageView.java | 14 +-- .../app/mealsmadeeasy/api/recipe/Recipe.java | 8 +- .../api/recipe/RecipeEntity.java | 30 +++-- .../api/recipe/RecipeServiceImpl.java | 8 +- .../api/recipe/comment/RecipeComment.java | 8 +- .../recipe/comment/RecipeCommentEntity.java | 23 ++-- .../comment/RecipeCommentServiceImpl.java | 4 +- .../api/recipe/comment/RecipeCommentView.java | 26 ++--- .../api/recipe/star/RecipeStar.java | 4 +- .../api/recipe/star/RecipeStarEntity.java | 15 +-- .../api/recipe/star/RecipeStarId.java | 26 ++--- .../api/recipe/star/RecipeStarRepository.java | 12 +- .../api/recipe/star/RecipeStarService.java | 4 +- .../recipe/star/RecipeStarServiceImpl.java | 22 ++-- .../api/recipe/view/FullRecipeView.java | 14 +-- .../api/recipe/view/RecipeInfoView.java | 14 +-- .../java/app/mealsmadeeasy/api/user/User.java | 2 +- .../mealsmadeeasy/api/user/UserEntity.java | 6 +- .../api/user/UserGrantedAuthorityEntity.java | 7 +- .../api/user/view/UserInfoView.java | 6 +- src/main/resources/application.properties | 2 +- .../db/migration/V1__init_schema.sql | 108 ++++++++++++++++++ .../recipe/ContainsRecipeStarsMatcher.java | 2 +- 35 files changed, 320 insertions(+), 196 deletions(-) create mode 100644 src/main/resources/db/migration/V1__init_schema.sql diff --git a/build.gradle b/build.gradle index 95d0cf4..4b26794 100644 --- a/build.gradle +++ b/build.gradle @@ -49,12 +49,17 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-webmvc' implementation 'org.springframework.boot:spring-boot-starter-jackson' + implementation 'org.springframework.boot:spring-boot-starter-flyway' runtimeOnly 'org.postgresql:postgresql' testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test' testImplementation 'org.springframework.boot:spring-boot-starter-jackson-test' testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + // flyway + implementation 'org.flywaydb:flyway-core' + implementation 'org.flywaydb:flyway-database-postgresql' + // Custom implementation 'io.jsonwebtoken:jjwt-api:0.13.0' implementation 'io.jsonwebtoken:jjwt-jackson:0.13.0' 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 bba59a3..938c5df 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepositoryTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepositoryTests.java @@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -36,7 +36,7 @@ public class RecipeStarRepositoryTests { private RecipeEntity getTestRecipe(UserEntity owner) { final RecipeEntity recipeDraft = new RecipeEntity(); - recipeDraft.setCreated(LocalDateTime.now()); + recipeDraft.setCreated(OffsetDateTime.now()); recipeDraft.setSlug("test-recipe"); recipeDraft.setOwner(owner); recipeDraft.setTitle("Test Recipe"); @@ -53,7 +53,7 @@ public class RecipeStarRepositoryTests { final RecipeStarEntity starDraft = new RecipeStarEntity(); final RecipeStarId starId = new RecipeStarId(); starId.setRecipeId(recipe.getId()); - starId.setOwnerUsername(owner.getUsername()); + starId.getOwnerId(owner.getId()); starDraft.setId(starId); this.recipeStarRepository.save(starDraft); @@ -61,7 +61,7 @@ public class RecipeStarRepositoryTests { this.recipeStarRepository.isStarer( recipe.getOwner().getUsername(), recipe.getSlug(), - owner.getUsername() + owner.getId() ), is(true) ); @@ -76,7 +76,7 @@ public class RecipeStarRepositoryTests { this.recipeStarRepository.isStarer( recipe.getOwner().getUsername(), recipe.getSlug(), - owner.getUsername() + owner.getId() ), is(false) ); diff --git a/src/main/java/app/mealsmadeeasy/api/auth/AuthController.java b/src/main/java/app/mealsmadeeasy/api/auth/AuthController.java index 15e6ca7..52f6110 100644 --- a/src/main/java/app/mealsmadeeasy/api/auth/AuthController.java +++ b/src/main/java/app/mealsmadeeasy/api/auth/AuthController.java @@ -1,6 +1,5 @@ package app.mealsmadeeasy.api.auth; -import app.mealsmadeeasy.api.security.AuthToken; import org.jetbrains.annotations.Nullable; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -8,6 +7,8 @@ import org.springframework.http.ResponseCookie; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.UUID; + @RestController @RequestMapping("/auth") public final class AuthController { @@ -31,9 +32,9 @@ public final class AuthController { } private ResponseEntity getLoginViewResponseEntity(LoginDetails loginDetails) { - final AuthToken refreshToken = loginDetails.getRefreshToken(); + final RefreshToken refreshToken = loginDetails.getRefreshToken(); final ResponseCookie refreshCookie = getRefreshTokenCookie( - refreshToken.getToken(), + refreshToken.getToken().toString(), refreshToken.getLifetime() ); final var loginView = new LoginView( @@ -60,7 +61,7 @@ public final class AuthController { @PostMapping("/refresh") public ResponseEntity refresh( - @CookieValue(value = "refresh-token", required = false) @Nullable String oldRefreshToken + @CookieValue(value = "refresh-token", required = false) @Nullable UUID oldRefreshToken ) throws LoginException { final LoginDetails loginDetails = this.authService.refresh(oldRefreshToken); return this.getLoginViewResponseEntity(loginDetails); @@ -68,7 +69,7 @@ public final class AuthController { @PostMapping("/logout") public ResponseEntity logout( - @CookieValue(value = "refresh-token", required = false) @Nullable String refreshToken + @CookieValue(value = "refresh-token", required = false) @Nullable UUID refreshToken ) { if (refreshToken != null) { this.authService.logout(refreshToken); diff --git a/src/main/java/app/mealsmadeeasy/api/auth/AuthService.java b/src/main/java/app/mealsmadeeasy/api/auth/AuthService.java index e1cecf8..a522f1f 100644 --- a/src/main/java/app/mealsmadeeasy/api/auth/AuthService.java +++ b/src/main/java/app/mealsmadeeasy/api/auth/AuthService.java @@ -2,8 +2,10 @@ package app.mealsmadeeasy.api.auth; import org.jetbrains.annotations.Nullable; +import java.util.UUID; + public interface AuthService { LoginDetails login(String username, String password) throws LoginException; - void logout(String refreshToken); - LoginDetails refresh(@Nullable String refreshToken) throws LoginException; + void logout(UUID refreshToken); + LoginDetails refresh(@Nullable UUID refreshToken) throws LoginException; } diff --git a/src/main/java/app/mealsmadeeasy/api/auth/AuthServiceImpl.java b/src/main/java/app/mealsmadeeasy/api/auth/AuthServiceImpl.java index 981fc3e..edf16fe 100644 --- a/src/main/java/app/mealsmadeeasy/api/auth/AuthServiceImpl.java +++ b/src/main/java/app/mealsmadeeasy/api/auth/AuthServiceImpl.java @@ -12,7 +12,7 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.stereotype.Service; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.util.UUID; import java.util.concurrent.TimeUnit; @@ -38,9 +38,9 @@ public class AuthServiceImpl implements AuthService { private RefreshToken createRefreshToken(UserEntity principal) { final RefreshTokenEntity refreshTokenDraft = new RefreshTokenEntity(); - refreshTokenDraft.setToken(UUID.randomUUID().toString()); - refreshTokenDraft.setIssued(LocalDateTime.now()); - refreshTokenDraft.setExpiration(LocalDateTime.now().plusSeconds(this.refreshTokenLifetime)); + refreshTokenDraft.setToken(UUID.randomUUID()); + refreshTokenDraft.setIssued(OffsetDateTime.now()); + refreshTokenDraft.setExpiration(OffsetDateTime.now().plusSeconds(this.refreshTokenLifetime)); refreshTokenDraft.setOwner(principal); return this.refreshTokenRepository.save(refreshTokenDraft); } @@ -64,13 +64,13 @@ public class AuthServiceImpl implements AuthService { @Override @Transactional - public void logout(String refreshToken) { + public void logout(UUID refreshToken) { this.refreshTokenRepository.findByToken(refreshToken).ifPresent(this.refreshTokenRepository::delete); } @Override @Transactional - public LoginDetails refresh(@Nullable String refreshToken) throws LoginException { + public LoginDetails refresh(@Nullable UUID refreshToken) throws LoginException { if (refreshToken == null) { throw new LoginException(LoginExceptionReason.NO_REFRESH_TOKEN, "No refresh token provided."); } @@ -83,7 +83,7 @@ public class AuthServiceImpl implements AuthService { if (old.isRevoked() || old.isDeleted()) { throw new LoginException(LoginExceptionReason.INVALID_REFRESH_TOKEN, "Invalid refresh token."); } - if (old.getExpires().isBefore(LocalDateTime.now())) { + if (old.getExpires().isBefore(OffsetDateTime.now())) { throw new LoginException(LoginExceptionReason.EXPIRED_REFRESH_TOKEN, "Refresh token is expired."); } diff --git a/src/main/java/app/mealsmadeeasy/api/auth/LoginDetails.java b/src/main/java/app/mealsmadeeasy/api/auth/LoginDetails.java index 60f5139..455be66 100644 --- a/src/main/java/app/mealsmadeeasy/api/auth/LoginDetails.java +++ b/src/main/java/app/mealsmadeeasy/api/auth/LoginDetails.java @@ -6,9 +6,9 @@ public final class LoginDetails { private final String username; private final AuthToken accessToken; - private final AuthToken refreshToken; + private final RefreshToken refreshToken; - public LoginDetails(String username, AuthToken accessToken, AuthToken refreshToken) { + public LoginDetails(String username, AuthToken accessToken, RefreshToken refreshToken) { this.username = username; this.accessToken = accessToken; this.refreshToken = refreshToken; @@ -22,7 +22,7 @@ public final class LoginDetails { return this.accessToken; } - public AuthToken getRefreshToken() { + public RefreshToken getRefreshToken() { return this.refreshToken; } diff --git a/src/main/java/app/mealsmadeeasy/api/auth/RefreshToken.java b/src/main/java/app/mealsmadeeasy/api/auth/RefreshToken.java index a20ff1e..88a49ff 100644 --- a/src/main/java/app/mealsmadeeasy/api/auth/RefreshToken.java +++ b/src/main/java/app/mealsmadeeasy/api/auth/RefreshToken.java @@ -1,11 +1,13 @@ package app.mealsmadeeasy.api.auth; -import app.mealsmadeeasy.api.security.AuthToken; +import java.time.OffsetDateTime; +import java.util.UUID; -import java.time.LocalDateTime; - -public interface RefreshToken extends AuthToken { - LocalDateTime getIssued(); +public interface RefreshToken { + UUID getToken(); + long getLifetime(); + OffsetDateTime getExpires(); + OffsetDateTime getIssued(); boolean isRevoked(); boolean isDeleted(); } diff --git a/src/main/java/app/mealsmadeeasy/api/auth/RefreshTokenEntity.java b/src/main/java/app/mealsmadeeasy/api/auth/RefreshTokenEntity.java index 03d8527..d93c331 100644 --- a/src/main/java/app/mealsmadeeasy/api/auth/RefreshTokenEntity.java +++ b/src/main/java/app/mealsmadeeasy/api/auth/RefreshTokenEntity.java @@ -3,68 +3,58 @@ package app.mealsmadeeasy.api.auth; import app.mealsmadeeasy.api.user.UserEntity; import jakarta.persistence.*; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.time.temporal.ChronoUnit; +import java.util.UUID; @Entity(name = "RefreshToken") +@Table(name = "refresh_token") public class RefreshTokenEntity implements RefreshToken { @Id - @GeneratedValue(strategy = GenerationType.AUTO) - @Column(nullable = false, updatable = false) - private Long id; - - @Column(unique = true, nullable = false) - private String token; + @Column(nullable = false) + private UUID token; @Column(nullable = false) - private LocalDateTime issued; + private OffsetDateTime issued; @Column(nullable = false) - private LocalDateTime expiration; + private OffsetDateTime expiration; - @Column(nullable = false) - private Boolean revoked = false; - - @JoinColumn(nullable = false) - @ManyToOne + @ManyToOne(optional = false) + @JoinColumn(name = "owner_id", nullable = false) private UserEntity owner; @Column(nullable = false) private Boolean deleted = false; - public Long getId() { - return this.id; - } - - public void setId(Long id) { - this.id = id; - } + @Column(nullable = false) + private Boolean revoked = false; @Override - public String getToken() { + public UUID getToken() { return this.token; } - public void setToken(String token) { + public void setToken(UUID token) { this.token = token; } @Override - public LocalDateTime getIssued() { + public OffsetDateTime getIssued() { return this.issued; } - public void setIssued(LocalDateTime issued) { + public void setIssued(OffsetDateTime issued) { this.issued = issued; } @Override - public LocalDateTime getExpires() { + public OffsetDateTime getExpires() { return this.expiration; } - public void setExpiration(LocalDateTime expiration) { + public void setExpiration(OffsetDateTime expiration) { this.expiration = expiration; } diff --git a/src/main/java/app/mealsmadeeasy/api/auth/RefreshTokenRepository.java b/src/main/java/app/mealsmadeeasy/api/auth/RefreshTokenRepository.java index 71fe26d..fbfa5fc 100644 --- a/src/main/java/app/mealsmadeeasy/api/auth/RefreshTokenRepository.java +++ b/src/main/java/app/mealsmadeeasy/api/auth/RefreshTokenRepository.java @@ -6,10 +6,11 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import java.util.Optional; +import java.util.UUID; public interface RefreshTokenRepository extends JpaRepository { - Optional findByToken(String token); + Optional findByToken(UUID token); @Modifying @Transactional diff --git a/src/main/java/app/mealsmadeeasy/api/image/Image.java b/src/main/java/app/mealsmadeeasy/api/image/Image.java index cc787de..5f655ca 100644 --- a/src/main/java/app/mealsmadeeasy/api/image/Image.java +++ b/src/main/java/app/mealsmadeeasy/api/image/Image.java @@ -3,13 +3,13 @@ package app.mealsmadeeasy.api.image; import app.mealsmadeeasy.api.user.User; import org.jetbrains.annotations.Nullable; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.util.Set; public interface Image { - Long getId(); - LocalDateTime getCreated(); - @Nullable LocalDateTime getModified(); + Integer getId(); + OffsetDateTime getCreated(); + @Nullable OffsetDateTime getModified(); String getUserFilename(); String getMimeType(); @Nullable String getAlt(); diff --git a/src/main/java/app/mealsmadeeasy/api/image/S3ImageEntity.java b/src/main/java/app/mealsmadeeasy/api/image/S3ImageEntity.java index 51df89b..84e5c1c 100644 --- a/src/main/java/app/mealsmadeeasy/api/image/S3ImageEntity.java +++ b/src/main/java/app/mealsmadeeasy/api/image/S3ImageEntity.java @@ -5,22 +5,23 @@ import app.mealsmadeeasy.api.user.UserEntity; import jakarta.persistence.*; import org.jetbrains.annotations.Nullable; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.util.HashSet; import java.util.Set; @Entity(name = "Image") +@Table(name = "image") public class S3ImageEntity implements Image { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(nullable = false, updatable = false) - private Long id; + private Integer id; @Column(nullable = false) - private LocalDateTime created = LocalDateTime.now(); + private OffsetDateTime created = OffsetDateTime.now(); - private LocalDateTime modified; + private OffsetDateTime modified; @Column(nullable = false) private String userFilename; @@ -47,32 +48,37 @@ public class S3ImageEntity implements Image { private Boolean isPublic = false; @ManyToMany + @JoinTable( + name = "image_viewer", + joinColumns = @JoinColumn(name = "image_id"), + inverseJoinColumns = @JoinColumn(name = "viewer_id") + ) private Set viewers = new HashSet<>(); @Override - public Long getId() { + public Integer getId() { return this.id; } - public void setId(Long id) { + public void setId(Integer id) { this.id = id; } @Override - public LocalDateTime getCreated() { + public OffsetDateTime getCreated() { return this.created; } - public void setCreated(LocalDateTime created) { + public void setCreated(OffsetDateTime created) { this.created = created; } @Override - public @Nullable LocalDateTime getModified() { + public @Nullable OffsetDateTime getModified() { return this.modified; } - public void setModified(LocalDateTime modified) { + public void setModified(OffsetDateTime modified) { this.modified = modified; } diff --git a/src/main/java/app/mealsmadeeasy/api/image/S3ImageService.java b/src/main/java/app/mealsmadeeasy/api/image/S3ImageService.java index 9ed7bf8..3b92a67 100644 --- a/src/main/java/app/mealsmadeeasy/api/image/S3ImageService.java +++ b/src/main/java/app/mealsmadeeasy/api/image/S3ImageService.java @@ -18,7 +18,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -225,7 +225,7 @@ public class S3ImageService implements ImageService { } } if (didUpdate) { - entity.setModified(LocalDateTime.now()); + entity.setModified(OffsetDateTime.now()); } return this.imageRepository.save(entity); } diff --git a/src/main/java/app/mealsmadeeasy/api/image/view/ImageView.java b/src/main/java/app/mealsmadeeasy/api/image/view/ImageView.java index 7fcce56..4d6ba6b 100644 --- a/src/main/java/app/mealsmadeeasy/api/image/view/ImageView.java +++ b/src/main/java/app/mealsmadeeasy/api/image/view/ImageView.java @@ -4,7 +4,7 @@ import app.mealsmadeeasy.api.image.Image; import app.mealsmadeeasy.api.user.view.UserInfoView; import org.jetbrains.annotations.Nullable; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.util.Set; import java.util.stream.Collectors; @@ -33,8 +33,8 @@ public class ImageView { } private String url; - private LocalDateTime created; - private @Nullable LocalDateTime modified; + private OffsetDateTime created; + private @Nullable OffsetDateTime modified; private String filename; private String mimeType; private @Nullable String alt; @@ -53,19 +53,19 @@ public class ImageView { this.url = url; } - public LocalDateTime getCreated() { + public OffsetDateTime getCreated() { return this.created; } - public void setCreated(LocalDateTime created) { + public void setCreated(OffsetDateTime created) { this.created = created; } - public @Nullable LocalDateTime getModified() { + public @Nullable OffsetDateTime getModified() { return this.modified; } - public void setModified(@Nullable LocalDateTime modified) { + public void setModified(@Nullable OffsetDateTime modified) { this.modified = modified; } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/Recipe.java b/src/main/java/app/mealsmadeeasy/api/recipe/Recipe.java index b1dcd65..248be5b 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/Recipe.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/Recipe.java @@ -6,13 +6,13 @@ import app.mealsmadeeasy.api.recipe.star.RecipeStar; import app.mealsmadeeasy.api.user.User; import org.jetbrains.annotations.Nullable; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.util.Set; public interface Recipe { - Long getId(); - LocalDateTime getCreated(); - @Nullable LocalDateTime getModified(); + Integer getId(); + OffsetDateTime getCreated(); + @Nullable OffsetDateTime getModified(); String getSlug(); String getTitle(); @Nullable Integer getPreparationTime(); diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEntity.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEntity.java index 65a1131..ef9ab17 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEntity.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEntity.java @@ -10,7 +10,7 @@ import app.mealsmadeeasy.api.user.UserEntity; import jakarta.persistence.*; import org.jetbrains.annotations.Nullable; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.util.HashSet; import java.util.Set; @@ -18,14 +18,14 @@ import java.util.Set; public final class RecipeEntity implements Recipe { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(nullable = false, updatable = false) - private Long id; + private Integer id; @Column(nullable = false) - private LocalDateTime created; + private OffsetDateTime created; - private LocalDateTime modified; + private OffsetDateTime modified; @Column(nullable = false, unique = true) private String slug; @@ -57,7 +57,7 @@ public final class RecipeEntity implements Recipe { private UserEntity owner; @OneToMany - @JoinColumn(name = "recipeId") + @JoinColumn(name = "recipe_id") private Set stars = new HashSet<>(); @OneToMany(mappedBy = "recipe") @@ -67,35 +67,41 @@ public final class RecipeEntity implements Recipe { 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; @Override - public Long getId() { + public Integer getId() { return this.id; } - public void setId(Long id) { + public void setId(Integer id) { this.id = id; } @Override - public LocalDateTime getCreated() { + public OffsetDateTime getCreated() { return this.created; } - public void setCreated(LocalDateTime created) { + public void setCreated(OffsetDateTime created) { this.created = created; } @Override - public @Nullable LocalDateTime getModified() { + public @Nullable OffsetDateTime getModified() { return this.modified; } - public void setModified(@Nullable LocalDateTime modified) { + public void setModified(@Nullable OffsetDateTime modified) { this.modified = modified; } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeServiceImpl.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeServiceImpl.java index ffcc56b..77a5dbb 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeServiceImpl.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeServiceImpl.java @@ -22,7 +22,7 @@ import org.springframework.security.access.prepost.PostAuthorize; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -53,7 +53,7 @@ public class RecipeServiceImpl implements RecipeService { throw new AccessDeniedException("Must be logged in."); } final RecipeEntity draft = new RecipeEntity(); - draft.setCreated(LocalDateTime.now()); + draft.setCreated(OffsetDateTime.now()); draft.setOwner((UserEntity) owner); draft.setSlug(spec.getSlug()); draft.setTitle(spec.getTitle()); @@ -222,7 +222,7 @@ public class RecipeServiceImpl implements RecipeService { } recipe.setMainImage(mainImage); - recipe.setModified(LocalDateTime.now()); + recipe.setModified(OffsetDateTime.now()); return this.recipeRepository.save(recipe); } @@ -279,7 +279,7 @@ public class RecipeServiceImpl implements RecipeService { if (viewer == null) { return null; } - return this.recipeStarRepository.isStarer(username, slug, viewer.getUsername()); + return this.recipeStarRepository.isStarer(username, slug, viewer.getId()); } @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 91a6a23..8640143 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeComment.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeComment.java @@ -4,12 +4,12 @@ import app.mealsmadeeasy.api.recipe.Recipe; import app.mealsmadeeasy.api.user.User; import org.jetbrains.annotations.Nullable; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; public interface RecipeComment { - Long getId(); - LocalDateTime getCreated(); - @Nullable LocalDateTime getModified(); + Integer getId(); + OffsetDateTime getCreated(); + @Nullable OffsetDateTime getModified(); String getRawText(); User getOwner(); Recipe getRecipe(); diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentEntity.java b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentEntity.java index 5c86dee..7ad4741 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentEntity.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentEntity.java @@ -4,20 +4,21 @@ import app.mealsmadeeasy.api.recipe.RecipeEntity; import app.mealsmadeeasy.api.user.UserEntity; import jakarta.persistence.*; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; @Entity(name = "RecipeComment") +@Table(name = "recipe_comment") public final class RecipeCommentEntity implements RecipeComment { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(nullable = false) - private Long id; + private Integer id; @Column(nullable = false, updatable = false) - private LocalDateTime created = LocalDateTime.now(); + private OffsetDateTime created = OffsetDateTime.now(); - private LocalDateTime modified; + private OffsetDateTime modified; @Lob @Basic(fetch = FetchType.LAZY) @@ -35,29 +36,29 @@ public final class RecipeCommentEntity implements RecipeComment { @JoinColumn(name = "recipe_id", nullable = false, updatable = false) private RecipeEntity recipe; - public Long getId() { + public Integer getId() { return this.id; } - public void setId(Long id) { + public void setId(Integer id) { this.id = id; } @Override - public LocalDateTime getCreated() { + public OffsetDateTime getCreated() { return this.created; } - public void setCreated(LocalDateTime created) { + public void setCreated(OffsetDateTime created) { this.created = created; } @Override - public LocalDateTime getModified() { + public OffsetDateTime getModified() { return this.modified; } - public void setModified(LocalDateTime modified) { + public void setModified(OffsetDateTime modified) { this.modified = modified; } 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 10611cd..a4ad726 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentServiceImpl.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentServiceImpl.java @@ -12,7 +12,7 @@ import org.springframework.security.access.prepost.PostAuthorize; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; import static java.util.Objects.requireNonNull; @@ -43,7 +43,7 @@ public class RecipeCommentServiceImpl implements RecipeCommentService { ) throws RecipeException { requireNonNull(commenter); final RecipeCommentEntity draft = new RecipeCommentEntity(); - draft.setCreated(LocalDateTime.now()); + draft.setCreated(OffsetDateTime.now()); draft.setRawText(body.getText()); draft.setCachedRenderedText(this.markdownService.renderAndCleanMarkdown(body.getText())); draft.setOwner((UserEntity) commenter); 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 8ec0340..371c4ac 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentView.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/comment/RecipeCommentView.java @@ -3,7 +3,7 @@ package app.mealsmadeeasy.api.recipe.comment; import app.mealsmadeeasy.api.user.view.UserInfoView; import org.jetbrains.annotations.Nullable; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; public class RecipeCommentView { @@ -21,35 +21,35 @@ public class RecipeCommentView { return view; } - private Long id; - private LocalDateTime created; - private @Nullable LocalDateTime modified; + private Integer id; + private OffsetDateTime created; + private @Nullable OffsetDateTime modified; private String text; private @Nullable String rawText; private UserInfoView owner; - private Long recipeId; + private Integer recipeId; - public Long getId() { + public Integer getId() { return this.id; } - public void setId(Long id) { + public void setId(Integer id) { this.id = id; } - public LocalDateTime getCreated() { + public OffsetDateTime getCreated() { return this.created; } - public void setCreated(LocalDateTime created) { + public void setCreated(OffsetDateTime created) { this.created = created; } - public @Nullable LocalDateTime getModified() { + public @Nullable OffsetDateTime getModified() { return this.modified; } - public void setModified(@Nullable LocalDateTime modified) { + public void setModified(@Nullable OffsetDateTime modified) { this.modified = modified; } @@ -77,11 +77,11 @@ public class RecipeCommentView { this.owner = owner; } - public Long getRecipeId() { + public Integer getRecipeId() { return this.recipeId; } - public void setRecipeId(Long recipeId) { + public void setRecipeId(Integer recipeId) { this.recipeId = recipeId; } 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 d83f482..cad0ab2 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,7 @@ package app.mealsmadeeasy.api.recipe.star; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; public interface RecipeStar { - LocalDateTime getDate(); + OffsetDateTime getTimestamp(); } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarEntity.java b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarEntity.java index c1290d9..c496991 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarEntity.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarEntity.java @@ -3,17 +3,19 @@ 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.LocalDateTime; +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 LocalDateTime date = LocalDateTime.now(); + private OffsetDateTime timestamp = OffsetDateTime.now(); public RecipeStarId getId() { return this.id; @@ -23,13 +25,12 @@ public final class RecipeStarEntity implements RecipeStar { this.id = id; } - @Override - public LocalDateTime getDate() { - return this.date; + public OffsetDateTime getTimestamp() { + return this.timestamp; } - public void setDate(LocalDateTime date) { - this.date = date; + public void setTimestamp(OffsetDateTime date) { + this.timestamp = date; } @Override diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarId.java b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarId.java index 7988c2f..b3536db 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarId.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarId.java @@ -8,25 +8,25 @@ import java.util.Objects; @Embeddable public class RecipeStarId { - @Column(nullable = false) - private String ownerUsername; + @Column(name = "owner_id", nullable = false) + private Integer ownerId; - @Column(nullable = false) - private Long recipeId; + @Column(name = "recipe_id", nullable = false) + private Integer recipeId; - public String getOwnerUsername() { - return this.ownerUsername; + public Integer getOwnerId() { + return this.ownerId; } - public void setOwnerUsername(String ownerUsername) { - this.ownerUsername = ownerUsername; + public void getOwnerId(Integer ownerId) { + this.ownerId = ownerId; } - public Long getRecipeId() { + public Integer getRecipeId() { return this.recipeId; } - public void setRecipeId(Long recipeId) { + public void setRecipeId(Integer recipeId) { this.recipeId = recipeId; } @@ -34,19 +34,19 @@ public class RecipeStarId { public boolean equals(Object o) { if (this == o) return true; if (o instanceof RecipeStarId other) { - return this.recipeId.equals(other.recipeId) && this.ownerUsername.equals(other.ownerUsername); + return this.recipeId.equals(other.recipeId) && this.ownerId.equals(other.ownerId); } return false; } @Override public int hashCode() { - return Objects.hash(this.recipeId, this.ownerUsername); + return Objects.hash(this.recipeId, this.ownerId); } @Override public String toString() { - return "RecipeStarId(" + this.recipeId + ", " + this.ownerUsername + ")"; + return "RecipeStarId(" + this.recipeId + ", " + this.ownerId + ")"; } } 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 6434174..25ba365 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepository.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepository.java @@ -9,15 +9,15 @@ import java.util.Optional; public interface RecipeStarRepository extends JpaRepository { - @Query("SELECT star FROM RecipeStar star WHERE star.id.recipeId = ?1 AND star.id.ownerUsername = ?2") - Optional findByRecipeIdAndOwnerUsername(Long recipeId, String username); + @Query("SELECT star FROM RecipeStar star WHERE star.id.recipeId = ?1 AND star.id.ownerId = ?2") + 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.ownerUsername = ?3") - boolean isStarer(String ownerUsername, String slug, String viewerUsername); + @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); @Modifying @Transactional - @Query("DELETE FROM RecipeStar star WHERE star.id.recipeId = ?1 AND star.id.ownerUsername = ?2") - void deleteByRecipeIdAndOwnerUsername(Long recipeId, String username); + @Query("DELETE FROM RecipeStar star WHERE star.id.recipeId = ?1 AND star.id.ownerId = ?2") + void deleteByRecipeIdAndOwnerId(Integer recipeId, Integer ownerId); } diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarService.java b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarService.java index 9444b5e..03e387d 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarService.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarService.java @@ -6,11 +6,11 @@ import app.mealsmadeeasy.api.user.User; import java.util.Optional; public interface RecipeStarService { - RecipeStar create(long recipeId, String ownerUsername); + RecipeStar create(Integer recipeId, Integer ownerId); RecipeStar create(String recipeOwnerUsername, String recipeSlug, User starer) throws RecipeException; Optional find(String recipeOwnerUsername, String recipeSlug, User starer) throws RecipeException; - void delete(long recipeId, String ownerUsername); + void delete(Integer recipeId, Integer ownerId); void delete(String recipeOwnerUsername, String recipeSlug, User starer) throws RecipeException; } 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 c1c1ee6..da2d563 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarServiceImpl.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/star/RecipeStarServiceImpl.java @@ -6,7 +6,7 @@ import app.mealsmadeeasy.api.recipe.RecipeService; import app.mealsmadeeasy.api.user.User; import org.springframework.stereotype.Service; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.util.Optional; @Service @@ -21,45 +21,45 @@ public class RecipeStarServiceImpl implements RecipeStarService { } @Override - public RecipeStar create(long recipeId, String ownerUsername) { + public RecipeStar create(Integer recipeId, Integer ownerId) { final RecipeStarEntity draft = new RecipeStarEntity(); final RecipeStarId id = new RecipeStarId(); id.setRecipeId(recipeId); - id.setOwnerUsername(ownerUsername); + id.getOwnerId(ownerId); draft.setId(id); - draft.setDate(LocalDateTime.now()); + draft.setTimestamp(OffsetDateTime.now()); return this.recipeStarRepository.save(draft); } @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.findByRecipeIdAndOwnerUsername( + final Optional existing = this.recipeStarRepository.findByRecipeIdAndOwnerId( recipe.getId(), - starer.getUsername() + starer.getId() ); if (existing.isPresent()) { return existing.get(); } - return this.create(recipe.getId(), starer.getUsername()); + return this.create(recipe.getId(), starer.getId()); } @Override public Optional find(String recipeOwnerUsername, String recipeSlug, User starer) throws RecipeException { final Recipe recipe = this.recipeService.getByUsernameAndSlug(recipeOwnerUsername, recipeSlug, starer); - return this.recipeStarRepository.findByRecipeIdAndOwnerUsername(recipe.getId(), starer.getUsername()) + return this.recipeStarRepository.findByRecipeIdAndOwnerId(recipe.getId(), starer.getId()) .map(RecipeStar.class::cast); } @Override - public void delete(long recipeId, String ownerUsername) { - this.recipeStarRepository.deleteByRecipeIdAndOwnerUsername(recipeId, ownerUsername); + public void delete(Integer recipeId, Integer ownerId) { + this.recipeStarRepository.deleteByRecipeIdAndOwnerId(recipeId, ownerId); } @Override public void delete(String recipeOwnerUsername, String recipeSlug, User starer) throws RecipeException { final Recipe recipe = this.recipeService.getByUsernameAndSlug(recipeOwnerUsername, recipeSlug, starer); - this.delete(recipe.getId(), starer.getUsername()); + this.delete(recipe.getId(), starer.getId()); } } 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 45e31b5..4db3021 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/view/FullRecipeView.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/view/FullRecipeView.java @@ -7,7 +7,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import org.jetbrains.annotations.Nullable; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; public class FullRecipeView { @@ -41,8 +41,8 @@ public class FullRecipeView { } private long id; - private LocalDateTime created; - private @Nullable LocalDateTime modified; + private OffsetDateTime created; + private @Nullable OffsetDateTime modified; private String slug; private String title; private @Nullable Integer preparationTime; @@ -64,19 +64,19 @@ public class FullRecipeView { this.id = id; } - public LocalDateTime getCreated() { + public OffsetDateTime getCreated() { return this.created; } - public void setCreated(LocalDateTime created) { + public void setCreated(OffsetDateTime created) { this.created = created; } - public @Nullable LocalDateTime getModified() { + public @Nullable OffsetDateTime getModified() { return this.modified; } - public void setModified(@Nullable LocalDateTime modified) { + public void setModified(@Nullable OffsetDateTime modified) { this.modified = modified; } 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 e39bf33..c7f214c 100644 --- a/src/main/java/app/mealsmadeeasy/api/recipe/view/RecipeInfoView.java +++ b/src/main/java/app/mealsmadeeasy/api/recipe/view/RecipeInfoView.java @@ -5,7 +5,7 @@ import app.mealsmadeeasy.api.recipe.Recipe; import app.mealsmadeeasy.api.user.view.UserInfoView; import org.jetbrains.annotations.Nullable; -import java.time.LocalDateTime; +import java.time.OffsetDateTime; public final class RecipeInfoView { @@ -27,8 +27,8 @@ public final class RecipeInfoView { } private long id; - private LocalDateTime created; - private LocalDateTime modified; + private OffsetDateTime created; + private OffsetDateTime modified; private String slug; private String title; private @Nullable Integer preparationTime; @@ -47,19 +47,19 @@ public final class RecipeInfoView { this.id = id; } - public LocalDateTime getCreated() { + public OffsetDateTime getCreated() { return this.created; } - public void setCreated(LocalDateTime created) { + public void setCreated(OffsetDateTime created) { this.created = created; } - public LocalDateTime getModified() { + public OffsetDateTime getModified() { return this.modified; } - public void setModified(LocalDateTime modified) { + public void setModified(OffsetDateTime modified) { this.modified = modified; } diff --git a/src/main/java/app/mealsmadeeasy/api/user/User.java b/src/main/java/app/mealsmadeeasy/api/user/User.java index 81369ac..a40a1d6 100644 --- a/src/main/java/app/mealsmadeeasy/api/user/User.java +++ b/src/main/java/app/mealsmadeeasy/api/user/User.java @@ -6,7 +6,7 @@ import java.util.Set; public interface User extends UserDetails { - Long getId(); + Integer getId(); String getEmail(); void setEmail(String email); diff --git a/src/main/java/app/mealsmadeeasy/api/user/UserEntity.java b/src/main/java/app/mealsmadeeasy/api/user/UserEntity.java index 0951c0e..f01cf9e 100644 --- a/src/main/java/app/mealsmadeeasy/api/user/UserEntity.java +++ b/src/main/java/app/mealsmadeeasy/api/user/UserEntity.java @@ -24,7 +24,7 @@ public final class UserEntity implements User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(nullable = false) - private Long id; + private Integer id; @Column(unique = true, nullable = false) private String username; @@ -51,11 +51,11 @@ public final class UserEntity implements User { private Boolean credentialsExpired; @Override - public Long getId() { + public Integer getId() { return this.id; } - public void setId(Long id) { + public void setId(Integer id) { this.id = id; } diff --git a/src/main/java/app/mealsmadeeasy/api/user/UserGrantedAuthorityEntity.java b/src/main/java/app/mealsmadeeasy/api/user/UserGrantedAuthorityEntity.java index acf5f39..0dc8fba 100644 --- a/src/main/java/app/mealsmadeeasy/api/user/UserGrantedAuthorityEntity.java +++ b/src/main/java/app/mealsmadeeasy/api/user/UserGrantedAuthorityEntity.java @@ -2,18 +2,19 @@ package app.mealsmadeeasy.api.user; import jakarta.persistence.*; -@Entity +@Entity(name = "UserGrantedAuthority") +@Table(name = "user_granted_authority") public final class UserGrantedAuthorityEntity implements UserGrantedAuthority { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(nullable = false) - private Long id; + private Integer id; private String authority; @ManyToOne - @JoinColumn(name = "user_entity_id") + @JoinColumn(name = "user_id") private UserEntity userEntity; @Override diff --git a/src/main/java/app/mealsmadeeasy/api/user/view/UserInfoView.java b/src/main/java/app/mealsmadeeasy/api/user/view/UserInfoView.java index c50b5cf..0e983e7 100644 --- a/src/main/java/app/mealsmadeeasy/api/user/view/UserInfoView.java +++ b/src/main/java/app/mealsmadeeasy/api/user/view/UserInfoView.java @@ -11,14 +11,14 @@ public class UserInfoView { return userInfoView; } - private long id; + private Integer id; private String username; - public long getId() { + public Integer getId() { return this.id; } - public void setId(long id) { + public void setId(Integer id) { this.id = id; } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a70c2c2..f933cff 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,5 @@ spring.application.name=meals-made-easy-api -spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.hibernate.ddl-auto=none spring.datasource.url=jdbc:postgresql://${POSTGRES_HOST:localhost}:${POSTGRES_PORT:5432}/${POSTGRES_DB:meals_made_easy_api} spring.datasource.username=${POSTGRES_USER:meals-made-easy-api-user} spring.datasource.password=${POSTGRES_PASSWORD} diff --git a/src/main/resources/db/migration/V1__init_schema.sql b/src/main/resources/db/migration/V1__init_schema.sql new file mode 100644 index 0000000..f3383e1 --- /dev/null +++ b/src/main/resources/db/migration/V1__init_schema.sql @@ -0,0 +1,108 @@ +CREATE TABLE "user" ( + id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + email VARCHAR(255) NOT NULL UNIQUE, + password VARCHAR(255) NOT NULL, + username VARCHAR(255) NOT NULL UNIQUE, + locked BOOLEAN NOT NULL, + expired BOOLEAN NOT NULL, + enabled BOOLEAN NOT NULL, + credentials_expired BOOLEAN NOT NULL +); + +CREATE TABLE user_granted_authority ( + id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + user_id INT NOT NULL, + authority VARCHAR(255), + FOREIGN KEY (user_id) REFERENCES "user" +); + +CREATE TABLE refresh_token ( + token UUID PRIMARY KEY, + issued TIMESTAMPTZ(6) NOT NULL, + expiration TIMESTAMPTZ(6) NOT NULL, + owner_id INT NOT NULL, + deleted BOOLEAN NOT NULL, + revoked BOOLEAN NOT NULL, + FOREIGN KEY (owner_id) REFERENCES "user" +); + +CREATE TABLE image ( + id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + created TIMESTAMPTZ(6) NOT NULL, + modified TIMESTAMPTZ(6), + + owner_id INT NOT NULL, + is_public BOOLEAN NOT NULL, + + object_name VARCHAR(255) NOT NULL, + user_filename VARCHAR(255) NOT NULL, + mime_type VARCHAR(255) NOT NULL, + alt VARCHAR(255), + caption VARCHAR(255), + + height INTEGER, + width INTEGER, + + FOREIGN KEY (owner_id) REFERENCES "user" +); + +CREATE TABLE image_viewer ( + image_id INT NOT NULL, + viewer_id INT NOT NULL, + PRIMARY KEY (image_id, viewer_id), + FOREIGN KEY (image_id) REFERENCES image, + FOREIGN KEY (viewer_id) REFERENCES "user" +); + +CREATE TABLE recipe ( + id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + created TIMESTAMPTZ(6) NOT NULL, + modified TIMESTAMPTZ(6), + + owner_id INT NOT NULL, + slug VARCHAR(255) NOT NULL, + is_public BOOLEAN NOT NULL, + + title VARCHAR(255) NOT NULL, + raw_text TEXT NOT NULL, + cached_rendered_text TEXT, + main_image_id INT, + + preparation_time INT, + cooking_time INT, + total_time INT, + + FOREIGN KEY (owner_id) REFERENCES "user", + FOREIGN KEY (main_image_id) REFERENCES image +); + +CREATE INDEX recipe_username_slug ON recipe (owner_id, slug); + +CREATE TABLE recipe_viewer ( + recipe_id INT NOT NULL, + viewer_id INT NOT NULL, + PRIMARY KEY (recipe_id, viewer_id), + FOREIGN KEY (recipe_id) REFERENCES recipe, + FOREIGN KEY (viewer_id) REFERENCES "user" +); + +CREATE TABLE recipe_comment ( + id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + created TIMESTAMPTZ(6) NOT NULL, + modified TIMESTAMPTZ(6), + owner_id INT NOT NULL, + recipe_id INT NOT NULL, + raw_text TEXT NOT NULL, + cached_rendered_text TEXT, + FOREIGN KEY (owner_id) REFERENCES "user", + FOREIGN KEY (recipe_id) REFERENCES recipe +); + +CREATE TABLE recipe_star ( + timestamp TIMESTAMPTZ(6) NOT NULL, + recipe_id INT NOT NULL, + owner_id INT NOT NULL, + PRIMARY KEY (recipe_id, owner_id), + FOREIGN KEY (recipe_id) references recipe, + FOREIGN KEY (owner_id) references "user" +); \ No newline at end of file diff --git a/src/testFixtures/java/app/mealsmadeeasy/api/recipe/ContainsRecipeStarsMatcher.java b/src/testFixtures/java/app/mealsmadeeasy/api/recipe/ContainsRecipeStarsMatcher.java index 854c9f1..e940aff 100644 --- a/src/testFixtures/java/app/mealsmadeeasy/api/recipe/ContainsRecipeStarsMatcher.java +++ b/src/testFixtures/java/app/mealsmadeeasy/api/recipe/ContainsRecipeStarsMatcher.java @@ -21,7 +21,7 @@ public class ContainsRecipeStarsMatcher extends ContainsItemsMatcher ((RecipeStarEntity) recipeStar).getId(), recipeStar -> ((RecipeStarEntity) recipeStar).getId(), (id0, id1) -> Objects.equals(id0.getRecipeId(), id1.getRecipeId()) - && Objects.equals(id0.getOwnerUsername(), id1.getOwnerUsername()) + && Objects.equals(id0.getOwnerId(), id1.getOwnerId()) ); }