Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@
import grep.neogulcoder.domain.alram.service.AlarmService;
import grep.neogulcoder.global.auth.Principal;
import grep.neogulcoder.global.response.ApiResponse;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
Expand All @@ -27,7 +24,7 @@ public ApiResponse<List<AlarmResponse>> getAllAlarms(@AuthenticationPrincipal Pr

@GetMapping("/unchecked/my")
public ApiResponse<List<AlarmResponse>> getAllUncheckedAlarm(
@AuthenticationPrincipal Principal userDetails) {
@AuthenticationPrincipal Principal userDetails) {
return ApiResponse.success(alarmService.getAllUncheckedAlarms(userDetails.getUserId()));
}

Expand All @@ -39,8 +36,8 @@ public ApiResponse<Void> checkAlarm(@AuthenticationPrincipal Principal userDetai

@PostMapping("/choose/{alarmId}/response")
public ApiResponse<Void> respondToInvite(@AuthenticationPrincipal Principal principal,
@PathVariable Long alarmId,
boolean accepted) {
@PathVariable Long alarmId,
boolean accepted) {
if (accepted) {
alarmService.acceptInvite(principal.getUserId(), alarmId);
} else {
Expand Down
173 changes: 114 additions & 59 deletions src/main/java/grep/neogulcoder/domain/alram/service/AlarmService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import grep.neogulcoder.domain.alram.repository.AlarmRepository;
import grep.neogulcoder.domain.alram.type.AlarmType;
import grep.neogulcoder.domain.alram.type.DomainType;
import grep.neogulcoder.domain.recruitment.comment.event.RecruitmentPostCommentEvent;
import grep.neogulcoder.domain.recruitment.post.RecruitmentPost;
import grep.neogulcoder.domain.recruitment.post.repository.RecruitmentPostRepository;
import grep.neogulcoder.domain.study.Study;
Expand All @@ -21,19 +22,26 @@
import grep.neogulcoder.domain.studyapplication.event.ApplicationEvent;
import grep.neogulcoder.domain.studyapplication.event.ApplicationStatusChangedEvent;
import grep.neogulcoder.domain.studyapplication.repository.ApplicationRepository;
import grep.neogulcoder.domain.studypost.StudyPost;
import grep.neogulcoder.domain.studypost.StudyPostErrorCode;
import grep.neogulcoder.domain.studypost.comment.event.StudyPostCommentEvent;
import grep.neogulcoder.domain.studypost.repository.StudyPostRepository;
import grep.neogulcoder.domain.timevote.event.TimeVotePeriodCreatedEvent;
import grep.neogulcoder.global.exception.business.BusinessException;
import grep.neogulcoder.global.exception.business.NotFoundException;
import grep.neogulcoder.global.provider.finder.MessageFinder;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static grep.neogulcoder.domain.study.exception.code.StudyErrorCode.*;
import static grep.neogulcoder.domain.studyapplication.exception.code.ApplicationErrorCode.*;
import static grep.neogulcoder.domain.recruitment.RecruitmentErrorCode.*;
import java.util.List;

import static grep.neogulcoder.domain.recruitment.RecruitmentErrorCode.NOT_FOUND;
import static grep.neogulcoder.domain.study.exception.code.StudyErrorCode.STUDY_LEADER_NOT_FOUND;
import static grep.neogulcoder.domain.study.exception.code.StudyErrorCode.STUDY_NOT_FOUND;
import static grep.neogulcoder.domain.studyapplication.exception.code.ApplicationErrorCode.APPLICATION_NOT_FOUND;
import static grep.neogulcoder.domain.studyapplication.exception.code.ApplicationErrorCode.APPLICATION_PARTICIPANT_LIMIT_EXCEEDED;

@Service
@RequiredArgsConstructor
Expand All @@ -43,61 +51,62 @@ public class AlarmService {
private final AlarmRepository alarmRepository;
private final MessageFinder messageFinder;
private final StudyRepository studyRepository;
private final StudyPostRepository studyPostRepository;
private final StudyMemberQueryRepository studyMemberQueryRepository;
private final StudyMemberRepository studyMemberRepository;
private final RecruitmentPostRepository recruitmentPostRepository;
private final ApplicationRepository applicationRepository;

@Transactional
public void saveAlarm(Long receiverId, AlarmType alarmType, DomainType domainType,
Long domainId) {
Long domainId) {
String message = messageFinder.findMessage(alarmType, domainType, domainId);
alarmRepository.save(Alarm.init(alarmType, receiverId, domainType, domainId, message));
}

public List<AlarmResponse> getAllUncheckedAlarms(Long receiverUserId) {
return alarmRepository.findAllByReceiverUserIdAndCheckedFalse(receiverUserId).stream()
.map(alarm -> AlarmResponse.toResponse(
alarm.getId(),
alarm.getReceiverUserId(),
alarm.getAlarmType(),
alarm.getDomainType(),
alarm.getDomainId(),
alarm.getMessage(),
alarm.isChecked(),
alarm.getCreatedDate()))
.toList();
.map(alarm -> AlarmResponse.toResponse(
alarm.getId(),
alarm.getReceiverUserId(),
alarm.getAlarmType(),
alarm.getDomainType(),
alarm.getDomainId(),
alarm.getMessage(),
alarm.isChecked(),
alarm.getCreatedDate()))
.toList();
}

public List<AlarmResponse> getAllAlarms(Long receiverUserId) {
return alarmRepository.findAllByReceiverUserId(receiverUserId).stream()
.map(alarm -> AlarmResponse.toResponse(
alarm.getId(),
alarm.getReceiverUserId(),
alarm.getAlarmType(),
alarm.getDomainType(),
alarm.getDomainId(),
alarm.getMessage(),
alarm.isChecked(),
alarm.getCreatedDate()))
.toList();
.map(alarm -> AlarmResponse.toResponse(
alarm.getId(),
alarm.getReceiverUserId(),
alarm.getAlarmType(),
alarm.getDomainType(),
alarm.getDomainId(),
alarm.getMessage(),
alarm.isChecked(),
alarm.getCreatedDate()))
.toList();
}

@Transactional
public void checkAllAlarmWithoutInvite(Long receiverUserId) {
List<Alarm> alarms = alarmRepository.findAllByReceiverUserIdAndCheckedFalse(receiverUserId);
alarms.stream()
.filter(alarm -> alarm.getAlarmType() != AlarmType.INVITE)
.forEach(Alarm::checkAlarm);
.filter(alarm -> alarm.getAlarmType() != AlarmType.INVITE)
.forEach(Alarm::checkAlarm);
}

@EventListener
public void handleStudyInviteEvent(StudyInviteEvent event) {
saveAlarm(
event.targetUserId(),
AlarmType.INVITE,
DomainType.STUDY,
event.studyId()
event.targetUserId(),
AlarmType.INVITE,
DomainType.STUDY,
event.studyId()
);
}

Expand All @@ -122,15 +131,15 @@ public void rejectInvite(Long alarmId) {
@EventListener
public void handleStudyExtendEvent(StudyExtendEvent event) {
List<StudyMember> members = studyMemberRepository.findAllByStudyIdAndActivatedTrue(
event.studyId());
event.studyId());

for (StudyMember member : members) {
if (!member.isLeader()) {
saveAlarm(
member.getUserId(),
AlarmType.STUDY_EXTEND,
DomainType.STUDY,
event.studyId()
member.getUserId(),
AlarmType.STUDY_EXTEND,
DomainType.STUDY,
event.studyId()
);
}
}
Expand All @@ -139,29 +148,29 @@ public void handleStudyExtendEvent(StudyExtendEvent event) {
@EventListener
public void handleStudyExtensionReminderEvent(StudyExtensionReminderEvent event) {
StudyMember leader = studyMemberRepository.findByStudyIdAndRoleAndActivatedTrue(
event.studyId(), StudyMemberRole.LEADER)
.orElseThrow(() -> new BusinessException(STUDY_LEADER_NOT_FOUND));
event.studyId(), StudyMemberRole.LEADER)
.orElseThrow(() -> new BusinessException(STUDY_LEADER_NOT_FOUND));

saveAlarm(
leader.getUserId(),
AlarmType.STUDY_EXTENSION_REMINDER,
DomainType.STUDY,
event.studyId()
leader.getUserId(),
AlarmType.STUDY_EXTENSION_REMINDER,
DomainType.STUDY,
event.studyId()
);
}

@EventListener
public void handleTimeVotePeriodCreatedEvent(TimeVotePeriodCreatedEvent event) {
List<StudyMember> members = studyMemberRepository.findAllByStudyIdAndActivatedTrue(
event.studyId());
event.studyId());

for (StudyMember member : members) {
if (!member.getUserId().equals(event.excludedUserId())) {
saveAlarm(
member.getUserId(),
AlarmType.TIME_VOTE_REQUEST,
DomainType.TIME_VOTE,
event.studyId()
member.getUserId(),
AlarmType.TIME_VOTE_REQUEST,
DomainType.TIME_VOTE,
event.studyId()
);
}
}
Expand All @@ -170,37 +179,83 @@ public void handleTimeVotePeriodCreatedEvent(TimeVotePeriodCreatedEvent event) {
@EventListener
public void handleApplicationEvent(ApplicationEvent event) {
RecruitmentPost recruitmentPost = recruitmentPostRepository.findByIdAndActivatedTrue(event.recruitmentPostId())
.orElseThrow(() -> new BusinessException(NOT_FOUND));
.orElseThrow(() -> new BusinessException(NOT_FOUND));

saveAlarm(
recruitmentPost.getUserId(),
AlarmType.STUDY_APPLICATION,
DomainType.RECRUITMENT_POST,
event.recruitmentPostId()
recruitmentPost.getUserId(),
AlarmType.STUDY_APPLICATION,
DomainType.RECRUITMENT_POST,
event.recruitmentPostId()
);
}

@EventListener
public void handleApplicationStatusChangedEvent(ApplicationStatusChangedEvent event) {
StudyApplication application = applicationRepository.findByIdAndActivatedTrue(event.applicationId())
.orElseThrow(() -> new BusinessException(APPLICATION_NOT_FOUND));
.orElseThrow(() -> new BusinessException(APPLICATION_NOT_FOUND));

saveAlarm(
application.getUserId(),
event.alarmType(),
DomainType.STUDY_APPLICATION,
application.getId()
application.getUserId(),
event.alarmType(),
DomainType.STUDY_APPLICATION,
application.getId()
);
}

@Transactional
@EventListener
public void handleRecruitmentPostCommentEvent(RecruitmentPostCommentEvent event) {
RecruitmentPost recruitmentPost = recruitmentPostRepository.findById(event.getPostId())
.orElseThrow(() -> new NotFoundException(NOT_FOUND));

String message = messageFinder.findMessage(
AlarmType.RECRUITMENT_POST_COMMENT,
DomainType.RECRUITMENT_POST,
recruitmentPost.getId()
);

alarmRepository.save(
Alarm.init(
AlarmType.RECRUITMENT_POST_COMMENT,
event.getTargetUserId(),
DomainType.RECRUITMENT_POST,
event.getPostId(),
message
)
);
}

@Transactional
@EventListener
public void handleStudyPostCommentEvent(StudyPostCommentEvent event) {
StudyPost studyPost = studyPostRepository.findById(event.getPostId())
.orElseThrow(() -> new NotFoundException(StudyPostErrorCode.NOT_FOUND_POST));

String message = messageFinder.findMessage(
AlarmType.STUDY_POST_COMMENT,
DomainType.STUDY_POST,
studyPost.getId()
);

alarmRepository.save(
Alarm.init(
AlarmType.STUDY_POST_COMMENT,
event.getTargetUserId(),
DomainType.STUDY_POST,
event.getPostId(),
message
)
);
}

private Alarm findValidAlarm(Long alarmId) {
return alarmRepository.findById(alarmId)
.orElseThrow(() -> new NotFoundException(AlarmErrorCode.ALARM_NOT_FOUND));
.orElseThrow(() -> new NotFoundException(AlarmErrorCode.ALARM_NOT_FOUND));
}

private Study findValidStudy(Long studyId) {
return studyRepository.findById(studyId)
.orElseThrow(() -> new NotFoundException(STUDY_NOT_FOUND));
.orElseThrow(() -> new NotFoundException(STUDY_NOT_FOUND));
}

private void validateParticipantStudyLimit(Long userId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ public enum AlarmType {
INVITE,
STUDY_EXTEND,
STUDY_EXTENSION_REMINDER,
STUDY_POST_COMMENT,
TIME_VOTE_REQUEST,
STUDY_APPLICATION,
STUDY_APPLICATION_APPROVED,
STUDY_APPLICATION_REJECTED
STUDY_APPLICATION_REJECTED,
RECRUITMENT_POST_COMMENT
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

public enum DomainType {
STUDY,
STUDY_POST,
TIME_VOTE,
RECRUITMENT_POST,
STUDY_APPLICATION
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ public class RecruitmentCommentSaveRequest {
private RecruitmentCommentSaveRequest() {
}

public RecruitmentCommentSaveRequest(String content) {
this.content = content;
}

public RecruitmentPostComment toEntity(RecruitmentPost post, long userId) {
return RecruitmentPostComment.builder()
.recruitmentPost(post)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package grep.neogulcoder.domain.recruitment.comment.event;

import lombok.Getter;

@Getter
public class RecruitmentPostCommentEvent {

private long targetUserId;
private long postId;

public RecruitmentPostCommentEvent(long targetUserId, long postId) {
this.targetUserId = targetUserId;
this.postId = postId;
}
}
Loading