Skip to content

Commit

Permalink
refactor: 알람기능 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
SangWoon123 committed Jul 20, 2024
1 parent 8e5dc38 commit 1966c3a
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.tukorea.planding.domain.notify.entity.NotificationType;
import com.tukorea.planding.domain.schedule.dto.request.PersonalScheduleRequest;
import com.tukorea.planding.domain.schedule.dto.request.websocket.SendCreateScheduleDTO;
import com.tukorea.planding.domain.schedule.dto.response.GroupScheduleAttendanceResponse;
import com.tukorea.planding.domain.schedule.dto.response.GroupScheduleResponse;
import com.tukorea.planding.domain.schedule.dto.response.PersonalScheduleResponse;
import com.tukorea.planding.domain.schedule.dto.response.ScheduleResponse;
import com.tukorea.planding.domain.schedule.entity.Schedule;
import lombok.*;

import java.time.LocalDate;
Expand All @@ -30,13 +33,14 @@ public class NotificationDTO {
private String date;
// 그룹 스케줄에만 해당하는 필드
private String groupName;
private String groupCode;

public static NotificationDTO createPersonalSchedule(Long scheduleId, String receiverCode, PersonalScheduleResponse response) {
public static NotificationDTO createPersonalSchedule(String receiverCode, PersonalScheduleResponse response) {
return NotificationDTO.builder()
.scheduleId(scheduleId)
.scheduleId(response.id())
.userCode(receiverCode)
.message(response.content())
.url("/api/v1/schedule/" + scheduleId)
.url("/api/v1/schedule/" + response.id())
.notificationType(NotificationType.PERSONAL_SCHEDULE)
.date(String.valueOf(response.scheduleDate()))
.time(response.startTime())
Expand All @@ -46,6 +50,7 @@ public static NotificationDTO createPersonalSchedule(Long scheduleId, String rec

public static NotificationDTO createDailySchedule(String receiverCode, String message, Long scheduleId, String date, Integer time) {
return NotificationDTO.builder()
.scheduleId(scheduleId)
.userCode(receiverCode)
.message(message)
.url("/api/v1/schedule/" + scheduleId)
Expand All @@ -56,15 +61,19 @@ public static NotificationDTO createDailySchedule(String receiverCode, String me
}

// 그룹 스케줄 생성 시 필요한 빌더 메서드
public static NotificationDTO createGroupSchedule(String receiverCode, ScheduleResponse response) {
public static NotificationDTO createGroupSchedule(String receiverCode, Schedule response) {
return NotificationDTO.builder()
.scheduleId(response.getId())
.userCode(receiverCode)
.message(response.content())
.url("/api/v1/schedule/" + response.id())
.message(response.getContent())
.url("/api/v1/schedule/" + response.getId())
.notificationType(NotificationType.GROUP_SCHEDULE)
.time(response.startTime())
.groupName(response.groupName())
.date(String.valueOf(response.getScheduleDate()))
.time(response.getStartTime())
.groupName(response.getGroupSchedule().getGroupRoom().getName())
.groupCode(response.getGroupSchedule().getGroupRoom().getGroupCode())
.build();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import com.tukorea.planding.domain.notify.repository.NotificationRepository;
import com.tukorea.planding.domain.notify.service.RedisMessageService;
import com.tukorea.planding.domain.notify.service.ScheduleNotificationService;
import com.tukorea.planding.domain.schedule.dto.response.ScheduleResponse;
import com.tukorea.planding.domain.schedule.entity.Schedule;
import com.tukorea.planding.domain.schedule.entity.ScheduleStatus;
import com.tukorea.planding.domain.schedule.repository.GroupScheduleAttendanceRepository;
import com.tukorea.planding.global.error.BusinessException;
import com.tukorea.planding.global.error.ErrorCode;
import lombok.RequiredArgsConstructor;
Expand All @@ -21,25 +23,22 @@
@Component
@Slf4j
@RequiredArgsConstructor
public class GroupScheduleNotificationHandler {
public class GroupScheduleNotificationHandler implements NotificationHandler {

private final RedisMessageService redisMessageService;
private final NotificationRepository notificationRepository;
private final ScheduleNotificationService scheduleNotificationService;
private final GroupQueryService groupQueryService;
private final GroupScheduleAttendanceRepository attendanceRepository;

public void sendGroupNotification(String groupCode, String userCode, NotificationDTO request) {
try {
if (groupQueryService.existGroupInUser(userCode, groupCode)) {
throw new BusinessException(ErrorCode.ACCESS_DENIED);
}

if (!groupQueryService.getGroupByCode(groupCode).isAlarm()) {
return;
}
@Override
public void sendNotification(NotificationDTO request) {
try {
validateNotificationRequest(request);

Notification notification = Notification.builder()
.userCode(userCode)
.userCode(request.getUserCode())
.groupName(request.getGroupName())
.notificationType(NotificationType.GROUP_SCHEDULE)
.scheduleDate(LocalDate.parse(request.getDate()))
Expand All @@ -50,20 +49,77 @@ public void sendGroupNotification(String groupCode, String userCode, Notificatio
notificationRepository.save(notification);
String channel = request.getUserCode();
redisMessageService.publish(channel, request);
} catch (BusinessException e) {
log.warn("[Group Schedule] 알람 전송 실패 - 접근 권한 없음 to user {}:{}", request.getUserCode(), e.getMessage());
} catch (Exception e) {
log.error("알람 전송 실패 to user {}:{}", userCode, e.getMessage(), e);
log.error("[Group Schedule] 알람 전송 실패 to user {}:{}", request.getUserCode(), e.getMessage(), e);
}
}

public void registerScheduleBeforeOneHour(String userCode, ScheduleResponse response) {

public void registerScheduleBeforeOneHour(String userCode, Schedule response) {
// 1시간 전 알림
try {
LocalTime starTime = LocalTime.of(response.startTime(), 0);
LocalDateTime oneHourBefore = LocalDateTime.of(response.scheduleDate(), starTime).minusHours(1);
LocalTime starTime = LocalTime.of(response.getStartTime(), 0);
LocalDateTime oneHourBefore = LocalDateTime.of(response.getScheduleDate(), starTime).minusHours(1);
NotificationDTO oneHourBeforeNotification = NotificationDTO.createGroupSchedule(userCode, response);
scheduleNotificationService.scheduleNotification(oneHourBeforeNotification, oneHourBefore);
} catch (Exception e) {
log.error("Group 스케줄 알람 등록 실패 for user {}: {}", userCode, e.getMessage(), e);
log.error("[Group Schedule] 1시간 전 알림 등록 실패 for user {}: {}", userCode, e.getMessage(), e);
}
}

public void updateScheduleBeforeOneHour(String userCode, Schedule schedule) {
try {
NotificationDTO notification = scheduleNotificationService.getNotificationByScheduleId(schedule.getId());
if (notification != null) {
scheduleNotificationService.removeNotification(notification);
log.info("[Group Schedule] 기존 그룹 알람 삭제 성공 scheduleId: {}, message: {}", schedule.getId(), notification.getMessage());
}

LocalTime starTime = LocalTime.of(schedule.getStartTime(), 0);
LocalDateTime oneHourBefore = LocalDateTime.of(schedule.getScheduleDate(), starTime).minusHours(1);
NotificationDTO oneHourBeforeNotification = NotificationDTO.createGroupSchedule(userCode, schedule);
scheduleNotificationService.scheduleNotification(oneHourBeforeNotification, oneHourBefore);
} catch (Exception e) {
log.error("[Group Schedule] 1시간 전 알림 업데이트 실패 for user {}: {}", userCode, e.getMessage(), e);
}
}

public void deleteScheduleBeforeOneHour(Long scheduleId) {
try {
NotificationDTO notification = scheduleNotificationService.getNotificationByScheduleId(scheduleId);
if (notification != null) {
scheduleNotificationService.removeNotification(notification);
}
} catch (Exception e) {
log.error("[Group Schedule] 1시간 전 알림 삭제 실패 scheduleId: {}", scheduleId, e.getMessage(), e);
}
}

private void validateNotificationRequest(NotificationDTO request) {
checkUserAccess(request);
checkGroupAlarm(request);
checkAttendanceStatus(request);
}

private void checkUserAccess(NotificationDTO request) {
if (!groupQueryService.existGroupInUser(request.getGroupCode(), request.getUserCode())) {
throw new BusinessException(ErrorCode.ACCESS_DENIED);
}
}

private void checkGroupAlarm(NotificationDTO request) {
if (!groupQueryService.getGroupByCode(request.getGroupCode()).isAlarm()) {
throw new BusinessException(ErrorCode.ALARM_NOT_FOUND);
}
}

private void checkAttendanceStatus(NotificationDTO request) {
boolean isPossible = attendanceRepository.findByUser_UserCodeAndSchedule_IdAndStatus(
request.getUserCode(), request.getScheduleId(), ScheduleStatus.POSSIBLE).isPresent();
if (!isPossible) {
throw new BusinessException(ErrorCode.INVALID_ATTENDANCE_STATUS);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.tukorea.planding.domain.notify.service.schedule;

import com.tukorea.planding.domain.notify.dto.NotificationDTO;

public interface NotificationHandler {
public void sendNotification(NotificationDTO request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.tukorea.planding.domain.notify.service.schedule;

import com.tukorea.planding.domain.notify.entity.NotificationType;
import com.tukorea.planding.global.error.BusinessException;
import com.tukorea.planding.global.error.ErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class NotificationHandlerFactory {

private final PersonalScheduleNotificationHandler personalScheduleNotificationHandler;
private final GroupScheduleNotificationHandler groupScheduleNotificationHandler;

public NotificationHandler getHandler(NotificationType notificationType) {
switch (notificationType) {
case PERSONAL_SCHEDULE:
return personalScheduleNotificationHandler;
case GROUP_SCHEDULE:
return groupScheduleNotificationHandler;
default:
throw new BusinessException(ErrorCode.ALARM_NOT_FOUND);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.tukorea.planding.domain.schedule.dto.response.PersonalScheduleResponse;
import com.tukorea.planding.domain.user.dto.UserInfo;
import com.tukorea.planding.domain.user.service.UserQueryService;
import com.tukorea.planding.global.error.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
Expand All @@ -22,22 +23,23 @@
@Component
@Slf4j
@RequiredArgsConstructor
public class PersonalScheduleNotificationHandler {
public class PersonalScheduleNotificationHandler implements NotificationHandler {

private final RedisMessageService redisMessageService;
private final NotificationRepository notificationRepository;
private final ScheduleNotificationService scheduleNotificationService;
private final UserQueryService userQueryService;

// 개인 스케줄 알림 코드
public void sendPersonalNotification(String userCode, NotificationDTO request) {
@Override
public void sendNotification(NotificationDTO request) {
try {
if (!userQueryService.getUserByUserCode(userCode).isAlarm()) {
if (!userQueryService.getUserByUserCode(request.getUserCode()).isAlarm()) {
return;
}

Notification notification = Notification.builder()
.userCode(userCode)
.userCode(request.getUserCode())
.groupName(null)
.notificationType(NotificationType.PERSONAL_SCHEDULE)
.scheduleDate(LocalDate.parse(request.getDate()))
Expand All @@ -48,34 +50,14 @@ public void sendPersonalNotification(String userCode, NotificationDTO request) {
notificationRepository.save(notification);
String channel = request.getUserCode();
redisMessageService.publish(channel, request);
} catch (BusinessException e) {
log.warn("[Personal Schedule] 알람 전송 실패 - 접근 권한 없음 to user {}:{}", request.getUserCode(), e.getMessage());
} catch (Exception e) {
log.error("알람 전송 실패 to user {}:{}", userCode, e.getMessage(), e);
log.error("[Personal Schedule] 알람 전송 실패 to user {}:{}", request.getUserCode(), e.getMessage(), e);
}

}

public void sendDailyNotification(String userCode, DailyNotificationDto request) {
try {
if (!userQueryService.getUserByUserCode(userCode).isAlarm()) {
return;
}

Notification notification = Notification.builder()
.userCode(userCode)
.groupName(null)
.notificationType(NotificationType.DAILY)
.scheduleDate(request.date())
.message(request.message())
.url(null)
.build();

notificationRepository.save(notification);
redisMessageService.publish(userCode, NotificationDTO.createDailySchedule(userCode, request.message(), null, String.valueOf(request.date()), null));
} catch (Exception e) {
log.error("정시 스케줄 알람 전송 실패 to user {}:{}", userCode, e.getMessage(), e);
}

}

public void registerScheduleBeforeDay(String userCode, PersonalScheduleResponse request) {
// 자정 알림
Expand All @@ -96,10 +78,10 @@ public void registerScheduleBeforeOneHour(String userCode, PersonalScheduleRespo
try {
LocalTime starTime = LocalTime.of(request.startTime(), 0);
LocalDateTime oneHourBefore = LocalDateTime.of(request.scheduleDate(), starTime).minusHours(1);
NotificationDTO oneHourBeforeNotification = NotificationDTO.createPersonalSchedule(request.id(), userCode, request);
NotificationDTO oneHourBeforeNotification = NotificationDTO.createPersonalSchedule(userCode, request);
scheduleNotificationService.scheduleNotification(oneHourBeforeNotification, oneHourBefore);
} catch (Exception e) {
log.error("스케줄 알람 등록 실패 for user {}: {}", userCode, e.getMessage(), e);
log.error("[Personal Schedule] 1시간 전 알림 등록 실패 for user {}: {}", userCode, e.getMessage(), e);
}
}

Expand All @@ -108,29 +90,26 @@ public void updateScheduleBeforeOneHour(Long scheduleId, PersonalScheduleRespons
NotificationDTO notification = scheduleNotificationService.getNotificationByScheduleId(scheduleId);
if (notification != null) {
scheduleNotificationService.removeNotification(notification);
log.info("update 기존 알람 삭제 scheduleId {}: {}", scheduleId, notification.getMessage());
log.info("[Personal Schedule] 기존 그룹 알람 삭제 성공 scheduleId: {}, message: {}", scheduleId, notification.getMessage());
}

LocalTime starTime = LocalTime.of(request.startTime(), 0);
LocalDateTime oneHourBefore = LocalDateTime.of(request.scheduleDate(), starTime).minusHours(1);
NotificationDTO oneHourBeforeNotification = NotificationDTO.createPersonalSchedule(scheduleId, userInfo.getUserCode(), request);
NotificationDTO oneHourBeforeNotification = NotificationDTO.createPersonalSchedule(userInfo.getUserCode(), request);
scheduleNotificationService.scheduleNotification(oneHourBeforeNotification, oneHourBefore);
} catch (Exception e) {
log.error("한 시간전 알림 업데이트 실패 scheduleId {}:{}", scheduleId, e.getMessage(), e);
log.error("[Personal Schedule] 1시간 전 알림 업데이트 실패 for user {}: {}", userInfo.getUserCode(), e.getMessage(), e);
}


}

public void deleteScheduleBeforeOneHour(Long scheduleId) {
try {
NotificationDTO notification = scheduleNotificationService.getNotificationByScheduleId(scheduleId);
if (notification != null) {
scheduleNotificationService.removeNotification(notification);
log.info("delete 기존 알람 삭제 scheduleId {}: {}", scheduleId, notification.getMessage());
}
} catch (Exception e) {
log.error("한 시간전 알림 업데이트 실패 scheduleId {}:{}", scheduleId, e.getMessage(), e);
log.error("[Personal Schedule] 1시간 전 알림 삭제 실패 scheduleId: {}", scheduleId, e.getMessage(), e);
}

}
Expand Down
Loading

0 comments on commit 1966c3a

Please sign in to comment.