From 01d9d758ec1b0afddaaf28571ab0fab2e37a3fd1 Mon Sep 17 00:00:00 2001 From: thguss Date: Wed, 16 Oct 2024 19:55:35 +0900 Subject: [PATCH 01/11] add: added schema.sql --- src/test/resources/application-test.yml | 9 ++++++++- src/test/resources/sql/schema.sql | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/sql/schema.sql diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml index 6ca11e87..163a6125 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application-test.yml @@ -3,13 +3,20 @@ spring: import: application-secret.yml activate: on-profile: test + datasource: url: jdbc:h2:mem:test;MODE=MYSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE username: sa password: + + sql: + init: + schema-locations: classpath:/sql/schema.sql + jpa: hibernate: ddl-auto: create + security: oauth2: client: @@ -46,4 +53,4 @@ jwt: softie: cron: init: - routine: "0 0 0 * * *" \ No newline at end of file + routine: "0 0 0 * * *" diff --git a/src/test/resources/sql/schema.sql b/src/test/resources/sql/schema.sql new file mode 100644 index 00000000..bd7c69bc --- /dev/null +++ b/src/test/resources/sql/schema.sql @@ -0,0 +1,2 @@ +CREATE SCHEMA IF NOT EXISTS softie; +SET SCHEMA softie; From a6a4cea886273c2a5e2feea78e48972fc0f47b03 Mon Sep 17 00:00:00 2001 From: thguss Date: Wed, 16 Oct 2024 20:56:52 +0900 Subject: [PATCH 02/11] fix: updated property name --- src/main/resources/application-dev.yml | 2 +- src/main/resources/application-prod.yml | 2 +- src/test/resources/application-test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index bbd65009..524a87d0 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -31,7 +31,7 @@ jwt: ACCESS_TOKEN_EXPIRED: 7200000 REFRESH_TOKEN_EXPIRED: 1209600000 -softie: +batch: cron: init: routine: "0 0 0 * * *" diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 3e118b34..10f9f9a0 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -31,7 +31,7 @@ jwt: ACCESS_TOKEN_EXPIRED: 7200000 REFRESH_TOKEN_EXPIRED: 1209600000 -softie: +batch: cron: init: routine: "0 0 0 * * *" diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml index 163a6125..7602b597 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application-test.yml @@ -50,7 +50,7 @@ jwt: ACCESS_TOKEN_EXPIRED: 60000 REFRESH_TOKEN_EXPIRED: 1209600000 -softie: +batch: cron: init: routine: "0 0 0 * * *" From 1d970d5871b7bfe4aa0d69ee9d441f9a72d8e802 Mon Sep 17 00:00:00 2001 From: thguss Date: Wed, 16 Oct 2024 20:57:40 +0900 Subject: [PATCH 03/11] fix: updated configuration by package --- .../soptie/server/batch/BatchProperties.java | 19 +++++++++++++++++++ .../config/JpaAuditingConfig.java | 2 +- .../config/JpaQueryFactoryConfig.java | 2 +- .../soptie/server/config/PropertyConfig.java | 11 +++++++++++ .../{api => }/config/SecurityConfig.java | 2 +- .../{api => }/config/SwaggerConfig.java | 2 +- .../config/TimezoneConfig.java | 2 +- 7 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/soptie/server/batch/BatchProperties.java rename src/main/java/com/soptie/server/{persistence => }/config/JpaAuditingConfig.java (81%) rename src/main/java/com/soptie/server/{persistence => }/config/JpaQueryFactoryConfig.java (88%) create mode 100644 src/main/java/com/soptie/server/config/PropertyConfig.java rename src/main/java/com/soptie/server/{api => }/config/SecurityConfig.java (98%) rename src/main/java/com/soptie/server/{api => }/config/SwaggerConfig.java (96%) rename src/main/java/com/soptie/server/{persistence => }/config/TimezoneConfig.java (85%) diff --git a/src/main/java/com/soptie/server/batch/BatchProperties.java b/src/main/java/com/soptie/server/batch/BatchProperties.java new file mode 100644 index 00000000..03803112 --- /dev/null +++ b/src/main/java/com/soptie/server/batch/BatchProperties.java @@ -0,0 +1,19 @@ +package com.soptie.server.batch; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "batch") +public record BatchProperties( + Cron cron +) { + + public record Cron( + Init init + ) { + + public record Init( + String routine + ) { + } + } +} diff --git a/src/main/java/com/soptie/server/persistence/config/JpaAuditingConfig.java b/src/main/java/com/soptie/server/config/JpaAuditingConfig.java similarity index 81% rename from src/main/java/com/soptie/server/persistence/config/JpaAuditingConfig.java rename to src/main/java/com/soptie/server/config/JpaAuditingConfig.java index 2c6b8964..6d72abe0 100644 --- a/src/main/java/com/soptie/server/persistence/config/JpaAuditingConfig.java +++ b/src/main/java/com/soptie/server/config/JpaAuditingConfig.java @@ -1,4 +1,4 @@ -package com.soptie.server.persistence.config; +package com.soptie.server.config; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; diff --git a/src/main/java/com/soptie/server/persistence/config/JpaQueryFactoryConfig.java b/src/main/java/com/soptie/server/config/JpaQueryFactoryConfig.java similarity index 88% rename from src/main/java/com/soptie/server/persistence/config/JpaQueryFactoryConfig.java rename to src/main/java/com/soptie/server/config/JpaQueryFactoryConfig.java index ed9b005e..603ebccf 100644 --- a/src/main/java/com/soptie/server/persistence/config/JpaQueryFactoryConfig.java +++ b/src/main/java/com/soptie/server/config/JpaQueryFactoryConfig.java @@ -1,4 +1,4 @@ -package com.soptie.server.persistence.config; +package com.soptie.server.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/com/soptie/server/config/PropertyConfig.java b/src/main/java/com/soptie/server/config/PropertyConfig.java new file mode 100644 index 00000000..782d8d49 --- /dev/null +++ b/src/main/java/com/soptie/server/config/PropertyConfig.java @@ -0,0 +1,11 @@ +package com.soptie.server.config; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import com.soptie.server.batch.BatchProperties; + +@Configuration +@EnableConfigurationProperties({BatchProperties.class}) +public class PropertyConfig { +} diff --git a/src/main/java/com/soptie/server/api/config/SecurityConfig.java b/src/main/java/com/soptie/server/config/SecurityConfig.java similarity index 98% rename from src/main/java/com/soptie/server/api/config/SecurityConfig.java rename to src/main/java/com/soptie/server/config/SecurityConfig.java index 0ab0adff..8fa214b6 100644 --- a/src/main/java/com/soptie/server/api/config/SecurityConfig.java +++ b/src/main/java/com/soptie/server/config/SecurityConfig.java @@ -1,4 +1,4 @@ -package com.soptie.server.api.config; +package com.soptie.server.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/com/soptie/server/api/config/SwaggerConfig.java b/src/main/java/com/soptie/server/config/SwaggerConfig.java similarity index 96% rename from src/main/java/com/soptie/server/api/config/SwaggerConfig.java rename to src/main/java/com/soptie/server/config/SwaggerConfig.java index e8f47c38..2dddf037 100644 --- a/src/main/java/com/soptie/server/api/config/SwaggerConfig.java +++ b/src/main/java/com/soptie/server/config/SwaggerConfig.java @@ -1,4 +1,4 @@ -package com.soptie.server.api.config; +package com.soptie.server.config; import static io.swagger.v3.oas.models.security.SecurityScheme.Type.*; diff --git a/src/main/java/com/soptie/server/persistence/config/TimezoneConfig.java b/src/main/java/com/soptie/server/config/TimezoneConfig.java similarity index 85% rename from src/main/java/com/soptie/server/persistence/config/TimezoneConfig.java rename to src/main/java/com/soptie/server/config/TimezoneConfig.java index e53925fb..8e52b012 100644 --- a/src/main/java/com/soptie/server/persistence/config/TimezoneConfig.java +++ b/src/main/java/com/soptie/server/config/TimezoneConfig.java @@ -1,4 +1,4 @@ -package com.soptie.server.persistence.config; +package com.soptie.server.config; import java.util.TimeZone; From 718e8f0aaa853b0d17e1c4445aa9b5781e698458 Mon Sep 17 00:00:00 2001 From: thguss Date: Wed, 16 Oct 2024 21:04:10 +0900 Subject: [PATCH 04/11] fix: updated constructor --- .../soptie/server/domain/member/Member.java | 8 ++++++++ .../domain/memberroutine/MemberRoutine.java | 19 ++++++++++++++----- .../soptie/server/domain/routine/Routine.java | 8 ++++++++ .../persistence/entity/MemberEntity.java | 9 +++++++++ .../entity/MemberRoutineEntity.java | 10 ++++++++++ .../persistence/entity/RoutineEntity.java | 8 ++++++++ 6 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/soptie/server/domain/member/Member.java b/src/main/java/com/soptie/server/domain/member/Member.java index f7877f9d..d7875992 100644 --- a/src/main/java/com/soptie/server/domain/member/Member.java +++ b/src/main/java/com/soptie/server/domain/member/Member.java @@ -1,16 +1,24 @@ package com.soptie.server.domain.member; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @Builder @Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) public class Member { private Long id; private Social socialInfo; private String refreshToken; private MemberCotton cottonInfo; + public Member(SocialType socialType, String socialId) { + this.socialInfo = new Social(socialType, socialId); + this.cottonInfo = new MemberCotton(0, 0); + } + public void resetRefreshToken() { this.refreshToken = null; } diff --git a/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutine.java b/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutine.java index 39c0aa57..14bcb2c8 100644 --- a/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutine.java +++ b/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutine.java @@ -1,10 +1,16 @@ package com.soptie.server.domain.memberroutine; +import com.soptie.server.domain.member.Member; +import com.soptie.server.domain.routine.Routine; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @Builder @Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) public class MemberRoutine { private Long id; private boolean isAchieved; @@ -13,14 +19,17 @@ public class MemberRoutine { private long memberId; private long routineId; + public MemberRoutine(Member member, Routine routine) { + this.isAchieved = false; + this.isAchievedToday = false; + this.achievementCount = 0; + this.memberId = member.getId(); + this.routineId = routine.getId(); + } + public void achieve() { this.isAchievedToday = true; this.achievementCount += !this.isAchieved ? 1 : -1; this.isAchieved = !this.isAchieved; } - - public void initAchievement() { - this.isAchievedToday = false; - this.isAchieved = false; - } } diff --git a/src/main/java/com/soptie/server/domain/routine/Routine.java b/src/main/java/com/soptie/server/domain/routine/Routine.java index 18b44401..2d8a359b 100644 --- a/src/main/java/com/soptie/server/domain/routine/Routine.java +++ b/src/main/java/com/soptie/server/domain/routine/Routine.java @@ -1,14 +1,22 @@ package com.soptie.server.domain.routine; import jakarta.validation.constraints.NotNull; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @Builder @Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) public class Routine { private Long id; @NotNull private String content; private long themeId; + + public Routine(String content, long themeId) { + this.content = content; + this.themeId = themeId; + } } diff --git a/src/main/java/com/soptie/server/persistence/entity/MemberEntity.java b/src/main/java/com/soptie/server/persistence/entity/MemberEntity.java index c13ff89a..fcd0854b 100644 --- a/src/main/java/com/soptie/server/persistence/entity/MemberEntity.java +++ b/src/main/java/com/soptie/server/persistence/entity/MemberEntity.java @@ -28,6 +28,7 @@ public class MemberEntity extends BaseEntity { @Column(nullable = false) private int rainbowCottonCount; + //TODO: 2번째 생성자 활용(Entity 보호) public MemberEntity(SocialType socialType, String socialId) { this.socialType = socialType; this.socialId = socialId; @@ -35,6 +36,14 @@ public MemberEntity(SocialType socialType, String socialId) { this.rainbowCottonCount = 0; } + public MemberEntity(Member member) { + this.socialType = member.getSocialInfo().getSocialType(); + this.socialId = member.getSocialInfo().getSocialId(); + this.refreshToken = member.getRefreshToken(); + this.basicCottonCount = member.getCottonInfo().getBasicCottonCount(); + this.rainbowCottonCount = member.getCottonInfo().getRainbowCottonCount(); + } + public void update(Member member) { this.refreshToken = member.getRefreshToken(); this.basicCottonCount = member.getCottonInfo().getBasicCottonCount(); diff --git a/src/main/java/com/soptie/server/persistence/entity/MemberRoutineEntity.java b/src/main/java/com/soptie/server/persistence/entity/MemberRoutineEntity.java index 2e5b3657..5b46cf35 100644 --- a/src/main/java/com/soptie/server/persistence/entity/MemberRoutineEntity.java +++ b/src/main/java/com/soptie/server/persistence/entity/MemberRoutineEntity.java @@ -38,6 +38,7 @@ public class MemberRoutineEntity extends BaseEntity { @Column(nullable = false) private long routineId; + //TODO: 아래 생성자 활용 (Entity 보호) public MemberRoutineEntity(Member member, Routine routine) { this.isAchieved = false; this.isAchievedToday = false; @@ -47,6 +48,15 @@ public MemberRoutineEntity(Member member, Routine routine) { this.routineId = routine.getId(); } + public MemberRoutineEntity(MemberRoutine memberRoutine) { + this.isAchieved = memberRoutine.isAchieved(); + this.isAchievedToday = memberRoutine.isAchievedToday(); + this.achievementCount = memberRoutine.getAchievementCount(); + this.isDeleted = false; + this.memberId = memberRoutine.getMemberId(); + this.routineId = memberRoutine.getRoutineId(); + } + public MemberRoutine toDomain() { return MemberRoutine.builder() .id(this.id) diff --git a/src/main/java/com/soptie/server/persistence/entity/RoutineEntity.java b/src/main/java/com/soptie/server/persistence/entity/RoutineEntity.java index 1f1fbfb2..fd92c340 100644 --- a/src/main/java/com/soptie/server/persistence/entity/RoutineEntity.java +++ b/src/main/java/com/soptie/server/persistence/entity/RoutineEntity.java @@ -5,10 +5,13 @@ import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Table; +import lombok.AccessLevel; import lombok.Getter; +import lombok.NoArgsConstructor; @Entity @Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "routine", schema = "softie") public class RoutineEntity extends BaseEntity { @Column(nullable = false) @@ -16,6 +19,11 @@ public class RoutineEntity extends BaseEntity { @Column(nullable = false) private long themeId; + public RoutineEntity(Routine routine) { + this.content = routine.getContent(); + this.themeId = routine.getThemeId(); + } + public Routine toDomain() { return Routine.builder() .id(this.id) From 20dfff748c6dab1b85cb068b95cc36fdc2fe6f66 Mon Sep 17 00:00:00 2001 From: thguss Date: Wed, 16 Oct 2024 21:04:31 +0900 Subject: [PATCH 05/11] add: added getter --- src/main/java/com/soptie/server/domain/member/Social.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/soptie/server/domain/member/Social.java b/src/main/java/com/soptie/server/domain/member/Social.java index 90f3a942..55cb3dac 100644 --- a/src/main/java/com/soptie/server/domain/member/Social.java +++ b/src/main/java/com/soptie/server/domain/member/Social.java @@ -2,8 +2,10 @@ import jakarta.validation.constraints.NotNull; import lombok.Builder; +import lombok.Getter; @Builder +@Getter public class Social { @NotNull protected SocialType socialType; From c8d8d2a6c42ffe8865351b211aeeb22c98571f26 Mon Sep 17 00:00:00 2001 From: thguss Date: Wed, 16 Oct 2024 21:08:43 +0900 Subject: [PATCH 06/11] add: added Fixture for Test --- .../server/support/fixture/MemberFixture.java | 13 ++++++++++ .../support/fixture/MemberRoutineFixture.java | 12 +++++++++ .../support/fixture/RoutineFixture.java | 26 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 src/test/java/com/soptie/server/support/fixture/MemberFixture.java create mode 100644 src/test/java/com/soptie/server/support/fixture/MemberRoutineFixture.java create mode 100644 src/test/java/com/soptie/server/support/fixture/RoutineFixture.java diff --git a/src/test/java/com/soptie/server/support/fixture/MemberFixture.java b/src/test/java/com/soptie/server/support/fixture/MemberFixture.java new file mode 100644 index 00000000..0bde07c6 --- /dev/null +++ b/src/test/java/com/soptie/server/support/fixture/MemberFixture.java @@ -0,0 +1,13 @@ +package com.soptie.server.support.fixture; + +import java.util.UUID; + +import com.soptie.server.domain.member.Member; +import com.soptie.server.domain.member.SocialType; + +public class MemberFixture { + + public static Member createDefault() { + return new Member(SocialType.KAKAO, UUID.randomUUID().toString()); + } +} diff --git a/src/test/java/com/soptie/server/support/fixture/MemberRoutineFixture.java b/src/test/java/com/soptie/server/support/fixture/MemberRoutineFixture.java new file mode 100644 index 00000000..496d673c --- /dev/null +++ b/src/test/java/com/soptie/server/support/fixture/MemberRoutineFixture.java @@ -0,0 +1,12 @@ +package com.soptie.server.support.fixture; + +import com.soptie.server.domain.member.Member; +import com.soptie.server.domain.memberroutine.MemberRoutine; +import com.soptie.server.domain.routine.Routine; + +public class MemberRoutineFixture { + + public static MemberRoutine createDefault(Member member, Routine routine) { + return new MemberRoutine(member, routine); + } +} diff --git a/src/test/java/com/soptie/server/support/fixture/RoutineFixture.java b/src/test/java/com/soptie/server/support/fixture/RoutineFixture.java new file mode 100644 index 00000000..308ed3e0 --- /dev/null +++ b/src/test/java/com/soptie/server/support/fixture/RoutineFixture.java @@ -0,0 +1,26 @@ +package com.soptie.server.support.fixture; + +import com.soptie.server.domain.routine.Routine; + +public class RoutineFixture { + String content = "테스트용 루틴"; + long themeId = 0L; + + public static RoutineFixture create() { + return new RoutineFixture(); + } + + public RoutineFixture content(String content) { + this.content = content; + return this; + } + + public RoutineFixture themeId(Long themeId) { + this.themeId = themeId; + return this; + } + + public Routine build() { + return new Routine(content, themeId); + } +} From ca3310d4c714ea307f6fc1795251a5519a9252f1 Mon Sep 17 00:00:00 2001 From: thguss Date: Wed, 16 Oct 2024 21:10:04 +0900 Subject: [PATCH 07/11] fix: updated package --- .../com/soptie/server/persistence/adapter/RoutineAdapter.java | 2 +- .../repository/{ => routine}/RoutineRepository.java | 2 +- src/test/java/com/soptie/server/support/RepositoryTest.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename src/main/java/com/soptie/server/persistence/repository/{ => routine}/RoutineRepository.java (91%) diff --git a/src/main/java/com/soptie/server/persistence/adapter/RoutineAdapter.java b/src/main/java/com/soptie/server/persistence/adapter/RoutineAdapter.java index 19ad311f..a7f80038 100644 --- a/src/main/java/com/soptie/server/persistence/adapter/RoutineAdapter.java +++ b/src/main/java/com/soptie/server/persistence/adapter/RoutineAdapter.java @@ -7,7 +7,7 @@ import com.soptie.server.common.support.RepositoryAdapter; import com.soptie.server.domain.routine.Routine; import com.soptie.server.persistence.entity.RoutineEntity; -import com.soptie.server.persistence.repository.RoutineRepository; +import com.soptie.server.persistence.repository.routine.RoutineRepository; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/soptie/server/persistence/repository/RoutineRepository.java b/src/main/java/com/soptie/server/persistence/repository/routine/RoutineRepository.java similarity index 91% rename from src/main/java/com/soptie/server/persistence/repository/RoutineRepository.java rename to src/main/java/com/soptie/server/persistence/repository/routine/RoutineRepository.java index 39d4f27a..f077abc0 100644 --- a/src/main/java/com/soptie/server/persistence/repository/RoutineRepository.java +++ b/src/main/java/com/soptie/server/persistence/repository/routine/RoutineRepository.java @@ -1,4 +1,4 @@ -package com.soptie.server.persistence.repository; +package com.soptie.server.persistence.repository.routine; import java.util.List; diff --git a/src/test/java/com/soptie/server/support/RepositoryTest.java b/src/test/java/com/soptie/server/support/RepositoryTest.java index 832174a9..15a5a3a7 100644 --- a/src/test/java/com/soptie/server/support/RepositoryTest.java +++ b/src/test/java/com/soptie/server/support/RepositoryTest.java @@ -8,8 +8,8 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; -import com.soptie.server.persistence.config.JpaAuditingConfig; -import com.soptie.server.persistence.config.JpaQueryFactoryConfig; +import com.soptie.server.config.JpaAuditingConfig; +import com.soptie.server.config.JpaQueryFactoryConfig; @DataJpaTest(showSql = false) @Import({JpaAuditingConfig.class, JpaQueryFactoryConfig.class}) From 5bd66e4eea9adc64cf769f6a43aa09faf6a78d63 Mon Sep 17 00:00:00 2001 From: thguss Date: Wed, 16 Oct 2024 21:10:38 +0900 Subject: [PATCH 08/11] add: added custom repository --- .../MemberRoutineRepository.java | 15 +++------ .../custom/MemberRoutineCustomRepository.java | 7 ++++ .../custom/MemberRoutineRepositoryImpl.java | 33 +++++++++++++++++++ 3 files changed, 45 insertions(+), 10 deletions(-) rename src/main/java/com/soptie/server/persistence/repository/{ => routine}/MemberRoutineRepository.java (62%) create mode 100644 src/main/java/com/soptie/server/persistence/repository/routine/custom/MemberRoutineCustomRepository.java create mode 100644 src/main/java/com/soptie/server/persistence/repository/routine/custom/MemberRoutineRepositoryImpl.java diff --git a/src/main/java/com/soptie/server/persistence/repository/MemberRoutineRepository.java b/src/main/java/com/soptie/server/persistence/repository/routine/MemberRoutineRepository.java similarity index 62% rename from src/main/java/com/soptie/server/persistence/repository/MemberRoutineRepository.java rename to src/main/java/com/soptie/server/persistence/repository/routine/MemberRoutineRepository.java index a437d76c..08383a1a 100644 --- a/src/main/java/com/soptie/server/persistence/repository/MemberRoutineRepository.java +++ b/src/main/java/com/soptie/server/persistence/repository/routine/MemberRoutineRepository.java @@ -1,4 +1,4 @@ -package com.soptie.server.persistence.repository; +package com.soptie.server.persistence.repository.routine; import java.util.List; @@ -7,25 +7,20 @@ import org.springframework.data.jpa.repository.Query; import com.soptie.server.persistence.entity.MemberRoutineEntity; +import com.soptie.server.persistence.repository.routine.custom.MemberRoutineCustomRepository; + +public interface MemberRoutineRepository + extends JpaRepository, MemberRoutineCustomRepository { -public interface MemberRoutineRepository extends JpaRepository { @Query( value = "SELECT * FROM member_routine WHERE member_id = :memberId AND is_deleted = true", nativeQuery = true) List findDeletedByMemberId(long memberId); - @Query( - value = "SELECT * FROM member_routine WHERE is_achieved = :isAchieved AND is_deleted = true", - nativeQuery = true) - List findDeletedByIsAchieved(boolean isAchieved); - List findByMemberId(long memberId); List findByIdIn(List ids); - @SuppressWarnings("SpringDataMethodInconsistencyInspection") - List findByIsAchieved(boolean isAchieved); - @Modifying @Query( value = "DELETE FROM member_routine WHERE member_id = :memberId", diff --git a/src/main/java/com/soptie/server/persistence/repository/routine/custom/MemberRoutineCustomRepository.java b/src/main/java/com/soptie/server/persistence/repository/routine/custom/MemberRoutineCustomRepository.java new file mode 100644 index 00000000..cf444242 --- /dev/null +++ b/src/main/java/com/soptie/server/persistence/repository/routine/custom/MemberRoutineCustomRepository.java @@ -0,0 +1,7 @@ +package com.soptie.server.persistence.repository.routine.custom; + +public interface MemberRoutineCustomRepository { + void bulkInitAchievement(); + + long countByAchieved(boolean isAchieved); +} diff --git a/src/main/java/com/soptie/server/persistence/repository/routine/custom/MemberRoutineRepositoryImpl.java b/src/main/java/com/soptie/server/persistence/repository/routine/custom/MemberRoutineRepositoryImpl.java new file mode 100644 index 00000000..8dc08a16 --- /dev/null +++ b/src/main/java/com/soptie/server/persistence/repository/routine/custom/MemberRoutineRepositoryImpl.java @@ -0,0 +1,33 @@ +package com.soptie.server.persistence.repository.routine.custom; + +import static com.soptie.server.persistence.entity.QMemberRoutineEntity.*; + +import org.springframework.stereotype.Repository; + +import com.querydsl.jpa.impl.JPAQueryFactory; + +import lombok.RequiredArgsConstructor; + +@Repository +@RequiredArgsConstructor +public class MemberRoutineRepositoryImpl implements MemberRoutineCustomRepository { + + private final JPAQueryFactory queryFactory; + + @Override + public void bulkInitAchievement() { + queryFactory.update(memberRoutineEntity) + .set(memberRoutineEntity.isAchieved, false) + .set(memberRoutineEntity.isAchievedToday, false) + .where(memberRoutineEntity.isAchieved.isTrue()) + .execute(); + } + + @Override + public long countByAchieved(boolean isAchieved) { + return queryFactory + .selectFrom(memberRoutineEntity) + .where(memberRoutineEntity.isAchieved.eq(isAchieved)) + .stream().count(); + } +} From db5e9cb3d01fd3018c919533c968d692b8f60aee Mon Sep 17 00:00:00 2001 From: thguss Date: Wed, 16 Oct 2024 21:10:57 +0900 Subject: [PATCH 09/11] fix: updated property --- .../java/com/soptie/server/batch/MemberRoutineScheduler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/soptie/server/batch/MemberRoutineScheduler.java b/src/main/java/com/soptie/server/batch/MemberRoutineScheduler.java index a20c3d25..f7f6c776 100644 --- a/src/main/java/com/soptie/server/batch/MemberRoutineScheduler.java +++ b/src/main/java/com/soptie/server/batch/MemberRoutineScheduler.java @@ -14,7 +14,7 @@ public class MemberRoutineScheduler { private final MemberRoutineService memberRoutineService; - @Scheduled(cron = "${softie.cron.init.routine}") + @Scheduled(cron = "${batch.cron.init.routine}") public void initMemberDailyRoutines() { memberRoutineService.initAchievement(); } From 08d1e0be3d22c9a15e65a6b56c46236c4d1f1c25 Mon Sep 17 00:00:00 2001 From: thguss Date: Wed, 16 Oct 2024 21:11:19 +0900 Subject: [PATCH 10/11] fix: updated bulk update query --- .../domain/memberroutine/MemberRoutineService.java | 5 +---- .../persistence/adapter/MemberRoutineAdapter.java | 13 +++---------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java b/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java index b8661442..539eb797 100644 --- a/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java +++ b/src/main/java/com/soptie/server/domain/memberroutine/MemberRoutineService.java @@ -91,10 +91,7 @@ public AchieveMemberRoutineResponse achieveMemberRoutine(long memberId, long mem @Transactional public void initAchievement() { - val memberRoutines = memberRoutineAdapter.findAchieved(); - for (val memberRoutine : memberRoutines) { - memberRoutine.initAchievement(); - } + memberRoutineAdapter.initAllAchievement(); } private Map> toRoutinesByTheme( diff --git a/src/main/java/com/soptie/server/persistence/adapter/MemberRoutineAdapter.java b/src/main/java/com/soptie/server/persistence/adapter/MemberRoutineAdapter.java index 5859451c..85945c06 100644 --- a/src/main/java/com/soptie/server/persistence/adapter/MemberRoutineAdapter.java +++ b/src/main/java/com/soptie/server/persistence/adapter/MemberRoutineAdapter.java @@ -1,6 +1,5 @@ package com.soptie.server.persistence.adapter; -import java.util.ArrayList; import java.util.List; import com.soptie.server.common.exception.ExceptionCode; @@ -10,7 +9,7 @@ import com.soptie.server.domain.memberroutine.MemberRoutine; import com.soptie.server.domain.routine.Routine; import com.soptie.server.persistence.entity.MemberRoutineEntity; -import com.soptie.server.persistence.repository.MemberRoutineRepository; +import com.soptie.server.persistence.repository.routine.MemberRoutineRepository; import lombok.RequiredArgsConstructor; import lombok.val; @@ -60,14 +59,8 @@ public void update(MemberRoutine memberRoutine) { memberRoutineEntity.update(memberRoutine); } - public List findAchieved() { - val memberRoutines = new ArrayList(); - memberRoutines.addAll(memberRoutineRepository.findByIsAchieved(true).stream() - .map(MemberRoutineEntity::toDomain) - .toList()); - memberRoutines.addAll(memberRoutineRepository.findDeletedByIsAchieved(true).stream().map( - MemberRoutineEntity::toDomain).toList()); - return memberRoutines; + public void initAllAchievement() { + memberRoutineRepository.bulkInitAchievement(); } private MemberRoutineEntity restore( From 0a64d6b13956147d306720ee9f3b939d478b79a9 Mon Sep 17 00:00:00 2001 From: thguss Date: Wed, 16 Oct 2024 21:12:20 +0900 Subject: [PATCH 11/11] test: test for initializing member_routine achievement --- .../batch/MemberRoutineSchedulerTest.java | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 src/test/java/com/soptie/server/batch/MemberRoutineSchedulerTest.java diff --git a/src/test/java/com/soptie/server/batch/MemberRoutineSchedulerTest.java b/src/test/java/com/soptie/server/batch/MemberRoutineSchedulerTest.java new file mode 100644 index 00000000..cf13675f --- /dev/null +++ b/src/test/java/com/soptie/server/batch/MemberRoutineSchedulerTest.java @@ -0,0 +1,103 @@ +package com.soptie.server.batch; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.scheduling.annotation.SchedulingConfigurer; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; +import org.springframework.transaction.annotation.Transactional; + +import com.soptie.server.domain.member.Member; +import com.soptie.server.domain.memberroutine.MemberRoutine; +import com.soptie.server.domain.memberroutine.MemberRoutineService; +import com.soptie.server.domain.routine.Routine; +import com.soptie.server.persistence.entity.MemberEntity; +import com.soptie.server.persistence.entity.MemberRoutineEntity; +import com.soptie.server.persistence.entity.RoutineEntity; +import com.soptie.server.persistence.repository.MemberRepository; +import com.soptie.server.persistence.repository.routine.MemberRoutineRepository; +import com.soptie.server.persistence.repository.routine.RoutineRepository; +import com.soptie.server.support.IntegrationTest; +import com.soptie.server.support.fixture.MemberFixture; +import com.soptie.server.support.fixture.MemberRoutineFixture; +import com.soptie.server.support.fixture.RoutineFixture; + +@IntegrationTest +public class MemberRoutineSchedulerTest implements SchedulingConfigurer { + + @Autowired + private MemberRoutineScheduler memberRoutineScheduler; + + @Autowired + private BatchProperties batchProperties; + + @SpyBean + private MemberRoutineService memberRoutineService; + + @SpyBean + private MemberRoutineRepository memberRoutineRepository; + + @SpyBean + private MemberRepository memberRepository; + + @SpyBean + private RoutineRepository routineRepository; + + private MemberEntity savedMember; + private List savedRoutines; + + @Override + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { + // 테스트에서 cron 트리거를 위한 스케줄링 등록 + String cronExpression = batchProperties.cron().init().routine(); + taskRegistrar.addCronTask(() -> memberRoutineScheduler.initMemberDailyRoutines(), cronExpression); + } + + @BeforeEach + public void setUp() { + savedMember = memberRepository.save(new MemberEntity(MemberFixture.createDefault())); + savedRoutines = routineRepository.saveAll( + IntStream.range(0, 5) + .mapToObj(i -> new RoutineEntity(RoutineFixture.create().themeId((long)i).build())) + .toList()); + } + + @Test + @Transactional + @DisplayName(value = "전체 회원 루틴의 하루 달성 정보를 초기화한다.") + public void testInitMemberRoutineAchievement() { + // given + List memberRoutines = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + MemberRoutine achievedMemberRoutine = createAchievedMemberRoutine(i); + memberRoutines.add(new MemberRoutineEntity(achievedMemberRoutine)); + } + memberRoutineRepository.saveAll(memberRoutines); + + // when + memberRoutineScheduler.initMemberDailyRoutines(); + + // then + verify(memberRoutineService, times(1)).initAchievement(); + + long count = memberRoutineRepository.countByAchieved(true); + assertEquals(0, count); + } + + private MemberRoutine createAchievedMemberRoutine(int themeIdx) { + Member member = savedMember.toDomain(); + Routine routine = savedRoutines.get(themeIdx).toDomain(); + MemberRoutine memberRoutine = MemberRoutineFixture.createDefault(member, routine); + memberRoutine.achieve(); // 루틴 달성 + return memberRoutine; + } +}