From 5d47a07f5898a7937b727743ea2c3e427132c381 Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:22:01 +0900 Subject: [PATCH 01/32] =?UTF-8?q?MOSU-28=20feat:=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=ED=86=A1=20=EA=B4=80=EB=A0=A8=20=EC=84=A4=EC=A0=95=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 --- src/main/resources/application.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index dcf44621..33bfbe6b 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -46,6 +46,9 @@ spring: redis: host: ${REDIS_HOST} port: ${VELKEY_PORT} + messages: + basename: messages + encoding: UTF-8 management: endpoints: @@ -70,3 +73,12 @@ toss: secret-key: test_sk_kYG57Eba3GYBMGeobgbLrpWDOxmA api: base-url: https://api.tosspayments.com/v1/payments + +alimtalk: + user-id: ${ALIMTALK_USER_ID} + api-key: ${ALIMTALK_API_KEY} + api: + base-url: ${ALIMTALK_URL} + +kakao: + channel-id: ${KAKAO_CHANNEL_ID} \ No newline at end of file From 44eb9f330a8ec1a0c6505d43a54f80cfa0237194 Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:23:03 +0900 Subject: [PATCH 02/32] =?UTF-8?q?MOSU-28=20feat:=20ApplicationNotifyStrate?= =?UTF-8?q?gy=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../strategy/ApplicationNotifyStrategy.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/strategy/ApplicationNotifyStrategy.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/ApplicationNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/ApplicationNotifyStrategy.java new file mode 100644 index 00000000..25b8b5fb --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/ApplicationNotifyStrategy.java @@ -0,0 +1,53 @@ +package life.mosu.mosuserver.infra.notify.strategy; + +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.APPLICATION_TEMPLATE_ID; +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.MYPAGE; +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.WARNING; + +import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaRepository; +import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolNotifyProjection; +import life.mosu.mosuserver.infra.notify.NotifyEvent; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.dto.ApplicationNotifyMessageDto; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventSuccessMessageDto; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class ApplicationNotifyStrategy implements NotifyStrategy { + + private final NotifyEventTemplate template; + private final ApplicationSchoolJpaRepository applicationSchoolJpaRepository; + + @Override + public NotifyEventRequest create(NotifyEvent event) { + ApplicationSchoolNotifyProjection projection = applicationSchoolJpaRepository.findPaymentByApplicationSchoolId( + event.id()); + + ApplicationNotifyMessageDto dto = new ApplicationNotifyMessageDto( + projection.paymentKey(), projection.examDate(), projection.schoolName(), + projection.lunch().getLunchName()); + + String alimTalkContent = template.getProcessedMessage( + "notify.exam.application.complete.alimtalk", + dto.toMap()); + + String smsContent = template.getProcessedMessage("notify.exam.application.complete.sms", + dto.toMap()); + + NotifyButtonUrls btnUrls = NotifyButtonUrls.of( + NotifyButtonUrl.of(WARNING, WARNING), + NotifyButtonUrl.of(MYPAGE, MYPAGE) + ); + + NotifyEventSuccessMessageDto eventMessage = NotifyEventSuccessMessageDto.create(1, + event.telNum(), alimTalkContent, + smsContent, "1", btnUrls); + return template.getNotifyEventSuccessTemplate(APPLICATION_TEMPLATE_ID, eventMessage); + } + +} From f9a4a8a741a8680fe7ec057dbd227a03ef35c70b Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:32:11 +0900 Subject: [PATCH 03/32] =?UTF-8?q?MOSU-28=20feat:=20=EA=B0=81=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=ED=86=A1=EC=9D=98=20request=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20strategy=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../strategy/ApplicationNotifyStrategy.java | 4 +- .../Exam1DayBeforeNotifyStrategy.java | 62 ++++++++++++++++++ .../Exam1WeekBeforeNotifyStrategy.java | 57 +++++++++++++++++ .../Exam3DayBeforeNotifyStrategy.java | 64 +++++++++++++++++++ .../strategy/InquiryAnswerNotifyStrategy.java | 51 +++++++++++++++ .../notify/strategy/RefundNotifyStrategy.java | 55 ++++++++++++++++ .../notify/strategy/SignUpNotifyStrategy.java | 42 ++++++++++++ 7 files changed, 333 insertions(+), 2 deletions(-) create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1DayBeforeNotifyStrategy.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1WeekBeforeNotifyStrategy.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam3DayBeforeNotifyStrategy.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/strategy/InquiryAnswerNotifyStrategy.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/strategy/RefundNotifyStrategy.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/strategy/SignUpNotifyStrategy.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/ApplicationNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/ApplicationNotifyStrategy.java index 25b8b5fb..67364c79 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/ApplicationNotifyStrategy.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/ApplicationNotifyStrategy.java @@ -8,7 +8,7 @@ import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolNotifyProjection; import life.mosu.mosuserver.infra.notify.NotifyEvent; import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; -import life.mosu.mosuserver.infra.notify.dto.ApplicationNotifyMessageDto; +import life.mosu.mosuserver.infra.notify.dto.ApplicationNotifyVariablesDto; import life.mosu.mosuserver.infra.notify.dto.NotifyEventSuccessMessageDto; import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; @@ -28,7 +28,7 @@ public NotifyEventRequest create(NotifyEvent event) { ApplicationSchoolNotifyProjection projection = applicationSchoolJpaRepository.findPaymentByApplicationSchoolId( event.id()); - ApplicationNotifyMessageDto dto = new ApplicationNotifyMessageDto( + ApplicationNotifyVariablesDto dto = new ApplicationNotifyVariablesDto( projection.paymentKey(), projection.examDate(), projection.schoolName(), projection.lunch().getLunchName()); diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1DayBeforeNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1DayBeforeNotifyStrategy.java new file mode 100644 index 00000000..57da224e --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1DayBeforeNotifyStrategy.java @@ -0,0 +1,62 @@ +package life.mosu.mosuserver.infra.notify.strategy; + +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.EXAM_1DAY_BEFORE_TEMPLATE_ID; +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.INQUIRY; +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.MYPAGE; + +import java.time.LocalDateTime; +import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaEntity; +import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaRepository; +import life.mosu.mosuserver.global.exception.CustomRuntimeException; +import life.mosu.mosuserver.global.exception.ErrorCode; +import life.mosu.mosuserver.infra.notify.NotifyEvent; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.dto.Exam1DayBeforeNotifyVariablesDto; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRemindMessageDto; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class Exam1DayBeforeNotifyStrategy implements NotifyStrategy { + + private final NotifyEventTemplate template; + private final ApplicationSchoolJpaRepository applicationSchoolJpaRepository; + + @Override + public NotifyEventRequest create(NotifyEvent event) { + ApplicationSchoolJpaEntity applicationSchool = applicationSchoolJpaRepository.findById( + event.id()).orElseThrow( + () -> new CustomRuntimeException(ErrorCode.APPLICATION_SCHOOL_NOT_FOUND)); + + Exam1DayBeforeNotifyVariablesDto dto = new Exam1DayBeforeNotifyVariablesDto( + applicationSchool.getExamDate(), applicationSchool.getExaminationNumber(), + applicationSchool.getSchoolName()); + + String alimTalkContent = template.getProcessedMessage( + "notify.exam.oneday.reminder.alimtalk", + dto.toMap()); + + String smsContent = template.getProcessedMessage("notify.exam.oneday.reminder.sms", + dto.toMap()); + + LocalDateTime reserveTime = applicationSchool.getExamDate() + .minusDays(1) + .atTime(8, 0); + + NotifyButtonUrls btnUrls = NotifyButtonUrls.of( + NotifyButtonUrl.of(INQUIRY, INQUIRY), + NotifyButtonUrl.of(MYPAGE, MYPAGE) + ); + + NotifyEventRemindMessageDto eventMessage = NotifyEventRemindMessageDto.create(1, + event.telNum(), reserveTime, + alimTalkContent, + smsContent, btnUrls); + + return template.getNotifyEventRemindTemplate(EXAM_1DAY_BEFORE_TEMPLATE_ID, eventMessage); + } +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1WeekBeforeNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1WeekBeforeNotifyStrategy.java new file mode 100644 index 00000000..43c0c76a --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1WeekBeforeNotifyStrategy.java @@ -0,0 +1,57 @@ +package life.mosu.mosuserver.infra.notify.strategy; + +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.EXAM_1WEEK_BEFORE_TEMPLATE_ID; +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.INQUIRY; + +import java.time.LocalDateTime; +import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaRepository; +import life.mosu.mosuserver.domain.applicationschool.OneWeekNotifyProjection; +import life.mosu.mosuserver.infra.notify.NotifyEvent; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.dto.Exam1WeekBeforeNotifyVariablesDto; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRemindMessageDto; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + + +@Component +@RequiredArgsConstructor +public class Exam1WeekBeforeNotifyStrategy implements NotifyStrategy { + + private final NotifyEventTemplate template; + private final ApplicationSchoolJpaRepository applicationSchoolJpaRepository; + + @Override + public NotifyEventRequest create(NotifyEvent event) { + OneWeekNotifyProjection projection = applicationSchoolJpaRepository.findOneWeekNotifyByApplicationSchoolId( + event.id()); + + Exam1WeekBeforeNotifyVariablesDto dto = new Exam1WeekBeforeNotifyVariablesDto( + projection.examDate(), projection.paymentKey(), projection.schoolName()); + + String alimTalkContent = template.getProcessedMessage( + "notify.exam.oneweek.reminder.alimtalk", + dto.toMap()); + + String smsContent = template.getProcessedMessage("notify.exam.oneweek.reminder.sms", + dto.toMap()); + + LocalDateTime reserveTime = projection.examDate() + .minusDays(7) + .atTime(8, 0); + + NotifyButtonUrls btnUrls = NotifyButtonUrls.of( + NotifyButtonUrl.of(INQUIRY, INQUIRY) + ); + + NotifyEventRemindMessageDto eventMessage = NotifyEventRemindMessageDto.create(1, + event.telNum(), reserveTime, + alimTalkContent, + smsContent, btnUrls); + + return template.getNotifyEventRemindTemplate(EXAM_1WEEK_BEFORE_TEMPLATE_ID, eventMessage); + } +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam3DayBeforeNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam3DayBeforeNotifyStrategy.java new file mode 100644 index 00000000..489ee7ac --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam3DayBeforeNotifyStrategy.java @@ -0,0 +1,64 @@ +package life.mosu.mosuserver.infra.notify.strategy; + +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.EXAM_3DAY_BEFORE_TEMPLATE_ID; +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.INQUIRY; +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.MYPAGE; + +import java.time.LocalDateTime; +import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaEntity; +import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaRepository; +import life.mosu.mosuserver.global.exception.CustomRuntimeException; +import life.mosu.mosuserver.global.exception.ErrorCode; +import life.mosu.mosuserver.infra.notify.NotifyEvent; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.dto.Exam3DayBeforeNotifyVariablesDto; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRemindMessageDto; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class Exam3DayBeforeNotifyStrategy implements NotifyStrategy { + + private final NotifyEventTemplate template; + private final ApplicationSchoolJpaRepository applicationSchoolJpaRepository; + + @Override + public NotifyEventRequest create(NotifyEvent event) { + ApplicationSchoolJpaEntity applicationSchool = applicationSchoolJpaRepository.findById( + event.id()).orElseThrow( + () -> new CustomRuntimeException(ErrorCode.APPLICATION_SCHOOL_NOT_FOUND)); + + Exam3DayBeforeNotifyVariablesDto dto = new Exam3DayBeforeNotifyVariablesDto( + applicationSchool.getExamDate(), applicationSchool.getExaminationNumber(), + applicationSchool.getSchoolName()); + + String alimTalkContent = template.getProcessedMessage( + "notify.exam.threeday.reminder.alimtalk", + dto.toMap()); + + String smsContent = template.getProcessedMessage("notify.exam.threeday.reminder.sms", + dto.toMap()); + + LocalDateTime reserveTime = applicationSchool.getExamDate() + .minusDays(3) + .atTime(8, 0); + + NotifyButtonUrls btnUrls = NotifyButtonUrls.of( + NotifyButtonUrl.of(INQUIRY, INQUIRY), + NotifyButtonUrl.of(MYPAGE, MYPAGE) + ); + + NotifyEventRemindMessageDto eventMessage = NotifyEventRemindMessageDto.create(1, + event.telNum(), reserveTime, + alimTalkContent, + smsContent, btnUrls); + + return template.getNotifyEventRemindTemplate(EXAM_3DAY_BEFORE_TEMPLATE_ID, eventMessage); + + + } +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/InquiryAnswerNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/InquiryAnswerNotifyStrategy.java new file mode 100644 index 00000000..5b368192 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/InquiryAnswerNotifyStrategy.java @@ -0,0 +1,51 @@ +package life.mosu.mosuserver.infra.notify.strategy; + +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.INQUIRY; +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.INQUIRY_ANSWER_TEMPLATE_ID; + +import life.mosu.mosuserver.domain.inquiry.InquiryJpaEntity; +import life.mosu.mosuserver.domain.inquiry.InquiryJpaRepository; +import life.mosu.mosuserver.global.exception.CustomRuntimeException; +import life.mosu.mosuserver.global.exception.ErrorCode; +import life.mosu.mosuserver.infra.notify.NotifyEvent; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.dto.InquiryAnswerNotifyVariablesDto; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventSuccessMessageDto; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class InquiryAnswerNotifyStrategy implements NotifyStrategy { + + private final NotifyEventTemplate template; + private final InquiryJpaRepository inquiryJpaRepository; + + @Override + public NotifyEventRequest create(NotifyEvent event) { + InquiryJpaEntity inquiry = inquiryJpaRepository.findById(event.id()) + .orElseThrow(() -> new CustomRuntimeException( + ErrorCode.INQUIRY_NOT_FOUND)); + + InquiryAnswerNotifyVariablesDto dto = new InquiryAnswerNotifyVariablesDto( + inquiry.getTitle()); + + String alimTalkContent = template.getProcessedMessage("notify.inquiry.answered.alimtalk", + dto.toMap()); + + NotifyButtonUrls btnUrls = NotifyButtonUrls.of( + NotifyButtonUrl.of(INQUIRY, INQUIRY) + ); + + NotifyEventSuccessMessageDto eventMessage = NotifyEventSuccessMessageDto.create(1, + event.telNum(), alimTalkContent, + "", "0", btnUrls); + return template.getNotifyEventSuccessTemplate(INQUIRY_ANSWER_TEMPLATE_ID, eventMessage); + + } + + +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/RefundNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/RefundNotifyStrategy.java new file mode 100644 index 00000000..a9d4db18 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/RefundNotifyStrategy.java @@ -0,0 +1,55 @@ +package life.mosu.mosuserver.infra.notify.strategy; + +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.MYPAGE; +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.REFUND_TEMPLATE_ID; + +import life.mosu.mosuserver.domain.refund.RefundJpaRepository; +import life.mosu.mosuserver.domain.refund.RefundNotifyProjection; +import life.mosu.mosuserver.infra.notify.NotifyEvent; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventSuccessMessageDto; +import life.mosu.mosuserver.infra.notify.dto.RefundNotifyVariablesDto; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class RefundNotifyStrategy implements NotifyStrategy { + + private final NotifyEventTemplate template; + private final RefundJpaRepository refundJpaRepository; + + @Override + public NotifyEventRequest create(NotifyEvent event) { + RefundNotifyProjection projection = refundJpaRepository.findRefundByApplicationSchoolId( + event.id()); + + //TODO: 가격 추가 + RefundNotifyVariablesDto dto = new RefundNotifyVariablesDto( + projection.paymentKey(), projection.examDate(), projection.schoolName(), + projection.paymentMethod().getName(), + projection.reason()); + + String alimTalkContent = template.getProcessedMessage( + "notify.refund.complete.alimtalk", + dto.toMap()); + + String smsContent = template.getProcessedMessage("notify.refund.complete.sms", + dto.toMap()); + + NotifyButtonUrls btnUrls = NotifyButtonUrls.of( + NotifyButtonUrl.of(MYPAGE, MYPAGE) + ); + + NotifyEventSuccessMessageDto eventMessage = NotifyEventSuccessMessageDto.create(1, + event.telNum(), alimTalkContent, + smsContent, "1", btnUrls); + return template.getNotifyEventSuccessTemplate(REFUND_TEMPLATE_ID + , eventMessage); + } + + +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/SignUpNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/SignUpNotifyStrategy.java new file mode 100644 index 00000000..3ca1f9dc --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/SignUpNotifyStrategy.java @@ -0,0 +1,42 @@ +package life.mosu.mosuserver.infra.notify.strategy; + +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.HOMEPAGE; +import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.SIGN_UP_TEMPLATE_ID; + +import java.util.Locale; +import life.mosu.mosuserver.domain.inquiry.InquiryJpaRepository; +import life.mosu.mosuserver.infra.notify.NotifyEvent; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventSuccessMessageDto; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.context.MessageSource; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class SignUpNotifyStrategy implements NotifyStrategy { + + private final MessageSource messageSource; + private final NotifyEventTemplate template; + private final InquiryJpaRepository inquiryJpaRepository; + + @Override + public NotifyEventRequest create(NotifyEvent event) { + + String alimTalkContent = messageSource.getMessage("notify.signup.complete.alimtalk", null, + Locale.KOREA); + + NotifyButtonUrls btnUrls = NotifyButtonUrls.of( + NotifyButtonUrl.of(HOMEPAGE, HOMEPAGE) + ); + + NotifyEventSuccessMessageDto eventMessage = NotifyEventSuccessMessageDto.create( + 1, event.telNum(), alimTalkContent, "", + "0", + btnUrls); + return template.getNotifyEventSuccessTemplate(SIGN_UP_TEMPLATE_ID, eventMessage); + } +} From abeeae7cfdd4af3e5c5ce077e92113bb7d50ae32 Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:33:29 +0900 Subject: [PATCH 04/32] =?UTF-8?q?MOSU-28=20feat:=20=EA=B0=81=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=ED=86=A1=20=EB=B3=80=EC=88=98=20dto=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/ApplicationNotifyVariablesDto.java | 22 ++++++++++++++++ .../dto/Exam1DayBeforeNotifyVariablesDto.java | 19 ++++++++++++++ .../Exam1WeekBeforeNotifyVariablesDto.java | 19 ++++++++++++++ .../dto/Exam3DayBeforeNotifyVariablesDto.java | 19 ++++++++++++++ .../dto/InquiryAnswerNotifyVariablesDto.java | 14 +++++++++++ .../notify/dto/RefundNotifyVariablesDto.java | 25 +++++++++++++++++++ 6 files changed, 118 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/dto/ApplicationNotifyVariablesDto.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/dto/Exam1DayBeforeNotifyVariablesDto.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/dto/Exam1WeekBeforeNotifyVariablesDto.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/dto/Exam3DayBeforeNotifyVariablesDto.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/dto/InquiryAnswerNotifyVariablesDto.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/dto/RefundNotifyVariablesDto.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/ApplicationNotifyVariablesDto.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/ApplicationNotifyVariablesDto.java new file mode 100644 index 00000000..5a8b0f5c --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/ApplicationNotifyVariablesDto.java @@ -0,0 +1,22 @@ +package life.mosu.mosuserver.infra.notify.dto; + +import java.time.LocalDate; +import java.util.Map; + +public record ApplicationNotifyVariablesDto( + String paymentKey, + LocalDate examDate, + String schoolName, + String lunch +) { + + public Map toMap() { + return Map.of( + "paymentKey", paymentKey, + "examDate", examDate.toString(), + "schoolName", schoolName, + "lunch", lunch + ); + } + +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/Exam1DayBeforeNotifyVariablesDto.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/Exam1DayBeforeNotifyVariablesDto.java new file mode 100644 index 00000000..b4cb7736 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/Exam1DayBeforeNotifyVariablesDto.java @@ -0,0 +1,19 @@ +package life.mosu.mosuserver.infra.notify.dto; + +import java.time.LocalDate; +import java.util.Map; + +public record Exam1DayBeforeNotifyVariablesDto( + LocalDate examDate, + String examinationNumber, + String schoolName +) { + + public Map toMap() { + return Map.of( + "examDate", examDate.toString(), + "examinationNumber", examinationNumber, + "schoolName", schoolName + ); + } +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/Exam1WeekBeforeNotifyVariablesDto.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/Exam1WeekBeforeNotifyVariablesDto.java new file mode 100644 index 00000000..7653c59c --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/Exam1WeekBeforeNotifyVariablesDto.java @@ -0,0 +1,19 @@ +package life.mosu.mosuserver.infra.notify.dto; + +import java.time.LocalDate; +import java.util.Map; + +public record Exam1WeekBeforeNotifyVariablesDto( + LocalDate examDate, + String paymentKey, + String schoolName +) { + + public Map toMap() { + return Map.of( + "examDate", examDate.toString(), + "paymentKey", paymentKey, + "schoolName", schoolName + ); + } +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/Exam3DayBeforeNotifyVariablesDto.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/Exam3DayBeforeNotifyVariablesDto.java new file mode 100644 index 00000000..a37c0cfa --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/Exam3DayBeforeNotifyVariablesDto.java @@ -0,0 +1,19 @@ +package life.mosu.mosuserver.infra.notify.dto; + +import java.time.LocalDate; +import java.util.Map; + +public record Exam3DayBeforeNotifyVariablesDto( + LocalDate examDate, + String examinationNumber, + String schoolName +) { + + public Map toMap() { + return Map.of( + "examDate", examDate.toString(), + "examinationNumber", examinationNumber, + "schoolName", schoolName + ); + } +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/InquiryAnswerNotifyVariablesDto.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/InquiryAnswerNotifyVariablesDto.java new file mode 100644 index 00000000..3b739c2d --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/InquiryAnswerNotifyVariablesDto.java @@ -0,0 +1,14 @@ +package life.mosu.mosuserver.infra.notify.dto; + +import java.util.Map; + +public record InquiryAnswerNotifyVariablesDto( + String title +) { + + public Map toMap() { + return Map.of( + "inquiryTitle", title + ); + } +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/RefundNotifyVariablesDto.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/RefundNotifyVariablesDto.java new file mode 100644 index 00000000..6adfd2a3 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/RefundNotifyVariablesDto.java @@ -0,0 +1,25 @@ +package life.mosu.mosuserver.infra.notify.dto; + +import java.time.LocalDate; +import java.util.Map; + +public record RefundNotifyVariablesDto( + String paymentKey, + LocalDate examDate, + String schoolName, +// String amount, + String paymentMethod, + String reason +) { + + public Map toMap() { + return Map.of( + "paymentKey", paymentKey, + "examDate", examDate.toString(), + "schoolName", schoolName, +// "amount", amount, + "paymentMethod", paymentMethod, + "reason", reason + ); + } +} From f1828d822a02aae25c2afa7bb9a2382776705012 Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:34:34 +0900 Subject: [PATCH 05/32] =?UTF-8?q?MOSU-28=20feat:=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=ED=86=A1=20request=20=EA=B4=80=EB=A0=A8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notify/dto/NotifyButtonUrl.java | 24 +++++++++++++++++++ .../notify/dto/NotifyButtonUrls.java | 21 ++++++++++++++++ .../notify/dto/NotifyEventRequest.java | 14 +++++++++++ 3 files changed, 59 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrl.java create mode 100644 src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrls.java create mode 100644 src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyEventRequest.java diff --git a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrl.java b/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrl.java new file mode 100644 index 00000000..a710b56c --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrl.java @@ -0,0 +1,24 @@ +package life.mosu.mosuserver.presentation.notify.dto; + +import java.util.Map; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class NotifyButtonUrl { + + private String urlPc; + private String urlMobile; + + public static NotifyButtonUrl of(String urlPc, String urlMobile) { + return new NotifyButtonUrl(urlPc, urlMobile); + } + + public Map toMap() { + return Map.of( + "url_pc", urlPc, + "url_mobile", urlMobile + ); + } +} \ No newline at end of file diff --git a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrls.java b/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrls.java new file mode 100644 index 00000000..eb621017 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrls.java @@ -0,0 +1,21 @@ +package life.mosu.mosuserver.presentation.notify.dto; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class NotifyButtonUrls { + + private final List btnUrls; + + public static NotifyButtonUrls of(NotifyButtonUrl... btns) { + return new NotifyButtonUrls(Arrays.asList(btns)); + } + + public List> toMapList() { + return btnUrls.stream().map(NotifyButtonUrl::toMap).collect(Collectors.toList()); + } +} diff --git a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyEventRequest.java b/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyEventRequest.java new file mode 100644 index 00000000..354fdf1b --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyEventRequest.java @@ -0,0 +1,14 @@ +package life.mosu.mosuserver.presentation.notify.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import java.util.Map; + +public record NotifyEventRequest( + @JsonProperty("userId") String userId, + @JsonProperty("api_key") String apiKey, + @JsonProperty("template_id") Integer templateId, + @JsonProperty("messages") List> messages +) { + +} \ No newline at end of file From 397caeadb0c9b55121b6260d2d2cfdaeba319939 Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:35:11 +0900 Subject: [PATCH 06/32] =?UTF-8?q?MOSU-28=20feat:=20MessageSourceConfig=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/MessageSourceConfig.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/global/config/MessageSourceConfig.java diff --git a/src/main/java/life/mosu/mosuserver/global/config/MessageSourceConfig.java b/src/main/java/life/mosu/mosuserver/global/config/MessageSourceConfig.java new file mode 100644 index 00000000..6f9cb3ea --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/global/config/MessageSourceConfig.java @@ -0,0 +1,18 @@ +package life.mosu.mosuserver.global.config; + +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ReloadableResourceBundleMessageSource; + +@Configuration +public class MessageSourceConfig { + + @Bean + public MessageSource messageSource() { + ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); + messageSource.setBasename("classpath:messages"); + messageSource.setDefaultEncoding("UTF-8"); + return messageSource; + } +} \ No newline at end of file From e65f5e2e39f17b6e25fe6dfa2989ef6bdfb91cc8 Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:35:36 +0900 Subject: [PATCH 07/32] =?UTF-8?q?MOSU-28=20feat:=20WebClientConfig=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/WebClientConfig.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/global/config/WebClientConfig.java diff --git a/src/main/java/life/mosu/mosuserver/global/config/WebClientConfig.java b/src/main/java/life/mosu/mosuserver/global/config/WebClientConfig.java new file mode 100644 index 00000000..a166b5ee --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/global/config/WebClientConfig.java @@ -0,0 +1,17 @@ +package life.mosu.mosuserver.global.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.web.reactive.function.client.WebClient; + +@Configuration +public class WebClientConfig { + + @Bean + public WebClient webClient() { + return WebClient.builder() + .defaultHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .build(); + } +} From f4247b51ce30323859362b5383d89830cfb9492f Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:36:13 +0900 Subject: [PATCH 08/32] =?UTF-8?q?MOSU-28=20feat:=20NotifyStrategy=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EB=B0=8F=20NotifyStrategyMap=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/notify/strategy/NotifyStrategy.java | 9 ++++ .../notify/strategy/NotifyStrategyMap.java | 43 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategy.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategyMap.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategy.java new file mode 100644 index 00000000..15eaa555 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategy.java @@ -0,0 +1,9 @@ +package life.mosu.mosuserver.infra.notify.strategy; + +import life.mosu.mosuserver.infra.notify.NotifyEvent; +import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; + +public interface NotifyStrategy { + + NotifyEventRequest create(NotifyEvent event); +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategyMap.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategyMap.java new file mode 100644 index 00000000..d924d4b1 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategyMap.java @@ -0,0 +1,43 @@ +package life.mosu.mosuserver.infra.notify.strategy; + +import java.util.EnumMap; +import java.util.Map; +import life.mosu.mosuserver.global.exception.CustomRuntimeException; +import life.mosu.mosuserver.global.exception.ErrorCode; +import life.mosu.mosuserver.presentation.notify.dto.NotifyStatus; +import org.springframework.stereotype.Component; + +@Component +public class NotifyStrategyMap { + + private final Map strategies = new EnumMap<>(NotifyStatus.class); + + public NotifyStrategyMap( + ApplicationNotifyStrategy application, + Exam1DayBeforeNotifyStrategy exam1Day, + Exam3DayBeforeNotifyStrategy exam3Day, + Exam1WeekBeforeNotifyStrategy exam1Week, + InquiryAnswerNotifyStrategy inquiryAnswer, + RefundNotifyStrategy refund, + SignUpNotifyStrategy signUp + + ) { + strategies.put(NotifyStatus.APPLICATION_SUCCESS, application); + strategies.put(NotifyStatus.EXAM_1DAY_BEFORE_REMINDER_INFO, exam1Day); + strategies.put(NotifyStatus.EXAM_3DAY_BEFORE_REMINDER_INFO, exam3Day); + strategies.put(NotifyStatus.EXAM_1WEEK_BEFORE_REMINDER_INFO, exam1Week); + strategies.put(NotifyStatus.INQUIRY_ANSWER_SUCCESS, inquiryAnswer); + strategies.put(NotifyStatus.REFUND_SUCCESS, refund); + strategies.put(NotifyStatus.SIGN_UP_SUCCESS, signUp); + + } + + public NotifyStrategy getStrategy(NotifyStatus status) { + NotifyStrategy strategy = strategies.get(status); + if (strategy == null) { + throw new CustomRuntimeException(ErrorCode.STRATEGY_NOT_FOUND); + } + return strategy; + } +} + From 8a2bbd57f3b712c70761717a2a30e3e53b42d69e Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:36:45 +0900 Subject: [PATCH 09/32] =?UTF-8?q?MOSU-28=20feat:=20Notify=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20request=20message=20dto=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/NotifyEventRemindMessageDto.java | 47 +++++++++++++++++++ .../dto/NotifyEventSuccessMessageDto.java | 40 ++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventRemindMessageDto.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventSuccessMessageDto.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventRemindMessageDto.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventRemindMessageDto.java new file mode 100644 index 00000000..0294384c --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventRemindMessageDto.java @@ -0,0 +1,47 @@ +package life.mosu.mosuserver.infra.notify.dto; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; + +public record NotifyEventRemindMessageDto( + Integer no, + String telNum, + LocalDateTime reserveTime, + String msgContent, + String smsContent, + NotifyButtonUrls btnUrls +) { + + public static NotifyEventRemindMessageDto create( + Integer no, + String telNum, + LocalDateTime reserveTime, + String msgContent, + String smsContent, + NotifyButtonUrls btnUrls + ) { + return new NotifyEventRemindMessageDto( + no, + telNum, + reserveTime, + msgContent, + smsContent, + btnUrls + ); + } + + public Map toMap() { + Map map = new HashMap<>(); + map.put("no", no); + map.put("tel_num", telNum); + map.put("reserve_time", reserveTime); + map.put("msg_content", msgContent); + map.put("sms_content", smsContent); + map.put("use_sms", "1"); + map.put("btn_url", btnUrls.toMapList()); + return map; + } + +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventSuccessMessageDto.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventSuccessMessageDto.java new file mode 100644 index 00000000..d2924ce6 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventSuccessMessageDto.java @@ -0,0 +1,40 @@ +package life.mosu.mosuserver.infra.notify.dto; + +import java.util.HashMap; +import java.util.Map; +import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; + +public record NotifyEventSuccessMessageDto( + Integer no, + String telNum, + String msgContent, + String smsContent, + String useSms, + NotifyButtonUrls btnUrls +) { + + public static NotifyEventSuccessMessageDto create( + Integer no, + String telNum, + String msgContent, + String smsContent, + String useSms, + NotifyButtonUrls btnUrls + ) { + return new NotifyEventSuccessMessageDto( + no, telNum, msgContent, smsContent, useSms, btnUrls + ); + } + + + public Map toMap() { + Map map = new HashMap<>(); + map.put("no", no); + map.put("tel_num", telNum); + map.put("msg_content", msgContent); + map.put("sms_content", smsContent); + map.put("use_sms", useSms); + map.put("btn_url", btnUrls.toMapList()); + return map; + } +} From d76a5c8c019d6dae6ee909e03e110bfab0db9b99 Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:37:21 +0900 Subject: [PATCH 10/32] =?UTF-8?q?MOSU-28=20feat:=20NotifyEventTemplate=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(request=20=ED=98=95=EC=8B=9D=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/notify/NotifyEventTemplate.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventTemplate.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventTemplate.java b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventTemplate.java new file mode 100644 index 00000000..bfe477ac --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventTemplate.java @@ -0,0 +1,58 @@ +package life.mosu.mosuserver.infra.notify; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRemindMessageDto; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventSuccessMessageDto; +import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.MessageSource; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class NotifyEventTemplate { + + private final MessageSource messageSource; + @Value("${alimtalk.user-id}") + private String userId; + @Value("${alimtalk.api-key}") + private String apiKey; + + public String getProcessedMessage(String code, Map variables) { + String message = messageSource.getMessage(code, null, Locale.KOREA); + for (Map.Entry entry : variables.entrySet()) { + message = StringUtils.replace(message, "#{" + entry.getKey() + "}", entry.getValue()); + } + return message; + } + + public NotifyEventRequest getNotifyEventSuccessTemplate( + Integer templateId, + NotifyEventSuccessMessageDto message + ) { + + return new NotifyEventRequest( + userId, + apiKey, + templateId, + List.of(message.toMap()) + ); + } + + public NotifyEventRequest getNotifyEventRemindTemplate( + Integer templateId, + NotifyEventRemindMessageDto message + ) { + + return new NotifyEventRequest( + userId, + apiKey, + templateId, + List.of(message.toMap()) + ); + } +} From ecbca02fdbc463b2b7299899eaf29d0918f03d09 Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:38:16 +0900 Subject: [PATCH 11/32] =?UTF-8?q?MOSU-28=20feat:=20NotifyStatus=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84,=20EventStatus=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/notify/dto/EventStatus.java | 5 +++++ .../presentation/notify/dto/NotifyStatus.java | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/presentation/notify/dto/EventStatus.java create mode 100644 src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyStatus.java diff --git a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/EventStatus.java b/src/main/java/life/mosu/mosuserver/presentation/notify/dto/EventStatus.java new file mode 100644 index 00000000..6643a73c --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/presentation/notify/dto/EventStatus.java @@ -0,0 +1,5 @@ +package life.mosu.mosuserver.presentation.notify.dto; + +public enum EventStatus { + SUCCESS, FAILURE, INFO +} diff --git a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyStatus.java b/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyStatus.java new file mode 100644 index 00000000..a09339f5 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyStatus.java @@ -0,0 +1,21 @@ +package life.mosu.mosuserver.presentation.notify.dto; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum NotifyStatus { + + // success + SIGN_UP_SUCCESS(EventStatus.SUCCESS, "회원 가입 완료"), + APPLICATION_SUCCESS(EventStatus.SUCCESS, "신청 완료"), + REFUND_SUCCESS(EventStatus.SUCCESS, "환불 완료"), + INQUIRY_ANSWER_SUCCESS(EventStatus.SUCCESS, "문의 답변 완료"), + + // info + EXAM_1WEEK_BEFORE_REMINDER_INFO(EventStatus.INFO, "시험 1주일 전 리마인드 알림"), + EXAM_3DAY_BEFORE_REMINDER_INFO(EventStatus.INFO, "시험 3일 전 리마인드 알림"), + EXAM_1DAY_BEFORE_REMINDER_INFO(EventStatus.INFO, "시험 하루 전 리마인드 알림"); + + private final EventStatus status; + private final String message; +} From 97b4ad8d391b8499db6eebf18789fba82ebeeff7 Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:38:37 +0900 Subject: [PATCH 12/32] =?UTF-8?q?MOSU-28=20feat:=20Notify=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20errorCode=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../life/mosu/mosuserver/global/exception/ErrorCode.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/life/mosu/mosuserver/global/exception/ErrorCode.java b/src/main/java/life/mosu/mosuserver/global/exception/ErrorCode.java index be7dd28b..4a0d5563 100644 --- a/src/main/java/life/mosu/mosuserver/global/exception/ErrorCode.java +++ b/src/main/java/life/mosu/mosuserver/global/exception/ErrorCode.java @@ -83,7 +83,11 @@ public enum ErrorCode { INQUIRY_ANSWER_ALREADY_EXISTS(HttpStatus.CONFLICT, "이미 문의 답변이 존재합니다."), // 공지 관련 에러 - NOTICE_NOT_FOUND(HttpStatus.NOT_FOUND, "공지사항을 찾을 수 없습니다."); + NOTICE_NOT_FOUND(HttpStatus.NOT_FOUND, "공지사항을 찾을 수 없습니다."), + + // 알림톡 관련 에러 + NOTIFY_STATUS_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 알림을 찾을 수 없습니다."), + STRATEGY_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 전략을 찾을 수 없습니다."); private final HttpStatus status; private final String message; From bc5b2dd4e0976d8918111557be0a9852d51ff6e7 Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:39:22 +0900 Subject: [PATCH 13/32] =?UTF-8?q?MOSU-28=20feat:=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=ED=86=A1=20=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/messages_ko.properties | 132 ++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 src/main/resources/messages_ko.properties diff --git a/src/main/resources/messages_ko.properties b/src/main/resources/messages_ko.properties new file mode 100644 index 00000000..87a51ce9 --- /dev/null +++ b/src/main/resources/messages_ko.properties @@ -0,0 +1,132 @@ +notify.exam.application.complete.alimtalk=\ +[\uBAA8\uC218] \uBAA8\uC758 \uC218\uB2A5 \uC2E0\uCCAD\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4!\n\n\ +\u25A0 \uACB0\uC81C\uBC88\uD638: #{paymentKey}\n\ +\u25A0 \uC751\uC2DC\uC77C\uC790: #{examDate}\n\ +\u25A0 \uC2DC\uD5D8\uC7A5\uC18C: #{schoolName}\n\ +\u25A0 \uB3C4\uC2DC\uB77D \uC2E0\uCCAD: #{lunch}\n\n\ +\uC2DC\uD5D8 1\uC8FC\uC77C \uC804, \uC2DC\uD5D8 \uAD00\uB828 \uC720\uC758\uC0AC\uD56D\uACFC \uC218\uD5D8\uD45C \uC548\uB0B4 \uB9AC\uB9C8\uC778\uB4DC \uC54C\uB9BC\uC774 \uBC1C\uC1A1\uB420 \uC608\uC815\uC785\uB2C8\uB2E4. +notify.exam.application.complete.sms=\ +[\uBAA8\uC218] \uBAA8\uC758 \uC218\uB2A5 \uC2E0\uCCAD\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4!\n\n\ +\u25A0 \uACB0\uC81C\uBC88\uD638: #{paymentKey}\n\ +\u25A0 \uC751\uC2DC\uC77C\uC790: #{examDate}\n\ +\u25A0 \uC2DC\uD5D8\uC7A5\uC18C: #{schoolName}\n\ +\u25A0 \uB3C4\uC2DC\uB77D \uC2E0\uCCAD: #{lunch}\n\n\ +\uC2DC\uD5D8 1\uC8FC\uC77C \uC804, \uC2DC\uD5D8 \uAD00\uB828 \uC720\uC758\uC0AC\uD56D\uACFC \uC218\uD5D8\uD45C \uC548\uB0B4 \uB9AC\uB9C8\uC778\uB4DC \uC54C\uB9BC\uC774 \uBC1C\uC1A1\uB420 \uC608\uC815\uC785\uB2C8\uB2E4. +notify.exam.oneweek.reminder.alimtalk=\ +[\uBAA8\uC218] \uBAA8\uC758 \uC218\uB2A5\uC774 1\uC8FC\uC77C \uC55E\uC73C\uB85C \uB2E4\uAC00\uC654\uC2B5\uB2C8\uB2E4!\n\n\ +\u25A0 \uC2DC\uD5D8\uC77C\uC790: #{examDate}\n\ +\u25A0 \uC218\uD5D8\uBC88\uD638: #{examinationNumber}\n\ +\u25A0 \uC2DC\uD5D8\uC7A5\uC18C: #{schoolName}\n\n\ + *\uC2DC\uD5D8 \uC804 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8*\n\ + - \uC624\uC804 08:00\uAE4C\uC9C0 \uC785\uC2E4 \uC644\uB8CC (\uC9C0\uAC01 \uC2DC \uBCC4\uB3C4\uB85C \uB9C8\uB828\uB41C \uB300\uAE30\uC2E4\uC5D0\uC11C \uB300\uAE30 \uD6C4 \uC785\uC7A5 \uAC00\uB2A5)\n\ + - \uC218\uD5D8\uD45C\uC640 \uC2E0\uBD84\uC99D \uC9C0\uCC38\n\ + - \uC751\uC2DC\uD560 \uBAA8\uC758\uACE0\uC0AC \uC9C0\uCC38\n\ + - \uC751\uC2DC\uD560 \uBAA8\uC758\uACE0\uC0AC \uD45C\uC9C0\uC5D0 \uC218\uD5D8\uBC88\uD638\uC640 \uC774\uB984 \uAE30\uC7AC\n\ + - \uB3C4\uC2DC\uB77D \uC2E0\uCCAD\uC790\uB294 \uD604\uC7A5 \uB3C4\uC2DC\uB77D \uC81C\uACF5\n\ + - \uAC10\uB3C5\uAD00 \uC9C0\uC2DC \uBBF8\uC774\uD589 \uC2DC \uD1F4\uC2E4 \uC870\uCE58 \uAC00\uB2A5\n\n\ + *\uC804\uCCB4 \uC720\uC758\uC0AC\uD56D \uAF2D \uC77D\uC5B4\uBCF4\uAE30* +notify.exam.oneweek.reminder.sms=\ +[\uBAA8\uC218] \uBAA8\uC758 \uC218\uB2A5\uC774 1\uC8FC\uC77C \uC55E\uC73C\uB85C \uB2E4\uAC00\uC654\uC2B5\uB2C8\uB2E4!\n\n\ +\u25A0 \uC2DC\uD5D8\uC77C\uC790: #{examDate}\n\ +\u25A0 \uC218\uD5D8\uBC88\uD638: #{examinationNumber}\n\ +\u25A0 \uC2DC\uD5D8\uC7A5\uC18C: #{schoolName}\n\n\ + *\uC2DC\uD5D8 \uC804 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8*\n\ + - \uC624\uC804 08:00\uAE4C\uC9C0 \uC785\uC2E4 \uC644\uB8CC (\uC9C0\uAC01 \uC2DC \uBCC4\uB3C4\uB85C \uB9C8\uB828\uB41C \uB300\uAE30\uC2E4\uC5D0\uC11C \uB300\uAE30 \uD6C4 \uC785\uC7A5 \uAC00\uB2A5)\n\ + - \uC218\uD5D8\uD45C\uC640 \uC2E0\uBD84\uC99D \uC9C0\uCC38\n\ + - \uC751\uC2DC\uD560 \uBAA8\uC758\uACE0\uC0AC \uC9C0\uCC38\n\ + - \uC751\uC2DC\uD560 \uBAA8\uC758\uACE0\uC0AC \uD45C\uC9C0\uC5D0 \uC218\uD5D8\uBC88\uD638\uC640 \uC774\uB984 \uAE30\uC7AC\n\ + - \uB3C4\uC2DC\uB77D \uC2E0\uCCAD\uC790\uB294 \uD604\uC7A5 \uB3C4\uC2DC\uB77D \uC81C\uACF5\n\ + - \uAC10\uB3C5\uAD00 \uC9C0\uC2DC \uBBF8\uC774\uD589 \uC2DC \uD1F4\uC2E4 \uC870\uCE58 \uAC00\uB2A5\n\n\ + *\uC804\uCCB4 \uC720\uC758\uC0AC\uD56D \uAF2D \uC77D\uC5B4\uBCF4\uAE30* +notify.exam.threeday.reminder.alimtalk=\ +[\uBAA8\uC218] \uBAA8\uC758 \uC218\uB2A5 \uC751\uC2DC\uC77C 3\uC77C \uC804 \uC785\uB2C8\uB2E4!\n\n\ +\u25A0 \uC2DC\uD5D8\uC77C\uC790: #{examDate}\n\ +\u25A0 \uC218\uD5D8\uBC88\uD638: #{examinationNumber}\n\ +\u25A0 \uC2DC\uD5D8\uC7A5\uC18C: #{schoolName}\n\n\ + *\uC2DC\uD5D8 \uC804 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8*\n\ + - \uC624\uC804 08:00\uAE4C\uC9C0 \uC785\uC2E4 \uC644\uB8CC (\uC9C0\uAC01 \uC2DC \uBCC4\uB3C4\uB85C \uB9C8\uB828\uB41C \uB300\uAE30\uC2E4\uC5D0\uC11C \uB300\uAE30 \uD6C4 \uC785\uC7A5 \uAC00\uB2A5)\n\ + - \uC218\uD5D8\uD45C\uC640 \uC2E0\uBD84\uC99D \uC9C0\uCC38\n\ + - \uC751\uC2DC\uD560 \uBAA8\uC758\uACE0\uC0AC \uC9C0\uCC38\n\ + - \uC751\uC2DC\uD560 \uBAA8\uC758\uACE0\uC0AC \uD45C\uC9C0\uC5D0 \uC218\uD5D8\uBC88\uD638\uC640 \uC774\uB984 \uAE30\uC7AC\n\ + - \uB3C4\uC2DC\uB77D \uC2E0\uCCAD\uC790\uB294 \uD604\uC7A5 \uB3C4\uC2DC\uB77D \uC81C\uACF5\n\ + - \uAC10\uB3C5\uAD00 \uC9C0\uC2DC \uBBF8\uC774\uD589 \uC2DC \uD1F4\uC2E4 \uC870\uCE58 \uAC00\uB2A5\n\n\ + *\uC804\uCCB4 \uC720\uC758\uC0AC\uD56D \uAF2D \uC77D\uC5B4\uBCF4\uAE30*\n\n\ + *\uC218\uD5D8\uD45C\uAC00 \uBC1C\uAE09\uB418\uC5C8\uC2B5\uB2C8\uB2E4.*\n\ +\uB9C8\uC774\uD398\uC774\uC9C0 > \uC2E0\uCCAD\uB0B4\uC5ED > \uC218\uD5D8\uD45C \uCD9C\uB825\uC5D0\uC11C \uD655\uC778\uD558\uC2E4 \uC218 \uC788\uC2B5\uB2C8\uB2E4. +notify.exam.threeday.reminder.sms=\ + [\uBAA8\uC218] \uBAA8\uC758 \uC218\uB2A5 \uC751\uC2DC\uC77C 3\uC77C \uC804 \uC785\uB2C8\uB2E4!\n\n\ +\u25A0 \uC2DC\uD5D8\uC77C\uC790: #{examDate}\n\ +\u25A0 \uC218\uD5D8\uBC88\uD638: #{examinationNumber}\n\ +\u25A0 \uC2DC\uD5D8\uC7A5\uC18C: #{schoolName}\n\n\ + *\uC2DC\uD5D8 \uC804 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8*\n\ + - \uC624\uC804 08:00\uAE4C\uC9C0 \uC785\uC2E4 \uC644\uB8CC (\uC9C0\uAC01 \uC2DC \uBCC4\uB3C4\uB85C \uB9C8\uB828\uB41C \uB300\uAE30\uC2E4\uC5D0\uC11C \uB300\uAE30 \uD6C4 \uC785\uC7A5 \uAC00\uB2A5)\n\ + - \uC218\uD5D8\uD45C\uC640 \uC2E0\uBD84\uC99D \uC9C0\uCC38\n\ + - \uC751\uC2DC\uD560 \uBAA8\uC758\uACE0\uC0AC \uC9C0\uCC38\n\ + - \uC751\uC2DC\uD560 \uBAA8\uC758\uACE0\uC0AC \uD45C\uC9C0\uC5D0 \uC218\uD5D8\uBC88\uD638\uC640 \uC774\uB984 \uAE30\uC7AC\n\ + - \uB3C4\uC2DC\uB77D \uC2E0\uCCAD\uC790\uB294 \uD604\uC7A5 \uB3C4\uC2DC\uB77D \uC81C\uACF5\n\ + - \uAC10\uB3C5\uAD00 \uC9C0\uC2DC \uBBF8\uC774\uD589 \uC2DC \uD1F4\uC2E4 \uC870\uCE58 \uAC00\uB2A5\n\n\ + *\uC804\uCCB4 \uC720\uC758\uC0AC\uD56D \uAF2D \uC77D\uC5B4\uBCF4\uAE30*\n\n\ + *\uC218\uD5D8\uD45C\uAC00 \uBC1C\uAE09\uB418\uC5C8\uC2B5\uB2C8\uB2E4.*\n\ +\uB9C8\uC774\uD398\uC774\uC9C0 > \uC2E0\uCCAD\uB0B4\uC5ED > \uC218\uD5D8\uD45C \uCD9C\uB825\uC5D0\uC11C \uD655\uC778\uD558\uC2E4 \uC218 \uC788\uC2B5\uB2C8\uB2E4. +notify.exam.oneday.reminder.alimtalk=\ +[\uBAA8\uC218] \uB0B4\uC77C\uC740 \uBAA8\uC758 \uC218\uB2A5 \uC751\uC2DC\uC77C\uC785\uB2C8\uB2E4!\n\n\ +\u25A0 \uC2DC\uD5D8\uC77C\uC790: #{examDate}\n\ +\u25A0 \uC218\uD5D8\uBC88\uD638: #{examinationNumber}\n\ +\u25A0 \uC2DC\uD5D8\uC7A5\uC18C: #{schoolName}\n\n\ + *\uC2DC\uD5D8 \uC804 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8*\n\ + - \uC624\uC804 08:00\uAE4C\uC9C0 \uC785\uC2E4 \uC644\uB8CC (\uC9C0\uAC01 \uC2DC \uBCC4\uB3C4\uB85C \uB9C8\uB828\uB41C \uB300\uAE30\uC2E4\uC5D0\uC11C \uB300\uAE30 \uD6C4 \uC785\uC7A5 \uAC00\uB2A5)\n\ + - \uC218\uD5D8\uD45C\uC640 \uC2E0\uBD84\uC99D \uC9C0\uCC38\n\ + - \uC751\uC2DC\uD560 \uBAA8\uC758\uACE0\uC0AC \uC9C0\uCC38\n\ + - \uC751\uC2DC\uD560 \uBAA8\uC758\uACE0\uC0AC \uD45C\uC9C0\uC5D0 \uC218\uD5D8\uBC88\uD638\uC640 \uC774\uB984 \uAE30\uC7AC\n\ + - \uB3C4\uC2DC\uB77D \uC2E0\uCCAD\uC790\uB294 \uD604\uC7A5 \uB3C4\uC2DC\uB77D \uC81C\uACF5\n\ + - \uAC10\uB3C5\uAD00 \uC9C0\uC2DC \uBBF8\uC774\uD589 \uC2DC \uD1F4\uC2E4 \uC870\uCE58 \uAC00\uB2A5\n\n\ + *\uC804\uCCB4 \uC720\uC758\uC0AC\uD56D \uAF2D \uC77D\uC5B4\uBCF4\uAE30*\n\n\ + *\uC218\uD5D8\uD45C\uAC00 \uBC1C\uAE09\uB418\uC5C8\uC2B5\uB2C8\uB2E4.*\n\ +\uB9C8\uC774\uD398\uC774\uC9C0 > \uC2E0\uCCAD\uB0B4\uC5ED > \uC218\uD5D8\uD45C \uCD9C\uB825\uC5D0\uC11C \uD655\uC778\uD558\uC2E4 \uC218 \uC788\uC2B5\uB2C8\uB2E4. +notify.exam.oneday.reminder.sms=\ +[\uBAA8\uC218] \uB0B4\uC77C\uC740 \uBAA8\uC758 \uC218\uB2A5 \uC751\uC2DC\uC77C\uC785\uB2C8\uB2E4!\n\n\ +\u25A0 \uC2DC\uD5D8\uC77C\uC790: #{examDate}\n\ +\u25A0 \uC218\uD5D8\uBC88\uD638: #{examinationNumber}\n\ +\u25A0 \uC2DC\uD5D8\uC7A5\uC18C: #{schoolName}\n\n\ + *\uC2DC\uD5D8 \uC804 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8*\n\ + - \uC624\uC804 08:00\uAE4C\uC9C0 \uC785\uC2E4 \uC644\uB8CC (\uC9C0\uAC01 \uC2DC \uBCC4\uB3C4\uB85C \uB9C8\uB828\uB41C \uB300\uAE30\uC2E4\uC5D0\uC11C \uB300\uAE30 \uD6C4 \uC785\uC7A5 \uAC00\uB2A5)\n\ + - \uC218\uD5D8\uD45C\uC640 \uC2E0\uBD84\uC99D \uC9C0\uCC38\n\ + - \uC751\uC2DC\uD560 \uBAA8\uC758\uACE0\uC0AC \uC9C0\uCC38\n\ + - \uC751\uC2DC\uD560 \uBAA8\uC758\uACE0\uC0AC \uD45C\uC9C0\uC5D0 \uC218\uD5D8\uBC88\uD638\uC640 \uC774\uB984 \uAE30\uC7AC\n\ + - \uB3C4\uC2DC\uB77D \uC2E0\uCCAD\uC790\uB294 \uD604\uC7A5 \uB3C4\uC2DC\uB77D \uC81C\uACF5\n\ + - \uAC10\uB3C5\uAD00 \uC9C0\uC2DC \uBBF8\uC774\uD589 \uC2DC \uD1F4\uC2E4 \uC870\uCE58 \uAC00\uB2A5\n\n\ + *\uC804\uCCB4 \uC720\uC758\uC0AC\uD56D \uAF2D \uC77D\uC5B4\uBCF4\uAE30*\n\n\ + *\uC218\uD5D8\uD45C\uAC00 \uBC1C\uAE09\uB418\uC5C8\uC2B5\uB2C8\uB2E4.*\n\ +\uB9C8\uC774\uD398\uC774\uC9C0 > \uC2E0\uCCAD\uB0B4\uC5ED > \uC218\uD5D8\uD45C \uCD9C\uB825\uC5D0\uC11C \uD655\uC778\uD558\uC2E4 \uC218 \uC788\uC2B5\uB2C8\uB2E4. +notify.signup.complete.alimtalk=\ +[\uBAA8\uC218] \uD68C\uC6D0\uAC00\uC785\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n\n\ +\uC9C0\uAE08\uBD80\uD130 \uBAA8\uC758\uC218\uB2A5 \uC2E0\uCCAD\uC744 \uC9C4\uD589\uD558\uC2E4 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n\ +\uC2E0\uCCAD \uB0B4\uC5ED\uC740 \uB9C8\uC774\uD398\uC774\uC9C0\uC5D0\uC11C \uD56D\uC2DC \uD655\uC778 \uAC00\uB2A5\uD569\uB2C8\uB2E4.\n\ +\uBAA8\uC218\uC640 \uD568\uAED8 \uC218\uB2A5\uC744 \uBBF8\uB9AC \uACBD\uD5D8\uD574\uBCF4\uC138\uC694!\n\ +\uCC44\uB110 \uCD94\uAC00\uD558\uACE0 \uC774 \uCC44\uB110\uC758 \uB9C8\uCF00\uD305 \uBA54\uC2DC\uC9C0 \uB4F1\uC744 \uCE74\uCE74\uC624\uD1A1\uC73C\uB85C \uBC1B\uAE30 +notify.inquiry.answered.alimtalk=\ +[\uBAA8\uC218] \uBB38\uC758\uD558\uC2E0 \uB0B4\uC6A9\uC5D0 \uB2F5\uBCC0\uC774 \uB4F1\uB85D\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n\n\ +\uC81C\uBAA9: #{inquiryTitle}\n\n\ +\uB2F5\uBCC0\uC740 [\uBB38\uC758\uD558\uAE30 > \uB0B4 \uBB38\uC758\uAE00 \uC870\uD68C]\uC5D0\uC11C \uD655\uC778\uD558\uC2E4 \uC218 \uC788\uC2B5\uB2C8\uB2E4. +notify.refund.complete.alimtalk=\ +[\uBAA8\uC218] \uD658\uBD88\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n\n\ +\u25A0 \uACB0\uC81C\uBC88\uD638: #{paymentKey}\n\ +\u25A0 \uC751\uC2DC\uC77C\uC790: #{examDate}\n\ +\u25A0 \uC2DC\uD5D8\uC7A5\uC18C: #{schoolName}\n\ +\u25A0 \uD658\uBD88 \uAE08\uC561: #{refundAmount}\n\ +\u25A0 \uACB0\uC81C \uC218\uB2E8: #{paymentMethod}\n\ +\u25A0 \uCC98\uB9AC \uC0AC\uC720: #{reason}\n\n\ +\uC694\uCCAD\uD558\uC2E0 \uD658\uBD88\uC740 \uB0B4\uBD80 \uADDC\uC815\uC5D0 \uB530\uB77C \uCC98\uB9AC\uB418\uC5C8\uC73C\uBA70,\n\ +\uACB0\uC81C \uC218\uB2E8\uC744 \uD1B5\uD574 \uC601\uC5C5\uC77C \uAE30\uC900 3~7\uC77C \uC774\uB0B4 \uC785\uAE08\uB420 \uC608\uC815\uC785\uB2C8\uB2E4.\n\ +\uD658\uBD88 \uB0B4\uC5ED \uBC0F \uC2E0\uCCAD \uC815\uBCF4\uB294 \uB9C8\uC774\uD398\uC774\uC9C0\uC5D0\uC11C \uD655\uC778\uD558\uC2E4 \uC218 \uC788\uC2B5\uB2C8\uB2E4. +notify.refund.complete.sms=\ +[\uBAA8\uC218] \uD658\uBD88\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n\n\ +\u25A0 \uACB0\uC81C\uBC88\uD638: #{paymentKey}\n\ +\u25A0 \uC751\uC2DC\uC77C\uC790: #{examDate}\n\ +\u25A0 \uC2DC\uD5D8\uC7A5\uC18C: #{schoolName}\n\ +\u25A0 \uD658\uBD88 \uAE08\uC561: #{refundAmount}\n\ +\u25A0 \uACB0\uC81C \uC218\uB2E8: #{paymentMethod}\n\ +\u25A0 \uCC98\uB9AC \uC0AC\uC720: #{reason}\n\n\ +\uC694\uCCAD\uD558\uC2E0 \uD658\uBD88\uC740 \uB0B4\uBD80 \uADDC\uC815\uC5D0 \uB530\uB77C \uCC98\uB9AC\uB418\uC5C8\uC73C\uBA70,\n\ +\uACB0\uC81C \uC218\uB2E8\uC744 \uD1B5\uD574 \uC601\uC5C5\uC77C \uAE30\uC900 3~7\uC77C \uC774\uB0B4 \uC785\uAE08\uB420 \uC608\uC815\uC785\uB2C8\uB2E4.\n\ +\uD658\uBD88 \uB0B4\uC5ED \uBC0F \uC2E0\uCCAD \uC815\uBCF4\uB294 \uB9C8\uC774\uD398\uC774\uC9C0\uC5D0\uC11C \uD655\uC778\uD558\uC2E4 \uC218 \uC788\uC2B5\uB2C8\uB2E4. From 34ed522dc24b86f61706641a1160ddad358198de Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:39:46 +0900 Subject: [PATCH 14/32] =?UTF-8?q?MOSU-28=20feat:=20NotifyConstants=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notify/constant/NotifyConstants.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/constant/NotifyConstants.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/constant/NotifyConstants.java b/src/main/java/life/mosu/mosuserver/infra/notify/constant/NotifyConstants.java new file mode 100644 index 00000000..b68c2947 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/constant/NotifyConstants.java @@ -0,0 +1,23 @@ +package life.mosu.mosuserver.infra.notify.constant; + +public final class NotifyConstants { + + public static final String HOMEPAGE = "https://www.mosuedu.com"; + public static final String MYPAGE = "https://www.mosuedu.com/mypage"; + public static final String WARNING = "https://www.mosuedu.com/warning"; + public static final String INQUIRY = "https://www.mosuedu.com/notice"; + + public static final Integer APPLICATION_TEMPLATE_ID = 50037; + public static final Integer EXAM_1DAY_BEFORE_TEMPLATE_ID = 50041; + public static final Integer EXAM_3DAY_BEFORE_TEMPLATE_ID = 50040; + public static final Integer EXAM_1WEEK_BEFORE_TEMPLATE_ID = 50039; + public static final Integer INQUIRY_ANSWER_TEMPLATE_ID = 50038; + public static final Integer SIGN_UP_TEMPLATE_ID = 50042; + public static final Integer REFUND_TEMPLATE_ID = 50043; + + + private NotifyConstants() { + } + + +} From f245fd33a4efa094aea070a04f462c7c6a2b59cc Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:40:22 +0900 Subject: [PATCH 15/32] =?UTF-8?q?MOSU-28=20feat:=20NotifyEvent,=20NotifyEv?= =?UTF-8?q?entListener,=20NotifyEventPublisher=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosuserver/infra/notify/NotifyEvent.java | 15 +++++++++++++ .../infra/notify/NotifyEventPublisher.java | 16 ++++++++++++++ .../notify/NotifyEventListener.java | 22 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/NotifyEvent.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventPublisher.java create mode 100644 src/main/java/life/mosu/mosuserver/presentation/notify/NotifyEventListener.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEvent.java b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEvent.java new file mode 100644 index 00000000..88990c4d --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEvent.java @@ -0,0 +1,15 @@ +package life.mosu.mosuserver.infra.notify; + +import life.mosu.mosuserver.presentation.notify.dto.NotifyStatus; + +public record NotifyEvent( + NotifyStatus status, + String telNum, + Long id +) { + + public static NotifyEvent create(NotifyStatus status, String telNum, Long id) { + return new NotifyEvent(status, telNum, id); + } + +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventPublisher.java b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventPublisher.java new file mode 100644 index 00000000..96536d01 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventPublisher.java @@ -0,0 +1,16 @@ +package life.mosu.mosuserver.infra.notify; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class NotifyEventPublisher { + + private final ApplicationEventPublisher publisher; + + public void notify(NotifyEvent event) { + publisher.publishEvent(event); + } +} diff --git a/src/main/java/life/mosu/mosuserver/presentation/notify/NotifyEventListener.java b/src/main/java/life/mosu/mosuserver/presentation/notify/NotifyEventListener.java new file mode 100644 index 00000000..2e1b61fc --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/presentation/notify/NotifyEventListener.java @@ -0,0 +1,22 @@ +package life.mosu.mosuserver.presentation.notify; + +import life.mosu.mosuserver.global.annotation.ReactiveEventListener; +import life.mosu.mosuserver.infra.notify.NotifyEvent; +import life.mosu.mosuserver.infra.notify.service.NotifyService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@RequiredArgsConstructor +public class NotifyEventListener { + + private final NotifyService notifyService; + + @ReactiveEventListener + public void notify(NotifyEvent event) { + notifyService.notify(event); + log.info("Notify event: {}", event); + } +} From 401a17aff13901c0d7c64ed181b9882f313c4ce5 Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:40:48 +0900 Subject: [PATCH 16/32] =?UTF-8?q?MOSU-28=20feat:=20ReactiveEventListener?= =?UTF-8?q?=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/annotation/ReactiveEventListener.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/global/annotation/ReactiveEventListener.java diff --git a/src/main/java/life/mosu/mosuserver/global/annotation/ReactiveEventListener.java b/src/main/java/life/mosu/mosuserver/global/annotation/ReactiveEventListener.java new file mode 100644 index 00000000..898ad70c --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/global/annotation/ReactiveEventListener.java @@ -0,0 +1,16 @@ +package life.mosu.mosuserver.global.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Async +@EventListener +public @interface ReactiveEventListener { + +} \ No newline at end of file From 633d821b03aa187a7f3e5fb25c2d685f035042cf Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:45:47 +0900 Subject: [PATCH 17/32] =?UTF-8?q?MOSU-28=20feat:=20=EB=8B=B5=EB=B3=80=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=EC=8B=9C=20=EC=95=8C=EB=A6=BC=ED=86=A1=20?= =?UTF-8?q?=EB=B0=9C=EC=86=A1=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inquiry/InquiryAnswerService.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java b/src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java index fd95e8f1..bafee8d4 100644 --- a/src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java +++ b/src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java @@ -4,12 +4,18 @@ import life.mosu.mosuserver.domain.inquiry.InquiryJpaRepository; import life.mosu.mosuserver.domain.inquiryAnswer.InquiryAnswerJpaEntity; import life.mosu.mosuserver.domain.inquiryAnswer.InquiryAnswerJpaRepository; +import life.mosu.mosuserver.domain.profile.ProfileJpaEntity; +import life.mosu.mosuserver.domain.profile.ProfileJpaRepository; +import life.mosu.mosuserver.domain.user.UserJpaRepository; import life.mosu.mosuserver.global.exception.CustomRuntimeException; import life.mosu.mosuserver.global.exception.ErrorCode; +import life.mosu.mosuserver.infra.notify.NotifyEvent; +import life.mosu.mosuserver.infra.notify.NotifyEventPublisher; import life.mosu.mosuserver.presentation.inquiry.dto.InquiryAnswerRequest; import life.mosu.mosuserver.presentation.inquiry.dto.InquiryAnswerUpdateRequest; import life.mosu.mosuserver.presentation.inquiry.dto.InquiryDetailResponse; import life.mosu.mosuserver.presentation.inquiry.dto.InquiryDetailResponse.InquiryAnswerDetailResponse; +import life.mosu.mosuserver.presentation.notify.dto.NotifyStatus; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; @@ -22,6 +28,10 @@ public class InquiryAnswerService { private final InquiryAnswerAttachmentService answerAttachmentService; private final InquiryAnswerJpaRepository inquiryAnswerJpaRepository; private final InquiryJpaRepository inquiryJpaRepository; + private final UserJpaRepository userJpaRepository; + private final ProfileJpaRepository profileJpaRepository; + private final NotifyEventPublisher notifyEventPublisher; + @Transactional public void createInquiryAnswer(Long postId, InquiryAnswerRequest request) { @@ -36,6 +46,13 @@ public void createInquiryAnswer(Long postId, InquiryAnswerRequest request) { answerAttachmentService.createAttachment(request.attachments(), answerEntity); inquiryEntity.updateStatusToComplete(); + + ProfileJpaEntity profile = profileJpaRepository.findByUserId(inquiryEntity.getUserId()) + .orElseThrow(() -> new RuntimeException("")); + NotifyEvent event = NotifyEvent.create(NotifyStatus.INQUIRY_ANSWER_SUCCESS, + profile.getPhoneNumber(), postId); + notifyEventPublisher.notify(event); + } @Transactional From 88c9b4dfdd83fe6d74bc57396ce5e112870e04fd Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:46:57 +0900 Subject: [PATCH 18/32] =?UTF-8?q?MOSU-28=20chore:=20webflux=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index f9c4143b..621905e8 100644 --- a/build.gradle +++ b/build.gradle @@ -85,6 +85,8 @@ dependencies { // poi-excel implementation 'org.apache.poi:poi-ooxml:5.4.0' + + implementation 'org.springframework.boot:spring-boot-starter-webflux' } tasks.named('test') { From 4cd5e74a05b8541cdab4a8bc8b0d0537278d099b Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:47:36 +0900 Subject: [PATCH 19/32] =?UTF-8?q?MOSU-28=20feat:=20NotifyService=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/notify/service/NotifyService.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/service/NotifyService.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/service/NotifyService.java b/src/main/java/life/mosu/mosuserver/infra/notify/service/NotifyService.java new file mode 100644 index 00000000..2c61e83e --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/service/NotifyService.java @@ -0,0 +1,41 @@ +package life.mosu.mosuserver.infra.notify.service; + +import life.mosu.mosuserver.infra.notify.NotifyEvent; +import life.mosu.mosuserver.infra.notify.strategy.NotifyStrategy; +import life.mosu.mosuserver.infra.notify.strategy.NotifyStrategyMap; +import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.WebClient; + +@Slf4j +@Service +@RequiredArgsConstructor +public class NotifyService { + + private final NotifyStrategyMap strategyMap; + private final WebClient webClient; + @Value("${alimtalk.api.base-url}") + private String alimTalkUrl; + + + public void notify(NotifyEvent event) { + + NotifyStrategy strategy = strategyMap.getStrategy(event.status()); + NotifyEventRequest request = strategy.create(event); + + webClient.post() + .uri(alimTalkUrl) + .bodyValue(request) + .retrieve() + .bodyToMono(String.class) + .doOnSuccess(response -> log.info("알림톡 응답: {}", response)) + .doOnError(error -> log.error("알림톡 전송 실패", error)) + .doOnTerminate(() -> + log.info("알림톡 전송 완료: {}", request)) + .subscribe(); + } + +} From 2a0a9c12e765fc5af01c709f5909f17bb8cf71ac Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:50:05 +0900 Subject: [PATCH 20/32] =?UTF-8?q?MOSU-28=20feat:=20ApplicationNotify,=20On?= =?UTF-8?q?eWeekNotify=20=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=A1=B0=ED=9A=8C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApplicationSchoolJpaRepository.java | 19 +++++++++++++++++++ .../ApplicationSchoolNotifyProjection.java | 13 +++++++++++++ .../OneWeekNotifyProjection.java | 11 +++++++++++ 3 files changed, 43 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/domain/applicationschool/ApplicationSchoolNotifyProjection.java create mode 100644 src/main/java/life/mosu/mosuserver/domain/applicationschool/OneWeekNotifyProjection.java diff --git a/src/main/java/life/mosu/mosuserver/domain/applicationschool/ApplicationSchoolJpaRepository.java b/src/main/java/life/mosu/mosuserver/domain/applicationschool/ApplicationSchoolJpaRepository.java index 0c4755ce..857a21d3 100644 --- a/src/main/java/life/mosu/mosuserver/domain/applicationschool/ApplicationSchoolJpaRepository.java +++ b/src/main/java/life/mosu/mosuserver/domain/applicationschool/ApplicationSchoolJpaRepository.java @@ -8,6 +8,7 @@ public interface ApplicationSchoolJpaRepository extends JpaRepository { +// boolean existsByUserIdAndSchoolIds(Long userId, List schoolId); boolean existsByUserIdAndSchoolId(Long userId, Long schoolId); @@ -15,7 +16,25 @@ public interface ApplicationSchoolJpaRepository extends boolean existsByApplicationId(Long applicationId); + @Query("SELECT COUNT(a) = :size FROM ApplicationSchoolJpaEntity a WHERE a.id IN :applicationSchoolIds") boolean existsAllByIds(@Param("applicationSchoolIds") List applicationSchoolIds, @Param("size") long size); + + @Query(""" + SELECT p.paymentKey, a.examDate, a.schoolName, a.lunch + FROM ApplicationSchoolJpaEntity a + LEFT JOIN PaymentJpaEntity p ON a.id = p.applicationSchoolId + WHERE a.id = :applicationSchoolId + """) + ApplicationSchoolNotifyProjection findPaymentByApplicationSchoolId(Long applicationSchoolId); + + @Query(""" + SELECT p.paymentKey, a.examDate, a.schoolName + FROM ApplicationSchoolJpaEntity a + JOIN PaymentJpaEntity p ON a.id = p.applicationSchoolId + WHERE a.id = :applicationSchoolId + """) + OneWeekNotifyProjection findOneWeekNotifyByApplicationSchoolId(Long applicationSchoolId); + } diff --git a/src/main/java/life/mosu/mosuserver/domain/applicationschool/ApplicationSchoolNotifyProjection.java b/src/main/java/life/mosu/mosuserver/domain/applicationschool/ApplicationSchoolNotifyProjection.java new file mode 100644 index 00000000..00d64e07 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/domain/applicationschool/ApplicationSchoolNotifyProjection.java @@ -0,0 +1,13 @@ +package life.mosu.mosuserver.domain.applicationschool; + +import java.time.LocalDate; +import life.mosu.mosuserver.domain.application.Lunch; + +public record ApplicationSchoolNotifyProjection( + String paymentKey, + LocalDate examDate, + String schoolName, + Lunch lunch +) { + +} diff --git a/src/main/java/life/mosu/mosuserver/domain/applicationschool/OneWeekNotifyProjection.java b/src/main/java/life/mosu/mosuserver/domain/applicationschool/OneWeekNotifyProjection.java new file mode 100644 index 00000000..cb63335b --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/domain/applicationschool/OneWeekNotifyProjection.java @@ -0,0 +1,11 @@ +package life.mosu.mosuserver.domain.applicationschool; + +import java.time.LocalDate; + +public record OneWeekNotifyProjection( + String paymentKey, + LocalDate examDate, + String schoolName +) { + +} From 9ff2c9a11aa4a9f10eb3959ea8176a83a9e0b2dc Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:50:39 +0900 Subject: [PATCH 21/32] =?UTF-8?q?MOSU-28=20feat:=20RefundNofity=20?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=EC=A0=95=EB=B3=B4=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/refund/RefundJpaRepository.java | 14 ++++++++++++++ .../domain/refund/RefundNotifyProjection.java | 15 +++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/domain/refund/RefundNotifyProjection.java diff --git a/src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaRepository.java b/src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaRepository.java index 3256da20..6fdc1ec8 100644 --- a/src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaRepository.java +++ b/src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaRepository.java @@ -1,6 +1,20 @@ package life.mosu.mosuserver.domain.refund; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; public interface RefundJpaRepository extends JpaRepository { + + @Query(""" + SELECT + p.paymentKey AS paymentKey, + a.examDate AS examDate, + p.paymentMethod AS paymentMethod, + r.reason AS reason + FROM RefundJpaEntity r + LEFT JOIN PaymentJpaEntity p ON r.applicationSchoolId = p.applicationSchoolId + LEFT JOIN ApplicationSchoolJpaEntity a ON r.applicationSchoolId = a.id + WHERE r.applicationSchoolId = :applicationSchoolId + """) + RefundNotifyProjection findRefundByApplicationSchoolId(Long applicationSchoolId); } diff --git a/src/main/java/life/mosu/mosuserver/domain/refund/RefundNotifyProjection.java b/src/main/java/life/mosu/mosuserver/domain/refund/RefundNotifyProjection.java new file mode 100644 index 00000000..c7aa3ace --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/domain/refund/RefundNotifyProjection.java @@ -0,0 +1,15 @@ +package life.mosu.mosuserver.domain.refund; + +import java.time.LocalDate; +import life.mosu.mosuserver.domain.payment.PaymentMethod; + +public record RefundNotifyProjection( + String paymentKey, + LocalDate examDate, + String schoolName, + PaymentMethod paymentMethod, + String reason + // TODO: 환불 금액 추가 +) { + +} From 32009b9bdaf4e03612dd682c49bb84744d20eefb Mon Sep 17 00:00:00 2001 From: chominju Date: Thu, 17 Jul 2025 00:51:10 +0900 Subject: [PATCH 22/32] =?UTF-8?q?MOSU-28=20feat:=20Application=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81=EC=9D=84=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EC=9E=84=EC=8B=9C=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/ApplicationService.java | 55 +++++++++++++++++++ .../domain/school/SchoolQueryRepository.java | 12 ++++ .../school/SchoolQueryRepositoryImpl.java | 38 +++++++++++++ .../infra/respository/BulkRepository.java | 25 +++++++++ 4 files changed, 130 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/domain/school/SchoolQueryRepository.java create mode 100644 src/main/java/life/mosu/mosuserver/domain/school/SchoolQueryRepositoryImpl.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/respository/BulkRepository.java diff --git a/src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java b/src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java index 2831ad9c..10a54dc7 100644 --- a/src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java +++ b/src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java @@ -11,6 +11,7 @@ import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaRepository; import life.mosu.mosuserver.domain.school.SchoolJpaEntity; import life.mosu.mosuserver.domain.school.SchoolJpaRepository; +import life.mosu.mosuserver.domain.school.SchoolQueryRepositoryImpl; import life.mosu.mosuserver.global.exception.CustomRuntimeException; import life.mosu.mosuserver.global.exception.ErrorCode; import life.mosu.mosuserver.global.util.FileRequest; @@ -31,6 +32,7 @@ public class ApplicationService { private final ApplicationJpaRepository applicationJpaRepository; private final ApplicationSchoolJpaRepository applicationSchoolJpaRepository; private final AdmissionTicketImageJpaRepository admissionTicketImageJpaRepository; + private final SchoolQueryRepositoryImpl schoolQueryRepository; private final SchoolJpaRepository schoolJpaRepository; // 신청 @@ -42,10 +44,12 @@ public ApplicationResponse apply(Long userId, ApplicationRequest request) { ApplicationJpaEntity application = applicationJpaRepository.save(request.toEntity(userId)); Long applicationId = application.getId(); + //수험표 저장 admissionTicketImageJpaRepository.save( createAdmissionTicketImageIfPresent(request.admissionTicket(), applicationId)); for (ApplicationSchoolRequest schoolRequest : schoolRequests) { + //해당 학교가 존재하는 학교인지 Long schoolId = schoolJpaRepository.findBySchoolNameAndAreaAndExamDate( schoolRequest.schoolName(), schoolRequest.validatedArea(schoolRequest.area()), @@ -53,21 +57,72 @@ public ApplicationResponse apply(Long userId, ApplicationRequest request) { .orElseThrow(() -> new CustomRuntimeException(ErrorCode.SCHOOL_NOT_FOUND)) .getId(); + //해당 학교를 이미 신청하였는지 if (applicationSchoolJpaRepository.existsByUserIdAndSchoolId(userId, schoolId)) { throw new CustomRuntimeException(ErrorCode.APPLICATION_SCHOOL_ALREADY_APPLIED); } + //해당 학교를 찾을 수 있는지 SchoolJpaEntity school = schoolJpaRepository.findById(schoolId) .orElseThrow(() -> new CustomRuntimeException(ErrorCode.SCHOOL_NOT_FOUND)); + //해당 학교를 신청했음을 저장하기 ApplicationSchoolJpaEntity applicationSchool = schoolRequest.toEntity(userId, applicationId, school); + + //반환용 리스트에 저장하기 savedEntities.add(applicationSchoolJpaRepository.save(applicationSchool)); } return ApplicationResponse.of(applicationId, savedEntities); } + //신청 - 리팩토링 +// @Transactional +// public ApplicationResponse apply(Long userId, ApplicationRequest request) { +// Set schoolRequests = request.schools(); +//// List savedEntities = new ArrayList<>(); +// +// ApplicationJpaEntity application = applicationJpaRepository.save(request.toEntity(userId)); +// Long applicationId = application.getId(); +// +// //수험표 저장 +// admissionTicketImageJpaRepository.save( +// createAdmissionTicketImageIfPresent(request.admissionTicket(), applicationId)); +// +// List> conditions = schoolRequests.stream() +// .map(school -> Triple.of( +// school.schoolName(), +// school.validatedArea(school.area()), +// school.examDate() +// )) +// .toList(); +// +// //이름, 지역, 날짜 조건에 맞는 학교가 있는지 +// List schoolIds = schoolQueryRepository.findSchoolsByConditions(conditions); +// if (schoolIds.size() != conditions.size()) { +// throw new CustomRuntimeException(ErrorCode.SCHOOL_NOT_FOUND); +// } +// +// //해당 학교를 이미 신청하였는지 +// if (applicationSchoolJpaRepository.existsByUserIdAndSchoolIds(userId, schoolIds)) { +// throw new CustomRuntimeException(ErrorCode.APPLICATION_SCHOOL_ALREADY_APPLIED); +// } +// + + /// / //해당 학교를 찾을 수 있는지 / SchoolJpaEntity school = + /// schoolJpaRepository.findById(schoolId) / .orElseThrow(() -> new + /// CustomRuntimeException(ErrorCode.SCHOOL_NOT_FOUND)); +// +// //해당 학교를 신청했음을 저장하기 +// ApplicationSchoolJpaEntity applicationSchool = schoolRequest.toEntity(userId, +// applicationId, school); +// +// //반환용 리스트에 저장하기 +// savedEntities.add(applicationSchoolJpaRepository.save(applicationSchool)); +// +// return ApplicationResponse.of(applicationId, savedEntities); +// } // 전체 신청 내역 조회 @Transactional(readOnly = true, propagation = Propagation.SUPPORTS) diff --git a/src/main/java/life/mosu/mosuserver/domain/school/SchoolQueryRepository.java b/src/main/java/life/mosu/mosuserver/domain/school/SchoolQueryRepository.java new file mode 100644 index 00000000..395d9973 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/domain/school/SchoolQueryRepository.java @@ -0,0 +1,12 @@ +package life.mosu.mosuserver.domain.school; + +import java.time.LocalDate; +import java.util.List; +import org.apache.commons.lang3.tuple.Triple; + +public interface SchoolQueryRepository { + + List findSchoolsByConditions( + List> conditions); + +} diff --git a/src/main/java/life/mosu/mosuserver/domain/school/SchoolQueryRepositoryImpl.java b/src/main/java/life/mosu/mosuserver/domain/school/SchoolQueryRepositoryImpl.java new file mode 100644 index 00000000..99d69be9 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/domain/school/SchoolQueryRepositoryImpl.java @@ -0,0 +1,38 @@ +package life.mosu.mosuserver.domain.school; + +import com.querydsl.core.BooleanBuilder; +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.time.LocalDate; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.tuple.Triple; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class SchoolQueryRepositoryImpl implements SchoolQueryRepository { + + private final JPAQueryFactory queryFactory; + + @Override + public List findSchoolsByConditions( + List> conditions) { + BooleanBuilder builder = new BooleanBuilder(); + + for (Triple cond : conditions) { + builder.or( + QSchoolJpaEntity.schoolJpaEntity.schoolName.eq(cond.getLeft()) + .and(QSchoolJpaEntity.schoolJpaEntity.area.eq(cond.getMiddle())) + .and(QSchoolJpaEntity.schoolJpaEntity.examDate.eq(cond.getRight())) + ); + } + + return queryFactory + .select(QSchoolJpaEntity.schoolJpaEntity.id) + .from(QSchoolJpaEntity.schoolJpaEntity) + .where(builder) + .fetch(); + } + + +} diff --git a/src/main/java/life/mosu/mosuserver/infra/respository/BulkRepository.java b/src/main/java/life/mosu/mosuserver/infra/respository/BulkRepository.java new file mode 100644 index 00000000..d495c486 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/respository/BulkRepository.java @@ -0,0 +1,25 @@ +package life.mosu.mosuserver.infra.respository; + +import java.util.List; +import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaEntity; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +@Repository +@RequiredArgsConstructor +public class BulkRepository { + + private final JdbcTemplate jdbcTemplate; + + @Transactional + public void saveAllApplicationSchools(List applicationSchools) { + String sql = """ + INSERT INTO application_school + (user_id, application_id, school_id, school_name, area, exam_date) + VALUES (?, ?, ?, ?, ?, ?) + """; + } + +} From f118a2dbb643eba4492e4b6fae26d194ee194faf Mon Sep 17 00:00:00 2001 From: KNU-K Date: Thu, 17 Jul 2025 02:56:35 +0900 Subject: [PATCH 23/32] =?UTF-8?q?feat:=20Notify=20=EA=B4=80=EB=A0=A8=20DTO?= =?UTF-8?q?=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=B0=8F=20=EC=83=81=ED=83=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notify/dto/EventStatus.java | 2 +- .../notify/dto/NotifyButtonUrl.java | 2 +- .../notify/dto/NotifyButtonUrls.java | 2 +- .../infra/notify/dto/NotifyEvent.java | 12 +++++++ .../infra/notify/dto/NotifyEventRequest.java | 11 +++++++ .../infra/notify/dto/NotifyStatus.java | 31 +++++++++++++++++++ .../notify/dto/NotifyEventRequest.java | 14 --------- .../presentation/notify/dto/NotifyStatus.java | 21 ------------- 8 files changed, 57 insertions(+), 38 deletions(-) rename src/main/java/life/mosu/mosuserver/{presentation => infra}/notify/dto/EventStatus.java (50%) rename src/main/java/life/mosu/mosuserver/{presentation => infra}/notify/dto/NotifyButtonUrl.java (89%) rename src/main/java/life/mosu/mosuserver/{presentation => infra}/notify/dto/NotifyButtonUrls.java (90%) create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEvent.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventRequest.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyStatus.java delete mode 100644 src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyEventRequest.java delete mode 100644 src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyStatus.java diff --git a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/EventStatus.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/EventStatus.java similarity index 50% rename from src/main/java/life/mosu/mosuserver/presentation/notify/dto/EventStatus.java rename to src/main/java/life/mosu/mosuserver/infra/notify/dto/EventStatus.java index 6643a73c..42ff0106 100644 --- a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/EventStatus.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/EventStatus.java @@ -1,4 +1,4 @@ -package life.mosu.mosuserver.presentation.notify.dto; +package life.mosu.mosuserver.infra.notify.dto; public enum EventStatus { SUCCESS, FAILURE, INFO diff --git a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrl.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyButtonUrl.java similarity index 89% rename from src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrl.java rename to src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyButtonUrl.java index a710b56c..b71d1291 100644 --- a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrl.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyButtonUrl.java @@ -1,4 +1,4 @@ -package life.mosu.mosuserver.presentation.notify.dto; +package life.mosu.mosuserver.infra.notify.dto; import java.util.Map; import lombok.Builder; diff --git a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrls.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyButtonUrls.java similarity index 90% rename from src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrls.java rename to src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyButtonUrls.java index eb621017..230d0928 100644 --- a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyButtonUrls.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyButtonUrls.java @@ -1,4 +1,4 @@ -package life.mosu.mosuserver.presentation.notify.dto; +package life.mosu.mosuserver.infra.notify.dto; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEvent.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEvent.java new file mode 100644 index 00000000..dcd9bf26 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEvent.java @@ -0,0 +1,12 @@ +package life.mosu.mosuserver.infra.notify.dto; + +public record NotifyEvent( + NotifyStatus status, + Long userId, + Long targetId +) { + + public static NotifyEvent create(NotifyStatus status, Long userId, Long targetId) { + return new NotifyEvent(status, userId, targetId); + } +} \ No newline at end of file diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventRequest.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventRequest.java new file mode 100644 index 00000000..8cb94292 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventRequest.java @@ -0,0 +1,11 @@ +package life.mosu.mosuserver.infra.notify.dto; + +import java.util.List; +import java.util.Map; + +public record NotifyEventRequest( + Integer templateId, + List> messages +) { + +} \ No newline at end of file diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyStatus.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyStatus.java new file mode 100644 index 00000000..ca7acc12 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyStatus.java @@ -0,0 +1,31 @@ +package life.mosu.mosuserver.infra.notify.dto; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +public enum NotifyStatus { + + // success + SIGN_UP_SUCCESS(EventStatus.SUCCESS, "회원 가입 완료", + "SignUpNotifyStrategy"), + APPLICATION_SUCCESS(EventStatus.SUCCESS, "신청 완료", + "ApplicationNotifyStrategy"), + REFUND_SUCCESS(EventStatus.SUCCESS, "환불 완료", + "RefundNotifyStrategy"), + INQUIRY_ANSWER_SUCCESS(EventStatus.SUCCESS, "문의 답변 완료", + "InquiryAnswerNotifyStrategy"), + + // info + EXAM_1WEEK_BEFORE_REMINDER_INFO(EventStatus.INFO, "시험 1주일 전 리마인드 알림", + "Exam1DayBeforeNotifyStrategy"), + EXAM_3DAY_BEFORE_REMINDER_INFO(EventStatus.INFO, "시험 3일 전 리마인드 알림", + "Exam3DayBeforeNotifyStrategy"), + EXAM_1DAY_BEFORE_REMINDER_INFO(EventStatus.INFO, "시험 하루 전 리마인드 알림", + "Exam1WeekBeforeNotifyStrategy"); + + private final EventStatus status; + private final String message; + private final String strategyName; +} diff --git a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyEventRequest.java b/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyEventRequest.java deleted file mode 100644 index 354fdf1b..00000000 --- a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyEventRequest.java +++ /dev/null @@ -1,14 +0,0 @@ -package life.mosu.mosuserver.presentation.notify.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; -import java.util.Map; - -public record NotifyEventRequest( - @JsonProperty("userId") String userId, - @JsonProperty("api_key") String apiKey, - @JsonProperty("template_id") Integer templateId, - @JsonProperty("messages") List> messages -) { - -} \ No newline at end of file diff --git a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyStatus.java b/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyStatus.java deleted file mode 100644 index a09339f5..00000000 --- a/src/main/java/life/mosu/mosuserver/presentation/notify/dto/NotifyStatus.java +++ /dev/null @@ -1,21 +0,0 @@ -package life.mosu.mosuserver.presentation.notify.dto; - -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public enum NotifyStatus { - - // success - SIGN_UP_SUCCESS(EventStatus.SUCCESS, "회원 가입 완료"), - APPLICATION_SUCCESS(EventStatus.SUCCESS, "신청 완료"), - REFUND_SUCCESS(EventStatus.SUCCESS, "환불 완료"), - INQUIRY_ANSWER_SUCCESS(EventStatus.SUCCESS, "문의 답변 완료"), - - // info - EXAM_1WEEK_BEFORE_REMINDER_INFO(EventStatus.INFO, "시험 1주일 전 리마인드 알림"), - EXAM_3DAY_BEFORE_REMINDER_INFO(EventStatus.INFO, "시험 3일 전 리마인드 알림"), - EXAM_1DAY_BEFORE_REMINDER_INFO(EventStatus.INFO, "시험 하루 전 리마인드 알림"); - - private final EventStatus status; - private final String message; -} From d768f97c2a4972df34756c9d8721d25152de3a72 Mon Sep 17 00:00:00 2001 From: KNU-K Date: Thu, 17 Jul 2025 02:57:41 +0900 Subject: [PATCH 24/32] =?UTF-8?q?feat:=20LunaSoftNotifier=20=EB=B0=8F=20No?= =?UTF-8?q?tifyClientAdapter,=20NotifyProperties=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/notify/LunaSoftNotifier.java | 65 +++++++++++++++++++ .../infra/notify/NotifyClientAdapter.java | 8 +++ .../infra/notify/NotifyProperties.java | 11 ++++ 3 files changed, 84 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/LunaSoftNotifier.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/NotifyClientAdapter.java create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/NotifyProperties.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/LunaSoftNotifier.java b/src/main/java/life/mosu/mosuserver/infra/notify/LunaSoftNotifier.java new file mode 100644 index 00000000..8d8a2cfe --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/LunaSoftNotifier.java @@ -0,0 +1,65 @@ +package life.mosu.mosuserver.infra.notify; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import java.util.Map; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.scheduler.Schedulers; + +@Component +@Slf4j +public class LunaSoftNotifier implements NotifyClientAdapter { + + private final WebClient webClient; + private final NotifyProperties properties; + + public LunaSoftNotifier( + WebClient webClient, + NotifyProperties properties + ) { + this.webClient = webClient; + this.properties = properties; + } + + @Override + public void send(NotifyEventRequest request) { + LunaNotifyRequest lunaRequest = createLunaNotifyRequest(request); + + webClient.post() + .uri(properties.alimTalkUrl) + .bodyValue(lunaRequest) + .retrieve() + .bodyToMono(String.class) + .publishOn(Schedulers.boundedElastic()) + .doOnSuccess(response -> log.info("알림톡 응답: {}", response)) + .doOnError(error -> log.error("알림톡 전송 실패", error)) + .doOnTerminate(() -> log.info("알림톡 전송 완료: {}", request)) + .subscribe(); + } + + private LunaNotifyRequest createLunaNotifyRequest(NotifyEventRequest request) { + return LunaNotifyRequest.of( + properties.userId, + properties.apiKey, + request.templateId(), + request.messages() + ); + } + + private record LunaNotifyRequest( + @JsonProperty("userId") String userId, + @JsonProperty("api_key") String apiKey, + @JsonProperty("template_id") Integer templateId, + @JsonProperty("messages") List> messages + ) { + + static LunaNotifyRequest of(String userId, String apiKey, Integer templateId, + List> messages) { + return new LunaNotifyRequest(userId, apiKey, templateId, messages); + } + } +} \ No newline at end of file diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/NotifyClientAdapter.java b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyClientAdapter.java new file mode 100644 index 00000000..ece759d4 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyClientAdapter.java @@ -0,0 +1,8 @@ +package life.mosu.mosuserver.infra.notify; + +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; + +public interface NotifyClientAdapter { + + void send(NotifyEventRequest request); +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/NotifyProperties.java b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyProperties.java new file mode 100644 index 00000000..78c76ee1 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyProperties.java @@ -0,0 +1,11 @@ +package life.mosu.mosuserver.infra.notify; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class NotifyProperties { + @Value("${alimtalk.api.base-url}") String alimTalkUrl; + @Value("${alimtalk.user-id}") String userId; + @Value("${alimtalk.api-key}") String apiKey; +} From 747d4bbc65dfbc3b1c85df1673f20f36424e6985 Mon Sep 17 00:00:00 2001 From: KNU-K Date: Thu, 17 Jul 2025 02:58:00 +0900 Subject: [PATCH 25/32] =?UTF-8?q?feat:=20NotifyStrategy=20=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=B0=8F=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=A0=84=EB=9E=B5=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81,=20targetPhoneNumber=20?= =?UTF-8?q?=EB=A7=A4=EA=B0=9C=EB=B3=80=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../strategy/ApplicationNotifyStrategy.java | 20 ++++----- .../Exam1DayBeforeNotifyStrategy.java | 20 ++++----- .../Exam1WeekBeforeNotifyStrategy.java | 20 ++++----- .../Exam3DayBeforeNotifyStrategy.java | 21 +++++---- .../strategy/InquiryAnswerNotifyStrategy.java | 24 ++++++----- .../infra/notify/strategy/NotifyStrategy.java | 6 +-- .../notify/strategy/NotifyStrategyMap.java | 43 ------------------- .../notify/strategy/RefundNotifyStrategy.java | 20 ++++----- .../notify/strategy/SignUpNotifyStrategy.java | 20 ++++----- 9 files changed, 76 insertions(+), 118 deletions(-) delete mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategyMap.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/ApplicationNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/ApplicationNotifyStrategy.java index 67364c79..39a8f1d9 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/ApplicationNotifyStrategy.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/ApplicationNotifyStrategy.java @@ -6,27 +6,27 @@ import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaRepository; import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolNotifyProjection; -import life.mosu.mosuserver.infra.notify.NotifyEvent; -import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplateGenerator; import life.mosu.mosuserver.infra.notify.dto.ApplicationNotifyVariablesDto; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.infra.notify.dto.NotifyEvent; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; import life.mosu.mosuserver.infra.notify.dto.NotifyEventSuccessMessageDto; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; -import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -@Component +@Component("ApplicationNotifyStrategy") @RequiredArgsConstructor public class ApplicationNotifyStrategy implements NotifyStrategy { - private final NotifyEventTemplate template; + private final NotifyEventTemplateGenerator template; private final ApplicationSchoolJpaRepository applicationSchoolJpaRepository; @Override - public NotifyEventRequest create(NotifyEvent event) { + public NotifyEventRequest apply(String targetPhoneNumber, NotifyEvent event) { ApplicationSchoolNotifyProjection projection = applicationSchoolJpaRepository.findPaymentByApplicationSchoolId( - event.id()); + event.targetId()); ApplicationNotifyVariablesDto dto = new ApplicationNotifyVariablesDto( projection.paymentKey(), projection.examDate(), projection.schoolName(), @@ -45,7 +45,7 @@ public NotifyEventRequest create(NotifyEvent event) { ); NotifyEventSuccessMessageDto eventMessage = NotifyEventSuccessMessageDto.create(1, - event.telNum(), alimTalkContent, + targetPhoneNumber, alimTalkContent, smsContent, "1", btnUrls); return template.getNotifyEventSuccessTemplate(APPLICATION_TEMPLATE_ID, eventMessage); } diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1DayBeforeNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1DayBeforeNotifyStrategy.java index 57da224e..fd9bc5b5 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1DayBeforeNotifyStrategy.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1DayBeforeNotifyStrategy.java @@ -9,27 +9,27 @@ import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaRepository; import life.mosu.mosuserver.global.exception.CustomRuntimeException; import life.mosu.mosuserver.global.exception.ErrorCode; -import life.mosu.mosuserver.infra.notify.NotifyEvent; -import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplateGenerator; import life.mosu.mosuserver.infra.notify.dto.Exam1DayBeforeNotifyVariablesDto; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.infra.notify.dto.NotifyEvent; import life.mosu.mosuserver.infra.notify.dto.NotifyEventRemindMessageDto; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; -import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -@Component +@Component("Exam1DayBeforeNotifyStrategy") @RequiredArgsConstructor public class Exam1DayBeforeNotifyStrategy implements NotifyStrategy { - private final NotifyEventTemplate template; + private final NotifyEventTemplateGenerator template; private final ApplicationSchoolJpaRepository applicationSchoolJpaRepository; @Override - public NotifyEventRequest create(NotifyEvent event) { + public NotifyEventRequest apply(String targetPhoneNumber, NotifyEvent event) { ApplicationSchoolJpaEntity applicationSchool = applicationSchoolJpaRepository.findById( - event.id()).orElseThrow( + event.targetId()).orElseThrow( () -> new CustomRuntimeException(ErrorCode.APPLICATION_SCHOOL_NOT_FOUND)); Exam1DayBeforeNotifyVariablesDto dto = new Exam1DayBeforeNotifyVariablesDto( @@ -53,7 +53,7 @@ public NotifyEventRequest create(NotifyEvent event) { ); NotifyEventRemindMessageDto eventMessage = NotifyEventRemindMessageDto.create(1, - event.telNum(), reserveTime, + targetPhoneNumber, reserveTime, alimTalkContent, smsContent, btnUrls); diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1WeekBeforeNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1WeekBeforeNotifyStrategy.java index 43c0c76a..042cf220 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1WeekBeforeNotifyStrategy.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam1WeekBeforeNotifyStrategy.java @@ -6,28 +6,28 @@ import java.time.LocalDateTime; import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaRepository; import life.mosu.mosuserver.domain.applicationschool.OneWeekNotifyProjection; -import life.mosu.mosuserver.infra.notify.NotifyEvent; -import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplateGenerator; import life.mosu.mosuserver.infra.notify.dto.Exam1WeekBeforeNotifyVariablesDto; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.infra.notify.dto.NotifyEvent; import life.mosu.mosuserver.infra.notify.dto.NotifyEventRemindMessageDto; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; -import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -@Component +@Component("Exam1WeekBeforeNotifyStrategy") @RequiredArgsConstructor public class Exam1WeekBeforeNotifyStrategy implements NotifyStrategy { - private final NotifyEventTemplate template; + private final NotifyEventTemplateGenerator template; private final ApplicationSchoolJpaRepository applicationSchoolJpaRepository; @Override - public NotifyEventRequest create(NotifyEvent event) { + public NotifyEventRequest apply(String targetPhoneNumber, NotifyEvent event) { OneWeekNotifyProjection projection = applicationSchoolJpaRepository.findOneWeekNotifyByApplicationSchoolId( - event.id()); + event.targetId()); Exam1WeekBeforeNotifyVariablesDto dto = new Exam1WeekBeforeNotifyVariablesDto( projection.examDate(), projection.paymentKey(), projection.schoolName()); @@ -48,7 +48,7 @@ public NotifyEventRequest create(NotifyEvent event) { ); NotifyEventRemindMessageDto eventMessage = NotifyEventRemindMessageDto.create(1, - event.telNum(), reserveTime, + targetPhoneNumber, reserveTime, alimTalkContent, smsContent, btnUrls); diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam3DayBeforeNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam3DayBeforeNotifyStrategy.java index 489ee7ac..1bd6b444 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam3DayBeforeNotifyStrategy.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/Exam3DayBeforeNotifyStrategy.java @@ -9,27 +9,27 @@ import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaRepository; import life.mosu.mosuserver.global.exception.CustomRuntimeException; import life.mosu.mosuserver.global.exception.ErrorCode; -import life.mosu.mosuserver.infra.notify.NotifyEvent; -import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplateGenerator; import life.mosu.mosuserver.infra.notify.dto.Exam3DayBeforeNotifyVariablesDto; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.infra.notify.dto.NotifyEvent; import life.mosu.mosuserver.infra.notify.dto.NotifyEventRemindMessageDto; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; -import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -@Component +@Component("Exam3DayBeforeNotifyStrategy") @RequiredArgsConstructor public class Exam3DayBeforeNotifyStrategy implements NotifyStrategy { - private final NotifyEventTemplate template; + private final NotifyEventTemplateGenerator template; private final ApplicationSchoolJpaRepository applicationSchoolJpaRepository; @Override - public NotifyEventRequest create(NotifyEvent event) { + public NotifyEventRequest apply(String targetPhoneNumber, NotifyEvent event) { ApplicationSchoolJpaEntity applicationSchool = applicationSchoolJpaRepository.findById( - event.id()).orElseThrow( + event.targetId()).orElseThrow( () -> new CustomRuntimeException(ErrorCode.APPLICATION_SCHOOL_NOT_FOUND)); Exam3DayBeforeNotifyVariablesDto dto = new Exam3DayBeforeNotifyVariablesDto( @@ -53,12 +53,11 @@ public NotifyEventRequest create(NotifyEvent event) { ); NotifyEventRemindMessageDto eventMessage = NotifyEventRemindMessageDto.create(1, - event.telNum(), reserveTime, + targetPhoneNumber, reserveTime, alimTalkContent, smsContent, btnUrls); return template.getNotifyEventRemindTemplate(EXAM_3DAY_BEFORE_TEMPLATE_ID, eventMessage); - } } diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/InquiryAnswerNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/InquiryAnswerNotifyStrategy.java index 5b368192..16361a17 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/InquiryAnswerNotifyStrategy.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/InquiryAnswerNotifyStrategy.java @@ -7,26 +7,30 @@ import life.mosu.mosuserver.domain.inquiry.InquiryJpaRepository; import life.mosu.mosuserver.global.exception.CustomRuntimeException; import life.mosu.mosuserver.global.exception.ErrorCode; -import life.mosu.mosuserver.infra.notify.NotifyEvent; -import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplateGenerator; import life.mosu.mosuserver.infra.notify.dto.InquiryAnswerNotifyVariablesDto; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.infra.notify.dto.NotifyEvent; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; import life.mosu.mosuserver.infra.notify.dto.NotifyEventSuccessMessageDto; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; -import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -@Component +@Slf4j +@Component("InquiryAnswerNotifyStrategy") @RequiredArgsConstructor public class InquiryAnswerNotifyStrategy implements NotifyStrategy { - private final NotifyEventTemplate template; + private final NotifyEventTemplateGenerator template; private final InquiryJpaRepository inquiryJpaRepository; + //inquiry ID 가 없음 @Override - public NotifyEventRequest create(NotifyEvent event) { - InquiryJpaEntity inquiry = inquiryJpaRepository.findById(event.id()) + public NotifyEventRequest apply(String targetPhoneNumber, NotifyEvent event) { + log.info("log: {}", inquiryJpaRepository.findAll()); + InquiryJpaEntity inquiry = inquiryJpaRepository.findById(event.targetId()) .orElseThrow(() -> new CustomRuntimeException( ErrorCode.INQUIRY_NOT_FOUND)); @@ -41,7 +45,7 @@ public NotifyEventRequest create(NotifyEvent event) { ); NotifyEventSuccessMessageDto eventMessage = NotifyEventSuccessMessageDto.create(1, - event.telNum(), alimTalkContent, + targetPhoneNumber, alimTalkContent, "", "0", btnUrls); return template.getNotifyEventSuccessTemplate(INQUIRY_ANSWER_TEMPLATE_ID, eventMessage); diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategy.java index 15eaa555..08421d52 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategy.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategy.java @@ -1,9 +1,9 @@ package life.mosu.mosuserver.infra.notify.strategy; -import life.mosu.mosuserver.infra.notify.NotifyEvent; -import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; +import life.mosu.mosuserver.infra.notify.dto.NotifyEvent; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; public interface NotifyStrategy { - NotifyEventRequest create(NotifyEvent event); + NotifyEventRequest apply(String targetPhoneNumber, NotifyEvent event); } diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategyMap.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategyMap.java deleted file mode 100644 index d924d4b1..00000000 --- a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/NotifyStrategyMap.java +++ /dev/null @@ -1,43 +0,0 @@ -package life.mosu.mosuserver.infra.notify.strategy; - -import java.util.EnumMap; -import java.util.Map; -import life.mosu.mosuserver.global.exception.CustomRuntimeException; -import life.mosu.mosuserver.global.exception.ErrorCode; -import life.mosu.mosuserver.presentation.notify.dto.NotifyStatus; -import org.springframework.stereotype.Component; - -@Component -public class NotifyStrategyMap { - - private final Map strategies = new EnumMap<>(NotifyStatus.class); - - public NotifyStrategyMap( - ApplicationNotifyStrategy application, - Exam1DayBeforeNotifyStrategy exam1Day, - Exam3DayBeforeNotifyStrategy exam3Day, - Exam1WeekBeforeNotifyStrategy exam1Week, - InquiryAnswerNotifyStrategy inquiryAnswer, - RefundNotifyStrategy refund, - SignUpNotifyStrategy signUp - - ) { - strategies.put(NotifyStatus.APPLICATION_SUCCESS, application); - strategies.put(NotifyStatus.EXAM_1DAY_BEFORE_REMINDER_INFO, exam1Day); - strategies.put(NotifyStatus.EXAM_3DAY_BEFORE_REMINDER_INFO, exam3Day); - strategies.put(NotifyStatus.EXAM_1WEEK_BEFORE_REMINDER_INFO, exam1Week); - strategies.put(NotifyStatus.INQUIRY_ANSWER_SUCCESS, inquiryAnswer); - strategies.put(NotifyStatus.REFUND_SUCCESS, refund); - strategies.put(NotifyStatus.SIGN_UP_SUCCESS, signUp); - - } - - public NotifyStrategy getStrategy(NotifyStatus status) { - NotifyStrategy strategy = strategies.get(status); - if (strategy == null) { - throw new CustomRuntimeException(ErrorCode.STRATEGY_NOT_FOUND); - } - return strategy; - } -} - diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/RefundNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/RefundNotifyStrategy.java index a9d4db18..e91b9889 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/RefundNotifyStrategy.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/RefundNotifyStrategy.java @@ -5,27 +5,27 @@ import life.mosu.mosuserver.domain.refund.RefundJpaRepository; import life.mosu.mosuserver.domain.refund.RefundNotifyProjection; -import life.mosu.mosuserver.infra.notify.NotifyEvent; -import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplateGenerator; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.infra.notify.dto.NotifyEvent; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; import life.mosu.mosuserver.infra.notify.dto.NotifyEventSuccessMessageDto; import life.mosu.mosuserver.infra.notify.dto.RefundNotifyVariablesDto; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; -import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -@Component +@Component("RefundNotifyStrategy") @RequiredArgsConstructor public class RefundNotifyStrategy implements NotifyStrategy { - private final NotifyEventTemplate template; + private final NotifyEventTemplateGenerator template; private final RefundJpaRepository refundJpaRepository; @Override - public NotifyEventRequest create(NotifyEvent event) { + public NotifyEventRequest apply(String targetPhoneNumber, NotifyEvent event) { RefundNotifyProjection projection = refundJpaRepository.findRefundByApplicationSchoolId( - event.id()); + event.targetId()); //TODO: 가격 추가 RefundNotifyVariablesDto dto = new RefundNotifyVariablesDto( @@ -45,7 +45,7 @@ public NotifyEventRequest create(NotifyEvent event) { ); NotifyEventSuccessMessageDto eventMessage = NotifyEventSuccessMessageDto.create(1, - event.telNum(), alimTalkContent, + targetPhoneNumber, alimTalkContent, smsContent, "1", btnUrls); return template.getNotifyEventSuccessTemplate(REFUND_TEMPLATE_ID , eventMessage); diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/SignUpNotifyStrategy.java b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/SignUpNotifyStrategy.java index 3ca1f9dc..2696923a 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/strategy/SignUpNotifyStrategy.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/strategy/SignUpNotifyStrategy.java @@ -4,27 +4,25 @@ import static life.mosu.mosuserver.infra.notify.constant.NotifyConstants.SIGN_UP_TEMPLATE_ID; import java.util.Locale; -import life.mosu.mosuserver.domain.inquiry.InquiryJpaRepository; -import life.mosu.mosuserver.infra.notify.NotifyEvent; -import life.mosu.mosuserver.infra.notify.NotifyEventTemplate; +import life.mosu.mosuserver.infra.notify.NotifyEventTemplateGenerator; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrl; +import life.mosu.mosuserver.infra.notify.dto.NotifyButtonUrls; +import life.mosu.mosuserver.infra.notify.dto.NotifyEvent; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; import life.mosu.mosuserver.infra.notify.dto.NotifyEventSuccessMessageDto; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrl; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; -import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; import lombok.RequiredArgsConstructor; import org.springframework.context.MessageSource; import org.springframework.stereotype.Component; -@Component +@Component("SignUpNotifyStrategy") @RequiredArgsConstructor public class SignUpNotifyStrategy implements NotifyStrategy { private final MessageSource messageSource; - private final NotifyEventTemplate template; - private final InquiryJpaRepository inquiryJpaRepository; + private final NotifyEventTemplateGenerator template; @Override - public NotifyEventRequest create(NotifyEvent event) { + public NotifyEventRequest apply(String targetPhoneNumber, NotifyEvent event) { String alimTalkContent = messageSource.getMessage("notify.signup.complete.alimtalk", null, Locale.KOREA); @@ -34,7 +32,7 @@ public NotifyEventRequest create(NotifyEvent event) { ); NotifyEventSuccessMessageDto eventMessage = NotifyEventSuccessMessageDto.create( - 1, event.telNum(), alimTalkContent, "", + 1, targetPhoneNumber, alimTalkContent, "", "0", btnUrls); return template.getNotifyEventSuccessTemplate(SIGN_UP_TEMPLATE_ID, eventMessage); From d5400be43c706ee718e96a4375c25374f58aab71 Mon Sep 17 00:00:00 2001 From: KNU-K Date: Thu, 17 Jul 2025 02:58:20 +0900 Subject: [PATCH 26/32] =?UTF-8?q?feat:=20NotifyConstants=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20?= =?UTF-8?q?=EB=B0=8F=20NotifyEvent=20DTO=EC=97=90=EC=84=9C=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20import=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/notify/constant/NotifyConstants.java | 10 ++++------ .../infra/notify/dto/NotifyEventRemindMessageDto.java | 1 - .../infra/notify/dto/NotifyEventSuccessMessageDto.java | 1 - 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/constant/NotifyConstants.java b/src/main/java/life/mosu/mosuserver/infra/notify/constant/NotifyConstants.java index b68c2947..fe186ad5 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/constant/NotifyConstants.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/constant/NotifyConstants.java @@ -1,5 +1,9 @@ package life.mosu.mosuserver.infra.notify.constant; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) public final class NotifyConstants { public static final String HOMEPAGE = "https://www.mosuedu.com"; @@ -14,10 +18,4 @@ public final class NotifyConstants { public static final Integer INQUIRY_ANSWER_TEMPLATE_ID = 50038; public static final Integer SIGN_UP_TEMPLATE_ID = 50042; public static final Integer REFUND_TEMPLATE_ID = 50043; - - - private NotifyConstants() { - } - - } diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventRemindMessageDto.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventRemindMessageDto.java index 0294384c..7336496b 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventRemindMessageDto.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventRemindMessageDto.java @@ -3,7 +3,6 @@ import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; public record NotifyEventRemindMessageDto( Integer no, diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventSuccessMessageDto.java b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventSuccessMessageDto.java index d2924ce6..ee5ffe31 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventSuccessMessageDto.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/dto/NotifyEventSuccessMessageDto.java @@ -2,7 +2,6 @@ import java.util.HashMap; import java.util.Map; -import life.mosu.mosuserver.presentation.notify.dto.NotifyButtonUrls; public record NotifyEventSuccessMessageDto( Integer no, From 7977e6c00fdd03ef498e3039aa5367238c67f7dd Mon Sep 17 00:00:00 2001 From: KNU-K Date: Thu, 17 Jul 2025 02:58:29 +0900 Subject: [PATCH 27/32] =?UTF-8?q?feat:=20NotifyService=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EB=A5=BC=20=EC=83=88=EB=A1=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=98=EA=B3=A0=20=EA=B8=B0=EC=A1=B4=20NotifyServic?= =?UTF-8?q?e=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A5=BC=20=EC=A0=9C=EA=B1=B0?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=EA=B5=AC=EC=A1=B0=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/notify/NotifyService.java | 41 +++++++++++++++++++ .../infra/notify/service/NotifyService.java | 41 ------------------- 2 files changed, 41 insertions(+), 41 deletions(-) create mode 100644 src/main/java/life/mosu/mosuserver/application/notify/NotifyService.java delete mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/service/NotifyService.java diff --git a/src/main/java/life/mosu/mosuserver/application/notify/NotifyService.java b/src/main/java/life/mosu/mosuserver/application/notify/NotifyService.java new file mode 100644 index 00000000..ee539d7a --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/application/notify/NotifyService.java @@ -0,0 +1,41 @@ +package life.mosu.mosuserver.application.notify; + +import life.mosu.mosuserver.domain.profile.ProfileJpaEntity; +import life.mosu.mosuserver.domain.profile.ProfileJpaRepository; +import life.mosu.mosuserver.global.exception.CustomRuntimeException; +import life.mosu.mosuserver.global.exception.ErrorCode; +import life.mosu.mosuserver.infra.notify.NotifyClientAdapter; +import life.mosu.mosuserver.infra.notify.dto.NotifyEvent; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; +import life.mosu.mosuserver.infra.notify.strategy.NotifyStrategy; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class NotifyService { + + private final NotifyClientAdapter notifier; + private final ProfileJpaRepository profileJpaRepository; + private final ApplicationContext applicationContext; + + public void notify(NotifyEvent event) { + NotifyStrategy strategy = getNotifyStrategy(event.status().getStrategyName()); + + ProfileJpaEntity profile = profileJpaRepository.findByUserId(event.targetId()) + .orElseThrow(() -> new CustomRuntimeException(ErrorCode.PROFILE_NOT_FOUND)); + String parsedPhoneNumber = profile.getPhoneNumber().replaceAll("-", ""); + + NotifyEventRequest request = strategy.apply(parsedPhoneNumber, event); + + notifier.send(request); + } + + private NotifyStrategy getNotifyStrategy(String strategyName) { + return (NotifyStrategy) applicationContext.getBean(strategyName); + } + +} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/service/NotifyService.java b/src/main/java/life/mosu/mosuserver/infra/notify/service/NotifyService.java deleted file mode 100644 index 2c61e83e..00000000 --- a/src/main/java/life/mosu/mosuserver/infra/notify/service/NotifyService.java +++ /dev/null @@ -1,41 +0,0 @@ -package life.mosu.mosuserver.infra.notify.service; - -import life.mosu.mosuserver.infra.notify.NotifyEvent; -import life.mosu.mosuserver.infra.notify.strategy.NotifyStrategy; -import life.mosu.mosuserver.infra.notify.strategy.NotifyStrategyMap; -import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.web.reactive.function.client.WebClient; - -@Slf4j -@Service -@RequiredArgsConstructor -public class NotifyService { - - private final NotifyStrategyMap strategyMap; - private final WebClient webClient; - @Value("${alimtalk.api.base-url}") - private String alimTalkUrl; - - - public void notify(NotifyEvent event) { - - NotifyStrategy strategy = strategyMap.getStrategy(event.status()); - NotifyEventRequest request = strategy.create(event); - - webClient.post() - .uri(alimTalkUrl) - .bodyValue(request) - .retrieve() - .bodyToMono(String.class) - .doOnSuccess(response -> log.info("알림톡 응답: {}", response)) - .doOnError(error -> log.error("알림톡 전송 실패", error)) - .doOnTerminate(() -> - log.info("알림톡 전송 완료: {}", request)) - .subscribe(); - } - -} From 5d80983b54efe6ac29152b1d03fc52520fdde850 Mon Sep 17 00:00:00 2001 From: KNU-K Date: Thu, 17 Jul 2025 02:58:36 +0900 Subject: [PATCH 28/32] =?UTF-8?q?feat:=20NotifyEventTemplateGenerator=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B2=98=EB=A6=AC=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notify/NotifyEventTemplateGenerator.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventTemplateGenerator.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventTemplateGenerator.java b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventTemplateGenerator.java new file mode 100644 index 00000000..5da898b1 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventTemplateGenerator.java @@ -0,0 +1,49 @@ +package life.mosu.mosuserver.infra.notify; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRemindMessageDto; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; +import life.mosu.mosuserver.infra.notify.dto.NotifyEventSuccessMessageDto; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.MessageSource; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class NotifyEventTemplateGenerator { + + private final MessageSource messageSource; + + public String getProcessedMessage(String code, Map variables) { + String message = messageSource.getMessage(code, null, Locale.KOREA); + for (Map.Entry entry : variables.entrySet()) { + message = StringUtils.replace(message, "#{" + entry.getKey() + "}", entry.getValue()); + } + return message; + } + + public NotifyEventRequest getNotifyEventSuccessTemplate( + Integer templateId, + NotifyEventSuccessMessageDto message + ) { + + return new NotifyEventRequest( + templateId, + List.of(message.toMap()) + ); + } + + public NotifyEventRequest getNotifyEventRemindTemplate( + Integer templateId, + NotifyEventRemindMessageDto message + ) { + + return new NotifyEventRequest( + templateId, + List.of(message.toMap()) + ); + } +} From 8601b0ac64bab64c0db7606ceb0208bcdbaecde8 Mon Sep 17 00:00:00 2001 From: KNU-K Date: Thu, 17 Jul 2025 02:58:45 +0900 Subject: [PATCH 29/32] =?UTF-8?q?feat:=20NotifyEvent=20=EB=B0=8F=20NotifyE?= =?UTF-8?q?ventTemplate=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosuserver/infra/notify/NotifyEvent.java | 15 ----- .../infra/notify/NotifyEventTemplate.java | 58 ------------------- 2 files changed, 73 deletions(-) delete mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/NotifyEvent.java delete mode 100644 src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventTemplate.java diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEvent.java b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEvent.java deleted file mode 100644 index 88990c4d..00000000 --- a/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEvent.java +++ /dev/null @@ -1,15 +0,0 @@ -package life.mosu.mosuserver.infra.notify; - -import life.mosu.mosuserver.presentation.notify.dto.NotifyStatus; - -public record NotifyEvent( - NotifyStatus status, - String telNum, - Long id -) { - - public static NotifyEvent create(NotifyStatus status, String telNum, Long id) { - return new NotifyEvent(status, telNum, id); - } - -} diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventTemplate.java b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventTemplate.java deleted file mode 100644 index bfe477ac..00000000 --- a/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventTemplate.java +++ /dev/null @@ -1,58 +0,0 @@ -package life.mosu.mosuserver.infra.notify; - -import java.util.List; -import java.util.Locale; -import java.util.Map; -import life.mosu.mosuserver.infra.notify.dto.NotifyEventRemindMessageDto; -import life.mosu.mosuserver.infra.notify.dto.NotifyEventSuccessMessageDto; -import life.mosu.mosuserver.presentation.notify.dto.NotifyEventRequest; -import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.MessageSource; -import org.springframework.stereotype.Component; - -@Component -@RequiredArgsConstructor -public class NotifyEventTemplate { - - private final MessageSource messageSource; - @Value("${alimtalk.user-id}") - private String userId; - @Value("${alimtalk.api-key}") - private String apiKey; - - public String getProcessedMessage(String code, Map variables) { - String message = messageSource.getMessage(code, null, Locale.KOREA); - for (Map.Entry entry : variables.entrySet()) { - message = StringUtils.replace(message, "#{" + entry.getKey() + "}", entry.getValue()); - } - return message; - } - - public NotifyEventRequest getNotifyEventSuccessTemplate( - Integer templateId, - NotifyEventSuccessMessageDto message - ) { - - return new NotifyEventRequest( - userId, - apiKey, - templateId, - List.of(message.toMap()) - ); - } - - public NotifyEventRequest getNotifyEventRemindTemplate( - Integer templateId, - NotifyEventRemindMessageDto message - ) { - - return new NotifyEventRequest( - userId, - apiKey, - templateId, - List.of(message.toMap()) - ); - } -} From 79e5ec69774e043c7371417ddaf7b91b7b8679c8 Mon Sep 17 00:00:00 2001 From: KNU-K Date: Thu, 17 Jul 2025 02:58:58 +0900 Subject: [PATCH 30/32] =?UTF-8?q?feat:=20NotifyEventPublisher=20=EB=B0=8F?= =?UTF-8?q?=20NotifyEventListener=EC=97=90=EC=84=9C=20NotifyEvent=20import?= =?UTF-8?q?=20=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosu/mosuserver/infra/notify/NotifyEventPublisher.java | 1 + .../mosuserver/presentation/notify/NotifyEventListener.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventPublisher.java b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventPublisher.java index 96536d01..f61f3147 100644 --- a/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventPublisher.java +++ b/src/main/java/life/mosu/mosuserver/infra/notify/NotifyEventPublisher.java @@ -1,5 +1,6 @@ package life.mosu.mosuserver.infra.notify; +import life.mosu.mosuserver.infra.notify.dto.NotifyEvent; import lombok.RequiredArgsConstructor; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; diff --git a/src/main/java/life/mosu/mosuserver/presentation/notify/NotifyEventListener.java b/src/main/java/life/mosu/mosuserver/presentation/notify/NotifyEventListener.java index 2e1b61fc..bc5c33d7 100644 --- a/src/main/java/life/mosu/mosuserver/presentation/notify/NotifyEventListener.java +++ b/src/main/java/life/mosu/mosuserver/presentation/notify/NotifyEventListener.java @@ -1,8 +1,8 @@ package life.mosu.mosuserver.presentation.notify; +import life.mosu.mosuserver.application.notify.NotifyService; import life.mosu.mosuserver.global.annotation.ReactiveEventListener; -import life.mosu.mosuserver.infra.notify.NotifyEvent; -import life.mosu.mosuserver.infra.notify.service.NotifyService; +import life.mosu.mosuserver.infra.notify.dto.NotifyEvent; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; From c5e51ed29ecf55c18ad6502750a92cadc7f3d445 Mon Sep 17 00:00:00 2001 From: KNU-K Date: Thu, 17 Jul 2025 02:59:04 +0900 Subject: [PATCH 31/32] =?UTF-8?q?feat:=20InquiryAnswerService=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20import=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/inquiry/InquiryAnswerService.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java b/src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java index bafee8d4..0c6497c8 100644 --- a/src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java +++ b/src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java @@ -4,18 +4,14 @@ import life.mosu.mosuserver.domain.inquiry.InquiryJpaRepository; import life.mosu.mosuserver.domain.inquiryAnswer.InquiryAnswerJpaEntity; import life.mosu.mosuserver.domain.inquiryAnswer.InquiryAnswerJpaRepository; -import life.mosu.mosuserver.domain.profile.ProfileJpaEntity; import life.mosu.mosuserver.domain.profile.ProfileJpaRepository; -import life.mosu.mosuserver.domain.user.UserJpaRepository; import life.mosu.mosuserver.global.exception.CustomRuntimeException; import life.mosu.mosuserver.global.exception.ErrorCode; -import life.mosu.mosuserver.infra.notify.NotifyEvent; import life.mosu.mosuserver.infra.notify.NotifyEventPublisher; import life.mosu.mosuserver.presentation.inquiry.dto.InquiryAnswerRequest; import life.mosu.mosuserver.presentation.inquiry.dto.InquiryAnswerUpdateRequest; import life.mosu.mosuserver.presentation.inquiry.dto.InquiryDetailResponse; import life.mosu.mosuserver.presentation.inquiry.dto.InquiryDetailResponse.InquiryAnswerDetailResponse; -import life.mosu.mosuserver.presentation.notify.dto.NotifyStatus; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; @@ -28,7 +24,6 @@ public class InquiryAnswerService { private final InquiryAnswerAttachmentService answerAttachmentService; private final InquiryAnswerJpaRepository inquiryAnswerJpaRepository; private final InquiryJpaRepository inquiryJpaRepository; - private final UserJpaRepository userJpaRepository; private final ProfileJpaRepository profileJpaRepository; private final NotifyEventPublisher notifyEventPublisher; @@ -47,11 +42,11 @@ public void createInquiryAnswer(Long postId, InquiryAnswerRequest request) { answerAttachmentService.createAttachment(request.attachments(), answerEntity); inquiryEntity.updateStatusToComplete(); - ProfileJpaEntity profile = profileJpaRepository.findByUserId(inquiryEntity.getUserId()) - .orElseThrow(() -> new RuntimeException("")); - NotifyEvent event = NotifyEvent.create(NotifyStatus.INQUIRY_ANSWER_SUCCESS, - profile.getPhoneNumber(), postId); - notifyEventPublisher.notify(event); +// ProfileJpaEntity profile = profileJpaRepository.findByUserId(inquiryEntity.getUserId()) +// .orElseThrow(() -> new RuntimeException("")); +// NotifyEvent event = NotifyEvent.create(NotifyStatus.INQUIRY_ANSWER_SUCCESS, +// profile.getPhoneNumber(), postId); +// notifyEventPublisher.notify(event); } From aa28d41fecb60db9b88aa065cab8868bd3132991 Mon Sep 17 00:00:00 2001 From: KNU-K Date: Thu, 17 Jul 2025 02:59:08 +0900 Subject: [PATCH 32/32] =?UTF-8?q?feat:=20DatabaseInitializer=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=A0=84=ED=99=94=EB=B2=88=ED=98=B8=EB=A5=BC=20?= =?UTF-8?q?=EA=B3=A0=EC=A0=95=20=EA=B0=92=EC=9C=BC=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 --- .../mosuserver/global/initializer/DatabaseInitializer.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/life/mosu/mosuserver/global/initializer/DatabaseInitializer.java b/src/main/java/life/mosu/mosuserver/global/initializer/DatabaseInitializer.java index bcc45d4e..2cc3bf53 100644 --- a/src/main/java/life/mosu/mosuserver/global/initializer/DatabaseInitializer.java +++ b/src/main/java/life/mosu/mosuserver/global/initializer/DatabaseInitializer.java @@ -107,8 +107,7 @@ private List initializeUsersAndProfiles(Random random) { .userName(user.getName()) .gender(user.getGender()) .birth(user.getBirth()) - .phoneNumber("010-" + String.format("%04d", i) + "-" + String.format("%04d", - i + 1000)) + .phoneNumber("010-4870-5466") .email("user" + i + "@example.com") .education(Education.values()[random.nextInt(Education.values().length)]) .schoolInfo(new SchoolInfoJpaVO("모수대학교" + (i % 3 + 1), "123-23", "서울시 모수구 모수동"))