Skip to content

Commit 2ccc745

Browse files
committed
feat(notification): 알림 전체 읽음/삭제 및 테스트 푸시 기능 추가
- 사용자의 모든 알림을 읽음 처리하는 기능 추가 - 알림 soft delete 방식으로 삭제 기능 구현 - 삭제된 알림은 목록에서 제외되도록 조회 로직 수정 - 테스트용 알림 푸시 전송 API (/api/notifications/test-push) 추가
1 parent fe33838 commit 2ccc745

4 files changed

Lines changed: 69 additions & 3 deletions

File tree

src/main/java/com/project/Journey/notification/controller/NotificationController.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,32 @@ public void read(@PathVariable Long id) {
4444
public ResponseEntity<Long> countUnread(@AuthenticationPrincipal CustomUserDetails user) {
4545
return ResponseEntity.ok(notificationService.countUnread(user.getMember().getId()));
4646
}
47+
48+
@Operation(summary = "전체 알림 읽음 처리")
49+
@PatchMapping("/read-all")
50+
public ResponseEntity<Void> readAll(@AuthenticationPrincipal CustomUserDetails user) {
51+
notificationService.markAllRead(user.getMember().getId());
52+
return ResponseEntity.ok().build();
53+
}
54+
55+
@Operation(summary = "알림 삭제(soft delete)")
56+
@DeleteMapping("/{id}")
57+
public ResponseEntity<Void> delete(@PathVariable Long id,
58+
@AuthenticationPrincipal CustomUserDetails user) {
59+
notificationService.delete(id, user.getMember().getId());
60+
return ResponseEntity.noContent().build();
61+
}
62+
63+
@Operation(summary = "[테스트] 알림 푸시 전송", description = "알림 전송 테스트용 API입니다.")
64+
@PostMapping("/test-push")
65+
public void testPush(
66+
@AuthenticationPrincipal CustomUserDetails sender,
67+
@RequestParam Long receiverId,
68+
@RequestParam String type,
69+
@RequestParam String message,
70+
@RequestParam String link
71+
) {
72+
notificationService.testPush(sender.getMember(), receiverId, type, message, link);
73+
}
74+
4775
}

src/main/java/com/project/Journey/notification/entity/Notification.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ public class Notification {
4444
@Column(nullable = false, updatable = false)
4545
private LocalDateTime createdAt;
4646

47+
@Column(nullable = false)
48+
private boolean isDeleted = false;
49+
50+
public void delete() {
51+
this.isDeleted = true;
52+
}
53+
4754
@PrePersist
4855
void onCreate() {
4956
this.createdAt = LocalDateTime.now();

src/main/java/com/project/Journey/notification/repository/NotificationRepository.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
@Repository
1111
public interface NotificationRepository extends JpaRepository<Notification, Long> {
12-
List<Notification> findByReceiverOrderByCreatedAtDesc(Member receiver);
1312
long countByReceiverAndReadFalse(Member receiver);
13+
List<Notification> findByReceiverAndIsDeletedFalseOrderByCreatedAtDesc(Member receiver);
14+
List<Notification> findByReceiverAndReadFalseAndIsDeletedFalse(Member receiver);
15+
1416
}

src/main/java/com/project/Journey/notification/service/NotificationService.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,40 @@ public void push(Member receiver,
5252
@Transactional(readOnly = true)
5353
public List<NotificationDTO> list(Long receiverId) {
5454
Member proxy = em.getReference(Member.class, receiverId);
55-
return notificationRepository.findByReceiverOrderByCreatedAtDesc(proxy)
56-
.stream().map(NotificationDTO::from).toList();
55+
return notificationRepository
56+
.findByReceiverAndIsDeletedFalseOrderByCreatedAtDesc(proxy)
57+
.stream()
58+
.map(NotificationDTO::from)
59+
.toList();
5760
}
5861

5962
public void markRead(Long id) {
6063
notificationRepository.findById(id).ifPresent(Notification::markAsRead);
6164
}
65+
66+
public void markAllRead(Long receiverId) {
67+
Member proxy = em.getReference(Member.class, receiverId);
68+
List<Notification> notifications = notificationRepository.findByReceiverAndReadFalseAndIsDeletedFalse(proxy);
69+
notifications.forEach(Notification::markAsRead);
70+
}
71+
72+
public void delete(Long id, Long receiverId) {
73+
Notification notification = notificationRepository.findById(id)
74+
.orElseThrow(() -> new IllegalArgumentException("알림이 존재하지 않습니다"));
75+
76+
if (!notification.getReceiver().getId().equals(receiverId)) {
77+
throw new IllegalStateException("삭제 권한이 없습니다");
78+
}
79+
80+
notification.delete();
81+
}
82+
83+
// 클라 테스트용
84+
public void testPush(Member sender, Long receiverId, String type, String message, String link) {
85+
Member receiver = em.getReference(Member.class, receiverId);
86+
87+
NotificationType notificationType = NotificationType.valueOf(type.toUpperCase());
88+
89+
push(receiver, sender, notificationType, message, link);
90+
}
6291
}

0 commit comments

Comments
 (0)