Skip to content

Commit 7c6de34

Browse files
authored
[�REFACTOR] �유저 테이블에 알맞게 알림 로직 수정 (#347)
* refactor: userId 어노테이션 수정 * feat(notification): repository 계층에서 read, unread 구분하지 않기 * feat(notification): 복수형 정적 팩토리 메서드 * test(notification): 변경 로직에 따라서 테스트 수정 * test(notification): 알림 쿼리 서비스 세분화 * test(notification): 쿼리 서비스 의존성 주입
1 parent 5b50d7d commit 7c6de34

File tree

11 files changed

+58
-77
lines changed

11 files changed

+58
-77
lines changed

src/main/java/com/somemore/domains/notification/controller/NotificationCommandController.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import com.somemore.domains.notification.dto.NotificationIdsRequestDto;
44
import com.somemore.domains.notification.usecase.NotificationCommandUseCase;
5-
import com.somemore.global.auth.annotation.CurrentUser;
5+
import com.somemore.global.auth.annotation.UserId;
66
import com.somemore.global.common.response.ApiResponse;
77
import io.swagger.v3.oas.annotations.Operation;
88
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -29,7 +29,7 @@ public class NotificationCommandController {
2929
@Operation(summary = "알림(1개) 읽음 처리", description = "알림 1개를 읽음 처리합니다.")
3030
@PatchMapping("/read/{notificationId}")
3131
public ApiResponse<String> markSingleNotification(
32-
@CurrentUser UUID userId,
32+
@UserId UUID userId,
3333
@PathVariable Long notificationId
3434
) {
3535
notificationCommandUseCase.markSingleNotificationAsRead(userId, notificationId);
@@ -40,7 +40,7 @@ public ApiResponse<String> markSingleNotification(
4040
@Operation(summary = "알림(N개) 읽음 처리", description = "알림 N개를 읽음 처리합니다.")
4141
@PostMapping("/read/multiple")
4242
public ApiResponse<String> markMultipleNotifications(
43-
@CurrentUser UUID userId,
43+
@UserId UUID userId,
4444
@RequestBody NotificationIdsRequestDto notificationIds
4545
) {
4646
notificationCommandUseCase.markMultipleNotificationsAsRead(userId, notificationIds);

src/main/java/com/somemore/domains/notification/dto/NotificationResponseDto.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import io.swagger.v3.oas.annotations.media.Schema;
88

99
import java.time.LocalDateTime;
10+
import java.util.List;
1011

1112
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
1213
@Schema(description = "알림 응답 DTO")
@@ -34,4 +35,10 @@ public static NotificationResponseDto from(Notification notification) {
3435
notification.getCreatedAt()
3536
);
3637
}
38+
39+
public static List<NotificationResponseDto> from(List<Notification> notifications) {
40+
return notifications.stream()
41+
.map(NotificationResponseDto::from)
42+
.toList();
43+
}
3744
}

src/main/java/com/somemore/domains/notification/repository/NotificationJpaRepository.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,9 @@
33
import com.somemore.domains.notification.domain.Notification;
44
import org.springframework.data.jpa.repository.JpaRepository;
55

6+
import java.util.List;
7+
import java.util.UUID;
8+
69
public interface NotificationJpaRepository extends JpaRepository<Notification, Long> {
10+
List<Notification> findAllByReceiverId(UUID receiverId);
711
}

src/main/java/com/somemore/domains/notification/repository/NotificationRepository.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ public interface NotificationRepository {
1616

1717
List<Notification> findAllByIds(List<Long> ids);
1818

19-
List<Notification> findByReceiverIdAndUnread(UUID userId);
20-
21-
List<Notification> findByReceiverIdAndRead(UUID userId);
19+
List<Notification> findAllByUserId(UUID userId);
2220

2321
void deleteAllInBatch();
2422
}
Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package com.somemore.domains.notification.repository;
22

3-
import com.querydsl.core.types.dsl.BooleanExpression;
4-
import com.querydsl.jpa.impl.JPAQueryFactory;
53
import com.somemore.domains.notification.domain.Notification;
6-
import com.somemore.domains.notification.domain.QNotification;
74
import lombok.RequiredArgsConstructor;
85
import org.springframework.stereotype.Repository;
96

@@ -16,9 +13,6 @@
1613
public class NotificationRepositoryImpl implements NotificationRepository {
1714

1815
private final NotificationJpaRepository notificationJpaRepository;
19-
private final JPAQueryFactory queryFactory;
20-
21-
private static final QNotification notification = QNotification.notification;
2216

2317
@Override
2418
public Notification save(Notification notification) {
@@ -36,35 +30,12 @@ public List<Notification> findAllByIds(List<Long> ids) {
3630
}
3731

3832
@Override
39-
public List<Notification> findByReceiverIdAndUnread(UUID receiverId) {
40-
return queryFactory.selectFrom(notification)
41-
.where(eqReceiverId(receiverId),
42-
isUnread())
43-
.fetch();
44-
}
45-
46-
@Override
47-
public List<Notification> findByReceiverIdAndRead(UUID receiverId) {
48-
return queryFactory.selectFrom(notification)
49-
.where(eqReceiverId(receiverId),
50-
isRead())
51-
.fetch();
33+
public List<Notification> findAllByUserId(UUID receiverId) {
34+
return notificationJpaRepository.findAllByReceiverId(receiverId);
5235
}
5336

5437
@Override
5538
public void deleteAllInBatch() {
5639
notificationJpaRepository.deleteAllInBatch();
5740
}
58-
59-
private static BooleanExpression eqReceiverId(UUID userId) {
60-
return notification.receiverId.eq(userId);
61-
}
62-
63-
private static BooleanExpression isUnread() {
64-
return notification.read.eq(false);
65-
}
66-
67-
private static BooleanExpression isRead() {
68-
return notification.read.eq(true);
69-
}
7041
}

src/main/java/com/somemore/domains/notification/service/NotificationCommandService.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import com.somemore.domains.notification.domain.Notification;
44
import com.somemore.domains.notification.dto.NotificationIdsRequestDto;
5-
import com.somemore.domains.notification.repository.NotificationRepository;
65
import com.somemore.domains.notification.usecase.NotificationCommandUseCase;
6+
import com.somemore.domains.notification.usecase.NotificationQueryUseCase;
77
import com.somemore.global.exception.BadRequestException;
88
import lombok.RequiredArgsConstructor;
99
import lombok.extern.slf4j.Slf4j;
@@ -13,7 +13,6 @@
1313
import java.util.List;
1414
import java.util.UUID;
1515

16-
import static com.somemore.global.exception.ExceptionMessage.NOT_EXISTS_NOTIFICATION;
1716
import static com.somemore.global.exception.ExceptionMessage.UNAUTHORIZED_NOTIFICATION;
1817

1918
@Slf4j
@@ -22,12 +21,11 @@
2221
@Transactional
2322
public class NotificationCommandService implements NotificationCommandUseCase {
2423

25-
private final NotificationRepository notificationRepository;
24+
private final NotificationQueryUseCase notificationQueryUseCase;
2625

2726
@Override
2827
public void markSingleNotificationAsRead(UUID userId, Long notificationId) {
29-
Notification notification = notificationRepository.findById(notificationId)
30-
.orElseThrow(() -> new BadRequestException(NOT_EXISTS_NOTIFICATION));
28+
Notification notification = notificationQueryUseCase.getNotification(notificationId);
3129

3230
validateNotificationOwnership(userId, notification.getReceiverId());
3331

@@ -36,7 +34,7 @@ public void markSingleNotificationAsRead(UUID userId, Long notificationId) {
3634

3735
@Override
3836
public void markMultipleNotificationsAsRead(UUID userId, NotificationIdsRequestDto notificationIds) {
39-
List<Notification> notifications = notificationRepository.findAllByIds(notificationIds.ids());
37+
List<Notification> notifications = notificationQueryUseCase.getNotifications(notificationIds.ids());
4038

4139
notifications.forEach(notification ->
4240
validateNotificationOwnership(userId, notification.getReceiverId()));

src/main/java/com/somemore/domains/notification/service/NotificationQueryService.java

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
import com.somemore.domains.notification.dto.NotificationResponseDto;
55
import com.somemore.domains.notification.repository.NotificationRepository;
66
import com.somemore.domains.notification.usecase.NotificationQueryUseCase;
7+
import com.somemore.global.exception.ExceptionMessage;
8+
import com.somemore.global.exception.NoSuchElementException;
79
import lombok.RequiredArgsConstructor;
810
import lombok.extern.slf4j.Slf4j;
911
import org.springframework.stereotype.Service;
1012
import org.springframework.transaction.annotation.Transactional;
1113

1214
import java.util.List;
1315
import java.util.UUID;
16+
import java.util.function.Predicate;
1417

1518
@Slf4j
1619
@Service
@@ -21,20 +24,34 @@ public class NotificationQueryService implements NotificationQueryUseCase {
2124
private final NotificationRepository notificationRepository;
2225

2326
@Override
24-
public List<NotificationResponseDto> getUnreadNotifications(UUID userId) {
25-
List<Notification> notifications = notificationRepository.findByReceiverIdAndUnread(userId);
26-
return dtoFrom(notifications);
27+
public Notification getNotification(Long id) {
28+
return notificationRepository.findById(id)
29+
.orElseThrow(() -> new NoSuchElementException(ExceptionMessage.NOT_EXISTS_NOTIFICATION));
2730
}
2831

2932
@Override
30-
public List<NotificationResponseDto> getReadNotifications(UUID userId) {
31-
List<Notification> notifications = notificationRepository.findByReceiverIdAndRead(userId);
32-
return dtoFrom(notifications);
33+
public List<Notification> getNotifications(UUID userId) {
34+
return notificationRepository.findAllByUserId(userId);
35+
}
36+
37+
@Override
38+
public List<Notification> getNotifications(List<Long> ids) {
39+
return notificationRepository.findAllByIds(ids);
40+
}
41+
42+
@Override
43+
public List<NotificationResponseDto> getUnreadNotifications(UUID userId) {
44+
List<Notification> notifications = getNotifications(userId).stream()
45+
.filter(Predicate.not(Notification::isRead))
46+
.toList();
47+
return NotificationResponseDto.from(notifications);
3348
}
3449

35-
private static List<NotificationResponseDto> dtoFrom(List<Notification> notifications) {
36-
return notifications.stream()
37-
.map(NotificationResponseDto::from)
50+
@Override
51+
public List<NotificationResponseDto> getReadNotifications(UUID userId) {
52+
List<Notification> notifications = getNotifications(userId).stream()
53+
.filter(Notification::isRead)
3854
.toList();
55+
return NotificationResponseDto.from(notifications);
3956
}
4057
}

src/main/java/com/somemore/domains/notification/usecase/NotificationQueryUseCase.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
package com.somemore.domains.notification.usecase;
22

3+
import com.somemore.domains.notification.domain.Notification;
34
import com.somemore.domains.notification.dto.NotificationResponseDto;
45

56
import java.util.List;
67
import java.util.UUID;
78

89
public interface NotificationQueryUseCase {
910

11+
Notification getNotification(Long id);
12+
13+
List<Notification> getNotifications(UUID userId);
14+
15+
List<Notification> getNotifications(List<Long> ids);
16+
1017
List<NotificationResponseDto> getUnreadNotifications(UUID userId);
1118

1219
List<NotificationResponseDto> getReadNotifications(UUID userId);

src/test/java/com/somemore/domains/notification/handler/NotificationHandlerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void handle() {
5353
notificationHandler.handle(notification);
5454

5555
// then
56-
List<Notification> notifications = notificationRepository.findByReceiverIdAndUnread(receiverId);
56+
List<Notification> notifications = notificationRepository.findAllByUserId(receiverId);
5757
assertThat(notifications).hasSize(1);
5858

5959
Notification savedNotification = notifications.getFirst();

src/test/java/com/somemore/domains/notification/repository/NotificationRepositoryTest.java

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,36 +42,14 @@ void setup() {
4242
}
4343
}
4444

45-
@DisplayName("사용자의 읽지 않은 알림을 조회한다.")
46-
@Test
47-
void findByReceiverIdAndUnread() {
48-
// when
49-
List<Notification> notifications = notificationRepository.findByReceiverIdAndUnread(receiverId);
50-
51-
// then
52-
assertThat(notifications).hasSize(10);
53-
assertThat(notifications.getFirst().isRead()).isFalse();
54-
}
55-
56-
@DisplayName("사용자의 읽은 알림을 조회한다.")
57-
@Test
58-
void findByReceiverIdAndRead() {
59-
// when
60-
List<Notification> notifications = notificationRepository.findByReceiverIdAndRead(receiverId);
61-
62-
// then
63-
assertThat(notifications).hasSize(10);
64-
assertThat(notifications.getFirst().isRead()).isTrue();
65-
}
66-
6745
@DisplayName("알림이 없는 사용자의 읽지 않은 알림을 조회하면 빈 리스트를 반환한다.")
6846
@Test
6947
void findByReceiverIdAndUnread_noNotifications() {
7048
// given
7149
UUID unknownReceiverId = UUID.randomUUID();
7250

7351
// when
74-
List<Notification> notifications = notificationRepository.findByReceiverIdAndUnread(unknownReceiverId);
52+
List<Notification> notifications = notificationRepository.findAllByUserId(unknownReceiverId);
7553

7654
// then
7755
assertThat(notifications).isEmpty();

0 commit comments

Comments
 (0)