Skip to content

Commit

Permalink
Merge pull request #176 from prgrms-web-devcourse-final-project/feature/
Browse files Browse the repository at this point in the history
#165-notification

Feature/#165 : 알림 의존성 제거 및 타 도메인 알림 요청 추가
  • Loading branch information
hgh1472 authored Dec 8, 2024
2 parents 62861dc + fa81ba0 commit 88669d6
Show file tree
Hide file tree
Showing 17 changed files with 122 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public ComplaintResponseDTO complain(ComplaintType type, Long letterId, Long rep
complaints.add(complaint);
if (complaints.needsWarningNotification()) {
Long writer = blockLetter(type, letterId);
notificationService.sendNotification(NotificationType.WARNING, writer, letterId);
notificationService.sendNotification(NotificationType.WARNING, writer, letterId, null);
userService.updateWarningCount(writer);
}
return ComplaintResponseDTO.from(repository.save(complaint));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package postman.bottler.letter.service;

import static postman.bottler.notification.domain.NotificationType.KEYWORD_REPLY;

import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
Expand All @@ -19,6 +21,7 @@
import postman.bottler.letter.exception.DuplicateReplyLetterException;
import postman.bottler.letter.exception.LetterAuthorMismatchException;
import postman.bottler.letter.exception.LetterNotFoundException;
import postman.bottler.notification.service.NotificationService;
import postman.bottler.reply.dto.ReplyType;

@Service
Expand All @@ -28,6 +31,7 @@ public class ReplyLetterService {
private final ReplyLetterRepository replyLetterRepository;
private final LetterService letterService;
private final LetterBoxService letterBoxService;
private final NotificationService notificationService;
private final RedisTemplate<String, Object> redisTemplate;

@Transactional
Expand All @@ -46,6 +50,8 @@ public ReplyLetterResponseDTO createReplyLetter(

saveLetterToBox(senderId, replyLetter, receiverId);
saveRecentReply(letterId, letterReplyRequestDTO.label(), receiverId);
notificationService.sendNotification(KEYWORD_REPLY, receiverInfo.receiverId(), replyLetter.getLetterId(),
replyLetter.getLabel());
return ReplyLetterResponseDTO.from(replyLetter);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,12 @@ public List<MapLetterAndDistance> findLettersByUserLocation(BigDecimal latitude,
}

@Override
public void findSourceMapLetterById(Long sourceMapLetterId) {
public MapLetter findSourceMapLetterById(Long sourceMapLetterId) {
MapLetterEntity activeLetter = mapLetterJpaRepository.findActiveById(sourceMapLetterId);
if (activeLetter == null) {
throw new SourceMapLetterNotFountException("원본 편지를 찾을 수 없습니다. 편지가 존재하지 않거나 삭제되었습니다.");
}
return MapLetterEntity.toDomain(activeLetter);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public interface MapLetterRepository {

List<MapLetterAndDistance> findLettersByUserLocation(BigDecimal latitude, BigDecimal longitude, Long userId);

void findSourceMapLetterById(Long sourceMapLetterId);
MapLetter findSourceMapLetterById(Long sourceMapLetterId);

void letterBlock(Long letterId);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package postman.bottler.mapletter.service;

import static postman.bottler.notification.domain.NotificationType.*;

import jakarta.validation.Valid;
import java.math.BigDecimal;
import java.time.LocalDateTime;
Expand Down Expand Up @@ -39,7 +41,9 @@
import postman.bottler.mapletter.exception.LetterAlreadyReplyException;
import postman.bottler.mapletter.exception.MapLetterAlreadyArchivedException;
import postman.bottler.mapletter.exception.PageRequestException;
import postman.bottler.notification.domain.NotificationType;
import postman.bottler.notification.dto.request.NotificationLabelRequestDTO;
import postman.bottler.notification.service.NotificationService;
import postman.bottler.reply.dto.ReplyType;
import postman.bottler.user.service.UserService;

Expand All @@ -50,6 +54,7 @@ public class MapLetterService {
private final ReplyMapLetterRepository replyMapLetterRepository;
private final MapLetterArchiveRepository mapLetterArchiveRepository;
private final UserService userService;
private final NotificationService notificationService;
private final RedisTemplate<String, Object> redisTemplate;

private static final double VIEW_DISTANCE = 15;
Expand All @@ -67,7 +72,9 @@ public MapLetter createTargetMapLetter(CreateTargetMapLetterRequestDTO createTar
Long userId) {
Long targetUserId = userService.getUserIdByNickname(createTargetMapLetterRequestDTO.target());
MapLetter mapLetter = MapLetter.createTargetMapLetter(createTargetMapLetterRequestDTO, userId, targetUserId);
return mapLetterRepository.save(mapLetter);
MapLetter save = mapLetterRepository.save(mapLetter);
notificationService.sendNotification(TARGET_LETTER, targetUserId, mapLetter.getId(), mapLetter.getLabel());
return save;
}

@Transactional(readOnly = true)
Expand Down Expand Up @@ -155,10 +162,12 @@ public ReplyMapLetter createReplyMapLetter(@Valid CreateReplyMapLetterRequestDTO
throw new LetterAlreadyReplyException("해당 편지에 이미 답장을 했습니다.");
}

mapLetterRepository.findSourceMapLetterById(createReplyMapLetterRequestDTO.sourceLetter());
MapLetter source = mapLetterRepository.findSourceMapLetterById(createReplyMapLetterRequestDTO.sourceLetter());
ReplyMapLetter replyMapLetter = ReplyMapLetter.createReplyMapLetter(createReplyMapLetterRequestDTO, userId);
ReplyMapLetter save = replyMapLetterRepository.save(replyMapLetter);
saveRecentReply(save.getReplyLetterId(), save.getLabel(), save.getSourceLetterId());
notificationService.sendNotification(MAP_REPLY, source.getCreateUserId(), save.getReplyLetterId(),
save.getLabel());
return save;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
Expand All @@ -34,7 +33,8 @@ public class NotificationController {
private final NotificationService notificationService;
private final SubscriptionService subscriptionService;

@Operation(summary = "알림 생성", description = "알림 유형, 알림 대상은 필수, 편지 관련 알림은 편지 ID를 등록합니다.")
@Operation(summary = "알림 생성",
description = "알림 유형, 알림 대상은 필수, 편지 관련 알림은 편지 ID와 라벨 이미지를 등록합니다.")
@PostMapping
public ApiResponse<NotificationResponseDTO> create(
@Valid @RequestBody NotificationRequestDTO notificationRequestDTO, BindingResult bindingResult) {
Expand All @@ -44,7 +44,7 @@ public ApiResponse<NotificationResponseDTO> create(
NotificationResponseDTO response = notificationService.sendNotification(
NotificationType.from(notificationRequestDTO.notificationType()),
notificationRequestDTO.receiver(),
notificationRequestDTO.letterId());
notificationRequestDTO.letterId(), notificationRequestDTO.label());
return ApiResponse.onCreateSuccess(response);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@ public class LetterNotification extends Notification {
@Setter
private String label;

protected LetterNotification(NotificationType type, long receiver, Long letterId, Boolean isRead) {
protected LetterNotification(NotificationType type, long receiver, Long letterId, Boolean isRead, String label) {
super(type, receiver, isRead);
validateLetterId(letterId);
this.letterId = letterId;
this.label = label;
}

protected LetterNotification(UUID id, NotificationType type, long receiver,
Long letterId, LocalDateTime createdAt, Boolean isRead) {
Long letterId, LocalDateTime createdAt, Boolean isRead, String label) {
super(id, type, receiver, createdAt, isRead);
validateLetterId(letterId);
this.letterId = letterId;
this.label = label;
}

private void validateLetterId(Long letterId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class Notification {

private final LocalDateTime createdAt;

private Boolean isRead;
private final Boolean isRead;

protected Notification(NotificationType type, Long receiver, Boolean isRead) {
this.id = UUID.randomUUID();
Expand All @@ -32,17 +32,17 @@ protected Notification(UUID id, NotificationType type, Long receiver, LocalDateT
this.isRead = isRead;
}

public static Notification create(NotificationType type, Long receiver, Long letterId) {
public static Notification create(NotificationType type, Long receiver, Long letterId, String label) {
if (type.isLetterNotification()) {
return new LetterNotification(type, receiver, letterId, false);
return new LetterNotification(type, receiver, letterId, false, label);
}
return new Notification(type, receiver, false);
}

public static Notification of(UUID id, NotificationType type, Long receiver,
Long letterId, LocalDateTime createdAt, Boolean isRead) {
Long letterId, LocalDateTime createdAt, Boolean isRead, String label) {
if (type.isLetterNotification()) {
return new LetterNotification(id, type, receiver, letterId, createdAt, isRead);
return new LetterNotification(id, type, receiver, letterId, createdAt, isRead, label);
}
return new Notification(id, type, receiver, createdAt, isRead);
}
Expand All @@ -61,6 +61,7 @@ public Boolean isMapLetterNotification() {

public Notification read() {
return Notification.of(id, type, receiver,
isLetterNotification() ? ((LetterNotification) this).getLetterId() : null, createdAt, true);
isLetterNotification() ? ((LetterNotification) this).getLetterId() : null, createdAt, true,
isLetterNotification() ? ((LetterNotification) this).getLabel() : null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import java.util.List;
import lombok.Builder;
import lombok.Getter;
import postman.bottler.notification.dto.request.NotificationLabelRequestDTO;
import postman.bottler.notification.dto.response.NotificationResponseDTO;

@Builder
Expand Down Expand Up @@ -33,55 +32,6 @@ public Notifications markAsRead() {
return new Notifications(changed);
}

public List<Long> extractMapIds() {
List<Long> ids = new ArrayList<>();
for (Notification notification : notifications) {
if (notification.isMapLetterNotification()) {
ids.add(((LetterNotification) notification).getLetterId());
}
}
return ids;
}

public List<Long> extractKeywordIds() {
List<Long> ids = new ArrayList<>();
for (Notification notification : notifications) {
if (notification.isKeywordLetterNotification()) {
ids.add(((LetterNotification) notification).getLetterId());
}
}
return ids;
}

public void setMapLabels(List<NotificationLabelRequestDTO> mapLabels) {
for (Notification notification : notifications) {
if (!notification.isMapLetterNotification()) {
continue;
}
mapLabels.stream()
.filter(label -> label.letterId() == ((LetterNotification) notification).getLetterId())
.forEach(label -> ((LetterNotification) notification).setLabel(label.label()));
}
}

public void setKeywordLabels(List<NotificationLabelRequestDTO> keywordLabels) {
for (Notification notification : notifications) {
if (!notification.isKeywordLetterNotification()) {
continue;
}
keywordLabels.stream()
.filter(label -> label.letterId() == ((LetterNotification) notification).getLetterId())
.forEach(label -> ((LetterNotification) notification).setLabel(label.label()));
}
}

public List<Long> getLetterIds() {
return notifications.stream()
.filter(Notification::isLetterNotification)
.map(notification -> ((LetterNotification) notification).getLetterId())
.toList();
}

public List<NotificationResponseDTO> createDTO() {
return notifications.stream()
.map(NotificationResponseDTO::from)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ public record NotificationRequestDTO(
@NotNull(message = "알림 대상은 필수입니다.")
Long receiver,

Long letterId
Long letterId,

String label
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ public enum NotificationHashKey {
RECEIVER("receiver"),
CREATED_AT("created_at"),
LETTER_ID("letter_id"),
IS_READ("is_read");
IS_READ("is_read"),
LABEL("label");

private final String key;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static postman.bottler.notification.infra.NotificationHashKey.CREATED_AT;
import static postman.bottler.notification.infra.NotificationHashKey.ID;
import static postman.bottler.notification.infra.NotificationHashKey.IS_READ;
import static postman.bottler.notification.infra.NotificationHashKey.LABEL;
import static postman.bottler.notification.infra.NotificationHashKey.LETTER_ID;
import static postman.bottler.notification.infra.NotificationHashKey.RECEIVER;
import static postman.bottler.notification.infra.NotificationHashKey.TYPE;
Expand Down Expand Up @@ -37,6 +38,8 @@ public class RedisNotification {

private Boolean isRead;

private String label;

public static RedisNotification from(Notification notification) {
return RedisNotification.builder()
.id(notification.getId())
Expand All @@ -46,11 +49,12 @@ public static RedisNotification from(Notification notification) {
((LetterNotification) notification).getLetterId() : null)
.createdAt(notification.getCreatedAt())
.isRead(notification.getIsRead())
.label(notification.isLetterNotification() ? ((LetterNotification) notification).getLabel() : null)
.build();
}

public Notification toDomain() {
return Notification.of(id, type, receiver, letterId, createdAt, isRead);
return Notification.of(id, type, receiver, letterId, createdAt, isRead, label);
}

public Map<String, Object> toMap() {
Expand All @@ -61,6 +65,7 @@ public Map<String, Object> toMap() {
map.put(LETTER_ID.getKey(), letterId);
map.put(CREATED_AT.getKey(), createdAt);
map.put(IS_READ.getKey(), isRead);
map.put(LABEL.getKey(), label);
return map;
}

Expand All @@ -72,6 +77,7 @@ public static RedisNotification create(RedisTemplate<String, Object> redisTempla
.createdAt((LocalDateTime) redisTemplate.opsForHash().get(key, CREATED_AT.getKey()))
.letterId((Long) redisTemplate.opsForHash().get(key, LETTER_ID.getKey()))
.isRead((Boolean) redisTemplate.opsForHash().get(key, IS_READ.getKey()))
.label((String) redisTemplate.opsForHash().get(key, LABEL.getKey()))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import postman.bottler.letter.service.LetterRepository;
import postman.bottler.mapletter.service.MapLetterRepository;
import postman.bottler.notification.domain.Notification;
import postman.bottler.notification.domain.NotificationType;
import postman.bottler.notification.domain.Notifications;
import postman.bottler.notification.domain.PushMessages;
import postman.bottler.notification.domain.Subscriptions;
import postman.bottler.notification.dto.request.NotificationLabelRequestDTO;
import postman.bottler.notification.dto.request.RecommendNotificationRequestDTO;
import postman.bottler.notification.dto.response.NotificationResponseDTO;

Expand All @@ -24,12 +21,9 @@ public class NotificationService {
private final SubscriptionRepository subscriptionRepository;
private final PushNotificationProvider pushNotificationProvider;

private final MapLetterRepository mapLetterRepository;
private final LetterRepository keywordLetterRepository;

@Transactional
public NotificationResponseDTO sendNotification(NotificationType type, Long userId, Long letterId) {
Notification notification = Notification.create(type, userId, letterId);
public NotificationResponseDTO sendNotification(NotificationType type, Long userId, Long letterId, String label) {
Notification notification = Notification.create(type, userId, letterId, label);
Subscriptions subscriptions = subscriptionRepository.findByUserId(userId);
NotificationResponseDTO result = NotificationResponseDTO.from(notificationRepository.save(notification));
if (subscriptions.isPushEnabled()) {
Expand All @@ -42,14 +36,6 @@ public NotificationResponseDTO sendNotification(NotificationType type, Long user
@Transactional
public List<NotificationResponseDTO> getUserNotifications(Long userId) {
Notifications notifications = notificationRepository.findByReceiver(userId);
List<Long> mapIds = notifications.extractMapIds();
List<NotificationLabelRequestDTO> mapLabels = mapLetterRepository.findAllByIds(mapIds).stream()
.map(letter -> new NotificationLabelRequestDTO(letter.getId(), letter.getLabel())).toList();
notifications.setMapLabels(mapLabels);
List<Long> keywordIds = notifications.extractKeywordIds();
List<NotificationLabelRequestDTO> keywordLabels = keywordLetterRepository.findAllByIds(keywordIds)
.stream().map(letter -> new NotificationLabelRequestDTO(letter.getId(), letter.getLabel())).toList();
notifications.setKeywordLabels(keywordLabels);
notifications.orderByCreatedAt();
List<NotificationResponseDTO> result = notifications.createDTO();
notificationRepository.updateNotifications(notifications.markAsRead());
Expand All @@ -60,7 +46,7 @@ public List<NotificationResponseDTO> getUserNotifications(Long userId) {
public void sendKeywordNotifications(List<RecommendNotificationRequestDTO> requests) {
requests.forEach(request -> {
notificationRepository.save(Notification.create(NotificationType.NEW_LETTER, request.userId(),
request.letterId()));
request.letterId(), request.label()));
});
Subscriptions allSubscriptions = subscriptionRepository.findAll();
if (allSubscriptions.isPushEnabled()) {
Expand Down
Loading

0 comments on commit 88669d6

Please sign in to comment.