-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add(.remind): 피드백 가능한 계획 목록 조회 API 구현 #199
base: dev
Are you sure you want to change the base?
Changes from all commits
d42c308
4d433fa
d4afcd9
5ae2fd0
731b11e
f5faa88
68d303f
6b96c34
cc911ac
8fa75a5
11c91c5
19d5db6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package me.ajaja.module.feedback.application; | ||
|
||
import java.util.List; | ||
|
||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import me.ajaja.global.common.BaseTime; | ||
import me.ajaja.module.feedback.domain.Feedback; | ||
import me.ajaja.module.feedback.domain.FeedbackQueryRepository; | ||
import me.ajaja.module.feedback.dto.FeedbackResponse; | ||
import me.ajaja.module.feedback.mapper.FeedbackMapper; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
@Transactional(readOnly = true) | ||
public class LoadEvaluableFeedbacksService { | ||
private final FeedbackQueryRepository feedbackQueryRepository; | ||
private final LoadEvaluableTargetsService loadEvaluableTargetsService; | ||
private final FeedbackMapper mapper; | ||
|
||
public List<FeedbackResponse.EvaluableFeedback> loadEvaluableFeedbacksByUserId(Long userId) { | ||
List<Feedback> feedbacks = feedbackQueryRepository.findAllFeedbacksByUserId(userId); | ||
|
||
return loadEvaluableTargetsService.findEvaluableTargetsByUserId(userId).stream() | ||
.filter(feedback -> isNotEvaluate(feedbacks, feedback.planId(), feedback.period())) | ||
.map(mapper::toResponse) | ||
.toList(); | ||
} | ||
|
||
private boolean isNotEvaluate(List<Feedback> feedbacks, Long planId, BaseTime period) { | ||
return feedbacks.stream().noneMatch(feedback -> | ||
feedback.getPlanId().equals(planId) && period.isWithinAMonth(feedback.getCreatedAt())); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package me.ajaja.module.feedback.application; | ||
|
||
import java.util.List; | ||
|
||
import me.ajaja.module.feedback.application.model.UpdatableFeedback; | ||
|
||
public interface LoadEvaluableTargetsService { // todo: 헥사고날 아키텍쳐 적용 후 네이밍 변경 | ||
List<UpdatableFeedback> findEvaluableTargetsByUserId(Long userId); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package me.ajaja.module.feedback.application.model; | ||
|
||
import me.ajaja.global.common.BaseTime; | ||
|
||
public record UpdatableFeedback( | ||
String title, | ||
Long planId, | ||
BaseTime period | ||
) { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,7 +26,7 @@ class FeedbackQueryRepositoryImpl implements FeedbackQueryRepository { | |
private final FeedbackMapper mapper; | ||
|
||
@Override | ||
public List<Feedback> findAllFeedbackByPlanId(Long planId) { | ||
public List<Feedback> findAllFeedbacksByPlanId(Long planId) { | ||
List<FeedbackEntity> entities = queryFactory.selectFrom(feedbackEntity) | ||
.where(feedbackEntity.planId.eq(planId)) | ||
.orderBy(feedbackEntity.createdAt.asc()) | ||
|
@@ -35,6 +35,17 @@ public List<Feedback> findAllFeedbackByPlanId(Long planId) { | |
return mapper.toDomain(entities); | ||
} | ||
|
||
@Override | ||
public List<Feedback> findAllFeedbacksByUserId(Long userId) { | ||
List<FeedbackEntity> entities = queryFactory.selectFrom(feedbackEntity) | ||
.where(feedbackEntity.userId.eq(userId) | ||
.and(feedbackEntity.createdAt.year().eq(BaseTime.now().getYear()))) | ||
.orderBy(feedbackEntity.planId.asc()) | ||
.fetch(); | ||
|
||
return mapper.toDomain(entities); | ||
Comment on lines
+40
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 다른 곳에서는 stream()으로 잘 넘기시는데 여기서는 달라서 코드에 통일성이 없어 보여요! |
||
} | ||
|
||
@Override | ||
public boolean existByPlanIdAndPeriod(Long planId, BaseTime period) { | ||
return queryFactory.selectFrom(feedbackEntity) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package me.ajaja.module.plan.adapter.out.persistence; | ||
|
||
import static me.ajaja.module.plan.adapter.out.persistence.model.QPlanEntity.*; | ||
|
||
import java.util.List; | ||
|
||
import org.springframework.stereotype.Repository; | ||
|
||
import com.querydsl.jpa.impl.JPAQueryFactory; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import me.ajaja.global.common.BaseTime; | ||
import me.ajaja.module.plan.application.port.out.FindEvaluablePlansPort; | ||
import me.ajaja.module.plan.domain.Plan; | ||
import me.ajaja.module.plan.mapper.PlanMapper; | ||
|
||
@Repository | ||
@RequiredArgsConstructor | ||
public class FindEvaluablePlansAdapter implements FindEvaluablePlansPort { | ||
private final JPAQueryFactory queryFactory; | ||
private final PlanMapper mapper; | ||
|
||
@Override | ||
public List<Plan> findEvaluablePlansByUserIdAndTime(Long id, BaseTime now) { | ||
return queryFactory.selectFrom(planEntity) | ||
.where(planEntity.userId.eq(id) | ||
.and(planEntity.createdAt.year().eq(now.getYear()))) | ||
.fetch() | ||
.stream() | ||
.map(mapper::toDomain) | ||
.toList(); | ||
} | ||
Comment on lines
+24
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 네이밍과 쿼리 사이 연관성이 없는 것 같아요..! |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package me.ajaja.module.plan.application; | ||
|
||
import java.util.List; | ||
|
||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import me.ajaja.global.common.BaseTime; | ||
import me.ajaja.module.feedback.application.LoadEvaluableTargetsService; | ||
import me.ajaja.module.feedback.application.model.UpdatableFeedback; | ||
import me.ajaja.module.plan.application.port.out.FindEvaluablePlansPort; | ||
import me.ajaja.module.plan.mapper.PlanMapper; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
@Transactional(readOnly = true) | ||
public class LoadEvaluablePlansService implements LoadEvaluableTargetsService { | ||
private FindEvaluablePlansPort findEvaluablePlansPort; | ||
private PlanMapper mapper; | ||
|
||
@Override | ||
public List<UpdatableFeedback> findEvaluableTargetsByUserId(Long userId) { | ||
BaseTime now = BaseTime.now(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. method 네이밍이 괜찮아서 바로 사용해도 괜찮을 것 같아요! |
||
return findEvaluablePlansPort.findEvaluablePlansByUserIdAndTime(userId, now).stream() | ||
.filter(plan -> plan.isWithinPeriod(now)) | ||
.map(mapper::toFeedbackModel) | ||
.toList(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package me.ajaja.module.plan.application.port.out; | ||
|
||
import java.util.List; | ||
|
||
import me.ajaja.global.common.BaseTime; | ||
import me.ajaja.module.plan.domain.Plan; | ||
|
||
public interface FindEvaluablePlansPort { | ||
List<Plan> findEvaluablePlansByUserIdAndTime(Long id, BaseTime now); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,20 +142,17 @@ public void disable() { | |
this.status = status.disable(); | ||
} | ||
|
||
public BaseTime getFeedbackPeriod(BaseTime current) { | ||
public BaseTime findFeedbackPeriod(BaseTime now) { | ||
return this.messages.stream() | ||
.filter(message -> current.isWithinAMonth( | ||
BaseTime.parse( | ||
this.createdAt.getYear(), | ||
message.getRemindDate().getRemindMonth(), | ||
message.getRemindDate().getRemindDay(), | ||
this.getRemindTime())) | ||
) | ||
.filter(message -> isWithinPeriod(now)) | ||
.findAny() | ||
.map(message -> BaseTime.parse(this.createdAt.getYear(), | ||
message.getRemindDate().getRemindMonth(), | ||
message.getRemindDate().getRemindDay(), | ||
this.getRemindTime())) | ||
.map(message -> message.parsePeriod(this.createdAt.getYear(), this.getRemindTime())) | ||
.orElseThrow(() -> new AjajaException(EXPIRED_FEEDBACK)); | ||
} | ||
|
||
public boolean isWithinPeriod(BaseTime now) { | ||
return this.messages.stream().anyMatch(message -> now.isWithinAMonth( | ||
message.parsePeriod(this.createdAt.getYear(), this.getRemindTime()) | ||
Comment on lines
+154
to
+155
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 가독성이 떨어져서 라인을 좀 바꿀까요?? 아니면 저처럼 map 쓰셔도 괜찮구! |
||
)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,11 +6,22 @@ | |
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.RequiredArgsConstructor; | ||
import me.ajaja.global.common.SelfValidating; | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class RemindInfo extends SelfValidating<RemindInfo> { | ||
@Getter | ||
@RequiredArgsConstructor | ||
private enum RemindTime { | ||
MORNING(9), | ||
AFTERNOON(13), | ||
EVENING(22); | ||
|
||
private final int time; | ||
} | ||
|
||
Comment on lines
+15
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이렇게 내부에서 쓰도록 변경했다면, 다음과 같이 불필요한 코드라인 수를 줄일 수 있을 것 같아요!
|
||
@Positive | ||
private int remindTotalPeriod; | ||
|
||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
최저수준에서 직접적으로 application 코드를 사용하라는 의도는 아니였습니다!
repository의 재사용성을 고려해서 시간은 외부에서 받도록!!