Skip to content

Commit acbdd41

Browse files
authored
Merge pull request #218 from prgrms-web-devcourse-final-project/feature/EA3-134-study-optimal-time-vote
[EA3-134] feature : 시간 투표 기간 생성 시 팀원에게 알림 전송 기능 추가
2 parents 2e6a327 + 50960dc commit acbdd41

File tree

7 files changed

+111
-17
lines changed

7 files changed

+111
-17
lines changed

src/main/java/grep/neogulcoder/domain/alram/exception/code/AlarmErrorCode.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ public enum AlarmErrorCode implements ErrorCode {
99

1010
ALARM_NOT_FOUND("A001",HttpStatus.NOT_FOUND,"알람을 찾을 수 없습니다.");
1111

12-
1312
private final String code;
1413
private final HttpStatus status;
1514
private final String message;
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package grep.neogulcoder.domain.alram.type;
22

33
public enum AlarmType {
4-
5-
INVITE
6-
4+
INVITE, TIME_VOTE_REQUEST
75
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package grep.neogulcoder.domain.alram.type;
22

33
public enum DomainType {
4-
STUDY
4+
STUDY, TIME_VOTE
55
}

src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVotePeriodResponse.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod;
44
import io.swagger.v3.oas.annotations.media.Schema;
55
import java.time.LocalDateTime;
6+
import java.util.List;
67
import lombok.Builder;
78
import lombok.Getter;
89

@@ -19,18 +20,24 @@ public class TimeVotePeriodResponse {
1920
@Schema(description = "종료일", example = "2025-07-30T23:59:59")
2021
private LocalDateTime endDate;
2122

23+
@Schema(description = "알림이 전송된 팀원 멤버 ID 목록", example = "[11, 12, 13]")
24+
private List<Long> notifiedMemberIds;
25+
2226
@Builder
23-
private TimeVotePeriodResponse(Long studyId, LocalDateTime startDate, LocalDateTime endDate) {
27+
private TimeVotePeriodResponse(Long studyId, LocalDateTime startDate, LocalDateTime endDate, List<Long> notifiedMemberIds) {
2428
this.studyId = studyId;
2529
this.startDate = startDate;
2630
this.endDate = endDate;
31+
this.notifiedMemberIds = notifiedMemberIds;
2732
}
2833

29-
public static TimeVotePeriodResponse from(TimeVotePeriod timeVotePeriod) {
34+
public static TimeVotePeriodResponse from(TimeVotePeriod timeVotePeriod, List<Long> notifiedMemberIds) {
3035
return TimeVotePeriodResponse.builder()
3136
.studyId(timeVotePeriod.getStudyId())
3237
.startDate(timeVotePeriod.getStartDate())
3338
.endDate(timeVotePeriod.getEndDate())
39+
.notifiedMemberIds(notifiedMemberIds)
3440
.build();
3541
}
3642
}
43+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package grep.neogulcoder.domain.timevote.provider;
2+
3+
import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.STUDY_NOT_FOUND;
4+
5+
import grep.neogulcoder.domain.alram.type.AlarmType;
6+
import grep.neogulcoder.domain.alram.type.DomainType;
7+
import grep.neogulcoder.domain.study.Study;
8+
import grep.neogulcoder.domain.study.repository.StudyRepository;
9+
import grep.neogulcoder.global.exception.business.NotFoundException;
10+
import grep.neogulcoder.global.provider.MessageProvidable;
11+
import lombok.RequiredArgsConstructor;
12+
import org.springframework.stereotype.Component;
13+
14+
@Component
15+
@RequiredArgsConstructor
16+
public class TimeVoteMessageProvider implements MessageProvidable {
17+
18+
private final StudyRepository studyRepository;
19+
20+
@Override
21+
public boolean isSupport(AlarmType alarmType) {
22+
return alarmType == AlarmType.TIME_VOTE_REQUEST;
23+
}
24+
25+
@Override
26+
public String provideMessage(DomainType domainType, Long domainId) {
27+
if (domainType != DomainType.TIME_VOTE) {
28+
throw new IllegalArgumentException("시간 투표 요청은 TIME_VOTE 도메인에만 해당됩니다.");
29+
}
30+
31+
Study study = studyRepository.findById(domainId)
32+
.orElseThrow(() -> new NotFoundException(STUDY_NOT_FOUND));
33+
34+
return String.format("[%s] 스터디장이 모임 일정 조율을 위한 투표를 요청했습니다.", study.getName());
35+
}
36+
}

src/main/java/grep/neogulcoder/domain/timevote/service/TimeVotePeriodService.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
package grep.neogulcoder.domain.timevote.service;
22

3-
import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.*;
4-
3+
import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.FORBIDDEN_TIME_VOTE_CREATE;
4+
import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.INVALID_TIME_VOTE_PERIOD;
5+
import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.STUDY_MEMBER_NOT_FOUND;
6+
import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.STUDY_NOT_FOUND;
7+
import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.TIME_VOTE_INVALID_DATE_RANGE;
8+
import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.TIME_VOTE_PERIOD_START_DATE_IN_PAST;
9+
10+
import grep.neogulcoder.domain.alram.service.AlarmService;
11+
import grep.neogulcoder.domain.alram.type.AlarmType;
12+
import grep.neogulcoder.domain.alram.type.DomainType;
513
import grep.neogulcoder.domain.study.Study;
614
import grep.neogulcoder.domain.study.StudyMember;
715
import grep.neogulcoder.domain.study.enums.StudyMemberRole;
@@ -14,9 +22,12 @@
1422
import grep.neogulcoder.domain.timevote.repository.TimeVoteRepository;
1523
import grep.neogulcoder.domain.timevote.repository.TimeVoteStatRepository;
1624
import grep.neogulcoder.global.exception.business.BusinessException;
25+
import grep.neogulcoder.global.provider.finder.MessageFinder;
1726
import java.time.LocalDateTime;
1827
import java.time.LocalTime;
1928
import java.time.temporal.ChronoUnit;
29+
import java.util.ArrayList;
30+
import java.util.List;
2031
import lombok.RequiredArgsConstructor;
2132
import org.springframework.stereotype.Service;
2233
import org.springframework.transaction.annotation.Transactional;
@@ -31,6 +42,8 @@ public class TimeVotePeriodService {
3142
private final TimeVoteStatRepository timeVoteStatRepository;
3243
private final StudyRepository studyRepository;
3344
private final StudyMemberRepository studyMemberRepository;
45+
private final AlarmService alarmService;
46+
private final MessageFinder messageFinder;
3447

3548
public TimeVotePeriodResponse createTimeVotePeriodAndReturn(TimeVotePeriodCreateRequest request, Long studyId, Long userId) {
3649
StudyMember studyMember = getValidStudyMember(studyId, userId);
@@ -48,7 +61,20 @@ public TimeVotePeriodResponse createTimeVotePeriodAndReturn(TimeVotePeriodCreate
4861

4962
TimeVotePeriod savedPeriod = timeVotePeriodRepository.save(request.toEntity(studyId, adjustedEndDate));
5063

51-
return TimeVotePeriodResponse.from(savedPeriod);
64+
getValidStudy(studyId);
65+
messageFinder.findMessage(AlarmType.TIME_VOTE_REQUEST, DomainType.TIME_VOTE, studyId);
66+
67+
List<StudyMember> members = studyMemberRepository.findAllByStudyIdAndActivatedTrue(studyId);
68+
List<Long> notifiedUserIds = new ArrayList<>();
69+
for (StudyMember member : members) {
70+
if (!member.getUserId().equals(userId)) {
71+
alarmService.saveAlarm(member.getUserId(), AlarmType.TIME_VOTE_REQUEST,
72+
DomainType.TIME_VOTE, studyId);
73+
notifiedUserIds.add(member.getId());
74+
}
75+
}
76+
77+
return TimeVotePeriodResponse.from(savedPeriod, notifiedUserIds);
5278
}
5379

5480
public void deleteAllTimeVoteDate(Long studyId) {

0 commit comments

Comments
 (0)