diff --git a/src/main/java/com/dnd/runus/application/badge/BadgeEventHandler.java b/src/main/java/com/dnd/runus/application/badge/BadgeEventHandler.java new file mode 100644 index 00000000..6b42c919 --- /dev/null +++ b/src/main/java/com/dnd/runus/application/badge/BadgeEventHandler.java @@ -0,0 +1,18 @@ +package com.dnd.runus.application.badge; + +import com.dnd.runus.application.member.event.SignupEvent; +import com.dnd.runus.global.constant.BadgeType; +import lombok.RequiredArgsConstructor; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class BadgeEventHandler { + private final BadgeService badgeService; + + @EventListener + public void handleSignupEvent(SignupEvent signupEvent) { + badgeService.achieveBadge(signupEvent.member(), BadgeType.PERSONAL_RECORD, 0); + } +} diff --git a/src/main/java/com/dnd/runus/application/badge/BadgeService.java b/src/main/java/com/dnd/runus/application/badge/BadgeService.java index 73789eff..5f64fe4c 100644 --- a/src/main/java/com/dnd/runus/application/badge/BadgeService.java +++ b/src/main/java/com/dnd/runus/application/badge/BadgeService.java @@ -1,8 +1,7 @@ package com.dnd.runus.application.badge; -import com.dnd.runus.domain.badge.BadgeAchievementRepository; -import com.dnd.runus.domain.badge.BadgeRepository; -import com.dnd.runus.domain.badge.BadgeWithAchieveStatusAndAchievedAt; +import com.dnd.runus.domain.badge.*; +import com.dnd.runus.domain.member.Member; import com.dnd.runus.global.constant.BadgeType; import com.dnd.runus.presentation.v1.badge.dto.response.AchievedBadgesResponse; import com.dnd.runus.presentation.v1.badge.dto.response.AllBadgesListResponse; @@ -26,6 +25,19 @@ public class BadgeService { private final BadgeAchievementRepository badgeAchievementRepository; private final BadgeRepository badgeRepository; + public void achieveBadge(Member member, BadgeType badgeType, int value) { + List badges = badgeRepository.findByTypeAndRequiredValueLessThanEqual(badgeType, value); + if (badges.isEmpty()) { + return; + } + + List badgeAchievements = badges.stream() + .map(badge -> new BadgeAchievement(badge, member)) + .toList(); + + badgeAchievementRepository.saveAllIgnoreDuplicated(badgeAchievements); + } + public AchievedBadgesResponse getAchievedBadges(long memberId) { return new AchievedBadgesResponse(badgeAchievementRepository.findByMemberIdWithBadge(memberId).stream() .map(badgeAchievement -> new AchievedBadgesResponse.AchievedBadge( diff --git a/src/main/java/com/dnd/runus/domain/badge/BadgeRepository.java b/src/main/java/com/dnd/runus/domain/badge/BadgeRepository.java index 2b36d5d7..975a15e3 100644 --- a/src/main/java/com/dnd/runus/domain/badge/BadgeRepository.java +++ b/src/main/java/com/dnd/runus/domain/badge/BadgeRepository.java @@ -1,7 +1,11 @@ package com.dnd.runus.domain.badge; +import com.dnd.runus.global.constant.BadgeType; + import java.util.List; public interface BadgeRepository { + List findByTypeAndRequiredValueLessThanEqual(BadgeType badgeType, int requiredValue); + List findAllBadgesWithAchieveStatusByMemberId(long memberId); } diff --git a/src/main/java/com/dnd/runus/infrastructure/persistence/domain/badge/BadgeRepositoryImpl.java b/src/main/java/com/dnd/runus/infrastructure/persistence/domain/badge/BadgeRepositoryImpl.java index db3d5235..e8751e95 100644 --- a/src/main/java/com/dnd/runus/infrastructure/persistence/domain/badge/BadgeRepositoryImpl.java +++ b/src/main/java/com/dnd/runus/infrastructure/persistence/domain/badge/BadgeRepositoryImpl.java @@ -1,8 +1,12 @@ package com.dnd.runus.infrastructure.persistence.domain.badge; +import com.dnd.runus.domain.badge.Badge; import com.dnd.runus.domain.badge.BadgeRepository; import com.dnd.runus.domain.badge.BadgeWithAchieveStatusAndAchievedAt; +import com.dnd.runus.global.constant.BadgeType; import com.dnd.runus.infrastructure.persistence.jooq.badge.JooqBadgeRepository; +import com.dnd.runus.infrastructure.persistence.jpa.badge.JpaBadgeRepository; +import com.dnd.runus.infrastructure.persistence.jpa.badge.entity.BadgeEntity; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -11,8 +15,16 @@ @Repository @RequiredArgsConstructor public class BadgeRepositoryImpl implements BadgeRepository { + private final JpaBadgeRepository jpaBadgeRepository; private final JooqBadgeRepository jooqBadgeRepository; + @Override + public List findByTypeAndRequiredValueLessThanEqual(BadgeType badgeType, int requiredValue) { + return jpaBadgeRepository.findByTypeAndRequiredValueLessThanEqual(badgeType, requiredValue).stream() + .map(BadgeEntity::toDomain) + .toList(); + } + @Override public List findAllBadgesWithAchieveStatusByMemberId(long memberId) { return jooqBadgeRepository.findAllBadgesWithAchieveStatusByMemberId(memberId); diff --git a/src/main/java/com/dnd/runus/infrastructure/persistence/jooq/badge/JooqBadgeAchievementRepository.java b/src/main/java/com/dnd/runus/infrastructure/persistence/jooq/badge/JooqBadgeAchievementRepository.java index 66f47878..b43685a2 100644 --- a/src/main/java/com/dnd/runus/infrastructure/persistence/jooq/badge/JooqBadgeAchievementRepository.java +++ b/src/main/java/com/dnd/runus/infrastructure/persistence/jooq/badge/JooqBadgeAchievementRepository.java @@ -30,6 +30,7 @@ public List findByMemberIdWithBadge(long memberId) { } public void saveAllIgnoreDuplicated(List badgeAchievements) { + OffsetDateTime now = OffsetDateTime.now(); dsl.batch(badgeAchievements.stream() .map(badgeAchievement -> dsl.insertInto(BADGE_ACHIEVEMENT) .set( @@ -38,8 +39,12 @@ public void saveAllIgnoreDuplicated(List badgeAchievements) { .set( BADGE_ACHIEVEMENT.MEMBER_ID, badgeAchievement.member().memberId()) - .set(BADGE_ACHIEVEMENT.CREATED_AT, badgeAchievement.createdAt()) - .set(BADGE_ACHIEVEMENT.UPDATED_AT, badgeAchievement.updatedAt()) + .set( + BADGE_ACHIEVEMENT.CREATED_AT, + badgeAchievement.createdAt() == null ? now : badgeAchievement.createdAt()) + .set( + BADGE_ACHIEVEMENT.UPDATED_AT, + badgeAchievement.updatedAt() == null ? now : badgeAchievement.updatedAt()) .onConflictDoNothing()) .toList()) .execute(); diff --git a/src/main/java/com/dnd/runus/infrastructure/persistence/jpa/badge/JpaBadgeRepository.java b/src/main/java/com/dnd/runus/infrastructure/persistence/jpa/badge/JpaBadgeRepository.java new file mode 100644 index 00000000..8eab0485 --- /dev/null +++ b/src/main/java/com/dnd/runus/infrastructure/persistence/jpa/badge/JpaBadgeRepository.java @@ -0,0 +1,11 @@ +package com.dnd.runus.infrastructure.persistence.jpa.badge; + +import com.dnd.runus.global.constant.BadgeType; +import com.dnd.runus.infrastructure.persistence.jpa.badge.entity.BadgeEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface JpaBadgeRepository extends JpaRepository { + List findByTypeAndRequiredValueLessThanEqual(BadgeType badgeType, int requiredValue); +}