From 5db50aa4d4bc5ce1c99ac0cd98fafe59c56422fb Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 2 Nov 2025 23:03:22 +0900 Subject: [PATCH 01/25] =?UTF-8?q?feat:=20User=EC=97=90=20birthday=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 --- src/main/java/leets/leenk/domain/user/domain/entity/User.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/leets/leenk/domain/user/domain/entity/User.java b/src/main/java/leets/leenk/domain/user/domain/entity/User.java index 80b60aee..53f26f06 100644 --- a/src/main/java/leets/leenk/domain/user/domain/entity/User.java +++ b/src/main/java/leets/leenk/domain/user/domain/entity/User.java @@ -14,6 +14,7 @@ import lombok.experimental.SuperBuilder; import org.hibernate.annotations.ColumnDefault; +import java.time.LocalDate; import java.time.LocalDateTime; @Getter @@ -38,6 +39,9 @@ public class User extends BaseEntity { private String profileImage; + @Column + private LocalDate birthday; + @Size(max = 4) @Column(length = 4) private String mbti; From 980a9553bb3003cdbb3c76893609e4e9a67e5f51 Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 2 Nov 2025 23:06:49 +0900 Subject: [PATCH 02/25] =?UTF-8?q?feat:=20=EC=83=9D=EC=9D=BC=EC=9E=90=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leenk/domain/user/domain/repository/UserRepository.java | 3 +++ .../domain/user/domain/service/user/UserGetService.java | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/leets/leenk/domain/user/domain/repository/UserRepository.java b/src/main/java/leets/leenk/domain/user/domain/repository/UserRepository.java index a9730d8c..ebc18d44 100644 --- a/src/main/java/leets/leenk/domain/user/domain/repository/UserRepository.java +++ b/src/main/java/leets/leenk/domain/user/domain/repository/UserRepository.java @@ -5,6 +5,7 @@ import org.springframework.data.domain.Slice; import org.springframework.data.jpa.repository.JpaRepository; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -22,4 +23,6 @@ public interface UserRepository extends JpaRepository { List findByDeleteDateIsNullAndLeaveDateBefore(LocalDateTime threshold); Optional findByName(String name); + + List findAllByBirthday(LocalDate today); } diff --git a/src/main/java/leets/leenk/domain/user/domain/service/user/UserGetService.java b/src/main/java/leets/leenk/domain/user/domain/service/user/UserGetService.java index d3e0f009..4ca6faf1 100644 --- a/src/main/java/leets/leenk/domain/user/domain/service/user/UserGetService.java +++ b/src/main/java/leets/leenk/domain/user/domain/service/user/UserGetService.java @@ -8,6 +8,7 @@ import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -47,4 +48,8 @@ public User findByEmail(String email) { return userRepository.findByName("마스터") .orElseThrow(UserNotFoundException::new); } + + public List findAllByBirthday(LocalDate today){ + return userRepository.findAllByBirthday(today); + } } From c35a15e0c875028c10826c1f55447f4ce1617fc7 Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 2 Nov 2025 23:07:51 +0900 Subject: [PATCH 03/25] =?UTF-8?q?feat:=20UserSetting=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=EC=97=90=20isBirthdayNotify=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20=EC=83=9D=EC=9D=BC=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EC=88=98=EC=8B=A0=20=EC=84=A4=EC=A0=95=EC=9D=B4=20?= =?UTF-8?q?=ED=99=9C=EC=84=B1=ED=99=94=EB=90=9C=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/NotificationSettingUpdateRequest.java | 5 ++++- .../leenk/domain/user/domain/entity/UserSetting.java | 8 ++++++++ .../user/domain/repository/UserSettingRepository.java | 4 ++++ .../domain/service/usersetting/UserSettingGetService.java | 4 ++++ .../service/usersetting/UserSettingUpdateService.java | 4 ++++ 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/leets/leenk/domain/user/application/dto/request/NotificationSettingUpdateRequest.java b/src/main/java/leets/leenk/domain/user/application/dto/request/NotificationSettingUpdateRequest.java index db3959d0..fd18467b 100644 --- a/src/main/java/leets/leenk/domain/user/application/dto/request/NotificationSettingUpdateRequest.java +++ b/src/main/java/leets/leenk/domain/user/application/dto/request/NotificationSettingUpdateRequest.java @@ -13,6 +13,9 @@ public record NotificationSettingUpdateRequest( Boolean newFeedNotify, @Schema(description = "새로운 공감 알림 여부 수정", example = "false") - Boolean newReactionNotify + Boolean newReactionNotify, + + @Schema(description = "생일 알림 여부 수정", example = "false") + Boolean birthdayNotify ) { } diff --git a/src/main/java/leets/leenk/domain/user/domain/entity/UserSetting.java b/src/main/java/leets/leenk/domain/user/domain/entity/UserSetting.java index 5caeea1f..0109307a 100644 --- a/src/main/java/leets/leenk/domain/user/domain/entity/UserSetting.java +++ b/src/main/java/leets/leenk/domain/user/domain/entity/UserSetting.java @@ -31,6 +31,10 @@ public class UserSetting extends BaseEntity { @Column(nullable = false, columnDefinition = "boolean default true") private boolean isNewReactionNotify; + @Column(nullable = false, columnDefinition = "boolean default true") + private boolean isBirthdayNotify; + + @OneToOne @JoinColumn(name = "user_id") private User user; @@ -51,4 +55,8 @@ public void updateIsNewFeedNotify(boolean isNewFeedNotify) { public void updateIsNewReactionNotify(boolean isNewReactionNotify) { this.isNewReactionNotify = isNewReactionNotify; } + + public void updateIsBirthdayNotify(boolean isBirthdayNotify) { + this.isBirthdayNotify = isBirthdayNotify; + } } diff --git a/src/main/java/leets/leenk/domain/user/domain/repository/UserSettingRepository.java b/src/main/java/leets/leenk/domain/user/domain/repository/UserSettingRepository.java index f024cf2b..369fc6a3 100644 --- a/src/main/java/leets/leenk/domain/user/domain/repository/UserSettingRepository.java +++ b/src/main/java/leets/leenk/domain/user/domain/repository/UserSettingRepository.java @@ -22,4 +22,8 @@ public interface UserSettingRepository extends JpaRepository "AND us.user.leaveDate IS NULL " + "AND us.user.id <> :authorUserId") List findAllActiveUsersWithNewLeenkNotifyTrueExcludingUserId(@Param("authorUserId") Long authorUserId); + + @Query("SELECT us.user FROM UserSetting us WHERE us.isBirthdayNotify = true " + + "AND us.user.leaveDate IS NULL") + List findAllActiveUsersWithBirthdayNotifyTrue(); } diff --git a/src/main/java/leets/leenk/domain/user/domain/service/usersetting/UserSettingGetService.java b/src/main/java/leets/leenk/domain/user/domain/service/usersetting/UserSettingGetService.java index 97c3dd8a..a855add3 100644 --- a/src/main/java/leets/leenk/domain/user/domain/service/usersetting/UserSettingGetService.java +++ b/src/main/java/leets/leenk/domain/user/domain/service/usersetting/UserSettingGetService.java @@ -26,4 +26,8 @@ public List getUsersToNotifyNewLeenk(Long authorId) { public UserSetting findByUser(User user) { return userSettingRepository.findByUser(user).orElseThrow(UserSettingNotFoundException::new); } + + public List getUsersToNotifyBirthday() { + return userSettingRepository.findAllActiveUsersWithBirthdayNotifyTrue(); + } } diff --git a/src/main/java/leets/leenk/domain/user/domain/service/usersetting/UserSettingUpdateService.java b/src/main/java/leets/leenk/domain/user/domain/service/usersetting/UserSettingUpdateService.java index 11a5e95d..f5ffcacf 100644 --- a/src/main/java/leets/leenk/domain/user/domain/service/usersetting/UserSettingUpdateService.java +++ b/src/main/java/leets/leenk/domain/user/domain/service/usersetting/UserSettingUpdateService.java @@ -23,5 +23,9 @@ public void updateNotificationSetting(UserSetting userSetting, NotificationSetti if (request.newReactionNotify() != null) { userSetting.updateIsNewReactionNotify(request.newReactionNotify()); } + + if (request.birthdayNotify() != null) { + userSetting.updateIsBirthdayNotify(request.birthdayNotify()); + } } } From fc961ce54ed8fb692a53fd18a51f374fd059f9eb Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 2 Nov 2025 23:10:49 +0900 Subject: [PATCH 04/25] =?UTF-8?q?feat:=20=EC=83=9D=EC=9D=BC=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC(BIRTHDAY=5FANNOUNCEMENT)=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20-=20BirthdayAnnouncem?= =?UTF-8?q?entContent=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20-=20NotificationType=20enum=EC=97=90=20BIRTHDAY=5FANNOUNCEME?= =?UTF-8?q?NT=20=EC=83=81=EC=88=98=20=EC=B6=94=EA=B0=80=20-=20=EB=A7=A4?= =?UTF-8?q?=ED=8D=BC=20=EC=B6=94=EA=B0=80=20-=20=EC=83=9D=EC=9D=BC=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20usecase=20=EA=B5=AC=ED=98=84(=EB=B3=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=A0=9C=EC=99=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/BirthdayNotificationMapper.java | 27 ++++++++ .../usecase/BirthdayNotificationUsecase.java | 62 +++++++++++++++++++ .../BirthdayAnnouncementContent.java | 13 ++++ .../domain/entity/enums/NotificationType.java | 5 +- .../mapper/SqsMessageEventMapper.java | 10 +++ 5 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java create mode 100644 src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java create mode 100644 src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayAnnouncementContent.java diff --git a/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java b/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java new file mode 100644 index 00000000..08d40a1e --- /dev/null +++ b/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java @@ -0,0 +1,27 @@ +package leets.leenk.domain.notification.application.mapper; + +import leets.leenk.domain.notification.domain.entity.Notification; +import leets.leenk.domain.notification.domain.entity.birthdayContent.BirthdayAnnouncementContent; +import leets.leenk.domain.notification.domain.entity.enums.NotificationType; +import leets.leenk.domain.user.domain.entity.User; +import org.springframework.stereotype.Component; + +@Component +public class BirthdayNotificationMapper { + public Notification toBirthdayAnnouncementNotification(User birthdayUser, User targetUser) { + return Notification.builder() + .userId(targetUser.getId()) + .notificationType(NotificationType.BIRTHDAY_ANNOUNCEMENT) + .content(toBirthdayAnnouncementContent(birthdayUser)) + .isRead(Boolean.FALSE) + .build(); + } + + private BirthdayAnnouncementContent toBirthdayAnnouncementContent(User birthdayUser) { + return BirthdayAnnouncementContent.builder() + .birthdayUserName(birthdayUser.getName()) + .title(NotificationType.BIRTHDAY_ANNOUNCEMENT.getTitle()) + .body(NotificationType.BIRTHDAY_ANNOUNCEMENT.getContent()) + .build(); + } +} diff --git a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java new file mode 100644 index 00000000..9471e9e7 --- /dev/null +++ b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java @@ -0,0 +1,62 @@ +package leets.leenk.domain.notification.application.usecase; + +import leets.leenk.domain.notification.application.mapper.BirthdayNotificationMapper; +import leets.leenk.domain.notification.domain.entity.Notification; +import leets.leenk.domain.notification.domain.service.NotificationSaveService; +import leets.leenk.domain.user.domain.entity.User; +import leets.leenk.domain.user.domain.service.user.UserGetService; +import leets.leenk.domain.user.domain.service.usersetting.UserSettingGetService; +import leets.leenk.global.sqs.application.mapper.SqsMessageEventMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class BirthdayNotificationUsecase { + + private final UserGetService userGetService; + private final UserSettingGetService userSettingGetService; + + private final BirthdayNotificationMapper birthdayNotificationMapper; + private final SqsMessageEventMapper sqsMessageEventMapper; + + private final ApplicationEventPublisher eventPublisher; + private final NotificationSaveService notificationSaveService; + + @Transactional + public void announceUserBirthday(LocalDate today) { + List birthdayUsers = userGetService.findAllByBirthday(today); + if (birthdayUsers.isEmpty()) { + return; + } + + List users = userSettingGetService.getUsersToNotifyBirthday(); + + + for (User receiver : users) { + for (User birthdayUser : birthdayUsers) { + if (receiver.equals(birthdayUser)) continue; + + Notification notification = birthdayNotificationMapper + .toBirthdayAnnouncementNotification(birthdayUser, receiver); + notificationSaveService.save(notification); + + if (receiver.getFcmToken() != null) { + eventPublisher.publishEvent( + sqsMessageEventMapper.fromBirthdayAnnouncement( + notification, + receiver.getFcmToken(), + birthdayUser + ) + ); + } + } + } + + } +} diff --git a/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayAnnouncementContent.java b/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayAnnouncementContent.java new file mode 100644 index 00000000..b8563f47 --- /dev/null +++ b/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayAnnouncementContent.java @@ -0,0 +1,13 @@ +package leets.leenk.domain.notification.domain.entity.birthdayContent; + +import leets.leenk.domain.notification.domain.entity.NotificationContent; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +@SuperBuilder +@NoArgsConstructor +@Getter +public class BirthdayAnnouncementContent extends NotificationContent { + private String birthdayUserName; +} diff --git a/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java b/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java index dcc1fc3d..442523a9 100644 --- a/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java +++ b/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java @@ -22,7 +22,10 @@ public enum NotificationType { FEED_TAG("Leenk", "이 나를 함께한 사람에 추가했어", "feeds"), NEW_FEED("Leenk", "새로운 게시글을 확인해 봐", "feeds"), FEED_FIRST_REACTION("Leenk", "내가 쓴 피드에 좋아요를 받았어", "feeds"), - FEED_REACTION_COUNT("Leenk", "내가 쓴 피드에 좋아요를 %d개 받았어", "feeds"); + FEED_REACTION_COUNT("Leenk", "내가 쓴 피드에 좋아요를 %d개 받았어", "feeds"), + + // Birthday + BIRTHDAY_ANNOUNCEMENT("Leenk", "오늘은 {name}의 생일이야\n축하해주러 가볼까?", "birthday"); private final String title; diff --git a/src/main/java/leets/leenk/global/sqs/application/mapper/SqsMessageEventMapper.java b/src/main/java/leets/leenk/global/sqs/application/mapper/SqsMessageEventMapper.java index 9a07bec5..7e0e2676 100644 --- a/src/main/java/leets/leenk/global/sqs/application/mapper/SqsMessageEventMapper.java +++ b/src/main/java/leets/leenk/global/sqs/application/mapper/SqsMessageEventMapper.java @@ -93,4 +93,14 @@ public SqsMessageEvent fromLeenkLeft(Notification notification, String fcmToken, .id(id) .build(); } + + public SqsMessageEvent fromBirthdayAnnouncement(Notification notification, String fcmToken, User birthdayUser) { + return SqsMessageEvent.builder() + .title(notification.getContent().getTitle()) + .content(notification.getContent().getBody().replace("{name}", + "[" + birthdayUser.getName() + "]")) + .fcmToken(fcmToken) + .path(notification.getNotificationType().getPath()) + .build(); + } } From 18d543fc92acb6dda488a8475b52716e16d70959 Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 2 Nov 2025 23:11:53 +0900 Subject: [PATCH 05/25] =?UTF-8?q?feat:=20=EC=83=9D=EC=9D=BC=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EC=8A=A4=EC=BC=80=EC=A4=84=EB=9F=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scheduler/BirthdayNotifyScheduler.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/java/leets/leenk/domain/notification/domain/service/scheduler/BirthdayNotifyScheduler.java diff --git a/src/main/java/leets/leenk/domain/notification/domain/service/scheduler/BirthdayNotifyScheduler.java b/src/main/java/leets/leenk/domain/notification/domain/service/scheduler/BirthdayNotifyScheduler.java new file mode 100644 index 00000000..b7a8f627 --- /dev/null +++ b/src/main/java/leets/leenk/domain/notification/domain/service/scheduler/BirthdayNotifyScheduler.java @@ -0,0 +1,25 @@ +package leets.leenk.domain.notification.domain.service.scheduler; + +import leets.leenk.domain.notification.application.usecase.BirthdayNotificationUsecase; +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.time.ZoneId; + +@Service +@RequiredArgsConstructor +public class BirthdayNotifyScheduler { + + private static final ZoneId KST = ZoneId.of("Asia/Seoul"); + + private final BirthdayNotificationUsecase birthdayNotificationUsecase; + + @Scheduled(cron = "0 0 0 * * *", zone = "Asia/Seoul") + public void sendBirthdayNotifications() { + LocalDate today = LocalDate.now(KST); + birthdayNotificationUsecase.announceUserBirthday(today); + + } +} From e0ffc48ce0d6e6b854a5c7031b98bc070a94988b Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 2 Nov 2025 23:12:32 +0900 Subject: [PATCH 06/25] =?UTF-8?q?fix:=20SQS=20=EB=A9=94=EC=8B=9C=EC=A7=80?= =?UTF-8?q?=20=EC=A0=84=EC=86=A1=20=EC=8B=9C=20null=20=EA=B0=92=20?= =?UTF-8?q?=EA=B8=B0=EB=B3=B8=20=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leenk/global/sqs/application/mapper/AwsSqsManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/leets/leenk/global/sqs/application/mapper/AwsSqsManager.java b/src/main/java/leets/leenk/global/sqs/application/mapper/AwsSqsManager.java index d16d4eda..091f89e9 100644 --- a/src/main/java/leets/leenk/global/sqs/application/mapper/AwsSqsManager.java +++ b/src/main/java/leets/leenk/global/sqs/application/mapper/AwsSqsManager.java @@ -40,14 +40,14 @@ public SendMessageRequest createPushAlarmMessageRequest(SqsMessageEvent event) { private MessageAttributeValue convertToAttributeValue(String value) { return MessageAttributeValue.builder() .dataType("String") - .stringValue(value) + .stringValue(value == null ? " " : value) .build(); } private MessageAttributeValue convertToAttributeValue(Long value) { return MessageAttributeValue.builder() .dataType("Number") - .stringValue(value.toString()) + .stringValue(value == null ? "0" : value.toString()) .build(); } } From 91d824add936bf2bd02daa396297e1f97cd73b1d Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 2 Nov 2025 23:34:29 +0900 Subject: [PATCH 07/25] =?UTF-8?q?refactor:=20SqsMessageEvent=20=EB=A7=A4?= =?UTF-8?q?=ED=8D=BC=EC=9D=98=20=EC=83=9D=EC=9D=BC=20SqsMessageEvent=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=A1=9C=EC=A7=81=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/usecase/BirthdayNotificationUsecase.java | 2 +- .../global/sqs/application/mapper/SqsMessageEventMapper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java index 9471e9e7..9edc553c 100644 --- a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java +++ b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java @@ -48,7 +48,7 @@ public void announceUserBirthday(LocalDate today) { if (receiver.getFcmToken() != null) { eventPublisher.publishEvent( - sqsMessageEventMapper.fromBirthdayAnnouncement( + sqsMessageEventMapper.toBirthdaySqsMessageEvent( notification, receiver.getFcmToken(), birthdayUser diff --git a/src/main/java/leets/leenk/global/sqs/application/mapper/SqsMessageEventMapper.java b/src/main/java/leets/leenk/global/sqs/application/mapper/SqsMessageEventMapper.java index 7e0e2676..5277d435 100644 --- a/src/main/java/leets/leenk/global/sqs/application/mapper/SqsMessageEventMapper.java +++ b/src/main/java/leets/leenk/global/sqs/application/mapper/SqsMessageEventMapper.java @@ -94,7 +94,7 @@ public SqsMessageEvent fromLeenkLeft(Notification notification, String fcmToken, .build(); } - public SqsMessageEvent fromBirthdayAnnouncement(Notification notification, String fcmToken, User birthdayUser) { + public SqsMessageEvent toBirthdaySqsMessageEvent(Notification notification, String fcmToken, User birthdayUser) { return SqsMessageEvent.builder() .title(notification.getContent().getTitle()) .content(notification.getContent().getBody().replace("{name}", From bf358e611a1542e00df9aa3e37a41ccb7adcfa2f Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 2 Nov 2025 23:36:00 +0900 Subject: [PATCH 08/25] =?UTF-8?q?feat:=20=EC=83=9D=EC=9D=BC=EC=9E=90?= =?UTF-8?q?=EC=97=90=EA=B2=8C=20=EC=83=9D=EC=9D=BC=20=EC=B6=95=ED=95=98=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/BirthdayNotificationMapper.java | 18 +++++++++++++++ .../usecase/BirthdayNotificationUsecase.java | 22 +++++++++++++++++++ .../BirthdayCelebrateContent.java | 13 +++++++++++ .../domain/entity/enums/NotificationType.java | 4 ++-- .../scheduler/BirthdayNotifyScheduler.java | 2 ++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayCelebrateContent.java diff --git a/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java b/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java index 08d40a1e..02695f72 100644 --- a/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java +++ b/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java @@ -2,6 +2,7 @@ import leets.leenk.domain.notification.domain.entity.Notification; import leets.leenk.domain.notification.domain.entity.birthdayContent.BirthdayAnnouncementContent; +import leets.leenk.domain.notification.domain.entity.birthdayContent.BirthdayCelebrateContent; import leets.leenk.domain.notification.domain.entity.enums.NotificationType; import leets.leenk.domain.user.domain.entity.User; import org.springframework.stereotype.Component; @@ -17,6 +18,15 @@ public Notification toBirthdayAnnouncementNotification(User birthdayUser, User t .build(); } + public Notification toBirthdayCelebrateNotification(User birthdayUser) { + return Notification.builder() + .userId(birthdayUser.getId()) + .notificationType(NotificationType.BIRTHDAY_CELEBRATE) + .content(toBirthdayCelebrateContent(birthdayUser)) + .isRead(Boolean.FALSE) + .build(); + } + private BirthdayAnnouncementContent toBirthdayAnnouncementContent(User birthdayUser) { return BirthdayAnnouncementContent.builder() .birthdayUserName(birthdayUser.getName()) @@ -24,4 +34,12 @@ private BirthdayAnnouncementContent toBirthdayAnnouncementContent(User birthdayU .body(NotificationType.BIRTHDAY_ANNOUNCEMENT.getContent()) .build(); } + + private BirthdayCelebrateContent toBirthdayCelebrateContent(User birthdayUser){ + return BirthdayCelebrateContent.builder() + .birthdayUserName(birthdayUser.getName()) + .title(NotificationType.BIRTHDAY_CELEBRATE.getTitle()) + .body(NotificationType.BIRTHDAY_CELEBRATE.getContent()) + .build(); + } } diff --git a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java index 9edc553c..39e92ba0 100644 --- a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java +++ b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java @@ -59,4 +59,26 @@ public void announceUserBirthday(LocalDate today) { } } + + @Transactional + public void celebrateBirthday(LocalDate today){ + List birthdayUsers = userGetService.findAllByBirthday(today); + + for (User birthdayUser : birthdayUsers){ + Notification notification = birthdayNotificationMapper + .toBirthdayCelebrateNotification(birthdayUser); + notificationSaveService.save(notification); + + if(birthdayUser.getFcmToken() != null) { + eventPublisher.publishEvent( + sqsMessageEventMapper.toBirthdaySqsMessageEvent( + notification, + birthdayUser.getFcmToken(), + birthdayUser + ) + ); + } + } + } + } diff --git a/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayCelebrateContent.java b/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayCelebrateContent.java new file mode 100644 index 00000000..8cd19b6c --- /dev/null +++ b/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayCelebrateContent.java @@ -0,0 +1,13 @@ +package leets.leenk.domain.notification.domain.entity.birthdayContent; + +import leets.leenk.domain.notification.domain.entity.NotificationContent; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +@SuperBuilder +@NoArgsConstructor +@Getter +public class BirthdayCelebrateContent extends NotificationContent { + private String birthdayUserName; +} diff --git a/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java b/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java index 442523a9..0fb049a3 100644 --- a/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java +++ b/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java @@ -25,8 +25,8 @@ public enum NotificationType { FEED_REACTION_COUNT("Leenk", "내가 쓴 피드에 좋아요를 %d개 받았어", "feeds"), // Birthday - BIRTHDAY_ANNOUNCEMENT("Leenk", "오늘은 {name}의 생일이야\n축하해주러 가볼까?", "birthday"); - + BIRTHDAY_ANNOUNCEMENT("Leenk", "오늘은 {name}의 생일이야\n축하해주러 가볼까?", "birthday"), + BIRTHDAY_CELEBRATE("Leenk", "생일 축하해, 멋쟁이 {name}!", "birthday"); private final String title; private final String content; diff --git a/src/main/java/leets/leenk/domain/notification/domain/service/scheduler/BirthdayNotifyScheduler.java b/src/main/java/leets/leenk/domain/notification/domain/service/scheduler/BirthdayNotifyScheduler.java index b7a8f627..54da2993 100644 --- a/src/main/java/leets/leenk/domain/notification/domain/service/scheduler/BirthdayNotifyScheduler.java +++ b/src/main/java/leets/leenk/domain/notification/domain/service/scheduler/BirthdayNotifyScheduler.java @@ -21,5 +21,7 @@ public void sendBirthdayNotifications() { LocalDate today = LocalDate.now(KST); birthdayNotificationUsecase.announceUserBirthday(today); + birthdayNotificationUsecase.celebrateBirthday(today); + } } From 80612f93ec338716e71e4aad7b7a3f0b9a898fb2 Mon Sep 17 00:00:00 2001 From: jj Date: Sat, 8 Nov 2025 23:01:22 +0900 Subject: [PATCH 09/25] =?UTF-8?q?feat:=20BirthdayLetterContent=20=EB=B0=8F?= =?UTF-8?q?=20BIRTHDAY=5FLETTER=20=ED=83=80=EC=9E=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../birthdayContent/BirthdayLetterContent.java | 14 ++++++++++++++ .../domain/entity/enums/NotificationType.java | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayLetterContent.java diff --git a/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayLetterContent.java b/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayLetterContent.java new file mode 100644 index 00000000..1952799e --- /dev/null +++ b/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayLetterContent.java @@ -0,0 +1,14 @@ +package leets.leenk.domain.notification.domain.entity.birthdayContent; + +import leets.leenk.domain.notification.domain.entity.NotificationContent; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +@SuperBuilder +@NoArgsConstructor +@Getter +public class BirthdayLetterContent extends NotificationContent { + private String senderName; + private Long birthdayLetterId; +} diff --git a/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java b/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java index 0fb049a3..d99691f4 100644 --- a/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java +++ b/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java @@ -26,7 +26,8 @@ public enum NotificationType { // Birthday BIRTHDAY_ANNOUNCEMENT("Leenk", "오늘은 {name}의 생일이야\n축하해주러 가볼까?", "birthday"), - BIRTHDAY_CELEBRATE("Leenk", "생일 축하해, 멋쟁이 {name}!", "birthday"); + BIRTHDAY_CELEBRATE("Leenk", "생일 축하해, 멋쟁이 {name}!", "birthday"), + BIRTHDAY_LETTER("Leenk", "{name}에게 생일 편지를 받았어!", "birthday"); private final String title; private final String content; From 524fb34dc5f980d2ff905d766f06de498c7c1c62 Mon Sep 17 00:00:00 2001 From: jj Date: Sat, 8 Nov 2025 23:30:07 +0900 Subject: [PATCH 10/25] =?UTF-8?q?refactor:=20toBirthdaySqsMessageEvent=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=EB=AA=85=EC=9D=84=20user?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/sqs/application/mapper/SqsMessageEventMapper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/leets/leenk/global/sqs/application/mapper/SqsMessageEventMapper.java b/src/main/java/leets/leenk/global/sqs/application/mapper/SqsMessageEventMapper.java index 5277d435..a19a02ff 100644 --- a/src/main/java/leets/leenk/global/sqs/application/mapper/SqsMessageEventMapper.java +++ b/src/main/java/leets/leenk/global/sqs/application/mapper/SqsMessageEventMapper.java @@ -94,11 +94,11 @@ public SqsMessageEvent fromLeenkLeft(Notification notification, String fcmToken, .build(); } - public SqsMessageEvent toBirthdaySqsMessageEvent(Notification notification, String fcmToken, User birthdayUser) { + public SqsMessageEvent toBirthdaySqsMessageEvent(Notification notification, String fcmToken, User user) { return SqsMessageEvent.builder() .title(notification.getContent().getTitle()) .content(notification.getContent().getBody().replace("{name}", - "[" + birthdayUser.getName() + "]")) + "[" + user.getName() + "]")) .fcmToken(fcmToken) .path(notification.getNotificationType().getPath()) .build(); From 7c558e1307413cff9c2df2b58a2dc109b82695d7 Mon Sep 17 00:00:00 2001 From: jj Date: Sat, 8 Nov 2025 23:31:17 +0900 Subject: [PATCH 11/25] =?UTF-8?q?feat:=20=EC=83=9D=EC=9D=BC=20=ED=8E=B8?= =?UTF-8?q?=EC=A7=80=20=EC=95=8C=EB=A6=BC=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usecase/BirthdayLetterUseCase.java | 4 ++++ .../mapper/BirthdayNotificationMapper.java | 20 +++++++++++++++++++ .../usecase/BirthdayNotificationUsecase.java | 20 +++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/src/main/java/leets/leenk/domain/birthday/application/usecase/BirthdayLetterUseCase.java b/src/main/java/leets/leenk/domain/birthday/application/usecase/BirthdayLetterUseCase.java index b031cbcf..c558aedc 100644 --- a/src/main/java/leets/leenk/domain/birthday/application/usecase/BirthdayLetterUseCase.java +++ b/src/main/java/leets/leenk/domain/birthday/application/usecase/BirthdayLetterUseCase.java @@ -9,6 +9,7 @@ import leets.leenk.domain.birthday.domain.entity.BirthdayLetterReadMark; import leets.leenk.domain.birthday.domain.service.BirthdayLetterSaveService; import leets.leenk.domain.birthday.domain.service.BirthdayLettersGetService; +import leets.leenk.domain.notification.application.usecase.BirthdayNotificationUsecase; import leets.leenk.domain.user.domain.entity.User; import leets.leenk.domain.user.domain.service.user.UserGetService; import lombok.RequiredArgsConstructor; @@ -28,6 +29,7 @@ public class BirthdayLetterUseCase { private final BirthdayLettersGetService birthdayLettersGetService; private final BirthdayLetterMapper birthdayLetterMapper; private final BirthdayChecker birthdayChecker; + private final BirthdayNotificationUsecase birthdayNotificationUsecase; @Transactional public void writeBirthdayLetter(long senderId, long receiverId, BirthdayLetterRequest request) { @@ -44,6 +46,8 @@ public void writeBirthdayLetter(long senderId, long receiverId, BirthdayLetterRe BirthdayLetter birthdayLetter = birthdayLetterMapper.toBirthdayLetter(sender, receiver, request); birthdayLetterSaveService.save(birthdayLetter); + + birthdayNotificationUsecase.saveBirthdayLetterNotification(birthdayLetter); } @Transactional(readOnly = true) diff --git a/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java b/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java index 02695f72..9a0c70d3 100644 --- a/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java +++ b/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java @@ -1,8 +1,10 @@ package leets.leenk.domain.notification.application.mapper; +import leets.leenk.domain.birthday.domain.entity.BirthdayLetter; import leets.leenk.domain.notification.domain.entity.Notification; import leets.leenk.domain.notification.domain.entity.birthdayContent.BirthdayAnnouncementContent; import leets.leenk.domain.notification.domain.entity.birthdayContent.BirthdayCelebrateContent; +import leets.leenk.domain.notification.domain.entity.birthdayContent.BirthdayLetterContent; import leets.leenk.domain.notification.domain.entity.enums.NotificationType; import leets.leenk.domain.user.domain.entity.User; import org.springframework.stereotype.Component; @@ -27,6 +29,15 @@ public Notification toBirthdayCelebrateNotification(User birthdayUser) { .build(); } + public Notification toBirthdayLetterNotification(BirthdayLetter birthdayLetter) { + return Notification.builder() + .userId(birthdayLetter.getReceiver().getId()) + .notificationType(NotificationType.BIRTHDAY_LETTER) + .content(toBirthdayLetterContent(birthdayLetter)) + .isRead(Boolean.FALSE) + .build(); + } + private BirthdayAnnouncementContent toBirthdayAnnouncementContent(User birthdayUser) { return BirthdayAnnouncementContent.builder() .birthdayUserName(birthdayUser.getName()) @@ -42,4 +53,13 @@ private BirthdayCelebrateContent toBirthdayCelebrateContent(User birthdayUser){ .body(NotificationType.BIRTHDAY_CELEBRATE.getContent()) .build(); } + + private BirthdayLetterContent toBirthdayLetterContent(BirthdayLetter birthdayLetter) { + return BirthdayLetterContent.builder() + .senderName(birthdayLetter.getSender().getName()) + .birthdayLetterId(birthdayLetter.getId()) + .title(NotificationType.BIRTHDAY_LETTER.getTitle()) + .body(NotificationType.BIRTHDAY_LETTER.getContent()) + .build(); + } } diff --git a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java index 39e92ba0..9cb4d492 100644 --- a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java +++ b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java @@ -1,5 +1,6 @@ package leets.leenk.domain.notification.application.usecase; +import leets.leenk.domain.birthday.domain.entity.BirthdayLetter; import leets.leenk.domain.notification.application.mapper.BirthdayNotificationMapper; import leets.leenk.domain.notification.domain.entity.Notification; import leets.leenk.domain.notification.domain.service.NotificationSaveService; @@ -81,4 +82,23 @@ public void celebrateBirthday(LocalDate today){ } } + @Transactional + public void saveBirthdayLetterNotification(BirthdayLetter birthdayLetter){ + User birthdayUser = birthdayLetter.getReceiver(); + + Notification notification = birthdayNotificationMapper.toBirthdayLetterNotification(birthdayLetter); + notificationSaveService.save(notification); + + if(birthdayUser.getFcmToken() != null){ + eventPublisher.publishEvent( + sqsMessageEventMapper.toBirthdaySqsMessageEvent( + notification, + birthdayUser.getFcmToken(), + birthdayLetter.getSender() + ) + ); + } + + } + } From 3feed414460e235c6ca5e5f031e81c89357efa4a Mon Sep 17 00:00:00 2001 From: jj Date: Sat, 8 Nov 2025 23:35:48 +0900 Subject: [PATCH 12/25] =?UTF-8?q?feat:=20NotificationContent=EC=97=90=20?= =?UTF-8?q?=EC=83=9D=EC=9D=BC=20=EA=B4=80=EB=A0=A8=20=EC=84=9C=EB=B8=8C?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification/domain/entity/NotificationContent.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/leets/leenk/domain/notification/domain/entity/NotificationContent.java b/src/main/java/leets/leenk/domain/notification/domain/entity/NotificationContent.java index 706b9622..bb5917ad 100644 --- a/src/main/java/leets/leenk/domain/notification/domain/entity/NotificationContent.java +++ b/src/main/java/leets/leenk/domain/notification/domain/entity/NotificationContent.java @@ -2,6 +2,9 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; +import leets.leenk.domain.notification.domain.entity.birthdayContent.BirthdayAnnouncementContent; +import leets.leenk.domain.notification.domain.entity.birthdayContent.BirthdayCelebrateContent; +import leets.leenk.domain.notification.domain.entity.birthdayContent.BirthdayLetterContent; import leets.leenk.domain.notification.domain.entity.feedContent.FeedFirstReactionNotificationContent; import leets.leenk.domain.notification.domain.entity.feedContent.FeedReactionCountNotificationContent; import leets.leenk.domain.notification.domain.entity.feedContent.FeedTagNotificationContent; @@ -28,7 +31,10 @@ @JsonSubTypes.Type(value = LeenkStartingSoonNotificationContent.class, name = "LEENK_STARTING_SOON"), @JsonSubTypes.Type(value = LeenkFinishedNotificationContent.class, name = "LEENK_FINISHED"), @JsonSubTypes.Type(value = LeenkStartedHostReminderNotificationContent.class, name = "LEENK_STARTED_HOST_REMINDER"), - @JsonSubTypes.Type(value = LeenkLeftNotificationContent.class, name = "LEENK_LEFT") + @JsonSubTypes.Type(value = LeenkLeftNotificationContent.class, name = "LEENK_LEFT"), + @JsonSubTypes.Type(value = BirthdayAnnouncementContent.class, name = "BIRTHDAY_ANNOUNCEMENT"), + @JsonSubTypes.Type(value = BirthdayCelebrateContent.class, name = "BIRTHDAY_CELEBRATE"), + @JsonSubTypes.Type(value = BirthdayLetterContent.class, name = "BIRTHDAY_LETTER") }) public class NotificationContent { From fb793ff9e2c35ac69b3c311150f2c330342dd843 Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 9 Nov 2025 00:38:42 +0900 Subject: [PATCH 13/25] =?UTF-8?q?feat:=20=EC=83=9D=EC=9D=BC=20=EA=B3=B5?= =?UTF-8?q?=EC=A7=80=20=EB=B0=8F=20=EC=83=9D=EC=9D=BC=20=EC=B6=95=ED=95=98?= =?UTF-8?q?=EC=97=90=20=EC=83=9D=EC=9D=BC=EC=9E=90=20userId=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/mapper/BirthdayNotificationMapper.java | 2 ++ .../entity/birthdayContent/BirthdayAnnouncementContent.java | 1 + .../domain/entity/birthdayContent/BirthdayCelebrateContent.java | 1 + 3 files changed, 4 insertions(+) diff --git a/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java b/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java index 9a0c70d3..b789dd2a 100644 --- a/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java +++ b/src/main/java/leets/leenk/domain/notification/application/mapper/BirthdayNotificationMapper.java @@ -40,6 +40,7 @@ public Notification toBirthdayLetterNotification(BirthdayLetter birthdayLetter) private BirthdayAnnouncementContent toBirthdayAnnouncementContent(User birthdayUser) { return BirthdayAnnouncementContent.builder() + .birthdayUserId(birthdayUser.getId()) .birthdayUserName(birthdayUser.getName()) .title(NotificationType.BIRTHDAY_ANNOUNCEMENT.getTitle()) .body(NotificationType.BIRTHDAY_ANNOUNCEMENT.getContent()) @@ -48,6 +49,7 @@ private BirthdayAnnouncementContent toBirthdayAnnouncementContent(User birthdayU private BirthdayCelebrateContent toBirthdayCelebrateContent(User birthdayUser){ return BirthdayCelebrateContent.builder() + .birthdayUserId(birthdayUser.getId()) .birthdayUserName(birthdayUser.getName()) .title(NotificationType.BIRTHDAY_CELEBRATE.getTitle()) .body(NotificationType.BIRTHDAY_CELEBRATE.getContent()) diff --git a/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayAnnouncementContent.java b/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayAnnouncementContent.java index b8563f47..4b86f7fe 100644 --- a/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayAnnouncementContent.java +++ b/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayAnnouncementContent.java @@ -9,5 +9,6 @@ @NoArgsConstructor @Getter public class BirthdayAnnouncementContent extends NotificationContent { + private Long birthdayUserId; private String birthdayUserName; } diff --git a/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayCelebrateContent.java b/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayCelebrateContent.java index 8cd19b6c..9c878612 100644 --- a/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayCelebrateContent.java +++ b/src/main/java/leets/leenk/domain/notification/domain/entity/birthdayContent/BirthdayCelebrateContent.java @@ -9,5 +9,6 @@ @NoArgsConstructor @Getter public class BirthdayCelebrateContent extends NotificationContent { + private Long birthdayUserId; private String birthdayUserName; } From d582f97ee63e34ba4d845b40e5d8869e3fc63ed9 Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 9 Nov 2025 16:06:10 +0900 Subject: [PATCH 14/25] =?UTF-8?q?feat:=20fix:=20=EC=83=9D=EC=9D=BC=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EC=8B=9C=20=EC=9C=A0=EC=A0=80=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20FCM=20=ED=86=A0=ED=81=B0=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=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 --- .../usecase/BirthdayNotificationUsecase.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java index 9cb4d492..3462d185 100644 --- a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java +++ b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java @@ -5,6 +5,7 @@ import leets.leenk.domain.notification.domain.entity.Notification; import leets.leenk.domain.notification.domain.service.NotificationSaveService; import leets.leenk.domain.user.domain.entity.User; +import leets.leenk.domain.user.domain.entity.UserSetting; import leets.leenk.domain.user.domain.service.user.UserGetService; import leets.leenk.domain.user.domain.service.usersetting.UserSettingGetService; import leets.leenk.global.sqs.application.mapper.SqsMessageEventMapper; @@ -70,7 +71,14 @@ public void celebrateBirthday(LocalDate today){ .toBirthdayCelebrateNotification(birthdayUser); notificationSaveService.save(notification); - if(birthdayUser.getFcmToken() != null) { + UserSetting userSetting; + try{ + userSetting = userSettingGetService.findByUser(birthdayUser); + } catch (Exception e){ + return; + } + + if(userSetting != null && userSetting.isBirthdayNotify() && birthdayUser.getFcmToken() != null) { eventPublisher.publishEvent( sqsMessageEventMapper.toBirthdaySqsMessageEvent( notification, @@ -89,7 +97,14 @@ public void saveBirthdayLetterNotification(BirthdayLetter birthdayLetter){ Notification notification = birthdayNotificationMapper.toBirthdayLetterNotification(birthdayLetter); notificationSaveService.save(notification); - if(birthdayUser.getFcmToken() != null){ + UserSetting userSetting; + try{ + userSetting = userSettingGetService.findByUser(birthdayUser); + } catch (Exception e){ + return; + } + + if(userSetting != null && userSetting.isBirthdayNotify() && birthdayUser.getFcmToken() != null){ eventPublisher.publishEvent( sqsMessageEventMapper.toBirthdaySqsMessageEvent( notification, From 90acd7a7acc9ad790c9835fef7cd7da8c3584684 Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 9 Nov 2025 16:09:12 +0900 Subject: [PATCH 15/25] =?UTF-8?q?refactor:=20=EB=8B=B9=EC=9D=BC=20?= =?UTF-8?q?=EC=83=9D=EC=9D=BC=EC=9E=90=20=EC=A1=B0=ED=9A=8C=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=9D=84=20findTodayBirthdayUsers()=EB=A1=9C=20?= =?UTF-8?q?=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/usecase/BirthdayNotificationUsecase.java | 6 ++++-- .../leenk/domain/user/domain/repository/UserRepository.java | 2 -- .../domain/user/domain/service/user/UserGetService.java | 4 ---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java index 3462d185..bca46815 100644 --- a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java +++ b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java @@ -1,6 +1,7 @@ package leets.leenk.domain.notification.application.usecase; import leets.leenk.domain.birthday.domain.entity.BirthdayLetter; +import leets.leenk.domain.birthday.domain.service.BirthdayGetService; import leets.leenk.domain.notification.application.mapper.BirthdayNotificationMapper; import leets.leenk.domain.notification.domain.entity.Notification; import leets.leenk.domain.notification.domain.service.NotificationSaveService; @@ -23,6 +24,7 @@ public class BirthdayNotificationUsecase { private final UserGetService userGetService; private final UserSettingGetService userSettingGetService; + private final BirthdayGetService birthdayGetService; private final BirthdayNotificationMapper birthdayNotificationMapper; private final SqsMessageEventMapper sqsMessageEventMapper; @@ -32,7 +34,7 @@ public class BirthdayNotificationUsecase { @Transactional public void announceUserBirthday(LocalDate today) { - List birthdayUsers = userGetService.findAllByBirthday(today); + List birthdayUsers = birthdayGetService.findTodayBirthdayUsers(today); if (birthdayUsers.isEmpty()) { return; } @@ -64,7 +66,7 @@ public void announceUserBirthday(LocalDate today) { @Transactional public void celebrateBirthday(LocalDate today){ - List birthdayUsers = userGetService.findAllByBirthday(today); + List birthdayUsers = birthdayGetService.findTodayBirthdayUsers(today); for (User birthdayUser : birthdayUsers){ Notification notification = birthdayNotificationMapper diff --git a/src/main/java/leets/leenk/domain/user/domain/repository/UserRepository.java b/src/main/java/leets/leenk/domain/user/domain/repository/UserRepository.java index b4f85f08..91aea96a 100644 --- a/src/main/java/leets/leenk/domain/user/domain/repository/UserRepository.java +++ b/src/main/java/leets/leenk/domain/user/domain/repository/UserRepository.java @@ -26,8 +26,6 @@ public interface UserRepository extends JpaRepository { Optional findByName(String name); - List findAllByBirthday(LocalDate today); - Optional findByProfileImage(String profileImage); @Query(""" diff --git a/src/main/java/leets/leenk/domain/user/domain/service/user/UserGetService.java b/src/main/java/leets/leenk/domain/user/domain/service/user/UserGetService.java index eb8f32db..9630e6fc 100644 --- a/src/main/java/leets/leenk/domain/user/domain/service/user/UserGetService.java +++ b/src/main/java/leets/leenk/domain/user/domain/service/user/UserGetService.java @@ -49,10 +49,6 @@ public User findByEmail(String email) { .orElseThrow(UserNotFoundException::new); } - public List findAllByBirthday(LocalDate today){ - return userRepository.findAllByBirthday(today); - } - public User findByProfileImage(String profileImage){ return userRepository.findByProfileImage(profileImage) .orElseThrow(UserNotFoundException::new); From 4d79804093d48c2931c8ae496233eba70c3088fb Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 9 Nov 2025 16:11:47 +0900 Subject: [PATCH 16/25] =?UTF-8?q?refactor:=20=EC=83=9D=EC=9D=BC=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EB=8C=80=EC=83=81=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=8B=9C=20=ED=83=88=ED=87=B4=20=EC=9C=A0=EC=A0=80(deleteDate)?= =?UTF-8?q?=20=EC=A0=9C=EC=99=B8=20=EC=A1=B0=EA=B1=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/domain/repository/UserSettingRepository.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/leets/leenk/domain/user/domain/repository/UserSettingRepository.java b/src/main/java/leets/leenk/domain/user/domain/repository/UserSettingRepository.java index 369fc6a3..62015990 100644 --- a/src/main/java/leets/leenk/domain/user/domain/repository/UserSettingRepository.java +++ b/src/main/java/leets/leenk/domain/user/domain/repository/UserSettingRepository.java @@ -24,6 +24,7 @@ public interface UserSettingRepository extends JpaRepository List findAllActiveUsersWithNewLeenkNotifyTrueExcludingUserId(@Param("authorUserId") Long authorUserId); @Query("SELECT us.user FROM UserSetting us WHERE us.isBirthdayNotify = true " + - "AND us.user.leaveDate IS NULL") + "AND us.user.leaveDate IS NULL " + + "AND us.user.deleteDate IS NULL") List findAllActiveUsersWithBirthdayNotifyTrue(); } From 702e72a3165e2153c5b7259e11bb5782880f25d3 Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 9 Nov 2025 16:58:03 +0900 Subject: [PATCH 17/25] =?UTF-8?q?fix:=20SQS=20=EB=A9=94=EC=8B=9C=EC=A7=80?= =?UTF-8?q?=20pathId=20null=20=EC=B2=98=EB=A6=AC=20=EC=8B=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=EA=B0=92=EC=9D=84=200=20->=20-1=EB=A1=9C=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 --- .../leenk/global/sqs/application/mapper/AwsSqsManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/leets/leenk/global/sqs/application/mapper/AwsSqsManager.java b/src/main/java/leets/leenk/global/sqs/application/mapper/AwsSqsManager.java index 091f89e9..74848cbe 100644 --- a/src/main/java/leets/leenk/global/sqs/application/mapper/AwsSqsManager.java +++ b/src/main/java/leets/leenk/global/sqs/application/mapper/AwsSqsManager.java @@ -47,7 +47,7 @@ private MessageAttributeValue convertToAttributeValue(String value) { private MessageAttributeValue convertToAttributeValue(Long value) { return MessageAttributeValue.builder() .dataType("Number") - .stringValue(value == null ? "0" : value.toString()) + .stringValue(value == null ? "-1" : value.toString()) .build(); } } From 1fe329a759d453ea2283d4ffdeca2464051875bd Mon Sep 17 00:00:00 2001 From: jj Date: Mon, 10 Nov 2025 14:41:52 +0900 Subject: [PATCH 18/25] =?UTF-8?q?refactor:=20=EC=83=9D=EC=9D=BC=20Notifica?= =?UTF-8?q?tionType=EC=9D=98=20path=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification/domain/entity/enums/NotificationType.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java b/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java index d99691f4..a150e899 100644 --- a/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java +++ b/src/main/java/leets/leenk/domain/notification/domain/entity/enums/NotificationType.java @@ -25,9 +25,9 @@ public enum NotificationType { FEED_REACTION_COUNT("Leenk", "내가 쓴 피드에 좋아요를 %d개 받았어", "feeds"), // Birthday - BIRTHDAY_ANNOUNCEMENT("Leenk", "오늘은 {name}의 생일이야\n축하해주러 가볼까?", "birthday"), - BIRTHDAY_CELEBRATE("Leenk", "생일 축하해, 멋쟁이 {name}!", "birthday"), - BIRTHDAY_LETTER("Leenk", "{name}에게 생일 편지를 받았어!", "birthday"); + BIRTHDAY_ANNOUNCEMENT("Leenk", "오늘은 {name}의 생일이야\n축하해주러 가볼까?", "birthday/users"), + BIRTHDAY_CELEBRATE("Leenk", "생일 축하해, 멋쟁이 {name}!", "birthday/users"), + BIRTHDAY_LETTER("Leenk", "{name}에게 생일 편지를 받았어!", "birthday/letters/me"); private final String title; private final String content; From c9520ebe472a7e8ec90e9dc6a05dd5fc65314bec Mon Sep 17 00:00:00 2001 From: jj Date: Mon, 10 Nov 2025 14:43:10 +0900 Subject: [PATCH 19/25] =?UTF-8?q?refactor:=20BirthdayNotifyScheduler=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=EB=A5=BC=20=EC=83=9D=EC=9D=BC=20=EB=94=94?= =?UTF-8?q?=EB=A0=89=ED=86=A0=EB=A6=AC=20=EB=82=B4=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/service/scheduler/BirthdayNotifyScheduler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/leets/leenk/domain/{notification => birthday}/domain/service/scheduler/BirthdayNotifyScheduler.java (92%) diff --git a/src/main/java/leets/leenk/domain/notification/domain/service/scheduler/BirthdayNotifyScheduler.java b/src/main/java/leets/leenk/domain/birthday/domain/service/scheduler/BirthdayNotifyScheduler.java similarity index 92% rename from src/main/java/leets/leenk/domain/notification/domain/service/scheduler/BirthdayNotifyScheduler.java rename to src/main/java/leets/leenk/domain/birthday/domain/service/scheduler/BirthdayNotifyScheduler.java index 54da2993..1b07d806 100644 --- a/src/main/java/leets/leenk/domain/notification/domain/service/scheduler/BirthdayNotifyScheduler.java +++ b/src/main/java/leets/leenk/domain/birthday/domain/service/scheduler/BirthdayNotifyScheduler.java @@ -1,4 +1,4 @@ -package leets.leenk.domain.notification.domain.service.scheduler; +package leets.leenk.domain.birthday.domain.service.scheduler; import leets.leenk.domain.notification.application.usecase.BirthdayNotificationUsecase; import lombok.RequiredArgsConstructor; From 536952bf6bba5e2760b8556942fa22562d36a542 Mon Sep 17 00:00:00 2001 From: jj Date: Mon, 10 Nov 2025 14:44:43 +0900 Subject: [PATCH 20/25] =?UTF-8?q?refactor:=20=EC=83=9D=EC=9D=BC=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=EC=9D=84=20=ED=97=88=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9D=80=20=EC=9C=A0=EC=A0=80=EB=8A=94=20?= =?UTF-8?q?=EC=83=9D=EC=9D=BC=20=EC=A0=80=EC=9E=A5=EC=9D=B4=20=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usecase/BirthdayNotificationUsecase.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java index bca46815..9f213c53 100644 --- a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java +++ b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java @@ -69,18 +69,20 @@ public void celebrateBirthday(LocalDate today){ List birthdayUsers = birthdayGetService.findTodayBirthdayUsers(today); for (User birthdayUser : birthdayUsers){ - Notification notification = birthdayNotificationMapper - .toBirthdayCelebrateNotification(birthdayUser); - notificationSaveService.save(notification); - UserSetting userSetting; try{ userSetting = userSettingGetService.findByUser(birthdayUser); } catch (Exception e){ - return; + continue; } + if(userSetting == null || !userSetting.isBirthdayNotify()) continue; + + Notification notification = birthdayNotificationMapper + .toBirthdayCelebrateNotification(birthdayUser); + notificationSaveService.save(notification); - if(userSetting != null && userSetting.isBirthdayNotify() && birthdayUser.getFcmToken() != null) { + + if(birthdayUser.getFcmToken() != null) { eventPublisher.publishEvent( sqsMessageEventMapper.toBirthdaySqsMessageEvent( notification, @@ -96,17 +98,18 @@ public void celebrateBirthday(LocalDate today){ public void saveBirthdayLetterNotification(BirthdayLetter birthdayLetter){ User birthdayUser = birthdayLetter.getReceiver(); - Notification notification = birthdayNotificationMapper.toBirthdayLetterNotification(birthdayLetter); - notificationSaveService.save(notification); - UserSetting userSetting; try{ userSetting = userSettingGetService.findByUser(birthdayUser); } catch (Exception e){ return; } + if(userSetting == null || !userSetting.isBirthdayNotify()) return; + + Notification notification = birthdayNotificationMapper.toBirthdayLetterNotification(birthdayLetter); + notificationSaveService.save(notification); - if(userSetting != null && userSetting.isBirthdayNotify() && birthdayUser.getFcmToken() != null){ + if(birthdayUser.getFcmToken() != null){ eventPublisher.publishEvent( sqsMessageEventMapper.toBirthdaySqsMessageEvent( notification, From a4de57c50236b0d3e365f2c819cc6cf0eb2eb9cd Mon Sep 17 00:00:00 2001 From: jj Date: Tue, 11 Nov 2025 21:09:21 +0900 Subject: [PATCH 21/25] =?UTF-8?q?style:=20UserGetService=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20import=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leenk/domain/user/domain/service/user/UserGetService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/leets/leenk/domain/user/domain/service/user/UserGetService.java b/src/main/java/leets/leenk/domain/user/domain/service/user/UserGetService.java index 9630e6fc..bd6bc737 100644 --- a/src/main/java/leets/leenk/domain/user/domain/service/user/UserGetService.java +++ b/src/main/java/leets/leenk/domain/user/domain/service/user/UserGetService.java @@ -8,7 +8,6 @@ import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; -import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; From 5124e489a6fcb67bed29a974ec30e32d300f1fcf Mon Sep 17 00:00:00 2001 From: jj Date: Tue, 11 Nov 2025 21:19:07 +0900 Subject: [PATCH 22/25] =?UTF-8?q?refactor:=20=EC=83=9D=EC=9D=BC=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EC=8B=9C=20UserSetting=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EB=B0=8F=20=EC=95=8C=EB=A6=BC=20=EC=97=AC=EB=B6=80?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EA=B3=B5=ED=86=B5?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usecase/BirthdayNotificationUsecase.java | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java index 9f213c53..40377bc4 100644 --- a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java +++ b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java @@ -69,13 +69,7 @@ public void celebrateBirthday(LocalDate today){ List birthdayUsers = birthdayGetService.findTodayBirthdayUsers(today); for (User birthdayUser : birthdayUsers){ - UserSetting userSetting; - try{ - userSetting = userSettingGetService.findByUser(birthdayUser); - } catch (Exception e){ - continue; - } - if(userSetting == null || !userSetting.isBirthdayNotify()) continue; + if (!isBirthdayNotificationEnabled(birthdayUser)) continue; Notification notification = birthdayNotificationMapper .toBirthdayCelebrateNotification(birthdayUser); @@ -98,13 +92,7 @@ public void celebrateBirthday(LocalDate today){ public void saveBirthdayLetterNotification(BirthdayLetter birthdayLetter){ User birthdayUser = birthdayLetter.getReceiver(); - UserSetting userSetting; - try{ - userSetting = userSettingGetService.findByUser(birthdayUser); - } catch (Exception e){ - return; - } - if(userSetting == null || !userSetting.isBirthdayNotify()) return; + if (!isBirthdayNotificationEnabled(birthdayUser)) return; Notification notification = birthdayNotificationMapper.toBirthdayLetterNotification(birthdayLetter); notificationSaveService.save(notification); @@ -121,4 +109,13 @@ public void saveBirthdayLetterNotification(BirthdayLetter birthdayLetter){ } + private boolean isBirthdayNotificationEnabled(User birthdayUser) { + try { + UserSetting userSetting = userSettingGetService.findByUser(birthdayUser); + return userSetting != null && userSetting.isBirthdayNotify(); + } catch (Exception e) { + return false; + } + } + } From 5fb7e38406fbc2acdab8cf4a672e30342e16334b Mon Sep 17 00:00:00 2001 From: jj Date: Tue, 11 Nov 2025 21:26:55 +0900 Subject: [PATCH 23/25] =?UTF-8?q?refactor:=20=EC=8A=A4=EC=BC=80=EC=A4=84?= =?UTF-8?q?=EB=9F=AC=EC=97=90=EC=84=9C=20=ED=95=98=EB=93=9C=EC=BD=94?= =?UTF-8?q?=EB=94=A9=EB=90=9C=20=ED=83=80=EC=9E=84=EC=A1=B4=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=EB=B0=8F=20=EC=A0=84=EC=97=AD=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?(jackson.time-zone)=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/service/scheduler/BirthdayNotifyScheduler.java | 7 ++----- src/main/resources/application.yml | 2 ++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/leets/leenk/domain/birthday/domain/service/scheduler/BirthdayNotifyScheduler.java b/src/main/java/leets/leenk/domain/birthday/domain/service/scheduler/BirthdayNotifyScheduler.java index 1b07d806..bcab9dfd 100644 --- a/src/main/java/leets/leenk/domain/birthday/domain/service/scheduler/BirthdayNotifyScheduler.java +++ b/src/main/java/leets/leenk/domain/birthday/domain/service/scheduler/BirthdayNotifyScheduler.java @@ -6,19 +6,16 @@ import org.springframework.stereotype.Service; import java.time.LocalDate; -import java.time.ZoneId; @Service @RequiredArgsConstructor public class BirthdayNotifyScheduler { - private static final ZoneId KST = ZoneId.of("Asia/Seoul"); - private final BirthdayNotificationUsecase birthdayNotificationUsecase; - @Scheduled(cron = "0 0 0 * * *", zone = "Asia/Seoul") + @Scheduled(cron = "0 0 0 * * *") public void sendBirthdayNotifications() { - LocalDate today = LocalDate.now(KST); + LocalDate today = LocalDate.now(); birthdayNotificationUsecase.announceUserBirthday(today); birthdayNotificationUsecase.celebrateBirthday(today); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 37f2e618..64f63945 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -3,6 +3,8 @@ spring: active: local jpa: open-in-view: false + jackson: + time-zone: Asia/Seoul springdoc: swagger-ui: From 90857c71d5cfab31dba595056dea849da3750b8e Mon Sep 17 00:00:00 2001 From: jj Date: Thu, 13 Nov 2025 20:47:05 +0900 Subject: [PATCH 24/25] =?UTF-8?q?refactor:=20=EC=83=9D=EC=9D=BC=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EC=A0=84=EC=86=A1=20=EC=A4=91=20=EA=B0=9C?= =?UTF-8?q?=EB=B3=84=20=EC=8B=A4=ED=8C=A8=EA=B0=80=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=ED=9D=90=EB=A6=84=EC=9D=84=20=EC=A4=91=EB=8B=A8=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20try-catch=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usecase/BirthdayNotificationUsecase.java | 59 +++++++++++-------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java index 40377bc4..6d2f03fb 100644 --- a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java +++ b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java @@ -7,10 +7,10 @@ import leets.leenk.domain.notification.domain.service.NotificationSaveService; import leets.leenk.domain.user.domain.entity.User; import leets.leenk.domain.user.domain.entity.UserSetting; -import leets.leenk.domain.user.domain.service.user.UserGetService; import leets.leenk.domain.user.domain.service.usersetting.UserSettingGetService; import leets.leenk.global.sqs.application.mapper.SqsMessageEventMapper; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,11 +18,11 @@ import java.time.LocalDate; import java.util.List; +@Slf4j @Service @RequiredArgsConstructor public class BirthdayNotificationUsecase { - private final UserGetService userGetService; private final UserSettingGetService userSettingGetService; private final BirthdayGetService birthdayGetService; @@ -41,23 +41,26 @@ public void announceUserBirthday(LocalDate today) { List users = userSettingGetService.getUsersToNotifyBirthday(); - for (User receiver : users) { for (User birthdayUser : birthdayUsers) { if (receiver.equals(birthdayUser)) continue; - Notification notification = birthdayNotificationMapper - .toBirthdayAnnouncementNotification(birthdayUser, receiver); - notificationSaveService.save(notification); - - if (receiver.getFcmToken() != null) { - eventPublisher.publishEvent( - sqsMessageEventMapper.toBirthdaySqsMessageEvent( - notification, - receiver.getFcmToken(), - birthdayUser - ) - ); + try { + Notification notification = birthdayNotificationMapper + .toBirthdayAnnouncementNotification(birthdayUser, receiver); + notificationSaveService.save(notification); + + if (receiver.getFcmToken() != null) { + eventPublisher.publishEvent( + sqsMessageEventMapper.toBirthdaySqsMessageEvent( + notification, + receiver.getFcmToken(), + birthdayUser + ) + ); + } + } catch (Exception e){ + log.error("알림 전송 실패", e); } } } @@ -71,19 +74,23 @@ public void celebrateBirthday(LocalDate today){ for (User birthdayUser : birthdayUsers){ if (!isBirthdayNotificationEnabled(birthdayUser)) continue; - Notification notification = birthdayNotificationMapper - .toBirthdayCelebrateNotification(birthdayUser); - notificationSaveService.save(notification); + try { + Notification notification = birthdayNotificationMapper + .toBirthdayCelebrateNotification(birthdayUser); + notificationSaveService.save(notification); - if(birthdayUser.getFcmToken() != null) { - eventPublisher.publishEvent( - sqsMessageEventMapper.toBirthdaySqsMessageEvent( - notification, - birthdayUser.getFcmToken(), - birthdayUser - ) - ); + if (birthdayUser.getFcmToken() != null) { + eventPublisher.publishEvent( + sqsMessageEventMapper.toBirthdaySqsMessageEvent( + notification, + birthdayUser.getFcmToken(), + birthdayUser + ) + ); + } + } catch (Exception e){ + log.error("알림 전송 실패", e); } } } From d2cfb5ab68705ce6d618fde1c2aeeb5679e9cc67 Mon Sep 17 00:00:00 2001 From: jj Date: Thu, 13 Nov 2025 20:48:28 +0900 Subject: [PATCH 25/25] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95=20=EC=A1=B0=ED=9A=8C=20=EC=8B=A4=ED=8C=A8?= =?UTF-8?q?=20=EB=A1=9C=EA=B7=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/usecase/BirthdayNotificationUsecase.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java index 6d2f03fb..5cecaa56 100644 --- a/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java +++ b/src/main/java/leets/leenk/domain/notification/application/usecase/BirthdayNotificationUsecase.java @@ -121,6 +121,7 @@ private boolean isBirthdayNotificationEnabled(User birthdayUser) { UserSetting userSetting = userSettingGetService.findByUser(birthdayUser); return userSetting != null && userSetting.isBirthdayNotify(); } catch (Exception e) { + log.error("사용자 설정 조회 실패 - userId: {}", birthdayUser.getId(), e); return false; } }