Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ public class NotificationDto {
private Long refId;
private boolean isRead;
private LocalDateTime createdAt;
private String message;

public static NotificationDto from(Notification notification) {
public static NotificationDto from(Notification notification, String message) {
return NotificationDto.builder()
.id(notification.getId())
.receiverId(notification.getReceiver().getId())
Expand All @@ -31,6 +32,7 @@ public static NotificationDto from(Notification notification) {
.refId(notification.getRefId())
.isRead(notification.isRead())
.createdAt(notification.getCreatedAt())
.message(message)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
Expand Down Expand Up @@ -71,7 +74,7 @@ public NotificationDto createNotification(Long receiverId, Long senderId, Notifi
publishNotificationToRedis(savedNotification, senderNickname, message);

log.info("알림 생성 및 발송: receiverId={}, type={}, refId={}", receiverId, type, refId);
return NotificationDto.from(savedNotification);
return NotificationDto.from(savedNotification, message);
}

@Override
Expand All @@ -87,7 +90,7 @@ public NotificationDto createSystemNotification(Long receiverId, NotificationTyp
publishNotificationToRedis(savedNotification, "시스템", message);

log.info("시스템 알림 생성 및 발송: receiverId={}, type={}, refId={}", receiverId, type, refId);
return NotificationDto.from(savedNotification);
return NotificationDto.from(savedNotification, message);
}

// ===== 미읽음 개수 조회 =====
Expand Down Expand Up @@ -143,8 +146,23 @@ public NotificationListResponseDto getNotifications(Long userId) {
combinedNotifications.addAll(unreadNotifications);
combinedNotifications.addAll(readNotifications);

// sender nickname 배치 조회
Set<Long> senderIds = combinedNotifications.stream()
.map(Notification::getSenderId)
.filter(Objects::nonNull)
Comment on lines +150 to +152
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

senderNickname을 결정하는 로직을 더 간결하게 개선할 수 있습니다. nicknameMap.getOrDefault는 키가 null인 경우에도 안전하게 동작하므로 명시적인 null 체크를 생략할 수 있습니다.

                    String senderNickname = nicknameMap.getOrDefault(n.getSenderId(), "시스템");

.collect(Collectors.toSet());
Map<Long, String> nicknameMap = senderIds.isEmpty()
? Collections.emptyMap()
: userRepository.findAllById(senderIds).stream()
.collect(Collectors.toMap(User::getId,
u -> u.getNickname() != null ? u.getNickname() : "시스템"));

List<NotificationDto> notificationDtos = combinedNotifications.stream()
.map(NotificationDto::from)
.map(n -> {
String senderNickname = nicknameMap.getOrDefault(n.getSenderId(), "시스템");
String message = generateNotificationMessage(n.getNotificationType(), senderNickname);
return NotificationDto.from(n, message);
})
Comment on lines +154 to +165
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

현재 로직은 시스템 알림(senderId가 null인 경우)과 닉네임이 없는 사용자를 모두 "시스템"이라는 닉네임으로 처리하고 있습니다. 시스템 알림과 일반 사용자를 구분하여 처리하는 것이 좋습니다. 다만, 탈퇴한 사용자와 같은 예외 케이스 처리는 현재 단계에서 나중에 진행해도 무방합니다.

또한, userRepository.findAllById(senderIds)는 User 엔티티 전체를 조회하므로, 알림 목록이 길어질 경우 성능 최적화를 위해 닉네임만 조회하는 프로젝션 사용을 고려해볼 수 있습니다.

Suggested change
Map<Long, String> nicknameMap = senderIds.isEmpty()
? Collections.emptyMap()
: userRepository.findAllById(senderIds).stream()
.collect(Collectors.toMap(User::getId,
u -> u.getNickname() != null ? u.getNickname() : "시스템"));
List<NotificationDto> notificationDtos = combinedNotifications.stream()
.map(NotificationDto::from)
.map(n -> {
String senderNickname = nicknameMap.getOrDefault(n.getSenderId(), "시스템");
String message = generateNotificationMessage(n.getNotificationType(), senderNickname);
return NotificationDto.from(n, message);
})
Map<Long, String> nicknameMap = senderIds.isEmpty()
? Collections.emptyMap()
: userRepository.findAllById(senderIds).stream()
.collect(Collectors.toMap(User::getId,
u -> (u.getNickname() != null && !u.getNickname().isBlank()) ? u.getNickname() : "이름 없음"));
List<NotificationDto> notificationDtos = combinedNotifications.stream()
.map(n -> {
String senderNickname = n.getSenderId() == null ? "시스템" : nicknameMap.getOrDefault(n.getSenderId(), "알 수 없는 사용자");
String message = generateNotificationMessage(n.getNotificationType(), senderNickname);
return NotificationDto.from(n, message);
})
References
  1. Implementation of edge cases, such as handling withdrawn users in queries, can be postponed.

.collect(Collectors.toList());

return NotificationListResponseDto.of(notificationDtos, unreadNotifications.size());
Expand Down
Loading