diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/notification/CountNotificationResponse.java b/src/main/java/clap/server/adapter/inbound/web/dto/notification/CountNotificationResponse.java new file mode 100644 index 00000000..0c9eba0b --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/dto/notification/CountNotificationResponse.java @@ -0,0 +1,7 @@ +package clap.server.adapter.inbound.web.dto.notification; + +public record CountNotificationResponse( + Long memberId, + Integer count +) { +} diff --git a/src/main/java/clap/server/adapter/inbound/web/notification/FindNotificationController.java b/src/main/java/clap/server/adapter/inbound/web/notification/FindNotificationController.java index 5dfc9b59..1feb38ed 100644 --- a/src/main/java/clap/server/adapter/inbound/web/notification/FindNotificationController.java +++ b/src/main/java/clap/server/adapter/inbound/web/notification/FindNotificationController.java @@ -2,7 +2,9 @@ import clap.server.adapter.inbound.security.SecurityUserDetails; import clap.server.adapter.inbound.web.dto.common.SliceResponse; +import clap.server.adapter.inbound.web.dto.notification.CountNotificationResponse; import clap.server.adapter.inbound.web.dto.notification.FindNotificationListResponse; +import clap.server.application.port.inbound.notification.CountNotificationUseCase; import clap.server.application.port.inbound.notification.FindNotificationListUsecase; import clap.server.common.annotation.architecture.WebAdapter; import io.swagger.v3.oas.annotations.Operation; @@ -27,6 +29,7 @@ public class FindNotificationController { private final FindNotificationListUsecase findNotificationListUsecase; + private final CountNotificationUseCase countNotificationUseCase; @Operation(summary = "알림 목록 조회 API") @Parameters({ @@ -41,4 +44,11 @@ public ResponseEntity> findNotificat Pageable pageable = PageRequest.of(page, size); return ResponseEntity.ok(findNotificationListUsecase.findNotificationList(securityUserDetails.getUserId(), pageable)); } + + @Operation(summary = "미확인 알림 개수 조회 API") + @GetMapping("/count") + public ResponseEntity countNotification( + @AuthenticationPrincipal SecurityUserDetails userInfo) { + return ResponseEntity.ok(countNotificationUseCase.countNotification(userInfo.getUserId())); + } } diff --git a/src/main/java/clap/server/adapter/outbound/persistense/NotificationPersistenceAdapter.java b/src/main/java/clap/server/adapter/outbound/persistense/NotificationPersistenceAdapter.java index b7330bd0..6df83e81 100644 --- a/src/main/java/clap/server/adapter/outbound/persistense/NotificationPersistenceAdapter.java +++ b/src/main/java/clap/server/adapter/outbound/persistense/NotificationPersistenceAdapter.java @@ -49,6 +49,11 @@ public List findNotificationsByMemberId(Long memberId) { .collect(Collectors.toList()); } + @Override + public Integer countNotification(Long memberId) { + return notificationRepository.countByIsReadFalseAndReceiver_MemberId(memberId); + } + @Override public void save(Notification notification) { notificationRepository.save(notificationPersistenceMapper.toEntity(notification)); diff --git a/src/main/java/clap/server/adapter/outbound/persistense/repository/notification/NotificationRepository.java b/src/main/java/clap/server/adapter/outbound/persistense/repository/notification/NotificationRepository.java index 0239cd44..e4462dd5 100644 --- a/src/main/java/clap/server/adapter/outbound/persistense/repository/notification/NotificationRepository.java +++ b/src/main/java/clap/server/adapter/outbound/persistense/repository/notification/NotificationRepository.java @@ -1,5 +1,6 @@ package clap.server.adapter.outbound.persistense.repository.notification; +import clap.server.adapter.outbound.persistense.entity.member.MemberEntity; import clap.server.adapter.outbound.persistense.entity.notification.NotificationEntity; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; @@ -15,4 +16,6 @@ public interface NotificationRepository extends JpaRepository findAllByReceiver_MemberIdOrderByCreatedAtDesc(Long receiverId, Pageable pageable); List findAllByReceiver_MemberId(Long memberId); + + Integer countByIsReadFalseAndReceiver_MemberId(Long memberId); } \ No newline at end of file diff --git a/src/main/java/clap/server/application/mapper/NotificationMapper.java b/src/main/java/clap/server/application/mapper/NotificationMapper.java index e2c83e52..4098dd39 100644 --- a/src/main/java/clap/server/application/mapper/NotificationMapper.java +++ b/src/main/java/clap/server/application/mapper/NotificationMapper.java @@ -1,6 +1,7 @@ package clap.server.application.mapper; import clap.server.adapter.inbound.web.dto.common.SliceResponse; +import clap.server.adapter.inbound.web.dto.notification.CountNotificationResponse; import clap.server.adapter.inbound.web.dto.notification.FindNotificationListResponse; import clap.server.domain.model.notification.Notification; import org.springframework.data.domain.Slice; @@ -28,4 +29,11 @@ public static SliceResponse toSliceOfFindNoticeLis slice.isLast() ); } + + public static CountNotificationResponse toCountNotificationResponse(Long userId, Integer count) { + return new CountNotificationResponse( + userId, + count + ); + } } diff --git a/src/main/java/clap/server/application/port/inbound/notification/CountNotificationUseCase.java b/src/main/java/clap/server/application/port/inbound/notification/CountNotificationUseCase.java new file mode 100644 index 00000000..f69158a6 --- /dev/null +++ b/src/main/java/clap/server/application/port/inbound/notification/CountNotificationUseCase.java @@ -0,0 +1,8 @@ +package clap.server.application.port.inbound.notification; + +import clap.server.adapter.inbound.web.dto.notification.CountNotificationResponse; + +public interface CountNotificationUseCase { + + CountNotificationResponse countNotification(Long userId); +} diff --git a/src/main/java/clap/server/application/port/outbound/notification/LoadNotificationPort.java b/src/main/java/clap/server/application/port/outbound/notification/LoadNotificationPort.java index 8954c40d..4e4a8731 100644 --- a/src/main/java/clap/server/application/port/outbound/notification/LoadNotificationPort.java +++ b/src/main/java/clap/server/application/port/outbound/notification/LoadNotificationPort.java @@ -15,4 +15,6 @@ public interface LoadNotificationPort { SliceResponse findAllByReceiverId(Long receiverId, Pageable pageable); List findNotificationsByMemberId(Long memberId); + + Integer countNotification(Long memberId); } \ No newline at end of file diff --git a/src/main/java/clap/server/application/service/notification/CountNotificationService.java b/src/main/java/clap/server/application/service/notification/CountNotificationService.java new file mode 100644 index 00000000..325688bc --- /dev/null +++ b/src/main/java/clap/server/application/service/notification/CountNotificationService.java @@ -0,0 +1,25 @@ +package clap.server.application.service.notification; + +import clap.server.adapter.inbound.web.dto.notification.CountNotificationResponse; +import clap.server.application.mapper.NotificationMapper; +import clap.server.application.port.inbound.notification.CountNotificationUseCase; +import clap.server.application.port.outbound.notification.LoadNotificationPort; +import clap.server.common.annotation.architecture.ApplicationService; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; + +@ApplicationService +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class CountNotificationService implements CountNotificationUseCase { + + private final LoadNotificationPort loadNotificationPort; + + @Transactional + @Override + public CountNotificationResponse countNotification(Long userId) { + Integer count = loadNotificationPort.countNotification(userId); + + return NotificationMapper.toCountNotificationResponse(userId, count); + } +} diff --git a/src/main/java/clap/server/application/service/notification/CreateNotificationService.java b/src/main/java/clap/server/application/service/notification/CreateNotificationService.java index 8071eba1..a99af8bc 100644 --- a/src/main/java/clap/server/application/service/notification/CreateNotificationService.java +++ b/src/main/java/clap/server/application/service/notification/CreateNotificationService.java @@ -4,6 +4,7 @@ import clap.server.common.annotation.architecture.ApplicationService; import clap.server.domain.model.notification.Notification; import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; @ApplicationService @RequiredArgsConstructor @@ -11,6 +12,7 @@ public class CreateNotificationService{ private final CommandNotificationPort commandNotificationPort; + @Transactional public void createNotification(Notification request) { commandNotificationPort.save(request);