Skip to content

Commit d89057f

Browse files
jueunk617namgigun
authored andcommitted
Fix: 와이어프레임 확인 후 status 제거 / actor 추가 작업
1 parent 58f4b3e commit d89057f

13 files changed

+195
-167
lines changed

src/main/java/com/back/domain/notification/controller/NotificationController.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,36 +46,58 @@ public ResponseEntity<RsData<NotificationResponse>> createNotification(
4646

4747
Notification notification = switch (request.targetType()) {
4848
case "USER" -> {
49-
User targetUser = userRepository.findById(request.targetId())
49+
// 수신자 조회
50+
User receiver = userRepository.findById(request.targetId())
5051
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));
52+
53+
// 발신자 조회
54+
User actor = userRepository.findById(request.actorId())
55+
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));
56+
5157
yield notificationService.createPersonalNotification(
52-
targetUser,
58+
receiver,
59+
actor,
5360
request.title(),
5461
request.message(),
5562
request.redirectUrl()
5663
);
5764
}
5865
case "ROOM" -> {
66+
// 스터디룸 조회
5967
Room room = roomRepository.findById(request.targetId())
6068
.orElseThrow(() -> new CustomException(ErrorCode.ROOM_NOT_FOUND));
69+
70+
// 발신자 조회
71+
User actor = userRepository.findById(request.actorId())
72+
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));
73+
6174
yield notificationService.createRoomNotification(
6275
room,
76+
actor,
6377
request.title(),
6478
request.message(),
6579
request.redirectUrl()
6680
);
6781
}
6882
case "COMMUNITY" -> {
69-
User targetUser = userRepository.findById(request.targetId())
83+
// 수신자 조회 (리뷰/게시글 작성자)
84+
User receiver = userRepository.findById(request.targetId())
85+
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));
86+
87+
// 발신자 조회 (댓글/좋아요 작성자)
88+
User actor = userRepository.findById(request.actorId())
7089
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));
90+
7191
yield notificationService.createCommunityNotification(
72-
targetUser,
92+
receiver,
93+
actor,
7394
request.title(),
7495
request.message(),
7596
request.redirectUrl()
7697
);
7798
}
7899
case "SYSTEM" -> {
100+
// 시스템 알림은 발신자 없음
79101
yield notificationService.createSystemNotification(
80102
request.title(),
81103
request.message(),
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.back.domain.notification.dto;
2+
3+
import com.back.domain.user.entity.User;
4+
5+
public record ActorDto(
6+
Long userId,
7+
String username,
8+
String profileImageUrl
9+
) {
10+
public static ActorDto from(User user) {
11+
if (user == null) return null;
12+
return new ActorDto(
13+
user.getId(),
14+
user.getNickname(),
15+
user.getProfileImageUrl()
16+
);
17+
}
18+
}
Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
package com.back.domain.notification.dto;
22

33
public record NotificationCreateRequest(
4-
String targetType, // USER, ROOM, SYSTEM
5-
Long targetId, // nullable (SYSTEM일 때 null)
4+
String targetType,
5+
Long targetId,
6+
Long actorId,
67
String title,
78
String message,
8-
String notificationType, // STUDY_REMINDER, ROOM_JOIN 등
9-
String redirectUrl, // targetUrl
10-
String scheduleType, // ONE_TIME (향후 확장용)
11-
String scheduledAt // 예약 시간 (향후 확장용)
12-
) {
13-
}
9+
String redirectUrl
10+
) {}

src/main/java/com/back/domain/notification/dto/NotificationItemDto.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public record NotificationItemDto(
1515
NotificationType notificationType,
1616
String targetUrl,
1717
boolean isRead,
18+
ActorDto actor,
1819
LocalDateTime createdAt
1920
) {
2021
public static NotificationItemDto from(Notification notification, boolean isRead) {
@@ -25,6 +26,7 @@ public static NotificationItemDto from(Notification notification, boolean isRead
2526
notification.getType(),
2627
notification.getTargetUrl(),
2728
isRead,
29+
ActorDto.from(notification.getActor()),
2830
notification.getCreatedAt()
2931
);
3032
}

src/main/java/com/back/domain/notification/dto/NotificationListResponse.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ public record NotificationListResponse(
1515
long unreadCount
1616
) {
1717

18-
// 페이지 정보 DTO
1918
public record PageableDto(
2019
int page,
2120
int size,

src/main/java/com/back/domain/notification/dto/NotificationResponse.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import java.time.LocalDateTime;
77

88
/**
9-
* 알림 응답 DTO
9+
* 알림 상세 응답 DTO
1010
*/
1111
public record NotificationResponse(
1212
Long notificationId,
@@ -15,6 +15,7 @@ public record NotificationResponse(
1515
NotificationType notificationType,
1616
String targetUrl,
1717
boolean isRead,
18+
ActorDto actor,
1819
LocalDateTime createdAt,
1920
LocalDateTime readAt
2021
) {
@@ -25,9 +26,10 @@ public static NotificationResponse from(Notification notification) {
2526
notification.getContent(),
2627
notification.getType(),
2728
notification.getTargetUrl(),
28-
false, // 읽음 여부는 NotificationListResponse에서 처리
29+
false,
30+
ActorDto.from(notification.getActor()),
2931
notification.getCreatedAt(),
30-
null // readAt은 NotificationRead에서 가져와야 함
32+
null
3133
);
3234
}
3335

@@ -39,6 +41,7 @@ public static NotificationResponse from(Notification notification, boolean isRea
3941
notification.getType(),
4042
notification.getTargetUrl(),
4143
isRead,
44+
ActorDto.from(notification.getActor()),
4245
notification.getCreatedAt(),
4346
readAt
4447
);
Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.back.domain.notification.dto;
22

3+
import com.back.domain.notification.entity.Notification;
34
import com.back.domain.notification.entity.NotificationType;
45

56
import java.time.LocalDateTime;
@@ -10,24 +11,18 @@ public record NotificationWebSocketDto(
1011
String message,
1112
NotificationType notificationType,
1213
String targetUrl,
14+
ActorDto actor,
1315
LocalDateTime createdAt
1416
) {
15-
16-
public static NotificationWebSocketDto from(
17-
Long notificationId,
18-
String title,
19-
String content,
20-
NotificationType type,
21-
String targetUrl,
22-
LocalDateTime createdAt) {
23-
17+
public static NotificationWebSocketDto from(Notification notification) {
2418
return new NotificationWebSocketDto(
25-
notificationId,
26-
title,
27-
content,
28-
type,
29-
targetUrl,
30-
createdAt
19+
notification.getId(),
20+
notification.getTitle(),
21+
notification.getContent(),
22+
notification.getType(),
23+
notification.getTargetUrl(),
24+
ActorDto.from(notification.getActor()),
25+
notification.getCreatedAt()
3126
);
3227
}
3328
}

src/main/java/com/back/domain/notification/entity/Notification.java

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,22 @@ public class Notification extends BaseEntity {
2020
private NotificationType type;
2121

2222
@ManyToOne(fetch = FetchType.LAZY)
23-
@JoinColumn(name = "user_id")
24-
private User user;
23+
@JoinColumn(name = "receiver_id")
24+
private User receiver; // 수신자 (누가 받는지)
25+
26+
@ManyToOne(fetch = FetchType.LAZY)
27+
@JoinColumn(name = "actor_id")
28+
private User actor; // 발신자 (누가 이 활동을 했는지)
2529

2630
@ManyToOne(fetch = FetchType.LAZY)
2731
@JoinColumn(name = "room_id")
2832
private Room room;
2933

3034
@Column(nullable = false)
31-
private String title;
32-
33-
@Column(columnDefinition = "TEXT", nullable = false)
34-
private String content;
35+
private String title; // 알림 제목 (필수)
3536

36-
@Enumerated(EnumType.STRING)
37-
@Column(nullable = false)
38-
private NotificationStatus status;
37+
@Column(columnDefinition = "TEXT")
38+
private String content; // 알림 본문 또는 댓글 미리보기 (선택)
3939

4040
private String targetUrl;
4141

@@ -47,40 +47,55 @@ private Notification(NotificationType type, String title, String content, String
4747
this.title = title;
4848
this.content = content;
4949
this.targetUrl = targetUrl;
50-
this.status = NotificationStatus.UNREAD;
5150
}
5251

5352
// 개인 알림 생성
54-
public static Notification createPersonalNotification(User user, String title, String content, String targetUrl) {
53+
public static Notification createPersonalNotification(
54+
User receiver,
55+
User actor,
56+
String title,
57+
String content,
58+
String targetUrl) {
5559
Notification notification = new Notification(NotificationType.PERSONAL, title, content, targetUrl);
56-
notification.user = user;
60+
notification.receiver = receiver;
61+
notification.actor = actor;
5762
return notification;
5863
}
5964

6065
// 스터디룸 알림 생성
61-
public static Notification createRoomNotification(Room room, String title, String content, String targetUrl) {
66+
public static Notification createRoomNotification(
67+
Room room,
68+
User actor,
69+
String title,
70+
String content,
71+
String targetUrl) {
6272
Notification notification = new Notification(NotificationType.ROOM, title, content, targetUrl);
6373
notification.room = room;
74+
notification.actor = actor;
6475
return notification;
6576
}
6677

67-
// 시스템 알림 생성
68-
public static Notification createSystemNotification(String title, String content, String targetUrl) {
78+
// 시스템 알림 생성 (발신자 없음, 모두에게 전달)
79+
public static Notification createSystemNotification(
80+
String title,
81+
String content,
82+
String targetUrl) {
6983
return new Notification(NotificationType.SYSTEM, title, content, targetUrl);
7084
}
7185

72-
// 커뮤니티 알림 생성
73-
public static Notification createCommunityNotification(User user, String title, String content, String targetUrl) {
86+
// 커뮤니티 알림 생성 (댓글, 좋아요 등)
87+
public static Notification createCommunityNotification(
88+
User receiver, // 수신자 (게시글 작성자)
89+
User actor, // 발신자 (댓글 작성자)
90+
String title,
91+
String content,
92+
String targetUrl) {
7493
Notification notification = new Notification(NotificationType.COMMUNITY, title, content, targetUrl);
75-
notification.user = user;
94+
notification.receiver = receiver;
95+
notification.actor = actor;
7696
return notification;
7797
}
7898

79-
// 알림을 읽음 상태로 변경
80-
public void markAsRead() {
81-
this.status = NotificationStatus.READ;
82-
}
83-
8499
// 전체 알림인지 확인
85100
public boolean isSystemNotification() {
86101
return this.type == NotificationType.SYSTEM;
@@ -93,13 +108,18 @@ public boolean isPersonalNotification() {
93108

94109
// 특정 유저에게 표시되어야 하는 알림인지 확인
95110
public boolean isVisibleToUser(Long userId) {
96-
97111
// 시스템 알림은 모두에게 표시
98112
if (isSystemNotification()) {
99113
return true;
100114
}
101115

102-
// 개인 알림은 해당 유저에게만 표시
103-
return user != null && user.getId().equals(userId);
116+
// 개인/커뮤니티 알림은 수신자에게만 표시
117+
return receiver != null && receiver.getId().equals(userId);
118+
}
119+
120+
// 특정 유저가 이 알림을 읽었는지 확인
121+
public boolean isReadBy(Long userId) {
122+
return notificationReads.stream()
123+
.anyMatch(read -> read.getUser().getId().equals(userId));
104124
}
105125
}

src/main/java/com/back/domain/notification/entity/NotificationStatus.java

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/main/java/com/back/domain/notification/repository/NotificationRepository.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
import java.util.List;
1010

1111
public interface NotificationRepository extends JpaRepository<Notification, Long>, NotificationRepositoryCustom {
12+
// 특정 스터디룸의 알림 조회
1213
Page<Notification> findByRoomIdOrderByCreatedAtDesc(Long roomId, Pageable pageable);
14+
15+
// 특정 타입의 알림 조회
1316
List<Notification> findByType(NotificationType type);
1417
}

0 commit comments

Comments
 (0)