Skip to content

Commit

Permalink
Merge pull request #747 from woowacourse-teams/fix/#724
Browse files Browse the repository at this point in the history
알림 작업 구조 개선 & 특정 알림 메시지 구체화
  • Loading branch information
pricelees authored Oct 24, 2024
2 parents ab2f929 + c2c2d0e commit 024565b
Show file tree
Hide file tree
Showing 56 changed files with 1,465 additions and 493 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import mouda.backend.chat.domain.Chats;
import mouda.backend.chat.implement.ChatRoomFinder;
import mouda.backend.chat.implement.ChatWriter;
import mouda.backend.chat.implement.sender.ChatNotificationSender;
import mouda.backend.chat.implement.notification.ChatNotificationSender;
import mouda.backend.chat.presentation.request.ChatCreateRequest;
import mouda.backend.chat.presentation.request.DateTimeConfirmRequest;
import mouda.backend.chat.presentation.request.LastReadChatRequest;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package mouda.backend.chat.domain;

import lombok.Builder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
@Builder
public class ChatNotificationEvent {

private final Long darakbangId;
private final ChatRoom chatRoom;
private final Chat appendedChat;
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package mouda.backend.chat.implement.sender;
package mouda.backend.chat.implement.notification;

import java.util.List;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import mouda.backend.bet.domain.Bet;
import mouda.backend.bet.implement.BetFinder;
import mouda.backend.chat.domain.Chat;
import mouda.backend.chat.domain.ChatNotificationEvent;
import mouda.backend.chat.domain.ChatRoom;
import mouda.backend.chat.domain.ChatRoomType;
import mouda.backend.chat.entity.ChatType;
Expand All @@ -20,82 +24,93 @@
import mouda.backend.darakbang.implement.DarakbangFinder;
import mouda.backend.moim.domain.Moim;
import mouda.backend.moim.implement.finder.MoimFinder;
import mouda.backend.notification.domain.NotificationEvent;
import mouda.backend.notification.domain.NotificationPayload;
import mouda.backend.notification.domain.NotificationType;
import mouda.backend.notification.domain.Recipient;
import mouda.backend.notification.implement.NotificationProcessor;

@Component
@EnableConfigurationProperties(UrlConfig.class)
@RequiredArgsConstructor
public class ChatNotificationSender {
public class ChatNotificationEventHandler {

private final UrlConfig urlConfig;
private final ChatRecipientFinder chatRecipientFinder;
private final ApplicationEventPublisher eventPublisher;
private final MoimFinder moimFinder;
private final BetFinder betFinder;
private final DarakbangFinder darakbangFinder;
private final ChatRecipientFinder chatRecipientFinder;
private final NotificationProcessor notificationProcessor;

@Async
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
@TransactionalEventListener(classes = ChatNotificationEvent.class, phase = TransactionPhase.AFTER_COMMIT)
public void sendChatNotification(
long darakbangId, ChatRoom chatRoom, Chat appendedChat
ChatNotificationEvent chatNotificationEvent
) {
long darakbangId = chatNotificationEvent.getDarakbangId();
ChatRoom chatRoom = chatNotificationEvent.getChatRoom();
Chat appendedChat = chatNotificationEvent.getAppendedChat();

ChatRoomType chatRoomType = chatRoom.getType();
long chatRoomId = chatRoom.getId();

if (chatRoomType == ChatRoomType.BET) {
Bet bet = betFinder.find(darakbangId, chatRoom.getTargetId());
sendBetNotification(bet, appendedChat, chatRoomId);
handleBetNotification(bet, appendedChat, chatRoomId);
return;
}

Moim moim = moimFinder.read(chatRoom.getTargetId(), darakbangId);
sendMoimNotification(moim, appendedChat, chatRoomId);
handleMoimNotification(moim, appendedChat, chatRoomId);
}

private void sendMoimNotification(
private void handleMoimNotification(
Moim moim, Chat chat, long chatRoomId
) {
List<Recipient> recipients = chatRecipientFinder.getMoimChatNotificationRecipients(moim.getId(),
chat.getAuthor());
long darakbangId = moim.getDarakbangId();

publishEvent(darakbangId, chatRoomId, moim.getTitle(), chat, recipients);
processNotification(darakbangId, chatRoomId, moim.getTitle(), chat, recipients);
}

private void sendBetNotification(Bet bet, Chat chat, long chatRoomId) {
private void handleBetNotification(Bet bet, Chat chat, long chatRoomId) {
List<Recipient> recipients = chatRecipientFinder.getBetChatNotificationRecipients(bet.getId(),
chat.getAuthor());
long darakbangId = bet.getDarakbangId();

publishEvent(darakbangId, chatRoomId, bet.getTitle(), chat, recipients);
processNotification(darakbangId, chatRoomId, bet.getTitle(), chat, recipients);
}

private void publishEvent(long darakbangId, long chatRoomId, String title, Chat chat, List<Recipient> recipients) {
private void processNotification(
long darakbangId, long chatRoomId, String title, Chat chat, List<Recipient> recipients
) {
Darakbang darakbang = darakbangFinder.findById(darakbangId);
ChatNotification chatNotification = ChatNotification.create(darakbang.getName(), title, chat);
ChatNotificationMessage chatNotificationMessage = ChatNotificationMessage.create(darakbang.getName(), title,
chat);

NotificationEvent notificationEvent = NotificationEvent.chatEvent(
chatNotification.getType(),
NotificationPayload payload = NotificationPayload.createChatPayload(
chatNotificationMessage.getType(),
darakbang.getName(),
chatNotification.getMessage(),
chatNotificationMessage.getMessage(),
urlConfig.getChatRoomUrl(darakbangId, chatRoomId),
recipients,
darakbangId,
chatRoomId
);

eventPublisher.publishEvent(notificationEvent);
notificationProcessor.process(payload);
}

@Getter
@RequiredArgsConstructor
static class ChatNotification {
static class ChatNotificationMessage {

private final String title;
private final NotificationType type;
private final String message;

public static ChatNotification create(String darakbangName, String title, Chat chat) {
public static ChatNotificationMessage create(String darakbangName, String title,
Chat chat) {
ChatType chatType = chat.getChatType();
String content = chat.getContent();

Expand All @@ -114,16 +129,19 @@ public static ChatNotification create(String darakbangName, String title, Chat c
return basicChat(title, message);
}

private static ChatNotification placeConfirmChat(String title, String message) {
return new ChatNotification(title, NotificationType.MOIM_PLACE_CONFIRMED, message);
private static ChatNotificationMessage placeConfirmChat(String title, String message) {
return new ChatNotificationMessage(title, NotificationType.MOIM_PLACE_CONFIRMED,
message);
}

private static ChatNotification dateTimeConfirmChat(String title, String message) {
return new ChatNotification(title, NotificationType.MOIM_TIME_CONFIRMED, message);
private static ChatNotificationMessage dateTimeConfirmChat(String title,
String message) {
return new ChatNotificationMessage(title, NotificationType.MOIM_TIME_CONFIRMED,
message);
}

private static ChatNotification basicChat(String title, String message) {
return new ChatNotification(title, NotificationType.NEW_CHAT, message);
private static ChatNotificationMessage basicChat(String title, String message) {
return new ChatNotificationMessage(title, NotificationType.NEW_CHAT, message);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package mouda.backend.chat.implement.notification;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import lombok.RequiredArgsConstructor;
import mouda.backend.chat.domain.Chat;
import mouda.backend.chat.domain.ChatNotificationEvent;
import mouda.backend.chat.domain.ChatRoom;

@Component
@RequiredArgsConstructor
public class ChatNotificationSender {

private final ApplicationEventPublisher eventPublisher;

public void sendChatNotification(long darakbangId, ChatRoom chatRoom, Chat appendedChat) {
ChatNotificationEvent event = ChatNotificationEvent.builder()
.darakbangId(darakbangId)
.chatRoom(chatRoom)
.appendedChat(appendedChat)
.build();

eventPublisher.publishEvent(event);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package mouda.backend.chat.implement.sender;
package mouda.backend.chat.implement.notification;

import java.util.List;
import java.util.stream.Stream;
Expand Down Expand Up @@ -48,25 +48,4 @@ public List<Recipient> getNotificationRecipients(Stream<DarakbangMember> memberS
.build())
.toList();
}

// todo: 구버전 채팅 기능 삭제시 같이 지워주세요.
public List<Recipient> getMoimChatNotificationRecipients(long moimId, DarakbangMember sender) {
List<Chamyo> chamyos = chamyoRepository.findAllByMoimId(moimId);

Stream<DarakbangMember> darakbangMemberStream = chamyos.stream()
.map(Chamyo::getDarakbangMember);

return getNotificationRecipients(darakbangMemberStream, sender);
}

// todo: 구버전 채팅 기능 삭제시 같이 지워주세요.
public List<Recipient> getNotificationRecipients(Stream<DarakbangMember> memberStream, DarakbangMember sender) {
return memberStream
.filter(darakbangMember -> darakbangMember.isNotSameMemberWith(sender))
.map(darakbangMember -> Recipient.builder()
.memberId(darakbangMember.getMemberId())
.darakbangMemberId(darakbangMember.getId())
.build())
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import mouda.backend.moim.domain.MoimRole;
import mouda.backend.moim.implement.finder.ChamyoFinder;
import mouda.backend.moim.implement.finder.MoimFinder;
import mouda.backend.moim.implement.sender.ChamyoNotificationSender;
import mouda.backend.moim.implement.notificiation.MoimRelatedNotificationSender;
import mouda.backend.moim.implement.writer.ChamyoWriter;
import mouda.backend.moim.implement.writer.MoimWriter;
import mouda.backend.moim.presentation.response.chamyo.ChamyoFindAllResponses;
Expand All @@ -28,7 +28,7 @@ public class ChamyoService {
private final MoimWriter moimWriter;
private final ChamyoFinder chamyoFinder;
private final ChamyoWriter chamyoWriter;
private final ChamyoNotificationSender chamyoNotificationSender;
private final MoimRelatedNotificationSender notificationSender;

@Transactional(readOnly = true)
public MoimRoleFindResponse findMoimRole(Long darakbangId, Long moimId, DarakbangMember darakbangMember) {
Expand All @@ -51,14 +51,14 @@ public void chamyoMoim(Long darakbangId, Long moimId, DarakbangMember darakbangM
Chamyo chamyo = chamyoWriter.saveAsMoimee(moim, darakbangMember);
moimWriter.updateMoimStatusIfFull(moim);

chamyoNotificationSender.sendChamyoNotification(moimId, darakbangMember, NotificationType.NEW_MOIMEE_JOINED);
notificationSender.sendChamyoNotification(chamyo, NotificationType.NEW_MOIMEE_JOINED);
}

public void cancelChamyo(Long darakbangId, Long moimId, DarakbangMember darakbangMember) {
Moim moim = moimFinder.read(moimId, darakbangId);
Chamyo chamyo = chamyoFinder.read(moim, darakbangMember);
chamyoWriter.delete(chamyo);

chamyoNotificationSender.sendChamyoNotification(moimId, darakbangMember, NotificationType.MOIMEE_LEFT);
notificationSender.sendChamyoNotification(chamyo, NotificationType.MOIMEE_LEFT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import mouda.backend.moim.domain.Comment;
import mouda.backend.moim.domain.Moim;
import mouda.backend.moim.implement.finder.MoimFinder;
import mouda.backend.moim.implement.sender.CommentNotificationSender;
import mouda.backend.moim.implement.notificiation.MoimRelatedNotificationSender;
import mouda.backend.moim.implement.writer.CommentWriter;
import mouda.backend.moim.presentation.request.comment.CommentCreateRequest;

Expand All @@ -19,14 +19,14 @@ public class CommentService {

private final MoimFinder moimFinder;
private final CommentWriter commentWriter;
private final CommentNotificationSender commentNotificationSender;
private final MoimRelatedNotificationSender notificationSender;

public void createComment(
Long darakbangId, Long moimId, DarakbangMember darakbangMember, CommentCreateRequest request
) {
Moim moim = moimFinder.read(moimId, darakbangId);
Comment comment = commentWriter.saveComment(moim, darakbangMember, request.parentId(), request.content());

commentNotificationSender.sendCommentNotification(comment, darakbangMember);
notificationSender.sendCommentNotification(comment, darakbangMember);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import mouda.backend.moim.domain.ParentComment;
import mouda.backend.moim.implement.finder.CommentFinder;
import mouda.backend.moim.implement.finder.MoimFinder;
import mouda.backend.moim.implement.sender.MoimNotificationSender;
import mouda.backend.moim.implement.notificiation.MoimRelatedNotificationSender;
import mouda.backend.moim.implement.writer.MoimWriter;
import mouda.backend.moim.presentation.request.moim.MoimCreateRequest;
import mouda.backend.moim.presentation.request.moim.MoimEditRequest;
Expand All @@ -32,8 +32,8 @@ public class MoimService {
private final MoimWriter moimWriter;
private final MoimFinder moimFinder;
private final CommentFinder commentFinder;
private final MoimNotificationSender moimNotificationSender;
private final ChatRoomFinder chatRoomFinder;
private final MoimRelatedNotificationSender notificationSender;

@Transactional(readOnly = true)
public MoimDetailsFindResponse findMoimDetails(long darakbangId, long moimId) {
Expand Down Expand Up @@ -76,29 +76,29 @@ public MoimFindAllResponses findZzimedMoim(DarakbangMember darakbangMember) {
public Moim createMoim(Long darakbangId, DarakbangMember darakbangMember, MoimCreateRequest moimCreateRequest) {
Moim moim = moimWriter.save(moimCreateRequest.toEntity(darakbangId), darakbangMember);

moimNotificationSender.sendMoimCreatedNotification(moim, darakbangMember, NotificationType.MOIM_CREATED);
notificationSender.sendMoimCreatedNotification(moim, darakbangMember, NotificationType.MOIM_CREATED);
return moim;
}

public void completeMoim(Long darakbangId, Long moimId, DarakbangMember darakbangMember) {
Moim moim = moimFinder.read(moimId, darakbangId);
moimWriter.completeMoim(moim, darakbangMember);

moimNotificationSender.sendMoimStatusChangedNotification(moim, NotificationType.MOIMING_COMPLETED);
notificationSender.sendMoimStatusChangeNotification(moim, NotificationType.MOIMING_COMPLETED);
}

public void cancelMoim(Long darakbangId, Long moimId, DarakbangMember darakbangMember) {
Moim moim = moimFinder.read(moimId, darakbangId);
moimWriter.cancelMoim(moim, darakbangMember);

moimNotificationSender.sendMoimStatusChangedNotification(moim, NotificationType.MOIM_CANCELLED);
notificationSender.sendMoimStatusChangeNotification(moim, NotificationType.MOIM_CANCELLED);
}

public void reopenMoim(Long darakbangId, Long moimId, DarakbangMember darakbangMember) {
Moim moim = moimFinder.read(moimId, darakbangId);
moimWriter.reopenMoim(moim, darakbangMember);

moimNotificationSender.sendMoimStatusChangedNotification(moim, NotificationType.MOINING_REOPENED);
notificationSender.sendMoimStatusChangeNotification(moim, NotificationType.MOINING_REOPENED);
}

public void editMoim(Long darakbangId, MoimEditRequest request, DarakbangMember darakbangMember) {
Expand All @@ -107,6 +107,6 @@ public void editMoim(Long darakbangId, MoimEditRequest request, DarakbangMember
moimWriter.updateMoim(moim, darakbangMember, request.title(), request.date(), request.time(), request.place(),
request.maxPeople(), request.description());

moimNotificationSender.sendMoimInfoModifiedNotification(moim, oldTitle, NotificationType.MOIM_MODIFIED);
notificationSender.sendMoimEditedNotification(moim, oldTitle, NotificationType.MOIM_MODIFIED);
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
package mouda.backend.moim.implement.sender;
package mouda.backend.moim.implement.notificiation;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

import lombok.RequiredArgsConstructor;
import mouda.backend.common.config.UrlConfig;
import mouda.backend.notification.implement.NotificationProcessor;

@Component
@RequiredArgsConstructor
@EnableConfigurationProperties(UrlConfig.class)
public abstract class AbstractMoimNotificationSender {
public abstract class AbstractMoimRelatedNotificationEventHandler {

private final UrlConfig urlConfig;
protected final UrlConfig urlConfig;
protected final NotificationProcessor notificationProcessor;

protected String getMoimUrl(long darakbangId, long moimId) {
return urlConfig.getMoimUrl(darakbangId, moimId);
}

protected String getChatRoomUrl(long darakbangId, long moimId) {
return urlConfig.getChatRoomUrl(darakbangId, moimId);
}
}
Loading

0 comments on commit 024565b

Please sign in to comment.