-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* refactor(BaseEntity): deleted를 BaseEntity에서 제외 * feat(Achievement): 업적 CRUD API 추가 * feat(Achievement): 유저 업적 등록, 조회 API 추가 * feat(Achievement): 도메인 이벤트 추가
- Loading branch information
Showing
36 changed files
with
820 additions
and
10 deletions.
There are no files selected for viewing
15 changes: 15 additions & 0 deletions
15
src/main/java/com/stempo/api/domain/application/event/AchievementDeletedEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.stempo.api.domain.application.event; | ||
|
||
import lombok.Getter; | ||
import org.springframework.context.ApplicationEvent; | ||
|
||
@Getter | ||
public class AchievementDeletedEvent extends ApplicationEvent { | ||
|
||
private final Long achievementId; | ||
|
||
public AchievementDeletedEvent(Object source, Long achievementId) { | ||
super(source); | ||
this.achievementId = achievementId; | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/com/stempo/api/domain/application/event/AchievementEventDispatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.stempo.api.domain.application.event; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.context.event.EventListener; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.List; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class AchievementEventDispatcher { | ||
|
||
private final List<AchievementEventProcessor> processors; | ||
|
||
@EventListener | ||
public void handleAchievementDeletedEvent(AchievementDeletedEvent event) { | ||
processors.forEach(processor -> processor.processAchievementDeleted(event.getAchievementId())); | ||
} | ||
|
||
@EventListener | ||
public void handleAchievementUpdatedEvent(AchievementUpdatedEvent event) { | ||
processors.forEach(processor -> processor.processAchievementUpdated(event.getAchievementId())); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/com/stempo/api/domain/application/event/AchievementEventProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.stempo.api.domain.application.event; | ||
|
||
public interface AchievementEventProcessor { | ||
|
||
void processAchievementDeleted(Long achievementId); | ||
|
||
void processAchievementUpdated(Long achievementId); | ||
} |
21 changes: 21 additions & 0 deletions
21
src/main/java/com/stempo/api/domain/application/event/AchievementEventProcessorRegistry.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.stempo.api.domain.application.event; | ||
|
||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
@Component | ||
public class AchievementEventProcessorRegistry { | ||
|
||
private final List<AchievementEventProcessor> processors = new ArrayList<>(); | ||
|
||
public void register(AchievementEventProcessor processor) { | ||
processors.add(processor); | ||
} | ||
|
||
public List<AchievementEventProcessor> getProcessors() { | ||
return Collections.unmodifiableList(processors); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/com/stempo/api/domain/application/event/AchievementUpdatedEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.stempo.api.domain.application.event; | ||
|
||
import lombok.Getter; | ||
import org.springframework.context.ApplicationEvent; | ||
|
||
@Getter | ||
public class AchievementUpdatedEvent extends ApplicationEvent { | ||
|
||
private final Long achievementId; | ||
|
||
public AchievementUpdatedEvent(Object source, Long achievementId) { | ||
super(source); | ||
this.achievementId = achievementId; | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/main/java/com/stempo/api/domain/application/event/UserAchievementEventProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.stempo.api.domain.application.event; | ||
|
||
import com.stempo.api.domain.domain.model.UserAchievement; | ||
import com.stempo.api.domain.domain.repository.UserAchievementRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.util.List; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class UserAchievementEventProcessor implements AchievementEventProcessor { | ||
|
||
private final UserAchievementRepository userAchievementRepository; | ||
|
||
@Override | ||
@Transactional | ||
public void processAchievementDeleted(Long achievementId) { | ||
List<UserAchievement> achievements = userAchievementRepository.findByAchievementId(achievementId); | ||
achievements.forEach(UserAchievement::delete); | ||
userAchievementRepository.saveAll(achievements); | ||
} | ||
|
||
@Override | ||
public void processAchievementUpdated(Long achievementId) { | ||
// do nothing | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
src/main/java/com/stempo/api/domain/application/service/AchievementService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.stempo.api.domain.application.service; | ||
|
||
import com.stempo.api.domain.presentation.dto.request.AchievementRequestDto; | ||
import com.stempo.api.domain.presentation.dto.request.AchievementUpdateRequestDto; | ||
import com.stempo.api.domain.presentation.dto.response.AchievementResponseDto; | ||
|
||
import java.util.List; | ||
|
||
public interface AchievementService { | ||
|
||
Long registerAchievement(AchievementRequestDto requestDto); | ||
|
||
List<AchievementResponseDto> getAchievements(); | ||
|
||
Long updateAchievement(Long achievementId, AchievementUpdateRequestDto requestDto); | ||
|
||
Long deleteAchievement(Long achievementId); | ||
} |
54 changes: 54 additions & 0 deletions
54
src/main/java/com/stempo/api/domain/application/service/AchievementServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.stempo.api.domain.application.service; | ||
|
||
import com.stempo.api.domain.application.event.AchievementDeletedEvent; | ||
import com.stempo.api.domain.application.event.AchievementUpdatedEvent; | ||
import com.stempo.api.domain.domain.model.Achievement; | ||
import com.stempo.api.domain.domain.repository.AchievementRepository; | ||
import com.stempo.api.domain.presentation.dto.request.AchievementRequestDto; | ||
import com.stempo.api.domain.presentation.dto.request.AchievementUpdateRequestDto; | ||
import com.stempo.api.domain.presentation.dto.response.AchievementResponseDto; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.context.ApplicationEventPublisher; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.List; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class AchievementServiceImpl implements AchievementService { | ||
|
||
private final AchievementRepository repository; | ||
private final ApplicationEventPublisher eventPublisher; | ||
|
||
@Override | ||
public Long registerAchievement(AchievementRequestDto requestDto) { | ||
Achievement achievement = AchievementRequestDto.toDomain(requestDto); | ||
return repository.save(achievement).getId(); | ||
} | ||
|
||
@Override | ||
public List<AchievementResponseDto> getAchievements() { | ||
List<Achievement> achievements = repository.findAll(); | ||
return achievements.stream() | ||
.map(AchievementResponseDto::toDto) | ||
.toList(); | ||
} | ||
|
||
@Override | ||
public Long updateAchievement(Long achievementId, AchievementUpdateRequestDto requestDto) { | ||
Achievement achievement = repository.findByIdOrThrow(achievementId); | ||
achievement.update(requestDto); | ||
repository.save(achievement); | ||
eventPublisher.publishEvent(new AchievementUpdatedEvent(this, achievement.getId())); | ||
return achievement.getId(); | ||
} | ||
|
||
@Override | ||
public Long deleteAchievement(Long achievementId) { | ||
Achievement achievement = repository.findByIdOrThrow(achievementId); | ||
achievement.delete(); | ||
repository.save(achievement); | ||
eventPublisher.publishEvent(new AchievementDeletedEvent(this, achievement.getId())); | ||
return achievement.getId(); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/com/stempo/api/domain/application/service/UserAchievementService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.stempo.api.domain.application.service; | ||
|
||
import com.stempo.api.domain.presentation.dto.response.UserAchievementResponseDto; | ||
|
||
import java.util.List; | ||
|
||
public interface UserAchievementService { | ||
|
||
Long registerUserAchievement(Long achievementId); | ||
|
||
List<UserAchievementResponseDto> getUserAchievements(); | ||
} |
49 changes: 49 additions & 0 deletions
49
src/main/java/com/stempo/api/domain/application/service/UserAchievementServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.stempo.api.domain.application.service; | ||
|
||
import com.stempo.api.domain.domain.model.Achievement; | ||
import com.stempo.api.domain.domain.model.UserAchievement; | ||
import com.stempo.api.domain.domain.repository.AchievementRepository; | ||
import com.stempo.api.domain.domain.repository.UserAchievementRepository; | ||
import com.stempo.api.domain.persistence.entity.UserAchievementEntity; | ||
import com.stempo.api.domain.presentation.dto.response.UserAchievementResponseDto; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class UserAchievementServiceImpl implements UserAchievementService { | ||
|
||
private final UserService userService; | ||
private final UserAchievementRepository userAchievementRepository; | ||
private final AchievementRepository achievementRepository; | ||
|
||
@Override | ||
public Long registerUserAchievement(Long achievementId) { | ||
String deviceTag = userService.getCurrentDeviceTag(); | ||
Optional<UserAchievementEntity> existingUserAchievement = userAchievementRepository.findByDeviceTagAndAchievementId(deviceTag, achievementId); | ||
|
||
if (existingUserAchievement.isPresent()) { | ||
return existingUserAchievement.get().getId(); | ||
} | ||
|
||
UserAchievement userAchievement = UserAchievement.create(achievementId, deviceTag); | ||
return userAchievementRepository.save(userAchievement).getId(); | ||
} | ||
|
||
@Override | ||
public List<UserAchievementResponseDto> getUserAchievements() { | ||
String deviceTag = userService.getCurrentDeviceTag(); | ||
List<UserAchievementEntity> userAchievements = userAchievementRepository.findByDeviceTag(deviceTag); | ||
return userAchievements.stream() | ||
.map(this::getUserAchievementResponseDto) | ||
.toList(); | ||
} | ||
|
||
private UserAchievementResponseDto getUserAchievementResponseDto(UserAchievementEntity ua) { | ||
Achievement achievement = achievementRepository.findByIdOrThrow(ua.getAchievementId()); | ||
return UserAchievementResponseDto.toDto(achievement); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
src/main/java/com/stempo/api/domain/domain/model/Achievement.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.stempo.api.domain.domain.model; | ||
|
||
import com.stempo.api.domain.presentation.dto.request.AchievementUpdateRequestDto; | ||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
|
||
import java.util.Optional; | ||
|
||
@Getter | ||
@Setter | ||
@Builder | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor(access = AccessLevel.PRIVATE) | ||
public class Achievement { | ||
|
||
private Long id; | ||
private String name; | ||
private String description; | ||
private String imageUrl; | ||
private boolean deleted; | ||
|
||
public void update(AchievementUpdateRequestDto requestDto) { | ||
Optional.ofNullable(requestDto.getName()).ifPresent(this::setName); | ||
Optional.ofNullable(requestDto.getDescription()).ifPresent(this::setDescription); | ||
Optional.ofNullable(requestDto.getImageUrl()).ifPresent(this::setImageUrl); | ||
} | ||
|
||
public void delete() { | ||
setDeleted(true); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
src/main/java/com/stempo/api/domain/domain/model/UserAchievement.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.stempo.api.domain.domain.model; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
@Getter | ||
@Setter | ||
@Builder | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor(access = AccessLevel.PRIVATE) | ||
public class UserAchievement { | ||
|
||
private Long id; | ||
private String deviceTag; | ||
private Long achievementId; | ||
private LocalDateTime createdAt; | ||
private boolean deleted; | ||
|
||
public static UserAchievement create(Long achievementId, String deviceTag) { | ||
return UserAchievement.builder() | ||
.achievementId(achievementId) | ||
.deviceTag(deviceTag) | ||
.build(); | ||
} | ||
|
||
public void delete() { | ||
setDeleted(true); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
src/main/java/com/stempo/api/domain/domain/repository/AchievementRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.stempo.api.domain.domain.repository; | ||
|
||
import com.stempo.api.domain.domain.model.Achievement; | ||
|
||
import java.util.List; | ||
|
||
public interface AchievementRepository { | ||
|
||
Achievement findByIdOrThrow(Long achievementId); | ||
|
||
List<Achievement> findAll(); | ||
|
||
Achievement save(Achievement achievement); | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/com/stempo/api/domain/domain/repository/UserAchievementRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.stempo.api.domain.domain.repository; | ||
|
||
import com.stempo.api.domain.domain.model.UserAchievement; | ||
import com.stempo.api.domain.persistence.entity.UserAchievementEntity; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
public interface UserAchievementRepository { | ||
|
||
UserAchievement save(UserAchievement userAchievement); | ||
|
||
void saveAll(List<UserAchievement> achievements); | ||
|
||
List<UserAchievementEntity> findByDeviceTag(String deviceTag); | ||
|
||
Optional<UserAchievementEntity> findByDeviceTagAndAchievementId(String deviceTag, Long achievementId); | ||
|
||
List<UserAchievement> findByAchievementId(Long achievementId); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.