From 905348fe2cdf155af1d211df69c453c61c02c611 Mon Sep 17 00:00:00 2001 From: jihwankim128 Date: Sun, 30 Nov 2025 17:26:21 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refactor:=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20?= =?UTF-8?q?=EC=B0=B8=EC=97=AC=20=EB=8F=99=EC=8B=9C=EC=84=B1=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ChallengeJoinConcurrencyTest.java | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/test/java/com/example/integration/challenge/ChallengeJoinConcurrencyTest.java b/src/test/java/com/example/integration/challenge/ChallengeJoinConcurrencyTest.java index 37925e4b..0c84346d 100644 --- a/src/test/java/com/example/integration/challenge/ChallengeJoinConcurrencyTest.java +++ b/src/test/java/com/example/integration/challenge/ChallengeJoinConcurrencyTest.java @@ -2,18 +2,18 @@ import static org.assertj.core.api.Assertions.*; -import java.math.BigDecimal; -import java.time.LocalDate; import java.util.concurrent.atomic.AtomicLong; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import com.example.green.domain.challenge.entity.challenge.TeamChallenge; -import com.example.green.domain.challenge.entity.challenge.vo.ChallengeDisplay; -import com.example.green.domain.challenge.repository.TeamChallengeRepository; -import com.example.green.domain.challenge.service.TeamChallengeService; +import com.example.green.domain.challenge.entity.challenge.Challenge; +import com.example.green.domain.challenge.entity.challenge.vo.ChallengeContent; +import com.example.green.domain.challenge.entity.challenge.vo.ChallengeInfo; +import com.example.green.domain.challenge.entity.challenge.vo.ChallengeType; +import com.example.green.domain.challenge.repository.ChallengeRepository; +import com.example.green.domain.challenge.service.ChallengeService; import com.example.integration.common.BaseIntegrationTest; import com.example.integration.common.concurrency.ConcurrencyTestResult; import com.example.integration.common.concurrency.ConcurrencyTestTemplate; @@ -21,27 +21,23 @@ class ChallengeJoinConcurrencyTest extends BaseIntegrationTest { @Autowired - private TeamChallengeService teamChallengeService; + private ChallengeService teamChallengeService; @Autowired - private TeamChallengeRepository teamChallengeRepository; + private ChallengeRepository teamChallengeRepository; - private TeamChallenge teamChallenge; + private Challenge teamChallenge; @BeforeEach void setUp() { teamChallengeRepository.deleteAllInBatch(); // 팀 챌린지 생성 (참가자 수 제한 없음) - teamChallenge = TeamChallenge.create( + teamChallenge = Challenge.of( "CHL-001", - "환경 정화 챌린지", - "thumbnail.jpg", - "환경 정화 활동을 함께 해요!", - BigDecimal.valueOf(100), - LocalDate.now(), - LocalDate.now().plusDays(7), - ChallengeDisplay.VISIBLE + ChallengeInfo.of("환경 정화 챌린지", 100), + ChallengeContent.of("환경 정화 활동을 함께 해요!", "https://thumbnail.jpg"), + ChallengeType.TEAM ); teamChallenge = teamChallengeRepository.saveAndFlush(teamChallenge); } @@ -54,7 +50,6 @@ void setUp() { // when & then ConcurrencyTestResult result = ConcurrencyTestTemplate.build() .threadCount(3) - .timeout(5) .execute(() -> { try { teamChallengeService.join(teamChallenge.getId(), memberIdGenerator.getAndIncrement()); @@ -65,7 +60,7 @@ void setUp() { } }); - TeamChallenge finalChallenge = teamChallengeRepository.findById(teamChallenge.getId()).orElseThrow(); + Challenge finalChallenge = teamChallengeRepository.findByIdWithThrow(teamChallenge.getId()); assertThat(result.allSucceeded()).isTrue(); assertThat(finalChallenge.getParticipantCount()).isEqualTo(3); } From 1393a78ed2608d944de76d456485811876a8e502 Mon Sep 17 00:00:00 2001 From: jihwankim128 Date: Sun, 30 Nov 2025 22:18:27 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20=EB=A0=88=EA=B1=B0=EC=8B=9C=20?= =?UTF-8?q?=EC=B1=8C=EB=A6=B0=EC=A7=80=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../command/dto/AdminChallengeCreateDto.java | 16 -- .../challenge/AdminChallengeDetailDto.java | 16 -- .../entity/challenge/BaseChallenge.java | 185 ------------------ .../challenge/BaseChallengeParticipation.java | 39 ---- .../entity/challenge/PersonalChallenge.java | 74 ------- .../PersonalChallengeParticipation.java | 49 ----- .../entity/challenge/TeamChallenge.java | 75 ------- .../challenge/TeamChallengeParticipation.java | 49 ----- .../entity/challenge/vo/ChallengeStatus.java | 17 -- .../querydsl/PersonalChallengeQueryImpl.java | 124 ------------ .../querydsl/TeamChallengeQueryImpl.java | 167 ---------------- .../executor/ChallengeGroupQueryExecutor.java | 8 +- .../PersonalChallengeQueryExecutor.java | 105 ---------- .../PersonalChallengePredicates.java | 50 ----- .../ChallengeGroupProjections.java | 4 +- .../PersonalChallengeProjections.java | 97 --------- .../projections/TeamChallengeProjections.java | 89 --------- .../PersonalChallengeRepository.java | 19 -- .../repository/TeamChallengeRepository.java | 23 --- .../query/PersonalChallengeQuery.java | 43 ---- .../repository/query/TeamChallengeQuery.java | 36 ---- .../service/PersonalChallengeService.java | 79 -------- .../service/TeamChallengeService.java | 80 -------- .../WeeklyRankingRepositoryImpl.java | 6 +- .../green/infra/client/dto/ChallengeDto.java | 10 - .../challenge/ChallengeTestDataSource.java | 11 +- .../query/ChallengeAdminQueryTest.java | 1 + .../challenge/query/ChallengeQueryTest.java | 1 + 28 files changed, 18 insertions(+), 1455 deletions(-) delete mode 100644 src/main/java/com/example/green/domain/challenge/entity/challenge/BaseChallenge.java delete mode 100644 src/main/java/com/example/green/domain/challenge/entity/challenge/BaseChallengeParticipation.java delete mode 100644 src/main/java/com/example/green/domain/challenge/entity/challenge/PersonalChallenge.java delete mode 100644 src/main/java/com/example/green/domain/challenge/entity/challenge/PersonalChallengeParticipation.java delete mode 100644 src/main/java/com/example/green/domain/challenge/entity/challenge/TeamChallenge.java delete mode 100644 src/main/java/com/example/green/domain/challenge/entity/challenge/TeamChallengeParticipation.java delete mode 100644 src/main/java/com/example/green/domain/challenge/entity/challenge/vo/ChallengeStatus.java delete mode 100644 src/main/java/com/example/green/domain/challenge/infra/querydsl/PersonalChallengeQueryImpl.java delete mode 100644 src/main/java/com/example/green/domain/challenge/infra/querydsl/TeamChallengeQueryImpl.java delete mode 100644 src/main/java/com/example/green/domain/challenge/infra/querydsl/executor/PersonalChallengeQueryExecutor.java delete mode 100644 src/main/java/com/example/green/domain/challenge/infra/querydsl/predicates/PersonalChallengePredicates.java delete mode 100644 src/main/java/com/example/green/domain/challenge/infra/querydsl/projections/PersonalChallengeProjections.java delete mode 100644 src/main/java/com/example/green/domain/challenge/infra/querydsl/projections/TeamChallengeProjections.java delete mode 100644 src/main/java/com/example/green/domain/challenge/repository/PersonalChallengeRepository.java delete mode 100644 src/main/java/com/example/green/domain/challenge/repository/TeamChallengeRepository.java delete mode 100644 src/main/java/com/example/green/domain/challenge/repository/query/PersonalChallengeQuery.java delete mode 100644 src/main/java/com/example/green/domain/challenge/repository/query/TeamChallengeQuery.java delete mode 100644 src/main/java/com/example/green/domain/challenge/service/PersonalChallengeService.java delete mode 100644 src/main/java/com/example/green/domain/challenge/service/TeamChallengeService.java diff --git a/src/main/java/com/example/green/domain/challenge/controller/command/dto/AdminChallengeCreateDto.java b/src/main/java/com/example/green/domain/challenge/controller/command/dto/AdminChallengeCreateDto.java index 0ed17df0..a2c938fa 100644 --- a/src/main/java/com/example/green/domain/challenge/controller/command/dto/AdminChallengeCreateDto.java +++ b/src/main/java/com/example/green/domain/challenge/controller/command/dto/AdminChallengeCreateDto.java @@ -5,8 +5,6 @@ import java.time.LocalDateTime; import com.example.green.domain.challenge.entity.challenge.Challenge; -import com.example.green.domain.challenge.entity.challenge.PersonalChallenge; -import com.example.green.domain.challenge.entity.challenge.TeamChallenge; import com.example.green.domain.challenge.entity.challenge.vo.ChallengeContent; import com.example.green.domain.challenge.entity.challenge.vo.ChallengeDisplay; import com.example.green.domain.challenge.entity.challenge.vo.ChallengeInfo; @@ -64,20 +62,6 @@ public AdminChallengeCreateDto( this(challengeName, challengePoint, null, null, challengeContent, challengeImageUrl, ChallengeDisplay.VISIBLE); } - public TeamChallenge toTeamChallenge(String challengeCode) { - return TeamChallenge.create( - challengeCode, challengeName, challengeImageUrl, challengeContent, - challengePoint, null, null, displayStatus - ); - } - - public PersonalChallenge toPersonalChallenge(String challengeCode) { - return PersonalChallenge.create( - challengeCode, challengeName, challengeImageUrl, challengeContent, - challengePoint, null, null, displayStatus - ); - } - public Challenge toChallenge(String challengeCode, ChallengeType challengeType) { ChallengeInfo info = ChallengeInfo.of(challengeName, challengePoint.intValue()); ChallengeContent content = ChallengeContent.of(challengeContent, challengeImageUrl); diff --git a/src/main/java/com/example/green/domain/challenge/controller/query/dto/challenge/AdminChallengeDetailDto.java b/src/main/java/com/example/green/domain/challenge/controller/query/dto/challenge/AdminChallengeDetailDto.java index 189eea36..0b5a706c 100644 --- a/src/main/java/com/example/green/domain/challenge/controller/query/dto/challenge/AdminChallengeDetailDto.java +++ b/src/main/java/com/example/green/domain/challenge/controller/query/dto/challenge/AdminChallengeDetailDto.java @@ -3,7 +3,6 @@ import java.math.BigDecimal; import java.time.LocalDate; -import com.example.green.domain.challenge.entity.challenge.BaseChallenge; import com.example.green.domain.challenge.entity.challenge.Challenge; import com.example.green.domain.challenge.entity.challenge.vo.ChallengeDisplay; import com.example.green.domain.challenge.entity.challenge.vo.ChallengeType; @@ -43,21 +42,6 @@ public record AdminChallengeDetailDto( String challengeContent ) { - public static AdminChallengeDetailDto from(BaseChallenge challenge) { - return new AdminChallengeDetailDto( - challenge.getId(), - challenge.getChallengeCode(), - challenge.getChallengeName(), - challenge.getChallengeType(), - challenge.getChallengePoint(), - challenge.getBeginDate(), - challenge.getEndDate(), - challenge.getDisplayStatus(), - challenge.getChallengeImage(), - challenge.getChallengeContent() - ); - } - public static AdminChallengeDetailDto from(Challenge challenge) { return new AdminChallengeDetailDto( challenge.getId(), diff --git a/src/main/java/com/example/green/domain/challenge/entity/challenge/BaseChallenge.java b/src/main/java/com/example/green/domain/challenge/entity/challenge/BaseChallenge.java deleted file mode 100644 index b09f64e3..00000000 --- a/src/main/java/com/example/green/domain/challenge/entity/challenge/BaseChallenge.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.example.green.domain.challenge.entity.challenge; - -import static com.example.green.global.utils.EntityValidator.*; - -import java.math.BigDecimal; -import java.time.LocalDate; -import java.time.LocalDateTime; - -import com.example.green.domain.challenge.entity.challenge.vo.ChallengeDisplay; -import com.example.green.domain.challenge.entity.challenge.vo.ChallengeStatus; -import com.example.green.domain.challenge.entity.challenge.vo.ChallengeType; -import com.example.green.domain.challenge.exception.ChallengeException; -import com.example.green.domain.challenge.exception.ChallengeExceptionMessage; -import com.example.green.domain.common.BaseEntity; - -import jakarta.persistence.Column; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.MappedSuperclass; -import jakarta.persistence.Version; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@MappedSuperclass -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public abstract class BaseChallenge extends BaseEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "challenge_code", length = 30, nullable = false) - private String challengeCode; - - @Column(length = 90, nullable = false) - private String challengeName; - - @Column(nullable = false, precision = 19, scale = 2) - private BigDecimal challengePoint; - - @Column(length = 100) - private String challengeImage; - - @Column(columnDefinition = "TEXT") - private String challengeContent; - - private LocalDate beginDate; - - private LocalDate endDate; - - @Enumerated(EnumType.STRING) - @Column(length = 20, nullable = false) - private ChallengeType challengeType; - - @Enumerated(EnumType.STRING) - @Column(length = 20, nullable = false) - private ChallengeStatus challengeStatus; - - @Enumerated(EnumType.STRING) - @Column(length = 20, nullable = false) - private ChallengeDisplay displayStatus; - - @Column(nullable = false) - private Integer participantCount; - - @Version - private Long version; - - protected BaseChallenge( - String challengeCode, - String challengeName, - String challengeImage, - String challengeContent, - BigDecimal challengePoint, - LocalDate beginDate, - LocalDate endDate, - ChallengeType challengeType, - ChallengeDisplay displayStatus - ) { - validateCreateParameters(challengeCode, challengeName, challengeImage, challengeContent, - beginDate, endDate, challengeType, displayStatus); - if (challengePoint.compareTo(BigDecimal.ZERO) < 0) { - throw new ChallengeException(ChallengeExceptionMessage.INVALID_MINIMUM_POINT); - } - this.challengeCode = challengeCode; - this.challengeName = challengeName; - this.challengeImage = challengeImage; - this.challengeContent = challengeContent; - this.challengePoint = challengePoint; - this.beginDate = beginDate; - this.endDate = endDate; - this.challengeType = challengeType; - this.challengeStatus = ChallengeStatus.PROCEEDING; - this.displayStatus = displayStatus; - this.participantCount = 0; - } - - private static void validateCreateParameters( - String challengeCode, - String challengeName, - String challengeImage, - String challengeContent, - LocalDate beginDate, - LocalDate endDate, - ChallengeType challengeType, - ChallengeDisplay displayStatus) { - validateEmptyString(challengeCode, "챌린지 코드는 필수값입니다."); - validateEmptyString(challengeName, "챌린지명은 필수값입니다."); - validateEmptyString(challengeImage, "챌린지 이미지는 필수값입니다."); - validateNullData(challengeContent, "챌린지 내용은 필수값입니다."); - validateNullData(challengeType, "챌린지 타입은 필수값입니다."); - validateNullData(displayStatus, "전시 여부 설정은 필수 값입니다."); - } - - protected abstract boolean isAlreadyParticipated(Long memberId); - - protected abstract void doAddParticipation(Long memberId, LocalDateTime now); - - protected abstract void doRemoveParticipation(Long memberId, LocalDateTime now); - - public boolean isActive(LocalDate now) { - return challengeStatus == ChallengeStatus.PROCEEDING - && displayStatus == ChallengeDisplay.VISIBLE; - } - - public void show() { - this.displayStatus = ChallengeDisplay.VISIBLE; - } - - public void hide() { - this.displayStatus = ChallengeDisplay.HIDDEN; - } - - public void updateImage(String newImageUrl) { - validateEmptyString(newImageUrl, "챌린지 이미지 URL은 필수값입니다."); - this.challengeImage = newImageUrl; - } - - public void updateBasicInfo( - String challengeName, - BigDecimal challengePoint, - String challengeContent - ) { - validateEmptyString(challengeName, "챌린지명은 필수값입니다."); - validateNullData(challengePoint, "챌린지 포인트는 필수값입니다."); - this.challengeName = challengeName; - this.challengePoint = challengePoint; - this.challengeContent = challengeContent; - } - - public final void addParticipation(Long memberId, LocalDateTime now) { - validateParticipation(memberId, now); - doAddParticipation(memberId, now); - this.participantCount++; - } - - public final void removeParticipation(Long memberId, LocalDateTime now) { - if (!isActive(now.toLocalDate())) { - throw new ChallengeException(ChallengeExceptionMessage.INACTIVE_CHALLENGE); - } - doRemoveParticipation(memberId, now); - decrementParticipantCount(); - } - - protected final void validateParticipation(Long memberId, LocalDateTime now) { - if (isAlreadyParticipated(memberId)) { - throw new ChallengeException(ChallengeExceptionMessage.ALREADY_PARTICIPATING); - } - if (!isActive(now.toLocalDate())) { - throw new ChallengeException(ChallengeExceptionMessage.INACTIVE_CHALLENGE); - } - } - - protected void decrementParticipantCount() { - if (this.participantCount == 0) { - throw new ChallengeException(ChallengeExceptionMessage.MAX_PARTICIPANTS_LESS_THAN_CURRENT); - } - this.participantCount--; - } -} \ No newline at end of file diff --git a/src/main/java/com/example/green/domain/challenge/entity/challenge/BaseChallengeParticipation.java b/src/main/java/com/example/green/domain/challenge/entity/challenge/BaseChallengeParticipation.java deleted file mode 100644 index 55aa2c4e..00000000 --- a/src/main/java/com/example/green/domain/challenge/entity/challenge/BaseChallengeParticipation.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.example.green.domain.challenge.entity.challenge; - -import java.time.LocalDateTime; - -import com.example.green.domain.common.BaseEntity; - -import jakarta.persistence.Column; -import jakarta.persistence.MappedSuperclass; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@MappedSuperclass -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public abstract class BaseChallengeParticipation extends BaseEntity { - - @Column(nullable = false) - private Long memberId; - - @Column(nullable = false) - private Integer certCount; - - @Column(nullable = false) - private LocalDateTime participatedAt; - - protected BaseChallengeParticipation( - Long memberId, - LocalDateTime participatedAt - ) { - this.certCount = 0; - this.memberId = memberId; - this.participatedAt = participatedAt; - } - - public boolean isParticipated(Long memberId) { - return this.memberId.equals(memberId); - } -} diff --git a/src/main/java/com/example/green/domain/challenge/entity/challenge/PersonalChallenge.java b/src/main/java/com/example/green/domain/challenge/entity/challenge/PersonalChallenge.java deleted file mode 100644 index 8614aff0..00000000 --- a/src/main/java/com/example/green/domain/challenge/entity/challenge/PersonalChallenge.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.example.green.domain.challenge.entity.challenge; - -import java.math.BigDecimal; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -import com.example.green.domain.challenge.entity.challenge.vo.ChallengeDisplay; -import com.example.green.domain.challenge.entity.challenge.vo.ChallengeType; -import com.example.green.domain.challenge.exception.ChallengeException; -import com.example.green.domain.challenge.exception.ChallengeExceptionMessage; - -import jakarta.persistence.CascadeType; -import jakarta.persistence.Entity; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -/** - * 개인 챌린지 엔티티 - */ -@Entity -@Table(name = "personal_challenges") -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class PersonalChallenge extends BaseChallenge { - - @OneToMany(mappedBy = "personalChallenge", cascade = CascadeType.ALL, orphanRemoval = true) - private List participations = new ArrayList<>(); - - private PersonalChallenge( - String challengeCode, String challengeName, String challengeImage, String challengeContent, - BigDecimal challengePoint, LocalDate beginDate, LocalDate endDate, ChallengeDisplay displayStatus - ) { - super(challengeCode, challengeName, challengeImage, challengeContent, challengePoint, beginDate, - endDate, ChallengeType.PERSONAL, displayStatus); - } - - public static PersonalChallenge create( - String challengeCode, String challengeName, String challengeImage, String challengeContent, - BigDecimal challengePoint, LocalDate beginDate, LocalDate endDate, ChallengeDisplay displayStatus - ) { - return new PersonalChallenge( - challengeCode, challengeName, challengeImage, challengeContent, - challengePoint, beginDate, endDate, displayStatus - ); - } - - protected boolean isAlreadyParticipated(Long memberId) { - return participations.stream() - .anyMatch(p -> p.getMemberId().equals(memberId)); - } - - protected void doAddParticipation(Long memberId, LocalDateTime now) { - PersonalChallengeParticipation participation = - PersonalChallengeParticipation.create(this, memberId, now); - participations.add(participation); - } - - protected void doRemoveParticipation(Long memberId, LocalDateTime now) { - PersonalChallengeParticipation participation = findParticipationByMemberId(memberId); - participations.remove(participation); - } - - private PersonalChallengeParticipation findParticipationByMemberId(Long memberId) { - return participations.stream() - .filter(p -> p.isParticipated(memberId)) - .findFirst() - .orElseThrow(() -> new ChallengeException(ChallengeExceptionMessage.NOT_PARTICIPATING_CHALLENGE)); - } -} \ No newline at end of file diff --git a/src/main/java/com/example/green/domain/challenge/entity/challenge/PersonalChallengeParticipation.java b/src/main/java/com/example/green/domain/challenge/entity/challenge/PersonalChallengeParticipation.java deleted file mode 100644 index dcd63b90..00000000 --- a/src/main/java/com/example/green/domain/challenge/entity/challenge/PersonalChallengeParticipation.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.example.green.domain.challenge.entity.challenge; - -import static com.example.green.global.utils.EntityValidator.*; - -import java.time.LocalDateTime; - -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Table(name = "personal_challenge_participations") -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@AllArgsConstructor(access = AccessLevel.PRIVATE) -@Builder(access = AccessLevel.PRIVATE) -public class PersonalChallengeParticipation extends BaseChallengeParticipation { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "personal_challenge_id", nullable = false) - private PersonalChallenge personalChallenge; - - public static PersonalChallengeParticipation create(PersonalChallenge challenge, Long memberId, LocalDateTime now) { - validateNullData(challenge, "개인 챌린지는 필수값입니다."); - validateAutoIncrementId(memberId, "회원 정보는 필수값입니다."); - validateNullData(now, "참여 시각은 필수값입니다."); - - return new PersonalChallengeParticipation(challenge, memberId, now); - } - - private PersonalChallengeParticipation(PersonalChallenge personalChallenge, Long memberId, LocalDateTime now) { - super(memberId, now); - this.personalChallenge = personalChallenge; - } -} diff --git a/src/main/java/com/example/green/domain/challenge/entity/challenge/TeamChallenge.java b/src/main/java/com/example/green/domain/challenge/entity/challenge/TeamChallenge.java deleted file mode 100644 index ba7cdfa7..00000000 --- a/src/main/java/com/example/green/domain/challenge/entity/challenge/TeamChallenge.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.example.green.domain.challenge.entity.challenge; - -import java.math.BigDecimal; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -import com.example.green.domain.challenge.entity.challenge.vo.ChallengeDisplay; -import com.example.green.domain.challenge.entity.challenge.vo.ChallengeType; -import com.example.green.domain.challenge.exception.ChallengeException; -import com.example.green.domain.challenge.exception.ChallengeExceptionMessage; - -import jakarta.persistence.CascadeType; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Table(name = "team_challenges") -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class TeamChallenge extends BaseChallenge { - - @Column(nullable = false) - private Integer teamCount; - - @OneToMany(mappedBy = "teamChallenge", cascade = CascadeType.ALL, orphanRemoval = true) - private List participations = new ArrayList<>(); - - private TeamChallenge( - String challengeCode, String challengeName, String challengeImage, String challengeContent, - BigDecimal challengePoint, LocalDate beginDate, LocalDate endDate, ChallengeDisplay displayStatus - ) { - super(challengeCode, challengeName, challengeImage, challengeContent, challengePoint, beginDate, - endDate, ChallengeType.TEAM, displayStatus); - this.teamCount = 0; - } - - public static TeamChallenge create( - String challengeCode, String challengeName, String challengeImage, String challengeContent, - BigDecimal challengePoint, LocalDate beginDate, LocalDate endDate, ChallengeDisplay displayStatus - ) { - return new TeamChallenge( - challengeCode, challengeName, challengeImage, challengeContent, - challengePoint, beginDate, endDate, displayStatus - ); - } - - protected boolean isAlreadyParticipated(Long memberId) { - return participations.stream() - .anyMatch(p -> p.getMemberId().equals(memberId)); - } - - protected void doAddParticipation(Long memberId, LocalDateTime now) { - TeamChallengeParticipation participation = TeamChallengeParticipation.create(this, memberId, now); - participations.add(participation); - } - - protected void doRemoveParticipation(Long memberId, LocalDateTime now) { - TeamChallengeParticipation participation = findParticipationByMemberId(memberId); - participations.remove(participation); - } - - private TeamChallengeParticipation findParticipationByMemberId(Long memberId) { - return participations.stream() - .filter(p -> p.isParticipated(memberId)) - .findFirst() - .orElseThrow(() -> new ChallengeException(ChallengeExceptionMessage.NOT_PARTICIPATING_CHALLENGE)); - } -} \ No newline at end of file diff --git a/src/main/java/com/example/green/domain/challenge/entity/challenge/TeamChallengeParticipation.java b/src/main/java/com/example/green/domain/challenge/entity/challenge/TeamChallengeParticipation.java deleted file mode 100644 index 9f9927f9..00000000 --- a/src/main/java/com/example/green/domain/challenge/entity/challenge/TeamChallengeParticipation.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.example.green.domain.challenge.entity.challenge; - -import static com.example.green.global.utils.EntityValidator.*; - -import java.time.LocalDateTime; - -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Table(name = "team_challenge_participations") -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@AllArgsConstructor(access = AccessLevel.PRIVATE) -@Builder(access = AccessLevel.PRIVATE) -public class TeamChallengeParticipation extends BaseChallengeParticipation { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "team_challenge_id", nullable = false) - private TeamChallenge teamChallenge; - - public static TeamChallengeParticipation create(TeamChallenge challenge, Long memberId, LocalDateTime now) { - validateNullData(challenge, "팀 챌린지는 필수입니다."); - validateAutoIncrementId(memberId, "회원 정보는 필수값입니다."); - validateNullData(now, "참여 시각은 필수입니다."); - - return new TeamChallengeParticipation(challenge, memberId, now); - } - - private TeamChallengeParticipation(TeamChallenge challenge, Long memberId, LocalDateTime participatedAt) { - super(memberId, participatedAt); - this.teamChallenge = challenge; - } -} diff --git a/src/main/java/com/example/green/domain/challenge/entity/challenge/vo/ChallengeStatus.java b/src/main/java/com/example/green/domain/challenge/entity/challenge/vo/ChallengeStatus.java deleted file mode 100644 index 7abba967..00000000 --- a/src/main/java/com/example/green/domain/challenge/entity/challenge/vo/ChallengeStatus.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.green.domain.challenge.entity.challenge.vo; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -/** - * 챌린지 상태 열거형 - */ -@RequiredArgsConstructor -@Getter -public enum ChallengeStatus { - PROCEEDING("진행중"), - DEADLINE("마감"), - COMPLETED("종료"); - - private final String description; -} diff --git a/src/main/java/com/example/green/domain/challenge/infra/querydsl/PersonalChallengeQueryImpl.java b/src/main/java/com/example/green/domain/challenge/infra/querydsl/PersonalChallengeQueryImpl.java deleted file mode 100644 index edd415e8..00000000 --- a/src/main/java/com/example/green/domain/challenge/infra/querydsl/PersonalChallengeQueryImpl.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.example.green.domain.challenge.infra.querydsl; - -import static com.example.green.domain.challenge.exception.ChallengeExceptionMessage.*; -import static com.example.green.domain.challenge.infra.querydsl.predicates.PersonalChallengePredicates.*; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.List; - -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminChallengeDetailDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminPersonalChallengesDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminPersonalParticipationDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDtoV2; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDto; -import com.example.green.domain.challenge.entity.challenge.PersonalChallenge; -import com.example.green.domain.challenge.exception.ChallengeException; -import com.example.green.domain.challenge.exception.ChallengeExceptionMessage; -import com.example.green.domain.challenge.infra.querydsl.executor.PersonalChallengeQueryExecutor; -import com.example.green.domain.challenge.infra.querydsl.predicates.PersonalChallengePredicates; -import com.example.green.domain.challenge.repository.PersonalChallengeRepository; -import com.example.green.domain.challenge.repository.query.PersonalChallengeQuery; -import com.example.green.global.api.page.CursorTemplate; -import com.example.green.global.api.page.PageTemplate; -import com.example.green.global.api.page.Pagination; -import com.querydsl.core.types.dsl.BooleanExpression; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -@Repository -@RequiredArgsConstructor -@Transactional(readOnly = true) -@Slf4j -public class PersonalChallengeQueryImpl implements PersonalChallengeQuery { - - private final PersonalChallengeRepository personalChallengeRepository; - private final PersonalChallengeQueryExecutor executor; - - public CursorTemplate findMyParticipationByCursor( - Long memberId, Long cursor, int size, LocalDateTime now - ) { - BooleanExpression condition = myParticipationCondition(memberId, cursor, now); - List participationChallenges = executor.executeParticipationQueryForClient(condition, size); - return CursorTemplate.from(participationChallenges, size, ChallengeDto::getCursor); - } - - public CursorTemplate findPersonalChallengesByCursor( - Long cursor, - int size, - LocalDateTime now - ) { - BooleanExpression condition = PersonalChallengePredicates.activeChallengeCondition(cursor, now); - List challenges = executor.executeChallengesQueryForClient(condition, size); - return CursorTemplate.from(challenges, size, ChallengeDto::getId); - } - - public PersonalChallenge getPersonalChallengeById(Long challengeId) { - return personalChallengeRepository.findById(challengeId) - .orElseThrow(() -> new ChallengeException(CHALLENGE_NOT_FOUND)); - } - - public ChallengeDetailDto findPersonalChallenge(Long challengeId, Long memberId) { - BooleanExpression participationExists = memberParticipationExists(challengeId, memberId); - return executor.executeChallengeDetailQuery(participationExists, challengeId); - } - - public AdminChallengeDetailDto getChallengeDetail(Long challengeId) { - PersonalChallenge personalChallenge = getPersonalChallengeById(challengeId); - return AdminChallengeDetailDto.from(personalChallenge); - } - - @Override - public PageTemplate findChallengePage(Integer page, Integer size) { - long count = personalChallengeRepository.count(); - Pagination pagination = Pagination.of(count, page, size); - List result = executor.executeChallengesQueryForAdmin(pagination); - return PageTemplate.of(result, pagination); - } - - @Override - public List findChallengePageForExcel() { - return executor.executeChallengeExcelQueryForAdmin(); - } - - @Override - public PageTemplate findParticipantByChallenge( - Long challengeId, Integer page, Integer size - ) { - long count = personalChallengeRepository.countParticipantByChallenge(challengeId); - Pagination pagination = Pagination.of(count, page, size); - List result = executor.executeParticipantQueryForAdmin(pagination, challengeId); - return PageTemplate.of(result, pagination); - } - - @Override - public List findParticipantByChallengeForExcel(Long challengeId) { - return executor.executeParticipantQueryForExcel(challengeId); - } - - @Override - public PersonalChallenge getPersonalChallengeByMemberAndDate( - Long challengeId, Long memberId, LocalDate challengeDate - ) { - if (!personalChallengeRepository.existsMembership(challengeId, memberId)) { - throw new ChallengeException(ChallengeExceptionMessage.NOT_PARTICIPATING_CHALLENGE); - } - PersonalChallenge challenge = getPersonalChallengeById(challengeId); - if (!challenge.isActive(challengeDate)) { - throw new ChallengeException(INACTIVE_CHALLENGE); - } - return challenge; - } - - @Override - public ChallengeDetailDtoV2 findPersonalChallengeV2(Long challengeId, Long memberId) { - BooleanExpression participationExists = memberParticipationExists(challengeId, memberId); - return executor.executeChallengeDetailQueryV2(participationExists, challengeId) - .orElseThrow(() -> new ChallengeException(CHALLENGE_NOT_FOUND)); - } -} diff --git a/src/main/java/com/example/green/domain/challenge/infra/querydsl/TeamChallengeQueryImpl.java b/src/main/java/com/example/green/domain/challenge/infra/querydsl/TeamChallengeQueryImpl.java deleted file mode 100644 index bea931a3..00000000 --- a/src/main/java/com/example/green/domain/challenge/infra/querydsl/TeamChallengeQueryImpl.java +++ /dev/null @@ -1,167 +0,0 @@ -package com.example.green.domain.challenge.infra.querydsl; - -import static com.example.green.domain.challenge.entity.challenge.QTeamChallenge.*; -import static com.example.green.domain.challenge.entity.challenge.QTeamChallengeParticipation.*; -import static com.example.green.domain.challenge.exception.ChallengeExceptionMessage.*; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Optional; - -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminChallengeDetailDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminTeamChallengesDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDtoV2; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDto; -import com.example.green.domain.challenge.entity.challenge.TeamChallenge; -import com.example.green.domain.challenge.entity.challenge.vo.ChallengeDisplay; -import com.example.green.domain.challenge.exception.ChallengeException; -import com.example.green.domain.challenge.infra.querydsl.projections.TeamChallengeProjections; -import com.example.green.domain.challenge.repository.TeamChallengeRepository; -import com.example.green.domain.challenge.repository.query.TeamChallengeQuery; -import com.example.green.global.api.page.CursorTemplate; -import com.example.green.global.api.page.PageTemplate; -import com.example.green.global.api.page.Pagination; -import com.example.green.infra.database.querydsl.BooleanExpressionConnector; -import com.querydsl.core.types.dsl.BooleanExpression; -import com.querydsl.jpa.JPAExpressions; -import com.querydsl.jpa.impl.JPAQueryFactory; - -import lombok.RequiredArgsConstructor; - -@Repository -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class TeamChallengeQueryImpl implements TeamChallengeQuery { - - private final JPAQueryFactory queryFactory; - private final TeamChallengeRepository teamChallengeRepository; - - public CursorTemplate findMyParticipationByCursor( - Long memberId, - Long cursor, - int size, - LocalDateTime now - ) { - List participation = queryFactory - .select(TeamChallengeProjections.toMyChallenges()) - .from(teamChallenge) - .join(teamChallenge.participations, teamChallengeParticipation) - .where(BooleanExpressionConnector.combineWithAnd( - activeChallengeCondition(cursor, now), - teamChallengeParticipation.memberId.eq(memberId) - )) - .orderBy(teamChallengeParticipation.id.desc()) - .limit(size + 1) - .fetch(); - - return CursorTemplate.from(participation, size, ChallengeDto::getCursor); - } - - public CursorTemplate findTeamChallengesByCursor( - Long cursor, - int size, - LocalDateTime now - ) { - List participation = queryFactory - .select(TeamChallengeProjections.toChallenges()) - .from(teamChallenge) - .where(activeChallengeCondition(cursor, now)) - .orderBy(teamChallenge.id.desc()) - .limit(size + 1) - .fetch(); - return CursorTemplate.from(participation, size, ChallengeDto::getId); - } - - public ChallengeDetailDto findTeamChallenge(Long challengeId, Long memberId) { - BooleanExpression exists = fromCondition(challengeId, memberId); - - return Optional.ofNullable(queryFactory - .select(TeamChallengeProjections.toChallengeByMember(exists)) - .from(teamChallenge) - .where(teamChallenge.id.eq(challengeId), teamChallenge.displayStatus.eq(ChallengeDisplay.VISIBLE)) - .fetchOne()) - .orElseThrow(() -> new ChallengeException(CHALLENGE_NOT_FOUND)); - } - - public TeamChallenge getTeamChallengeById(Long challengeId) { - return teamChallengeRepository.findById(challengeId) - .orElseThrow(() -> new ChallengeException(CHALLENGE_NOT_FOUND)); - } - - public PageTemplate findChallengePage(Integer page, Integer size) { - long count = teamChallengeRepository.count(); - Pagination pagination = Pagination.of(count, page, size); - - List result = queryFactory - .select(TeamChallengeProjections.toChallengesForAdmin()) - .from(teamChallenge) - .orderBy(teamChallenge.id.desc()) - .offset(pagination.calculateOffset()) - .limit(pagination.getPageSize()) - .fetch(); - - return PageTemplate.of(result, pagination); - } - - @Override - public AdminChallengeDetailDto getChallengeDetail(Long challengeId) { - TeamChallenge teamChallenge = getTeamChallengeById(challengeId); - return AdminChallengeDetailDto.from(teamChallenge); - } - - public List findTeamChallengeForExcel() { - return queryFactory - .select(TeamChallengeProjections.toChallengesForAdmin()) - .from(teamChallenge) - .orderBy(teamChallenge.id.desc()) - .fetch(); - } - - public void validateGroupPeriod(Long challengeId, LocalDate challengeDate) { - if (!teamChallengeRepository.isGroupPeriodValidForChallenge(challengeId, challengeDate)) { - throw new ChallengeException(MISMATCH_GROUP_PERIOD_RANGE); - } - } - - @Override - public ChallengeDetailDtoV2 findTeamChallengeV2(Long challengeId, Long memberId) { - BooleanExpression exists = fromCondition(challengeId, memberId); - return Optional.ofNullable(queryFactory - .select(TeamChallengeProjections.toChallengeByMemberV2(exists)) - .from(teamChallenge) - .where(teamChallenge.id.eq(challengeId), teamChallenge.displayStatus.eq(ChallengeDisplay.VISIBLE)) - .fetchOne()) - .orElseThrow(() -> new ChallengeException(CHALLENGE_NOT_FOUND)); - } - - private static BooleanExpression fromCondition(Long challengeId, Long memberId) { - BooleanExpression exists = JPAExpressions.selectOne() - .from(teamChallengeParticipation) - .where( - teamChallengeParticipation.teamChallenge.id.eq(challengeId), - teamChallengeParticipation.memberId.eq(memberId) - ).exists(); - return exists; - } - - private BooleanExpression activeChallengeCondition(Long cursor, LocalDateTime now) { - return BooleanExpressionConnector.combineWithAnd( - teamChallenge.displayStatus.eq(ChallengeDisplay.VISIBLE), - teamChallenge.beginDate.loe(now.toLocalDate()), - teamChallenge.endDate.goe(now.toLocalDate()), - cursorCondition(cursor) - ); - } - - private BooleanExpression cursorCondition(Long cursor) { - if (cursor == null) { - return null; - } - return teamChallenge.id.lt(cursor); - } -} diff --git a/src/main/java/com/example/green/domain/challenge/infra/querydsl/executor/ChallengeGroupQueryExecutor.java b/src/main/java/com/example/green/domain/challenge/infra/querydsl/executor/ChallengeGroupQueryExecutor.java index cbe81230..86c34ff9 100644 --- a/src/main/java/com/example/green/domain/challenge/infra/querydsl/executor/ChallengeGroupQueryExecutor.java +++ b/src/main/java/com/example/green/domain/challenge/infra/querydsl/executor/ChallengeGroupQueryExecutor.java @@ -1,6 +1,6 @@ package com.example.green.domain.challenge.infra.querydsl.executor; -import static com.example.green.domain.challenge.entity.challenge.QTeamChallengeParticipation.*; +import static com.example.green.domain.challenge.entity.challenge.QParticipation.*; import static com.example.green.domain.challenge.entity.group.QChallengeGroup.*; import static com.example.green.domain.challenge.entity.group.QChallengeGroupParticipation.*; import static com.example.green.domain.challenge.infra.querydsl.projections.ChallengeGroupProjections.*; @@ -103,9 +103,9 @@ public List executeGroupParticipantForExcelQuery(Long c private JPAQuery createBaseParticipantQuery(Long challengeId) { return queryFactory.from(challengeGroup) .join(challengeGroup.participants, challengeGroupParticipation) - .join(teamChallengeParticipation) - .on(teamChallengeParticipation.teamChallenge.id.eq(challengeId) - .and(teamChallengeParticipation.memberId.eq(challengeGroupParticipation.memberId))) + .join(participation) + .on(participation.challenge.id.eq(challengeId) + .and(participation.memberId.eq(challengeGroupParticipation.memberId))) .where(challengeGroup.teamChallengeId.eq(challengeId)); } diff --git a/src/main/java/com/example/green/domain/challenge/infra/querydsl/executor/PersonalChallengeQueryExecutor.java b/src/main/java/com/example/green/domain/challenge/infra/querydsl/executor/PersonalChallengeQueryExecutor.java deleted file mode 100644 index 5c7f211d..00000000 --- a/src/main/java/com/example/green/domain/challenge/infra/querydsl/executor/PersonalChallengeQueryExecutor.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.example.green.domain.challenge.infra.querydsl.executor; - -import static com.example.green.domain.challenge.entity.challenge.QPersonalChallenge.*; -import static com.example.green.domain.challenge.entity.challenge.QPersonalChallengeParticipation.*; - -import java.util.List; -import java.util.Optional; - -import org.springframework.stereotype.Component; - -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminPersonalChallengesDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminPersonalParticipationDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDtoV2; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDto; -import com.example.green.domain.challenge.entity.challenge.vo.ChallengeDisplay; -import com.example.green.domain.challenge.infra.querydsl.projections.PersonalChallengeProjections; -import com.example.green.global.api.page.Pagination; -import com.querydsl.core.types.dsl.BooleanExpression; -import com.querydsl.jpa.impl.JPAQueryFactory; - -import lombok.RequiredArgsConstructor; - -@Component -@RequiredArgsConstructor -public class PersonalChallengeQueryExecutor { - - private final JPAQueryFactory queryFactory; - - public List executeParticipationQueryForClient(BooleanExpression condition, int size) { - return queryFactory.select(PersonalChallengeProjections.toMyChallenges()) - .from(personalChallenge) - .join(personalChallenge.participations, personalChallengeParticipation) - .where(condition) - .orderBy(personalChallengeParticipation.id.desc()) - .limit(size + 1) - .fetch(); - } - - public List executeChallengesQueryForClient(BooleanExpression condition, int size) { - return queryFactory.select(PersonalChallengeProjections.toChallenges()) - .from(personalChallenge) - .where(condition) - .orderBy(personalChallenge.id.desc()) - .limit(size + 1) - .fetch(); - } - - public ChallengeDetailDto executeChallengeDetailQuery(BooleanExpression participationExists, Long challengeId) { - return queryFactory.select(PersonalChallengeProjections.toChallengeByMember(participationExists)) - .from(personalChallenge) - .where(personalChallenge.id.eq(challengeId)) - .fetchOne(); - } - - public Optional executeChallengeDetailQueryV2(BooleanExpression participationExists, - Long challengeId) { - return Optional.ofNullable( - queryFactory.select(PersonalChallengeProjections.toChallengeByMemberV2(participationExists)) - .from(personalChallenge) - .where(personalChallenge.id.eq(challengeId), - personalChallenge.displayStatus.eq(ChallengeDisplay.VISIBLE)) - .fetchOne()); - } - - public List executeChallengesQueryForAdmin(Pagination pagination) { - return queryFactory - .select(PersonalChallengeProjections.toChallengesForAdmin()) - .from(personalChallenge) - .orderBy(personalChallenge.id.desc()) - .offset(pagination.calculateOffset()) - .limit(pagination.getPageSize()) - .fetch(); - } - - public List executeChallengeExcelQueryForAdmin() { - return queryFactory - .select(PersonalChallengeProjections.toChallengesForAdmin()) - .from(personalChallenge) - .orderBy(personalChallenge.id.desc()) - .fetch(); - } - - public List executeParticipantQueryForAdmin( - Pagination pagination, Long challengeId - ) { - return queryFactory - .select(PersonalChallengeProjections.toParticipationForAdmin()) - .from(personalChallengeParticipation) - .where(personalChallengeParticipation.personalChallenge.id.eq(challengeId)) - .orderBy(personalChallengeParticipation.participatedAt.desc()) - .offset(pagination.calculateOffset()) - .limit(pagination.getPageSize()) - .fetch(); - } - - public List executeParticipantQueryForExcel(Long challengeId) { - return queryFactory - .select(PersonalChallengeProjections.toParticipationForAdmin()) - .from(personalChallengeParticipation) - .where(personalChallengeParticipation.personalChallenge.id.eq(challengeId)) - .orderBy(personalChallengeParticipation.participatedAt.desc()) - .fetch(); - } -} diff --git a/src/main/java/com/example/green/domain/challenge/infra/querydsl/predicates/PersonalChallengePredicates.java b/src/main/java/com/example/green/domain/challenge/infra/querydsl/predicates/PersonalChallengePredicates.java deleted file mode 100644 index 693bd1c6..00000000 --- a/src/main/java/com/example/green/domain/challenge/infra/querydsl/predicates/PersonalChallengePredicates.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.example.green.domain.challenge.infra.querydsl.predicates; - -import static com.example.green.domain.challenge.entity.challenge.QPersonalChallenge.*; -import static com.example.green.domain.challenge.entity.challenge.QPersonalChallengeParticipation.*; - -import java.time.LocalDateTime; - -import com.example.green.domain.challenge.entity.challenge.vo.ChallengeDisplay; -import com.example.green.infra.database.querydsl.BooleanExpressionConnector; -import com.querydsl.core.types.dsl.BooleanExpression; -import com.querydsl.jpa.JPAExpressions; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class PersonalChallengePredicates { - - public static BooleanExpression myParticipationCondition(Long memberId, Long cursor, LocalDateTime now) { - return BooleanExpressionConnector.combineWithAnd( - activeChallengeCondition(cursor, now), - personalChallengeParticipation.memberId.eq(memberId) - ); - } - - public static BooleanExpression activeChallengeCondition(Long cursor, LocalDateTime now) { - return BooleanExpressionConnector.combineWithAnd( - personalChallenge.beginDate.loe(now.toLocalDate()), - personalChallenge.endDate.goe(now.toLocalDate()), - personalChallenge.displayStatus.eq(ChallengeDisplay.VISIBLE), - getCursorCondition(cursor) - ); - } - - public static BooleanExpression memberParticipationExists(Long challengeId, Long memberId) { - return JPAExpressions.selectOne() - .from(personalChallengeParticipation) - .where( - personalChallengeParticipation.personalChallenge.id.eq(challengeId), - personalChallengeParticipation.memberId.eq(memberId) - ).exists(); - } - - private static BooleanExpression getCursorCondition(Long cursor) { - if (cursor == null || cursor <= 0) { - return null; - } - return personalChallenge.id.lt(cursor); - } -} \ No newline at end of file diff --git a/src/main/java/com/example/green/domain/challenge/infra/querydsl/projections/ChallengeGroupProjections.java b/src/main/java/com/example/green/domain/challenge/infra/querydsl/projections/ChallengeGroupProjections.java index aae3eef8..bce5c6ae 100644 --- a/src/main/java/com/example/green/domain/challenge/infra/querydsl/projections/ChallengeGroupProjections.java +++ b/src/main/java/com/example/green/domain/challenge/infra/querydsl/projections/ChallengeGroupProjections.java @@ -1,6 +1,6 @@ package com.example.green.domain.challenge.infra.querydsl.projections; -import static com.example.green.domain.challenge.entity.challenge.QTeamChallengeParticipation.*; +import static com.example.green.domain.challenge.entity.challenge.QParticipation.*; import static com.example.green.domain.challenge.entity.group.QChallengeGroup.*; import static com.example.green.domain.challenge.entity.group.QChallengeGroupParticipation.*; @@ -57,7 +57,7 @@ public static ConstructorExpression toParticipantByChal AdminTeamParticipantDto.class, challengeGroup.teamCode, challengeGroupParticipation.memberId, - teamChallengeParticipation.participatedAt, + participation.createdDate, challengeGroupParticipation.createdDate ); } diff --git a/src/main/java/com/example/green/domain/challenge/infra/querydsl/projections/PersonalChallengeProjections.java b/src/main/java/com/example/green/domain/challenge/infra/querydsl/projections/PersonalChallengeProjections.java deleted file mode 100644 index 785d7b33..00000000 --- a/src/main/java/com/example/green/domain/challenge/infra/querydsl/projections/PersonalChallengeProjections.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.example.green.domain.challenge.infra.querydsl.projections; - -import static com.example.green.domain.challenge.entity.challenge.QPersonalChallenge.*; -import static com.example.green.domain.challenge.entity.challenge.QPersonalChallengeParticipation.*; - -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminPersonalChallengesDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminPersonalParticipationDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDtoV2; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDto; -import com.querydsl.core.types.ConstructorExpression; -import com.querydsl.core.types.Projections; -import com.querydsl.core.types.dsl.BooleanExpression; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class PersonalChallengeProjections { - - public static ConstructorExpression toMyChallenges() { - return Projections.constructor( - ChallengeDto.class, - personalChallenge.id, - personalChallenge.challengeName, - personalChallenge.beginDate, - personalChallenge.endDate, - personalChallenge.challengeImage, - personalChallenge.challengePoint, - personalChallenge.participantCount, - personalChallengeParticipation.id - ); - } - - public static ConstructorExpression toChallenges() { - return Projections.constructor( - ChallengeDto.class, - personalChallenge.id, - personalChallenge.challengeName, - personalChallenge.beginDate, - personalChallenge.endDate, - personalChallenge.challengeImage, - personalChallenge.challengePoint, - personalChallenge.participantCount - ); - } - - public static ConstructorExpression toChallengeByMember(BooleanExpression exists) { - return Projections.constructor( - ChallengeDetailDto.class, - personalChallenge.id, - personalChallenge.challengeName, - personalChallenge.beginDate, - personalChallenge.endDate, - personalChallenge.challengeImage, - personalChallenge.challengePoint, - exists - ); - } - - public static ConstructorExpression toChallengeByMemberV2(BooleanExpression exists) { - return Projections.constructor( - ChallengeDetailDtoV2.class, - personalChallenge.id, - personalChallenge.challengeName, - personalChallenge.beginDate, - personalChallenge.endDate, - personalChallenge.challengeImage, - personalChallenge.challengeContent, - personalChallenge.challengePoint, - exists - ); - } - - public static ConstructorExpression toChallengesForAdmin() { - return Projections.constructor( - AdminPersonalChallengesDto.class, - personalChallenge.id, - personalChallenge.challengeCode, - personalChallenge.challengeName, - personalChallenge.beginDate, - personalChallenge.endDate, - personalChallenge.challengePoint, - personalChallenge.displayStatus, - personalChallenge.createdDate - ); - } - - public static ConstructorExpression toParticipationForAdmin() { - return Projections.constructor( - AdminPersonalParticipationDto.class, - personalChallengeParticipation.memberId, - personalChallengeParticipation.participatedAt, - personalChallengeParticipation.certCount - ); - } -} diff --git a/src/main/java/com/example/green/domain/challenge/infra/querydsl/projections/TeamChallengeProjections.java b/src/main/java/com/example/green/domain/challenge/infra/querydsl/projections/TeamChallengeProjections.java deleted file mode 100644 index f5d3db93..00000000 --- a/src/main/java/com/example/green/domain/challenge/infra/querydsl/projections/TeamChallengeProjections.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.example.green.domain.challenge.infra.querydsl.projections; - -import static com.example.green.domain.challenge.entity.challenge.QTeamChallenge.*; -import static com.example.green.domain.challenge.entity.challenge.QTeamChallengeParticipation.*; - -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminTeamChallengesDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDtoV2; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDto; -import com.querydsl.core.types.ConstructorExpression; -import com.querydsl.core.types.Expression; -import com.querydsl.core.types.Projections; -import com.querydsl.core.types.dsl.BooleanExpression; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class TeamChallengeProjections { - - public static ConstructorExpression toMyChallenges() { - return Projections.constructor( - ChallengeDto.class, - teamChallenge.id, - teamChallenge.challengeName, - teamChallenge.beginDate, - teamChallenge.endDate, - teamChallenge.challengeImage, - teamChallenge.challengePoint, - teamChallenge.participantCount, - teamChallengeParticipation.id - ); - } - - public static Expression toChallenges() { - return Projections.constructor( - ChallengeDto.class, - teamChallenge.id, - teamChallenge.challengeName, - teamChallenge.beginDate, - teamChallenge.endDate, - teamChallenge.challengeImage, - teamChallenge.challengePoint, - teamChallenge.participantCount - ); - } - - public static ConstructorExpression toChallengeByMember(BooleanExpression exists) { - return Projections.constructor( - ChallengeDetailDto.class, - teamChallenge.id, - teamChallenge.challengeName, - teamChallenge.beginDate, - teamChallenge.endDate, - teamChallenge.challengeImage, - teamChallenge.challengePoint, - exists - ); - } - - public static ConstructorExpression toChallengeByMemberV2(BooleanExpression exists) { - return Projections.constructor( - ChallengeDetailDtoV2.class, - teamChallenge.id, - teamChallenge.challengeName, - teamChallenge.beginDate, - teamChallenge.endDate, - teamChallenge.challengeImage, - teamChallenge.challengeContent, - teamChallenge.challengePoint, - exists - ); - } - - public static ConstructorExpression toChallengesForAdmin() { - return Projections.constructor( - AdminTeamChallengesDto.class, - teamChallenge.id, - teamChallenge.challengeCode, - teamChallenge.challengeName, - teamChallenge.beginDate, - teamChallenge.endDate, - teamChallenge.challengePoint, - teamChallenge.teamCount, - teamChallenge.displayStatus, - teamChallenge.createdDate - ); - } -} diff --git a/src/main/java/com/example/green/domain/challenge/repository/PersonalChallengeRepository.java b/src/main/java/com/example/green/domain/challenge/repository/PersonalChallengeRepository.java deleted file mode 100644 index a4d1968c..00000000 --- a/src/main/java/com/example/green/domain/challenge/repository/PersonalChallengeRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.example.green.domain.challenge.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - -import com.example.green.domain.challenge.entity.challenge.PersonalChallenge; - -public interface PersonalChallengeRepository extends JpaRepository { - - @Query("SELECT COUNT(p) FROM PersonalChallengeParticipation p WHERE p.personalChallenge.id = :personalChallengeId") - long countParticipantByChallenge(Long personalChallengeId); - - @Query(""" - SELECT count(p) > 0 FROM PersonalChallengeParticipation p - WHERE p.personalChallenge.id=:challengeId - AND p.memberId=:memberId - """) - boolean existsMembership(Long challengeId, Long memberId); -} diff --git a/src/main/java/com/example/green/domain/challenge/repository/TeamChallengeRepository.java b/src/main/java/com/example/green/domain/challenge/repository/TeamChallengeRepository.java deleted file mode 100644 index ae292ab9..00000000 --- a/src/main/java/com/example/green/domain/challenge/repository/TeamChallengeRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.green.domain.challenge.repository; - -import java.time.LocalDate; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.stereotype.Repository; - -import com.example.green.domain.challenge.entity.challenge.TeamChallenge; - -@Repository -public interface TeamChallengeRepository extends JpaRepository { - - @Query(""" - SELECT COUNT(tc) > 0 - FROM TeamChallenge tc - WHERE tc.id = :challengeId - AND tc.displayStatus = 'VISIBLE' - AND tc.beginDate <= :challengeDate - AND tc.endDate >= :challengeDate - """) - boolean isGroupPeriodValidForChallenge(Long challengeId, LocalDate challengeDate); -} diff --git a/src/main/java/com/example/green/domain/challenge/repository/query/PersonalChallengeQuery.java b/src/main/java/com/example/green/domain/challenge/repository/query/PersonalChallengeQuery.java deleted file mode 100644 index 95992268..00000000 --- a/src/main/java/com/example/green/domain/challenge/repository/query/PersonalChallengeQuery.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.example.green.domain.challenge.repository.query; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.List; - -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminChallengeDetailDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminPersonalChallengesDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminPersonalParticipationDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDtoV2; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDto; -import com.example.green.domain.challenge.entity.challenge.PersonalChallenge; -import com.example.green.global.api.page.CursorTemplate; -import com.example.green.global.api.page.PageTemplate; - -public interface PersonalChallengeQuery { - - CursorTemplate findMyParticipationByCursor( - Long memberId, Long cursor, int size, LocalDateTime now); - - CursorTemplate findPersonalChallengesByCursor( - Long cursor, int size, LocalDateTime now); - - PersonalChallenge getPersonalChallengeById(Long challengeId); - - ChallengeDetailDto findPersonalChallenge(Long challengeId, Long memberId); - - AdminChallengeDetailDto getChallengeDetail(Long challengeId); - - PageTemplate findChallengePage(Integer page, Integer size); - - List findChallengePageForExcel(); - - PageTemplate findParticipantByChallenge( - Long challengeId, Integer page, Integer size); - - List findParticipantByChallengeForExcel(Long challengeId); - - PersonalChallenge getPersonalChallengeByMemberAndDate(Long challengeId, Long memberId, LocalDate challengeDate); - - ChallengeDetailDtoV2 findPersonalChallengeV2(Long challengeId, Long memberId); -} diff --git a/src/main/java/com/example/green/domain/challenge/repository/query/TeamChallengeQuery.java b/src/main/java/com/example/green/domain/challenge/repository/query/TeamChallengeQuery.java deleted file mode 100644 index 4ca61a1a..00000000 --- a/src/main/java/com/example/green/domain/challenge/repository/query/TeamChallengeQuery.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.example.green.domain.challenge.repository.query; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.List; - -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminChallengeDetailDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.AdminTeamChallengesDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDto; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDetailDtoV2; -import com.example.green.domain.challenge.controller.query.dto.challenge.ChallengeDto; -import com.example.green.domain.challenge.entity.challenge.TeamChallenge; -import com.example.green.global.api.page.CursorTemplate; -import com.example.green.global.api.page.PageTemplate; - -public interface TeamChallengeQuery { - - CursorTemplate findMyParticipationByCursor( - Long memberId, Long cursor, int size, LocalDateTime now); - - CursorTemplate findTeamChallengesByCursor(Long cursor, int size, LocalDateTime now); - - ChallengeDetailDto findTeamChallenge(Long challengeId, Long memberId); - - TeamChallenge getTeamChallengeById(Long challengeId); - - PageTemplate findChallengePage(Integer page, Integer size); - - AdminChallengeDetailDto getChallengeDetail(Long challengeId); - - List findTeamChallengeForExcel(); - - void validateGroupPeriod(Long challengeId, LocalDate challengeDate); - - ChallengeDetailDtoV2 findTeamChallengeV2(Long challengeId, Long memberId); -} diff --git a/src/main/java/com/example/green/domain/challenge/service/PersonalChallengeService.java b/src/main/java/com/example/green/domain/challenge/service/PersonalChallengeService.java deleted file mode 100644 index 51eece3f..00000000 --- a/src/main/java/com/example/green/domain/challenge/service/PersonalChallengeService.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.example.green.domain.challenge.service; - -import org.springframework.dao.OptimisticLockingFailureException; -import org.springframework.retry.annotation.Backoff; -import org.springframework.retry.annotation.Retryable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.example.green.domain.challenge.controller.command.dto.AdminChallengeCreateDto; -import com.example.green.domain.challenge.controller.command.dto.AdminChallengeUpdateDto; -import com.example.green.domain.challenge.entity.challenge.PersonalChallenge; -import com.example.green.domain.challenge.repository.PersonalChallengeRepository; -import com.example.green.domain.challenge.repository.query.PersonalChallengeQuery; -import com.example.green.domain.common.sequence.SequenceService; -import com.example.green.domain.common.sequence.SequenceType; -import com.example.green.global.utils.TimeUtils; -import com.example.green.infra.client.FileClient; - -import lombok.RequiredArgsConstructor; - -@Service -@Transactional -@RequiredArgsConstructor -public class PersonalChallengeService { - - private final PersonalChallengeRepository personalChallengeRepository; - private final PersonalChallengeQuery personalChallengeQuery; - private final FileClient fileClient; - private final SequenceService sequenceService; - private final TimeUtils timeUtils; - - public Long create(AdminChallengeCreateDto request) { - String challengeCode = sequenceService.generateCode(SequenceType.PERSONAL_CHALLENGE, timeUtils.now()); - PersonalChallenge challenge = request.toPersonalChallenge(challengeCode); - PersonalChallenge savedChallenge = personalChallengeRepository.save(challenge); - fileClient.confirmUsingImage(savedChallenge.getChallengeImage()); - - return savedChallenge.getId(); - } - - @Retryable( - retryFor = OptimisticLockingFailureException.class, - backoff = @Backoff(delay = 100, multiplier = 2) - ) - public void join(Long challengeId, Long memberId) { - PersonalChallenge personalChallenge = personalChallengeQuery.getPersonalChallengeById(challengeId); - personalChallenge.addParticipation(memberId, timeUtils.now()); - } - - @Retryable( - retryFor = OptimisticLockingFailureException.class, - backoff = @Backoff(delay = 100, multiplier = 2) - ) - public void leave(Long challengeId, Long memberId) { - PersonalChallenge personalChallenge = personalChallengeQuery.getPersonalChallengeById(challengeId); - personalChallenge.removeParticipation(memberId, timeUtils.now()); - } - - public void show(Long challengeId) { - PersonalChallenge personalChallenge = personalChallengeQuery.getPersonalChallengeById(challengeId); - personalChallenge.show(); - } - - public void hide(Long challengeId) { - PersonalChallenge personalChallenge = personalChallengeQuery.getPersonalChallengeById(challengeId); - personalChallenge.hide(); - } - - public void update(Long challengeId, AdminChallengeUpdateDto dto) { - PersonalChallenge personalChallenge = personalChallengeQuery.getPersonalChallengeById(challengeId); - personalChallenge.updateBasicInfo( - dto.challengeName(), dto.challengePoint(), dto.challengeContent() - ); - - String beforeImageUrl = personalChallenge.getChallengeImage(); - personalChallenge.updateImage(dto.challengeImageUrl()); - fileClient.swapImage(beforeImageUrl, personalChallenge.getChallengeImage()); - } -} diff --git a/src/main/java/com/example/green/domain/challenge/service/TeamChallengeService.java b/src/main/java/com/example/green/domain/challenge/service/TeamChallengeService.java deleted file mode 100644 index 91de5295..00000000 --- a/src/main/java/com/example/green/domain/challenge/service/TeamChallengeService.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.example.green.domain.challenge.service; - -import org.springframework.dao.OptimisticLockingFailureException; -import org.springframework.retry.annotation.Backoff; -import org.springframework.retry.annotation.Retryable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.example.green.domain.challenge.controller.command.dto.AdminChallengeCreateDto; -import com.example.green.domain.challenge.controller.command.dto.AdminChallengeUpdateDto; -import com.example.green.domain.challenge.entity.challenge.TeamChallenge; -import com.example.green.domain.challenge.repository.TeamChallengeRepository; -import com.example.green.domain.challenge.repository.query.TeamChallengeQuery; -import com.example.green.domain.common.sequence.SequenceService; -import com.example.green.domain.common.sequence.SequenceType; -import com.example.green.global.utils.TimeUtils; -import com.example.green.infra.client.FileClient; - -import lombok.RequiredArgsConstructor; - -@Service -@Transactional -@RequiredArgsConstructor -public class TeamChallengeService { - - private final TeamChallengeRepository teamChallengeRepository; - private final TeamChallengeQuery teamChallengeQuery; - private final FileClient fileClient; - private final SequenceService sequenceService; - private final TimeUtils timeUtils; - - public Long create(AdminChallengeCreateDto dto) { - String challengeCode = sequenceService.generateCode(SequenceType.TEAM_CHALLENGE, timeUtils.now()); - TeamChallenge challenge = dto.toTeamChallenge(challengeCode); - TeamChallenge savedChallenge = teamChallengeRepository.save(challenge); - fileClient.confirmUsingImage(savedChallenge.getChallengeImage()); - - return savedChallenge.getId(); - } - - @Retryable( - retryFor = OptimisticLockingFailureException.class, - backoff = @Backoff(delay = 100, multiplier = 2) - ) - public void join(Long challengeId, Long memberId) { - TeamChallenge teamChallenge = teamChallengeQuery.getTeamChallengeById(challengeId); - teamChallenge.addParticipation(memberId, timeUtils.now()); - } - - @Retryable( - retryFor = OptimisticLockingFailureException.class, - backoff = @Backoff(delay = 100, multiplier = 2) - ) - public void leave(Long challengeId, Long memberId) { - TeamChallenge teamChallenge = teamChallengeQuery.getTeamChallengeById(challengeId); - teamChallenge.removeParticipation(memberId, timeUtils.now()); - // todo: 그룹 탈퇴 처리 필요, 하지만 지금 나가기 기능도 없어서 구현 X - } - - public void show(Long challengeId) { - TeamChallenge teamChallenge = teamChallengeQuery.getTeamChallengeById(challengeId); - teamChallenge.show(); - } - - public void hide(Long challengeId) { - TeamChallenge teamChallenge = teamChallengeQuery.getTeamChallengeById(challengeId); - teamChallenge.hide(); - } - - public void update(Long challengeId, AdminChallengeUpdateDto dto) { - TeamChallenge teamChallenge = teamChallengeQuery.getTeamChallengeById(challengeId); - teamChallenge.updateBasicInfo( - dto.challengeName(), dto.challengePoint(), dto.challengeContent() - ); - - String beforeImageUrl = teamChallenge.getChallengeImage(); - teamChallenge.updateImage(dto.challengeImageUrl()); - fileClient.swapImage(beforeImageUrl, teamChallenge.getChallengeImage()); - } -} diff --git a/src/main/java/com/example/green/domain/dashboard/rankingmodule/repository/WeeklyRankingRepositoryImpl.java b/src/main/java/com/example/green/domain/dashboard/rankingmodule/repository/WeeklyRankingRepositoryImpl.java index 468def1b..c7e88907 100644 --- a/src/main/java/com/example/green/domain/dashboard/rankingmodule/repository/WeeklyRankingRepositoryImpl.java +++ b/src/main/java/com/example/green/domain/dashboard/rankingmodule/repository/WeeklyRankingRepositoryImpl.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Optional; -import com.example.green.domain.challenge.entity.challenge.QBaseChallengeParticipation; +import com.example.green.domain.challenge.entity.challenge.QParticipation; import com.example.green.domain.dashboard.rankingmodule.entity.QWeeklyRanking; import com.example.green.domain.dashboard.rankingmodule.entity.WeeklyRanking; import com.example.green.domain.member.entity.QMember; @@ -26,7 +26,7 @@ public List findTopMembersOfWeek(LocalDate weekStart, int topN) { QMember member = QMember.member; QPointTransaction point = QPointTransaction.pointTransaction; - QBaseChallengeParticipation challenge = QBaseChallengeParticipation.baseChallengeParticipation; + QParticipation challenge = QParticipation.participation; LocalDateTime startDateTime = weekStart.atStartOfDay(); LocalDateTime endDateTime = weekStart.plusDays(6).atTime(23, 59, 59); @@ -47,7 +47,7 @@ public List findTopMembersOfWeek(LocalDate weekStart, int topN) { ) .leftJoin(challenge).on( challenge.memberId.eq(member.id) - .and(challenge.participatedAt.between(startDateTime, endDateTime)) + .and(challenge.createdDate.between(startDateTime, endDateTime)) ) .groupBy(member.id, member.name, member.profile.profileImageUrl) .orderBy( diff --git a/src/main/java/com/example/green/infra/client/dto/ChallengeDto.java b/src/main/java/com/example/green/infra/client/dto/ChallengeDto.java index 941f782d..74ac49e0 100644 --- a/src/main/java/com/example/green/infra/client/dto/ChallengeDto.java +++ b/src/main/java/com/example/green/infra/client/dto/ChallengeDto.java @@ -1,6 +1,5 @@ package com.example.green.infra.client.dto; -import com.example.green.domain.challenge.entity.challenge.BaseChallenge; import com.example.green.domain.challenge.entity.challenge.Challenge; public record ChallengeDto( @@ -12,15 +11,6 @@ public record ChallengeDto( String challengeType ) { - public static ChallengeDto from(BaseChallenge challenge) { - return new ChallengeDto( - challenge.getId(), challenge.getChallengeName(), challenge.getChallengeCode(), - challenge.getChallengeImage(), - challenge.getChallengePoint().intValue(), - challenge.getChallengeType().getCode() - ); - } - public static ChallengeDto from(Challenge challenge) { return new ChallengeDto( challenge.getId(), diff --git a/src/test/java/com/example/integration/challenge/ChallengeTestDataSource.java b/src/test/java/com/example/integration/challenge/ChallengeTestDataSource.java index c23ac724..a30c5883 100644 --- a/src/test/java/com/example/integration/challenge/ChallengeTestDataSource.java +++ b/src/test/java/com/example/integration/challenge/ChallengeTestDataSource.java @@ -24,10 +24,15 @@ public class ChallengeTestDataSource { @Autowired private EntityManager entityManager; - public void 챌린지_50개_생성() { - challengeRepository.deleteAllInBatch(); + public void init() { + entityManager.createNativeQuery("TRUNCATE TABLE challenge_participations CASCADE").executeUpdate(); + entityManager.createNativeQuery("TRUNCATE TABLE challenges CASCADE").executeUpdate(); entityManager.createNativeQuery("ALTER SEQUENCE challenges_id_seq RESTART WITH 1").executeUpdate(); + entityManager.createNativeQuery("ALTER SEQUENCE challenge_participations_id_seq RESTART WITH 1") + .executeUpdate(); + } + public void 챌린지_50개_생성() { List challenges = new ArrayList<>(); for (int i = 1; i <= 50; i++) { ChallengeInfo info = ChallengeInfo.of("challenge" + i, i); @@ -39,8 +44,6 @@ public class ChallengeTestDataSource { } public void 챌린지_참여_역순() { - entityManager.createNativeQuery("ALTER SEQUENCE challenge_participations_id_seq RESTART WITH 1") - .executeUpdate(); for (long id = 50; id >= 1; id--) { Challenge challenge = challengeRepository.findByIdWithThrow(id); challenge.participate(1L); diff --git a/src/test/java/com/example/integration/challenge/query/ChallengeAdminQueryTest.java b/src/test/java/com/example/integration/challenge/query/ChallengeAdminQueryTest.java index 9f0bd01a..ccc8e9db 100644 --- a/src/test/java/com/example/integration/challenge/query/ChallengeAdminQueryTest.java +++ b/src/test/java/com/example/integration/challenge/query/ChallengeAdminQueryTest.java @@ -30,6 +30,7 @@ public class ChallengeAdminQueryTest extends BaseIntegrationTest { @BeforeEach void setUp() { + dataSource.init(); dataSource.챌린지_50개_생성(); } diff --git a/src/test/java/com/example/integration/challenge/query/ChallengeQueryTest.java b/src/test/java/com/example/integration/challenge/query/ChallengeQueryTest.java index 1b34896e..9a1067ed 100644 --- a/src/test/java/com/example/integration/challenge/query/ChallengeQueryTest.java +++ b/src/test/java/com/example/integration/challenge/query/ChallengeQueryTest.java @@ -30,6 +30,7 @@ public class ChallengeQueryTest extends BaseIntegrationTest { @BeforeEach void setUp() { + dataSource.init(); dataSource.챌린지_50개_생성(); }