From 0510b35416dfb9c81c7be29236d3a8b3198d89ad Mon Sep 17 00:00:00 2001 From: Hanbi Date: Mon, 18 Nov 2024 22:02:55 +0900 Subject: [PATCH 1/8] =?UTF-8?q?refactor(notification):=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/domain/RelationFunctionEnum.java | 2 +- .../constants/NotificationMessage.java | 14 ++-- .../notification/domain/Notification.java | 8 ++ .../dto/NotificationListResponse.java | 12 +-- .../service/NotificationService.java | 75 +++++++++++++------ .../V23__modify_notification_table.sql | 15 ++++ 6 files changed, 89 insertions(+), 37 deletions(-) create mode 100644 src/main/resources/db/migration/V23__modify_notification_table.sql diff --git a/src/main/java/site/coach_coach/coach_coach_server/common/domain/RelationFunctionEnum.java b/src/main/java/site/coach_coach/coach_coach_server/common/domain/RelationFunctionEnum.java index ac46f34e..91f18301 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/common/domain/RelationFunctionEnum.java +++ b/src/main/java/site/coach_coach/coach_coach_server/common/domain/RelationFunctionEnum.java @@ -1,5 +1,5 @@ package site.coach_coach.coach_coach_server.common.domain; public enum RelationFunctionEnum { - review, ask, like, match, refusal, cancel + review, ask, like, match, refusal, cancel, routine, request } diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/constants/NotificationMessage.java b/src/main/java/site/coach_coach/coach_coach_server/notification/constants/NotificationMessage.java index 8141e1fb..50a6929b 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/constants/NotificationMessage.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/constants/NotificationMessage.java @@ -4,13 +4,15 @@ @Getter public enum NotificationMessage { - REVIEW_MESSAGE("새로운 리뷰가 작성되었습니다."), - ASK_MESSAGE("매칭을 신청하였습니다."), - LIKE_MESSAGE("회원님을 관심 코치로 등록하였습니다."), - MATCH_MESSAGE("회원님의 매칭 신청을 수락하셨습니다."), - REFUSAL_MESSAGE("매칭 신청을 거절하였습니다."), + REVIEW_MESSAGE("새로운 리뷰가 작성되었습니다!"), + ASK_MESSAGE("코치 매칭을 요청했어요!"), + LIKE_MESSAGE("회원님을 관심 코치로 등록했어요!"), + MATCH_MESSAGE("코치 매칭을 수락했어요!"), + MATCH_REQUEST_MESSAGE(" 님께 코치 매칭을 요청했어요! 답변이 오면 빠르게 알려드릴게요 :)"), + REFUSAL_MESSAGE("매칭 요청을 거절하였습니다."), CANCEL_MESSAGE("매칭을 취소하였습니다."), - USER_MESSAGE("님이 "); + ROUTINE_MESSAGE("새로운 루틴을 등록했어요."), + USER_MESSAGE(" 님이 "); private final String message; diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/domain/Notification.java b/src/main/java/site/coach_coach/coach_coach_server/notification/domain/Notification.java index bc27758d..eb01e2d3 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/domain/Notification.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/domain/Notification.java @@ -39,6 +39,10 @@ public class Notification extends DateEntity { @JoinColumn(name = "user_id") private User user; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "coach_id") + private User coach; + @NotBlank @Column(name = "message", nullable = false, length = 100) @Size(max = 100) @@ -48,4 +52,8 @@ public class Notification extends DateEntity { @Column(name = "relation_function") @Enumerated(EnumType.STRING) private RelationFunctionEnum relationFunction; + + @NotNull + @Column(name = "is_read") + private boolean isRead; } diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/dto/NotificationListResponse.java b/src/main/java/site/coach_coach/coach_coach_server/notification/dto/NotificationListResponse.java index 7b640b7a..369f51a1 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/dto/NotificationListResponse.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/dto/NotificationListResponse.java @@ -4,21 +4,15 @@ import lombok.Builder; import site.coach_coach.coach_coach_server.common.domain.RelationFunctionEnum; -import site.coach_coach.coach_coach_server.notification.domain.Notification; @Builder public record NotificationListResponse( Long notificationId, + String nickname, + String profileImageUrl, String message, RelationFunctionEnum relationFunction, + boolean isRead, LocalDateTime createdAt ) { - public static NotificationListResponse from(Notification notification) { - return new NotificationListResponse( - notification.getNotificationId(), - notification.getMessage(), - notification.getRelationFunction(), - notification.getCreatedAt() - ); - } } diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java b/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java index 84261b59..b8110db2 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java @@ -37,7 +37,7 @@ public List getAllNotifications(Long userId) { return user.getNotifications() .stream() - .map(NotificationListResponse::from) + .map(this::buildNotificationResponse) .toList(); } @@ -53,17 +53,9 @@ public void createNotification(Long userId, Long coachId, RelationFunctionEnum r throw new InvalidInputException(ErrorMessage.INVALID_REQUEST); } - User receiver; - - if (relationFunction == RelationFunctionEnum.match || relationFunction == RelationFunctionEnum.refusal - || relationFunction == RelationFunctionEnum.cancel) { - receiver = user; - } else { - receiver = coach; - } - Notification notification = Notification.builder() - .user(receiver) + .user(user) + .coach(coach) .message(message) .relationFunction(relationFunction) .build(); @@ -90,17 +82,58 @@ public void deleteAllNotifications(Long userId) { private String createMessage(User user, User coach, RelationFunctionEnum relationFunction) { return switch (relationFunction) { - case ask -> user.getNickname() + NotificationMessage.USER_MESSAGE.getMessage() - + NotificationMessage.ASK_MESSAGE.getMessage(); - case like -> user.getNickname() + NotificationMessage.USER_MESSAGE.getMessage() - + NotificationMessage.LIKE_MESSAGE.getMessage(); + case ask -> String.format( + "%s%s%s", user.getNickname(), NotificationMessage.USER_MESSAGE.getMessage(), + NotificationMessage.ASK_MESSAGE.getMessage() + ); + case like -> String.format( + "%s%s%s", user.getNickname(), NotificationMessage.USER_MESSAGE.getMessage(), + NotificationMessage.LIKE_MESSAGE.getMessage() + ); case review -> NotificationMessage.REVIEW_MESSAGE.getMessage(); - case match -> coach.getNickname() + NotificationMessage.USER_MESSAGE.getMessage() - + NotificationMessage.MATCH_MESSAGE.getMessage(); - case refusal -> coach.getNickname() + NotificationMessage.USER_MESSAGE.getMessage() - + NotificationMessage.REFUSAL_MESSAGE.getMessage(); - case cancel -> coach.getNickname() + NotificationMessage.USER_MESSAGE.getMessage() - + NotificationMessage.CANCEL_MESSAGE.getMessage(); + case match -> String.format( + "%s%s%s", coach.getNickname(), NotificationMessage.USER_MESSAGE.getMessage(), + NotificationMessage.MATCH_MESSAGE.getMessage() + ); + case refusal -> String.format( + "%s%s%s", coach.getNickname(), NotificationMessage.USER_MESSAGE.getMessage(), + NotificationMessage.REFUSAL_MESSAGE.getMessage() + ); + case cancel -> String.format( + "%s%s%s", coach.getNickname(), NotificationMessage.USER_MESSAGE.getMessage(), + NotificationMessage.CANCEL_MESSAGE.getMessage() + ); + case routine -> String.format( + "%s%s%s", coach.getNickname(), NotificationMessage.USER_MESSAGE.getMessage(), + NotificationMessage.ROUTINE_MESSAGE.getMessage() + ); + case request -> coach.getNickname() + NotificationMessage.MATCH_REQUEST_MESSAGE.getMessage(); + }; + } + + private NotificationListResponse buildNotificationResponse(Notification notification) { + User sender; + if (isCoachSender(notification.getRelationFunction())) { + sender = notification.getCoach(); + } else { + sender = notification.getUser(); + } + return NotificationListResponse.builder() + .notificationId(notification.getNotificationId()) + .nickname(sender.getNickname()) + .profileImageUrl(sender.getProfileImageUrl()) + .message(notification.getMessage()) + .relationFunction(notification.getRelationFunction()) + .isRead(notification.isRead()) + .createdAt(notification.getCreatedAt()) + .build(); + } + + private boolean isCoachSender(RelationFunctionEnum relationFunction) { + return switch (relationFunction) { + case match, refusal, cancel, request, routine -> true; + default -> false; }; } + } diff --git a/src/main/resources/db/migration/V23__modify_notification_table.sql b/src/main/resources/db/migration/V23__modify_notification_table.sql new file mode 100644 index 00000000..77f47280 --- /dev/null +++ b/src/main/resources/db/migration/V23__modify_notification_table.sql @@ -0,0 +1,15 @@ +ALTER TABLE `coachcoach`.`notifications` + ADD COLUMN `is_read` BIT(1) NOT NULL DEFAULT b'0' AFTER `relation_function`, +CHANGE COLUMN `message` `message` VARCHAR(200) NOT NULL , +CHANGE COLUMN `relation_function` `relation_function` ENUM('ask', 'like', 'review', 'match', 'refusal', 'cancel', 'routine', 'request') NOT NULL ; + +ALTER TABLE `coachcoach`.`notifications` + ADD COLUMN `coach_id` BIGINT NOT NULL AFTER `user_id`; +ALTER TABLE `coachcoach`.`notifications` + ADD INDEX `fk_notifications_coach_id_idx` (`coach_id` ASC) VISIBLE; +ALTER TABLE `coachcoach`.`notifications` + ADD CONSTRAINT `fk_notifications_coach_id` + FOREIGN KEY (`coach_id`) + REFERENCES `coachcoach`.`users` (`user_id`) + ON DELETE CASCADE + ON UPDATE NO ACTION; From f81534e8fdb7017ee9511c6a57dae3dad56bd66d Mon Sep 17 00:00:00 2001 From: Hanbi Date: Mon, 18 Nov 2024 22:03:39 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat(notification):=20=EC=9D=BD=EC=9D=8C=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification/service/NotificationService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java b/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java index b8110db2..0779dc53 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java @@ -58,6 +58,7 @@ public void createNotification(Long userId, Long coachId, RelationFunctionEnum r .coach(coach) .message(message) .relationFunction(relationFunction) + .isRead(false) .build(); notificationRepository.save(notification); } From 2c2afdfe57e21212d48747df194868658cee59bb Mon Sep 17 00:00:00 2001 From: Hanbi Date: Mon, 18 Nov 2024 22:27:49 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat(notification):=20=EC=9D=BD=EC=9D=8C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/NotificationController.java | 20 +++++++++++++++ .../notification/domain/Notification.java | 4 +++ .../repository/NotificationRepository.java | 7 ++++++ .../service/NotificationService.java | 25 +++++++++++++++---- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/controller/NotificationController.java b/src/main/java/site/coach_coach/coach_coach_server/notification/controller/NotificationController.java index b72928ba..7d5280ea 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/controller/NotificationController.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/controller/NotificationController.java @@ -7,6 +7,7 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -52,4 +53,23 @@ public ResponseEntity deleteNotification( new SuccessResponse(HttpStatus.OK.value(), SuccessMessage.DELETE_NOTIFICATION_SUCCESS.getMessage()) ); } + + @PatchMapping("/v1/notifications/{notificationId}/read") + public ResponseEntity markNotificationAsRead( + @AuthenticationPrincipal CustomUserDetails userDetails, + @PathVariable(name = "notificationId") Long notificationId + ) { + Long userId = userDetails.getUserId(); + notificationService.markNotificationAsRead(userId, notificationId); + return ResponseEntity.noContent().build(); + } + + @PatchMapping("/v1/notifications/read") + public ResponseEntity markAllNotificationsAsRead( + @AuthenticationPrincipal CustomUserDetails userDetails + ) { + Long userId = userDetails.getUserId(); + notificationService.markAllNotificationsAsRead(userId); + return ResponseEntity.noContent().build(); + } } diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/domain/Notification.java b/src/main/java/site/coach_coach/coach_coach_server/notification/domain/Notification.java index eb01e2d3..994b878d 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/domain/Notification.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/domain/Notification.java @@ -56,4 +56,8 @@ public class Notification extends DateEntity { @NotNull @Column(name = "is_read") private boolean isRead; + + public void markAsRead() { + this.isRead = true; + } } diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/repository/NotificationRepository.java b/src/main/java/site/coach_coach/coach_coach_server/notification/repository/NotificationRepository.java index d311c118..30e90527 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/repository/NotificationRepository.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/repository/NotificationRepository.java @@ -1,9 +1,16 @@ package site.coach_coach.coach_coach_server.notification.repository; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import site.coach_coach.coach_coach_server.notification.domain.Notification; public interface NotificationRepository extends JpaRepository { int countByUser_UserId(Long userId); + + @Query("SELECT n FROM Notification n WHERE n.user.userId = :userId AND n.isRead = false") + List findUnreadNotificationsByUserId(@Param("userId") Long userId); } diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java b/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java index 0779dc53..fa6eb7e6 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java @@ -1,6 +1,5 @@ package site.coach_coach.coach_coach_server.notification.service; -import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Service; @@ -63,6 +62,7 @@ public void createNotification(Long userId, Long coachId, RelationFunctionEnum r notificationRepository.save(notification); } + @Transactional public void deleteNotification(Long userId, Long notificationId) { Notification notification = notificationRepository.findById(notificationId) .orElseThrow(() -> new NotFoundException(ErrorMessage.NOT_FOUND_NOTIFICATION)); @@ -75,10 +75,26 @@ public void deleteNotification(Long userId, Long notificationId) { public void deleteAllNotifications(Long userId) { User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - List notifications = new ArrayList<>(user.getNotifications()); - if (!notifications.isEmpty()) { - notificationRepository.deleteAll(notifications); + notificationRepository.deleteAll(user.getNotifications()); + } + + @Transactional + public void markNotificationAsRead(Long userId, Long notificationId) { + Notification notification = notificationRepository.findById(notificationId) + .orElseThrow(() -> new NotFoundException(ErrorMessage.NOT_FOUND_NOTIFICATION)); + + if (!notification.getUser().getUserId().equals(userId)) { + throw new AccessDeniedException(); } + notification.markAsRead(); + notificationRepository.save(notification); + } + + @Transactional + public void markAllNotificationsAsRead(Long userId) { + List unreadNotifications = notificationRepository.findUnreadNotificationsByUserId(userId); + unreadNotifications.forEach(Notification::markAsRead); + notificationRepository.saveAll(unreadNotifications); } private String createMessage(User user, User coach, RelationFunctionEnum relationFunction) { @@ -136,5 +152,4 @@ private boolean isCoachSender(RelationFunctionEnum relationFunction) { default -> false; }; } - } From 74c52bfe363ca927a16e281d02b3cfa7b311fb03 Mon Sep 17 00:00:00 2001 From: Hanbi Date: Tue, 19 Nov 2024 11:26:25 +0900 Subject: [PATCH 4/8] =?UTF-8?q?chore:=20db=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ..._count_column.sql => V22__add_total_user_count_column.sql} | 0 .../resources/db/migration/V23__modify_notification_table.sql | 4 +--- 2 files changed, 1 insertion(+), 3 deletions(-) rename src/main/resources/db/migration/{V22_add_total_user_count_column.sql => V22__add_total_user_count_column.sql} (100%) diff --git a/src/main/resources/db/migration/V22_add_total_user_count_column.sql b/src/main/resources/db/migration/V22__add_total_user_count_column.sql similarity index 100% rename from src/main/resources/db/migration/V22_add_total_user_count_column.sql rename to src/main/resources/db/migration/V22__add_total_user_count_column.sql diff --git a/src/main/resources/db/migration/V23__modify_notification_table.sql b/src/main/resources/db/migration/V23__modify_notification_table.sql index 77f47280..5bc707f1 100644 --- a/src/main/resources/db/migration/V23__modify_notification_table.sql +++ b/src/main/resources/db/migration/V23__modify_notification_table.sql @@ -10,6 +10,4 @@ ALTER TABLE `coachcoach`.`notifications` ALTER TABLE `coachcoach`.`notifications` ADD CONSTRAINT `fk_notifications_coach_id` FOREIGN KEY (`coach_id`) - REFERENCES `coachcoach`.`users` (`user_id`) - ON DELETE CASCADE - ON UPDATE NO ACTION; + REFERENCES `coachcoach`.`users` (`user_id`); From cf3ebcc25de16f99e7b538f1b07f430ce87e270d Mon Sep 17 00:00:00 2001 From: Hanbi Date: Tue, 19 Nov 2024 13:54:24 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat(notification):=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coach_coach_server/coach/service/CoachService.java | 4 ++-- .../coach_coach_server/routine/service/RoutineService.java | 5 +++++ ..._count_column.sql => V22_add_total_user_count_column.sql} | 0 3 files changed, 7 insertions(+), 2 deletions(-) rename src/main/resources/db/migration/{V22__add_total_user_count_column.sql => V22_add_total_user_count_column.sql} (100%) diff --git a/src/main/java/site/coach_coach/coach_coach_server/coach/service/CoachService.java b/src/main/java/site/coach_coach/coach_coach_server/coach/service/CoachService.java index ec697286..22d1b5d0 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/coach/service/CoachService.java +++ b/src/main/java/site/coach_coach/coach_coach_server/coach/service/CoachService.java @@ -148,6 +148,7 @@ public void contactCoach(User user, Long coachId) { newMatching.getUserCoachMatchingId()); Long chatRoomId = chatRoomService.createChatRoom(chatRoomRequest); + notificationService.createNotification(user.getUserId(), coachId, RelationFunctionEnum.request); notificationService.createNotification(user.getUserId(), coachId, RelationFunctionEnum.ask); } @@ -274,6 +275,7 @@ public void addCoachToFavorites(Long userId, Long coachId) { if (!userCoachLikeRepository.existsByUser_UserIdAndCoach_CoachId(userId, coachId)) { userCoachLikeRepository.save(new UserCoachLike(null, user, coach)); } + notificationService.createNotification(userId, coachId, RelationFunctionEnum.like); } @Transactional @@ -286,7 +288,6 @@ public void deleteCoachToFavorites(Long userId, Long coachId) { } } - public List getMatchingUsersByCoachId(Long coachUserId) { Long coachId = coachRepository.findCoachIdByUserId(coachUserId) .orElseThrow(() -> new NotFoundException(ErrorMessage.NOT_FOUND_COACH)); @@ -321,7 +322,6 @@ private MatchingUserResponseDto buildMatchingUserResponseDto(Matching matching) ); } - @Transactional public void addReview(Long userId, Long coachId, ReviewRequestDto requestDto) { User user = getUserById(userId); diff --git a/src/main/java/site/coach_coach/coach_coach_server/routine/service/RoutineService.java b/src/main/java/site/coach_coach/coach_coach_server/routine/service/RoutineService.java index 94f5badb..70925618 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/routine/service/RoutineService.java +++ b/src/main/java/site/coach_coach/coach_coach_server/routine/service/RoutineService.java @@ -13,10 +13,12 @@ import site.coach_coach.coach_coach_server.coach.domain.Coach; import site.coach_coach.coach_coach_server.coach.repository.CoachRepository; import site.coach_coach.coach_coach_server.common.constants.ErrorMessage; +import site.coach_coach.coach_coach_server.common.domain.RelationFunctionEnum; import site.coach_coach.coach_coach_server.common.exception.AccessDeniedException; import site.coach_coach.coach_coach_server.common.exception.NotFoundException; import site.coach_coach.coach_coach_server.matching.domain.Matching; import site.coach_coach.coach_coach_server.matching.repository.MatchingRepository; +import site.coach_coach.coach_coach_server.notification.service.NotificationService; import site.coach_coach.coach_coach_server.routine.domain.Routine; import site.coach_coach.coach_coach_server.routine.dto.CreateRoutineRequest; import site.coach_coach.coach_coach_server.routine.dto.RoutineCreatorDto; @@ -38,6 +40,7 @@ public class RoutineService { private final CoachRepository coachRepository; private final UserRepository userRepository; private final SportRepository sportRepository; + private final NotificationService notificationService; private int numberOfCompletedRoutine; public void checkIsMatching(Long userId, Long coachId) { @@ -130,6 +133,8 @@ public Routine createRoutine(CreateRoutineRequest createRoutineRequest, Long use Coach coach = coachRepository.findById(coachId) .orElseThrow(() -> new NotFoundException(ErrorMessage.NOT_FOUND_COACH)); routineBuilder.coach(coach); + notificationService.createNotification(createRoutineRequest.userId(), coachId, + RelationFunctionEnum.routine); } return routineRepository.save(routineBuilder.build()); diff --git a/src/main/resources/db/migration/V22__add_total_user_count_column.sql b/src/main/resources/db/migration/V22_add_total_user_count_column.sql similarity index 100% rename from src/main/resources/db/migration/V22__add_total_user_count_column.sql rename to src/main/resources/db/migration/V22_add_total_user_count_column.sql From d35cfb268ef0fdaccd583d7e4cbcbe711b120066 Mon Sep 17 00:00:00 2001 From: Hanbi Date: Tue, 19 Nov 2024 14:22:41 +0900 Subject: [PATCH 6/8] =?UTF-8?q?refactor:=20=EB=A1=9C=EC=A7=81=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coach/service/CoachService.java | 16 +++++++++------- .../repository/NotificationRepository.java | 2 +- .../routine/service/RoutineService.java | 2 +- .../user/service/UserService.java | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/site/coach_coach/coach_coach_server/coach/service/CoachService.java b/src/main/java/site/coach_coach/coach_coach_server/coach/service/CoachService.java index 22d1b5d0..099c4996 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/coach/service/CoachService.java +++ b/src/main/java/site/coach_coach/coach_coach_server/coach/service/CoachService.java @@ -148,8 +148,9 @@ public void contactCoach(User user, Long coachId) { newMatching.getUserCoachMatchingId()); Long chatRoomId = chatRoomService.createChatRoom(chatRoomRequest); - notificationService.createNotification(user.getUserId(), coachId, RelationFunctionEnum.request); - notificationService.createNotification(user.getUserId(), coachId, RelationFunctionEnum.ask); + notificationService.createNotification(user.getUserId(), coach.getUser().getUserId(), + RelationFunctionEnum.request); + notificationService.createNotification(user.getUserId(), coach.getUser().getUserId(), RelationFunctionEnum.ask); } @Transactional @@ -166,9 +167,9 @@ public void deleteMatching(Long coachUserId, Long userId) { boolean isMatching = matching.getIsMatching(); matchingRepository.delete(matching); if (isMatching) { - notificationService.createNotification(userId, coach.getCoachId(), RelationFunctionEnum.cancel); + notificationService.createNotification(userId, coach.getUser().getUserId(), RelationFunctionEnum.cancel); } else { - notificationService.createNotification(userId, coach.getCoachId(), RelationFunctionEnum.refusal); + notificationService.createNotification(userId, coach.getUser().getUserId(), RelationFunctionEnum.refusal); } } @@ -275,7 +276,7 @@ public void addCoachToFavorites(Long userId, Long coachId) { if (!userCoachLikeRepository.existsByUser_UserIdAndCoach_CoachId(userId, coachId)) { userCoachLikeRepository.save(new UserCoachLike(null, user, coach)); } - notificationService.createNotification(userId, coachId, RelationFunctionEnum.like); + notificationService.createNotification(userId, coach.getUser().getUserId(), RelationFunctionEnum.like); } @Transactional @@ -342,7 +343,8 @@ public void addReview(Long userId, Long coachId, ReviewRequestDto requestDto) { Review review = new Review(null, coach, user, requestDto.contents(), requestDto.stars()); reviewRepository.save(review); - notificationService.createNotification(user.getUserId(), coachId, RelationFunctionEnum.review); + notificationService.createNotification(user.getUserId(), coach.getUser().getUserId(), + RelationFunctionEnum.review); } @Transactional @@ -567,6 +569,6 @@ public void updateMatchingStatus(Long coachUserId, Long userId) { matching.markAsMatched(); coach.increaseTotalUserCount(); - notificationService.createNotification(userId, coach.getCoachId(), RelationFunctionEnum.match); + notificationService.createNotification(userId, coachUserId, RelationFunctionEnum.match); } } diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/repository/NotificationRepository.java b/src/main/java/site/coach_coach/coach_coach_server/notification/repository/NotificationRepository.java index 30e90527..81ec5b97 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/repository/NotificationRepository.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/repository/NotificationRepository.java @@ -9,7 +9,7 @@ import site.coach_coach.coach_coach_server.notification.domain.Notification; public interface NotificationRepository extends JpaRepository { - int countByUser_UserId(Long userId); + int countByUser_UserIdAndIsReadFalse(Long userId); @Query("SELECT n FROM Notification n WHERE n.user.userId = :userId AND n.isRead = false") List findUnreadNotificationsByUserId(@Param("userId") Long userId); diff --git a/src/main/java/site/coach_coach/coach_coach_server/routine/service/RoutineService.java b/src/main/java/site/coach_coach/coach_coach_server/routine/service/RoutineService.java index 70925618..2dbd3a1d 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/routine/service/RoutineService.java +++ b/src/main/java/site/coach_coach/coach_coach_server/routine/service/RoutineService.java @@ -133,7 +133,7 @@ public Routine createRoutine(CreateRoutineRequest createRoutineRequest, Long use Coach coach = coachRepository.findById(coachId) .orElseThrow(() -> new NotFoundException(ErrorMessage.NOT_FOUND_COACH)); routineBuilder.coach(coach); - notificationService.createNotification(createRoutineRequest.userId(), coachId, + notificationService.createNotification(createRoutineRequest.userId(), userIdByJwt, RelationFunctionEnum.routine); } diff --git a/src/main/java/site/coach_coach/coach_coach_server/user/service/UserService.java b/src/main/java/site/coach_coach/coach_coach_server/user/service/UserService.java index 4abc3810..171ab0d3 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/user/service/UserService.java +++ b/src/main/java/site/coach_coach/coach_coach_server/user/service/UserService.java @@ -115,7 +115,7 @@ private AuthResponse getLoggedInUserAuthStatus(User user) { GenderEnum gender = user.getGender(); String profileImageUrl = user.getProfileImageUrl(); boolean isCoach = user.getIsCoach(); - int countOfNotifications = notificationRepository.countByUser_UserId(user.getUserId()); + int countOfNotifications = notificationRepository.countByUser_UserIdAndIsReadFalse(user.getUserId()); return AuthResponse.builder() .isLogin(true) .nickname(nickname) From 63cda8acb1f42ad6bd3ec3a2acb166505b497e66 Mon Sep 17 00:00:00 2001 From: Hanbi Date: Tue, 19 Nov 2024 14:33:03 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor(notification):=20url=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification/controller/NotificationController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/controller/NotificationController.java b/src/main/java/site/coach_coach/coach_coach_server/notification/controller/NotificationController.java index 7d5280ea..68b502da 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/controller/NotificationController.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/controller/NotificationController.java @@ -54,7 +54,7 @@ public ResponseEntity deleteNotification( ); } - @PatchMapping("/v1/notifications/{notificationId}/read") + @PatchMapping("/v1/notifications/{notificationId}") public ResponseEntity markNotificationAsRead( @AuthenticationPrincipal CustomUserDetails userDetails, @PathVariable(name = "notificationId") Long notificationId @@ -64,7 +64,7 @@ public ResponseEntity markNotificationAsRead( return ResponseEntity.noContent().build(); } - @PatchMapping("/v1/notifications/read") + @PatchMapping("/v1/notifications") public ResponseEntity markAllNotificationsAsRead( @AuthenticationPrincipal CustomUserDetails userDetails ) { From c0cecd3ba14a396dfa8574e553f8911df69020e5 Mon Sep 17 00:00:00 2001 From: Hanbi Date: Tue, 19 Nov 2024 19:17:25 +0900 Subject: [PATCH 8/8] =?UTF-8?q?refactor:=20=EC=95=8C=EB=A6=BC=20=EC=A0=84?= =?UTF-8?q?=EC=B2=B4=20=EC=A1=B0=ED=9A=8C=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification/repository/NotificationRepository.java | 8 ++++---- .../notification/service/NotificationService.java | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/repository/NotificationRepository.java b/src/main/java/site/coach_coach/coach_coach_server/notification/repository/NotificationRepository.java index 81ec5b97..b305ec64 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/repository/NotificationRepository.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/repository/NotificationRepository.java @@ -1,8 +1,7 @@ package site.coach_coach.coach_coach_server.notification.repository; -import java.util.List; - import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -11,6 +10,7 @@ public interface NotificationRepository extends JpaRepository { int countByUser_UserIdAndIsReadFalse(Long userId); - @Query("SELECT n FROM Notification n WHERE n.user.userId = :userId AND n.isRead = false") - List findUnreadNotificationsByUserId(@Param("userId") Long userId); + @Modifying + @Query("UPDATE Notification n SET n.isRead = TRUE WHERE n.user.userId = :userId AND n.isRead = FALSE") + void updateIsReadByUserID(@Param("userId") Long userId); } diff --git a/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java b/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java index fa6eb7e6..60271fcd 100644 --- a/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java +++ b/src/main/java/site/coach_coach/coach_coach_server/notification/service/NotificationService.java @@ -92,9 +92,7 @@ public void markNotificationAsRead(Long userId, Long notificationId) { @Transactional public void markAllNotificationsAsRead(Long userId) { - List unreadNotifications = notificationRepository.findUnreadNotificationsByUserId(userId); - unreadNotifications.forEach(Notification::markAsRead); - notificationRepository.saveAll(unreadNotifications); + notificationRepository.updateIsReadByUserID(userId); } private String createMessage(User user, User coach, RelationFunctionEnum relationFunction) {