Skip to content

Commit ff26cb4

Browse files
authored
Merge pull request #197 from Hrr-HabbitRoutineResult/feat/196-notification-response-fields
[Feat] 알림 목록 조회 API 응답 필드 추가 및 변환 로직 개선
2 parents c5e9b7b + 3b12999 commit ff26cb4

File tree

3 files changed

+70
-20
lines changed

3 files changed

+70
-20
lines changed

src/main/java/com/hrr/backend/domain/notification/converter/NotificationConverter.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,56 @@
11
package com.hrr.backend.domain.notification.converter;
22

33
import com.hrr.backend.domain.notification.dto.NotificationResponseDto;
4+
import com.hrr.backend.domain.notification.entity.NotificationDelivery;
5+
import com.hrr.backend.domain.notification.entity.NotificationEvent;
46
import com.hrr.backend.domain.notification.entity.NotificationSetting;
7+
import com.hrr.backend.global.exception.GlobalException;
8+
import com.hrr.backend.global.response.ErrorCode;
9+
import lombok.extern.slf4j.Slf4j;
510
import org.springframework.stereotype.Component;
611

12+
@Slf4j
713
@Component
814
public class NotificationConverter {
915

16+
// 알림 목록 정보 DTO 변환
17+
public NotificationResponseDto.InfoDto toInfoDto(NotificationDelivery delivery, String imageUrl) {
18+
// 전달받은 배달 객체가 null인 경우
19+
if (delivery == null) {
20+
log.error("[Critical] NotificationDelivery is null during conversion process");
21+
throw new GlobalException(ErrorCode._INTERNAL_SERVER_ERROR);
22+
}
23+
24+
NotificationEvent event = delivery.getEvent();
25+
26+
// 연결된 이벤트 정보가 없는 경우
27+
if (event == null) {
28+
log.error("[Data Integrity Error] NotificationDelivery(ID: {}) has no associated NotificationEvent", delivery.getId());
29+
throw new GlobalException(ErrorCode._INTERNAL_SERVER_ERROR);
30+
}
31+
32+
// 알림 타입이 없는 경우
33+
if (event.getType() == null) {
34+
log.error("[Data Integrity Error] NotificationEvent(ID: {}) has no associated NotificationType", event.getId());
35+
throw new GlobalException(ErrorCode._INTERNAL_SERVER_ERROR);
36+
}
37+
38+
return NotificationResponseDto.InfoDto.builder()
39+
.id(delivery.getId())
40+
.title(event.getTitle())
41+
.message(event.getMessage())
42+
.imageUrl(imageUrl)
43+
.category(event.getCategory())
44+
.type(event.getType().getTypeName())
45+
.targetType(event.getTargetType())
46+
.targetId(event.getTargetId())
47+
.contextType(event.getContextType())
48+
.contextId(event.getContextId())
49+
.isRead(delivery.getIsRead())
50+
.createdAt(delivery.getCreatedAt())
51+
.build();
52+
}
53+
1054
public NotificationResponseDto.SettingInfoDto toSettingInfoDto(NotificationSetting setting) {
1155
return NotificationResponseDto.SettingInfoDto.builder()
1256
.isAllPaused(setting.isAllPaused())

src/main/java/com/hrr/backend/domain/notification/dto/NotificationResponseDto.java

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.hrr.backend.domain.notification.entity.NotificationDelivery;
44
import com.hrr.backend.domain.notification.entity.NotificationEvent;
55
import com.hrr.backend.domain.notification.entity.enums.NotificationCategory;
6+
import com.hrr.backend.domain.notification.entity.enums.NotificationTypeName;
7+
import com.hrr.backend.domain.notification.entity.enums.ResourceType;
68
import io.swagger.v3.oas.annotations.media.Schema;
79
import lombok.*;
810

@@ -16,7 +18,7 @@ public class NotificationResponseDto {
1618
@AllArgsConstructor
1719
@Schema(description = "알림 목록 정보 DTO")
1820
public static class InfoDto {
19-
@Schema(description = "알림 배달 ID", example = "1")
21+
@Schema(description = "알림 ID", example = "1")
2022
private Long id;
2123

2224
@Schema(description = "알림 제목", example = "내 인증에 댓글이 달렸어요")
@@ -25,34 +27,32 @@ public static class InfoDto {
2527
@Schema(description = "알림 메시지", example = "어 저랑 같은 문제 풀었는데...")
2628
private String message;
2729

30+
@Schema(description = "알림 썸네일 이미지 URL", example = "https://example/image.jpg")
31+
private String imageUrl;
32+
2833
@Schema(description = "알림 카테고리", example = "VERIFICATION")
2934
private NotificationCategory category;
3035

31-
@Schema(description = "이동 대상 타입", example = "COMMENT")
32-
private String targetType;
36+
@Schema(description = "알림 상세 타입 (프론트 분기 처리용)", example = "CHALLENGE_EXTENSION")
37+
private NotificationTypeName type;
38+
39+
@Schema(description = "이동 대상 타입", example = "CHALLENGE")
40+
private ResourceType targetType;
3341

34-
@Schema(description = "이동 대상 ID", example = "501")
42+
@Schema(description = "이동 대상 ID", example = "2")
3543
private Long targetId;
3644

45+
@Schema(description = "추가 컨텍스트 타입", example = "ROUND")
46+
private ResourceType contextType;
47+
48+
@Schema(description = "추가 컨텍스트 ID", example = "3")
49+
private Long contextId;
50+
3751
@Schema(description = "읽음 여부 (true: 읽음, false: 안읽음-NEW)", example = "false")
3852
private Boolean isRead;
3953

4054
@Schema(description = "알림 발생 시간", example = "2025-12-25T14:30:00")
4155
private LocalDateTime createdAt;
42-
43-
public static InfoDto from(NotificationDelivery delivery) {
44-
NotificationEvent event = delivery.getEvent();
45-
return InfoDto.builder()
46-
.id(delivery.getId())
47-
.title(event.getTitle())
48-
.message(event.getMessage())
49-
.category(event.getCategory())
50-
.targetType(event.getTargetType().name())
51-
.targetId(event.getTargetId())
52-
.isRead(delivery.getIsRead())
53-
.createdAt(delivery.getCreatedAt())
54-
.build();
55-
}
5656
}
5757

5858
@Getter
@@ -62,7 +62,7 @@ public static InfoDto from(NotificationDelivery delivery) {
6262
@Schema(description = "알림 읽음 처리 결과 DTO")
6363
public static class ReadResultDto {
6464

65-
@Schema(description = "알림 배달 ID", example = "1")
65+
@Schema(description = "알림 ID", example = "1")
6666
private Long notificationId;
6767

6868
@Schema(description = "읽음 여부", example = "true")

src/main/java/com/hrr/backend/domain/notification/service/NotificationServiceImpl.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.hrr.backend.global.exception.GlobalException;
1313
import com.hrr.backend.global.response.ErrorCode;
1414
import com.hrr.backend.global.response.SliceResponseDto;
15+
import com.hrr.backend.global.s3.S3UrlUtil;
1516
import lombok.RequiredArgsConstructor;
1617
import org.springframework.data.domain.PageRequest;
1718
import org.springframework.data.domain.Pageable;
@@ -28,6 +29,8 @@ public class NotificationServiceImpl implements NotificationService {
2829
private final NotificationSettingRepository notificationSettingRepository;
2930
private final NotificationConverter notificationConverter;
3031

32+
private final S3UrlUtil s3UrlUtil;
33+
3134
@Override
3235
public SliceResponseDto<NotificationResponseDto.InfoDto> getNotificationList(
3336
User user, NotificationCategory category, int page, int size) {
@@ -41,7 +44,10 @@ public SliceResponseDto<NotificationResponseDto.InfoDto> getNotificationList(
4144

4245
// Slice 내부의 엔티티를 DTO로 변환
4346
Slice<NotificationResponseDto.InfoDto> dtoSlice = deliverySlice
44-
.map(NotificationResponseDto.InfoDto::from);
47+
.map(delivery -> {
48+
String fullUrl = s3UrlUtil.toFullUrl(delivery.getEvent().getImageKey());
49+
return notificationConverter.toInfoDto(delivery, fullUrl);
50+
});
4551

4652
return new SliceResponseDto<>(dtoSlice);
4753
}

0 commit comments

Comments
 (0)