From a6d06f7761cb3033aed950b9e101371c3e6abcbb Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Wed, 15 Jan 2025 14:45:54 +0900 Subject: [PATCH 01/31] =?UTF-8?q?[MODIFY]=20API=20PathVariable=20=EA=B0=92?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 예약 알림 식별 기준 값을 `notificationId` -> `alarmId`으로 변경함에 따라 API 요구사항을 변경했습니다. --- .../operation/web/alarm/api/AlarmApi.java | 23 +++++++++++++++++-- .../web/alarm/api/AlarmApiController.java | 19 +++++++++++---- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApi.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApi.java index ff41e779..480f4900 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApi.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApi.java @@ -2,7 +2,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; -import org.sopt.makers.operation.alarm.domain.Status; +import org.sopt.makers.operation.alarm.domain.AlarmStatus; import org.sopt.makers.operation.dto.BaseResponse; import org.sopt.makers.operation.web.alarm.dto.request.AlarmInstantSendRequest; import org.sopt.makers.operation.web.alarm.dto.request.AlarmScheduleSendRequest; @@ -79,7 +79,7 @@ public interface AlarmApi { ) ResponseEntity> getAlarms( @RequestParam(required = false) Integer generation, - @RequestParam(required = false) Status status, + @RequestParam(required = false) AlarmStatus status, Pageable pageable ); @@ -120,4 +120,23 @@ ResponseEntity> getAlarms( } ) ResponseEntity> deleteAlarm(@PathVariable long alarmId); + + @Operation( + summary = "알림 상태 업데이트 API (Web Hook)", + responses = { + @ApiResponse( + responseCode = "204", + description = "알림 상태 업데이트 성공" + ), + @ApiResponse( + responseCode = "404", + description = "알림이 존재하지 않습니다." + ), + @ApiResponse( + responseCode = "500", + description = "서버 내부 오류" + ) + } + ) + ResponseEntity> updateAlarmStatus(@PathVariable long alarmId); } diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java index d7908dc7..4602d031 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java @@ -5,11 +5,12 @@ import static org.sopt.makers.operation.code.success.web.AlarmSuccessCode.SUCCESS_GET_ALARMS; import static org.sopt.makers.operation.code.success.web.AlarmSuccessCode.SUCCESS_SCHEDULE_ALARM; import static org.sopt.makers.operation.code.success.web.AlarmSuccessCode.SUCCESS_SEND_ALARM; +import static org.sopt.makers.operation.code.success.web.AlarmSuccessCode.SUCCESS_UPDATE_ALARM_STATUS; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.val; -import org.sopt.makers.operation.alarm.domain.Status; +import org.sopt.makers.operation.alarm.domain.AlarmStatus; import org.sopt.makers.operation.dto.BaseResponse; import org.sopt.makers.operation.util.ApiResponseUtil; import org.sopt.makers.operation.web.alarm.dto.request.AlarmInstantSendRequest; @@ -17,10 +18,11 @@ import org.sopt.makers.operation.web.alarm.service.AlarmService; import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -50,7 +52,7 @@ public ResponseEntity> sendScheduleAlarm(@Valid AlarmScheduleSen @GetMapping public ResponseEntity> getAlarms( @RequestParam(required = false) Integer generation, - @RequestParam(required = false) Status status, + @RequestParam(required = false) AlarmStatus status, Pageable pageable ) { val response = alarmService.getAlarms(generation, status, pageable); @@ -70,4 +72,13 @@ public ResponseEntity> deleteAlarm(@PathVariable long alarmId) { alarmService.deleteAlarm(alarmId); return ApiResponseUtil.success(SUCCESS_DELETE_ALARM); } + + @Override + @PatchMapping("/{alarmId}") + public ResponseEntity> updateAlarmStatus(@PathVariable long alarmId) { + + return ApiResponseUtil.success(SUCCESS_UPDATE_ALARM_STATUS); + } + + } From f9980f4700dfdba47c12b805d3c2d4c81e9c0d19 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Wed, 15 Jan 2025 16:27:46 +0900 Subject: [PATCH 02/31] =?UTF-8?q?[MODIFY]=20Alarm=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EB=B0=8F=20=EC=9E=AC=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{Category.java => AlarmCategory.java} | 2 +- .../{LinkType.java => AlarmLinkType.java} | 4 ++-- .../alarm/domain/AlarmSendAction.java | 6 +++++ .../domain/{Status.java => AlarmStatus.java} | 7 +++--- .../alarm/domain/AlarmTargetPart.java | 22 +++++++++++++++++++ .../alarm/domain/AlarmTargetType.java | 16 ++++++++++++++ .../operation/alarm/domain/TargetType.java | 14 ------------ 7 files changed, 51 insertions(+), 20 deletions(-) rename operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/{Category.java => AlarmCategory.java} (88%) rename operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/{LinkType.java => AlarmLinkType.java} (74%) create mode 100644 operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmSendAction.java rename operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/{Status.java => AlarmStatus.java} (59%) create mode 100644 operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTargetPart.java create mode 100644 operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTargetType.java delete mode 100644 operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/TargetType.java diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Category.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmCategory.java similarity index 88% rename from operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Category.java rename to operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmCategory.java index 0e65900a..14ca9d40 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Category.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmCategory.java @@ -5,7 +5,7 @@ @Getter @AllArgsConstructor -public enum Category { +public enum AlarmCategory { NOTICE("공지"), NEWS("소식"); diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/LinkType.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmLinkType.java similarity index 74% rename from operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/LinkType.java rename to operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmLinkType.java index fcfeb5e3..3b451ef2 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/LinkType.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmLinkType.java @@ -5,6 +5,6 @@ @Getter @AllArgsConstructor -public enum LinkType { - WEB, APP +public enum AlarmLinkType { + WEB, APP, NONE } diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmSendAction.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmSendAction.java new file mode 100644 index 00000000..655c09fa --- /dev/null +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmSendAction.java @@ -0,0 +1,6 @@ +package org.sopt.makers.operation.alarm.domain; + +public enum AlarmSendAction { + SEND, + SEND_ALL, +} diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Status.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmStatus.java similarity index 59% rename from operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Status.java rename to operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmStatus.java index 40775c32..d1647433 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Status.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmStatus.java @@ -5,9 +5,10 @@ @Getter @AllArgsConstructor -public enum Status { - SCHEDULED("발송 예약"), - COMPLETED("발송 완료"); +public enum AlarmStatus { + SCHEDULED("예약 완료"), + COMPLETED("발송 완료"), + FAILED("발송 실패"); private final String description; } diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTargetPart.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTargetPart.java new file mode 100644 index 00000000..d222664d --- /dev/null +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTargetPart.java @@ -0,0 +1,22 @@ +package org.sopt.makers.operation.alarm.domain; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import static lombok.AccessLevel.PRIVATE; + +@Getter +@RequiredArgsConstructor(access = PRIVATE) +public enum AlarmTargetPart { + ALL("전체"), + PLAN("기획"), + DESIGN("디자인"), + WEB("웹"), + ANDROID("안드로이드"), + iOS("iOS"), + SERVER("서버"), + UNDEFINED("없음") + ; + + private final String name; +} diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTargetType.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTargetType.java new file mode 100644 index 00000000..7ec6c615 --- /dev/null +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTargetType.java @@ -0,0 +1,16 @@ +package org.sopt.makers.operation.alarm.domain; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum AlarmTargetType { + ALL("전체 회원", AlarmSendAction.SEND_ALL), + ACTIVE("활동 회원", AlarmSendAction.SEND), + CSV("CSV", AlarmSendAction.SEND), + ; + + private final String name; + private final AlarmSendAction action; +} diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/TargetType.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/TargetType.java deleted file mode 100644 index 371402d2..00000000 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/TargetType.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.sopt.makers.operation.alarm.domain; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public enum TargetType { - ALL("sendAll"), - ACTIVE("send"), - CSV("send"); - - private final String action; -} From dee0fa28f56b7b0d6de10ac5c2a6bc66fc71508d Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Wed, 15 Jan 2025 16:53:45 +0900 Subject: [PATCH 03/31] =?UTF-8?q?[FEAT]=20AlarmContent=20Entity=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(Embedded)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Content 관심사를 분리하여 관리할 수 있도록 Embedded Entity로 구현했습니다. - 생성자 팩토리 함수를 제공하여 필요한 링크 유형에 따른 객체 생성이 가능하도록 했습니다. --- .../operation/alarm/domain/AlarmContent.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmContent.java diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmContent.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmContent.java new file mode 100644 index 00000000..ec4dfd3f --- /dev/null +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmContent.java @@ -0,0 +1,65 @@ +package org.sopt.makers.operation.alarm.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import static lombok.AccessLevel.PRIVATE; +import static lombok.AccessLevel.PROTECTED; + +@Getter +@Builder(access = PRIVATE) +@NoArgsConstructor(access = PROTECTED) +@AllArgsConstructor(access = PRIVATE) +@Embeddable +public class AlarmContent { + + @Column(name = "category", nullable = false) + @Enumerated(EnumType.STRING) + AlarmCategory category; + + @Column(name = "title", nullable = false) + String title; + + @Column(name = "content", columnDefinition = "TEXT") + String content; + + @Column(name = "link_path", columnDefinition = "TEXT") + String linkPath; + + @Column(name = "link_type", nullable = false) + @Enumerated(EnumType.STRING) + AlarmLinkType linkType; + + public static AlarmContent withAppLink(String title, String content, AlarmCategory category, String link) { + return AlarmContent.builder() + .title(title) + .content(content) + .linkPath(link) + .linkType(AlarmLinkType.APP) + .build(); + } + + public static AlarmContent withWebLink(String title, String content, AlarmCategory category, String link) { + return AlarmContent.builder() + .title(title) + .content(content) + .linkPath(link) + .linkType(AlarmLinkType.WEB) + .build(); + } + + public static AlarmContent withoutLink(String title, String content, AlarmCategory category) { + return AlarmContent.builder() + .title(title) + .content(content) + .linkType(AlarmLinkType.NONE) + .build(); + } + +} From d19cc3ffb1392716f34e4369a928a23c7608faff Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Wed, 15 Jan 2025 17:20:40 +0900 Subject: [PATCH 04/31] =?UTF-8?q?[FEAT]=20AlarmTarget=20Entity=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(Embedded)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 발송 대상에 대한 관심사를 분리하기 위해 Embedded Entity를 구현했습니다. --- .../operation/alarm/domain/AlarmTarget.java | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTarget.java diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTarget.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTarget.java new file mode 100644 index 00000000..faad8c20 --- /dev/null +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTarget.java @@ -0,0 +1,79 @@ +package org.sopt.makers.operation.alarm.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Embeddable; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; + +import org.sopt.makers.operation.schedule.converter.StringListConverter; + +import java.util.List; + +import static lombok.AccessLevel.PRIVATE; +import static lombok.AccessLevel.PROTECTED; + +@Getter +@Builder(access = PRIVATE) +@NoArgsConstructor(access = PROTECTED) +@AllArgsConstructor(access = PRIVATE) +@Embeddable +public class AlarmTarget { + + @Column(name = "action", nullable = false, updatable = false, insertable = false) + private AlarmSendAction sendAction; + + @Column(name = "part", nullable = false, updatable = false, insertable = false) + private AlarmTargetPart targetPart; + + @Column(name = "target_type", nullable = false, updatable = false, insertable = false) + private AlarmTargetType targetType; + + @Column(name = "generation", updatable = false, insertable = false) + private Integer generation; + + @Column(name = "targets", columnDefinition = "TEXT", updatable = false) + @Convert(converter = StringListConverter.class) + private List targetIds; + + public static AlarmTarget all() { + return AlarmTarget.builder() + .sendAction(AlarmSendAction.SEND_ALL) + .targetType(AlarmTargetType.ALL) + .targetPart(AlarmTargetPart.ALL) + .build(); + } + + public static AlarmTarget partialForAll(AlarmTargetPart targetPart, List targetIds) { + return AlarmTarget.builder() + .sendAction(AlarmSendAction.SEND) + .targetType(AlarmTargetType.ALL) + .targetPart(targetPart) + .targetIds(targetIds) + .build(); + } + + public static AlarmTarget partialForActive(int generation, AlarmTargetPart targetPart, List targetIds) { + return AlarmTarget.builder() + .sendAction(AlarmSendAction.SEND) + .targetType(AlarmTargetType.ACTIVE) + .generation(generation) + .targetPart(targetPart) + .targetIds(targetIds) + .build(); + } + + + public static AlarmTarget partialForCsv(List targetIds) { + return AlarmTarget.builder() + .sendAction(AlarmSendAction.SEND) + .targetType(AlarmTargetType.CSV) + .targetPart(AlarmTargetPart.UNDEFINED) + .targetIds(targetIds) + .build(); + } + +} From 0b0bbb2ac9a1b39c41c446adb2f06695408b1e3a Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Wed, 15 Jan 2025 17:24:48 +0900 Subject: [PATCH 05/31] =?UTF-8?q?[REFACTOR]=20=EA=B4=80=EC=8B=AC=EC=82=AC?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC=20=EB=B0=98=EC=98=81=20=EA=B0=9C=ED=8E=B8?= =?UTF-8?q?=20AlarmEntity=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../makers/operation/alarm/domain/Alarm.java | 142 +++++++----------- 1 file changed, 51 insertions(+), 91 deletions(-) diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Alarm.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Alarm.java index 4690d024..25af4d5c 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Alarm.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Alarm.java @@ -1,117 +1,77 @@ package org.sopt.makers.operation.alarm.domain; -import static java.util.Objects.nonNull; - -import jakarta.persistence.Column; -import jakarta.persistence.Convert; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import jakarta.persistence.Entity; +import jakarta.persistence.Embedded; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import lombok.Builder; + import lombok.Getter; +import lombok.Builder; import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; + import org.sopt.makers.operation.common.domain.BaseEntity; -import org.sopt.makers.operation.common.domain.Part; -import org.sopt.makers.operation.schedule.converter.StringListConverter; -@Entity -@NoArgsConstructor +import java.time.LocalDateTime; + +import static lombok.AccessLevel.PRIVATE; +import static lombok.AccessLevel.PROTECTED; + @Getter +@Entity +@Table(name = "alarms") +@Builder(access = PRIVATE) +@NoArgsConstructor(access = PROTECTED) +@AllArgsConstructor(access = PRIVATE) public class Alarm extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "alarm_id") private Long id; - private String title; - - @Column(columnDefinition = "TEXT") - private String content; - - @Column(nullable = false) - @Enumerated(value = EnumType.STRING) - private Category category; - - @Enumerated(value = EnumType.STRING) - private Part part; - - @Enumerated(value = EnumType.STRING) - private LinkType linkType; - - private String link; - - @Column(nullable = false) - @Enumerated(value = EnumType.STRING) - private AlarmType alarmType; - - @Enumerated(value = EnumType.STRING) - private TargetType targetType; - - @Enumerated(value = EnumType.STRING) - private Status status; - - @Column(columnDefinition = "TEXT", nullable = false) - @Convert(converter = StringListConverter.class) - private List targetList; - - private String sendAt; - - private Integer createdGeneration; - - @Builder - public Alarm( - Category category, - String title, - String content, - AlarmType alarmType, - String link, - LinkType linkType, - Part part, - Status status, - TargetType targetType, - List targetList, - Integer createdGeneration - ) { - this.category = category; - this.title = title; - this.content = content; - this.alarmType = alarmType; - this.linkType = linkType; - this.targetType = targetType; - setLink(link); - setTargetsInfo(part, targetList); - this.status = status; - this.createdGeneration = createdGeneration; - } + @Enumerated(EnumType.STRING) + private AlarmStatus status; - private void setLink(String link) { - if (nonNull(link)) { - this.link = link; - } - } + @Enumerated(EnumType.STRING) + private AlarmType type; + + @Embedded + private AlarmTarget target; - private void setTargetsInfo(Part part, List targetList) { - if (nonNull(targetList)) { - this.targetList = targetList; - } else { - this.part = part; - this.targetList = new ArrayList<>(); - } + @Embedded + private AlarmContent content; + + private LocalDateTime intendedAt; + + private LocalDateTime sendAt; + + public static Alarm instant(AlarmTarget target, AlarmContent content) { + return Alarm.builder() + .status(AlarmStatus.COMPLETED) + .type(AlarmType.INSTANT) + .target(target) + .content(content) + .intendedAt(LocalDateTime.now()) + .build(); } - public void updateToSent(String sendAt) { - this.sendAt = sendAt; - this.status = Status.COMPLETED; + public static Alarm scheduled(AlarmTarget target, AlarmContent content, LocalDateTime intendedAt) { + return Alarm.builder() + .status(AlarmStatus.SCHEDULED) + .type(AlarmType.RESERVED) + .target(target) + .content(content) + .intendedAt(intendedAt) + .build(); } - public boolean hasTargets() { - return Objects.nonNull(this.targetList) && this.targetList.size() > 0; + public void updateStatusToComplete() { + this.status = AlarmStatus.COMPLETED; + this.sendAt = LocalDateTime.now(); } + } From 833d5b80aa5f71c190e0f241a44986309ec56ea1 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Wed, 15 Jan 2025 17:30:06 +0900 Subject: [PATCH 06/31] =?UTF-8?q?[FEAT]=20=EC=95=8C=EB=A6=BC=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=83=81=EC=88=98=20Util=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit private static 팩토리 메서드를 제공했습니다. - `isSupportedAppLink` : 입력된 link가 지원되는 앱 링크 경로인지 검사합니다. --- .../operation/constant/AlarmConstant.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 operation-common/src/main/java/org/sopt/makers/operation/constant/AlarmConstant.java diff --git a/operation-common/src/main/java/org/sopt/makers/operation/constant/AlarmConstant.java b/operation-common/src/main/java/org/sopt/makers/operation/constant/AlarmConstant.java new file mode 100644 index 00000000..4c409e63 --- /dev/null +++ b/operation-common/src/main/java/org/sopt/makers/operation/constant/AlarmConstant.java @@ -0,0 +1,26 @@ +package org.sopt.makers.operation.constant; + +import lombok.RequiredArgsConstructor; + +import java.util.List; + +import static lombok.AccessLevel.PRIVATE; + +@RequiredArgsConstructor(access = PRIVATE) +public final class AlarmConstant { + private static final List SUPPORTED_APP_LINK = List.of( + "home", + "home/notification", + "home/mypage", + "home/attendance", + "home/attendance/attendance-modal", + "home/soptamp", + "home/soptamp/entire-ranking", + "home/soptamp/current-generation-ranking" + ); + + public static boolean isSupportedAppLink(String link) { + return SUPPORTED_APP_LINK.contains(link); + } + +} From b0db63e6e9d41395d9feac0ea66d6cc039091d24 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Wed, 15 Jan 2025 17:31:10 +0900 Subject: [PATCH 07/31] =?UTF-8?q?[REFACTOR]=20AppLink=20=EC=BB=A8=ED=85=90?= =?UTF-8?q?=EC=B8=A0=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=9C=A0=ED=9A=A8?= =?UTF-8?q?=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Util 클래스에 정의되어 있는 "앱링크 유효성 검사" 메서드를 통해 AppLink 컨텐츠 객체 생성자 메서드에서 유효성 검사를 진행합니다. --- .../makers/operation/alarm/domain/AlarmContent.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmContent.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmContent.java index ec4dfd3f..3e99d472 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmContent.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmContent.java @@ -4,13 +4,18 @@ import jakarta.persistence.Embeddable; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; -import lombok.AllArgsConstructor; -import lombok.Builder; + import lombok.Getter; +import lombok.Builder; import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; + +import org.sopt.makers.operation.exception.AlarmException; +import org.sopt.makers.operation.code.failure.AlarmFailureCode; import static lombok.AccessLevel.PRIVATE; import static lombok.AccessLevel.PROTECTED; +import static org.sopt.makers.operation.constant.AlarmConstant.isSupportedAppLink; @Getter @Builder(access = PRIVATE) @@ -37,6 +42,9 @@ public class AlarmContent { AlarmLinkType linkType; public static AlarmContent withAppLink(String title, String content, AlarmCategory category, String link) { + if (!isSupportedAppLink(link)) { + throw new AlarmException(AlarmFailureCode.INVALID_LINK); + } return AlarmContent.builder() .title(title) .content(content) From f8b09c8ea38a7b2e2a69579d941aa6af7946e7d1 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Wed, 15 Jan 2025 17:32:20 +0900 Subject: [PATCH 08/31] =?UTF-8?q?[ADD]=20Alarm=20=EA=B4=80=EB=A0=A8=20Succ?= =?UTF-8?q?ess/Failure=20Code=20=ED=95=AD=EB=AA=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Failure : 지원하지 않는 앱링크에 대한 에러 - Success : 상태값 업데이트에 대한 성공 --- .../org/sopt/makers/operation/code/failure/AlarmFailureCode.java | 1 + .../sopt/makers/operation/code/success/web/AlarmSuccessCode.java | 1 + 2 files changed, 2 insertions(+) diff --git a/operation-common/src/main/java/org/sopt/makers/operation/code/failure/AlarmFailureCode.java b/operation-common/src/main/java/org/sopt/makers/operation/code/failure/AlarmFailureCode.java index 87c50ac8..d47be86c 100644 --- a/operation-common/src/main/java/org/sopt/makers/operation/code/failure/AlarmFailureCode.java +++ b/operation-common/src/main/java/org/sopt/makers/operation/code/failure/AlarmFailureCode.java @@ -13,6 +13,7 @@ public enum AlarmFailureCode implements FailureCode { FAIL_SEND_ALARM(BAD_REQUEST, "알림 즉시 발송에 실패하였습니다."), FAIL_SCHEDULE_ALARM(BAD_REQUEST, "알림 예약 발송에 실패하였습니다."), INVALID_ALARM(NOT_FOUND, "알림이 존재하지 않습니다."), + INVALID_LINK(BAD_REQUEST, "지원하지 않는 링크입니다."), FAIL_INACTIVE_USERS(BAD_REQUEST, "비활동 유저 불러오기에 실패하였습니다."), INVALID_ALARM_TARGET_TYPE(BAD_REQUEST, "올바르지 않은 알림 타겟 타입입니다."), INVALID_SCHEDULE_ALARM_FORMAT(BAD_REQUEST, "알림 예약 시간 포맷이 맞지 않습니다."); diff --git a/operation-common/src/main/java/org/sopt/makers/operation/code/success/web/AlarmSuccessCode.java b/operation-common/src/main/java/org/sopt/makers/operation/code/success/web/AlarmSuccessCode.java index 37b16369..a2de6dc0 100644 --- a/operation-common/src/main/java/org/sopt/makers/operation/code/success/web/AlarmSuccessCode.java +++ b/operation-common/src/main/java/org/sopt/makers/operation/code/success/web/AlarmSuccessCode.java @@ -14,6 +14,7 @@ public enum AlarmSuccessCode implements SuccessCode { SUCCESS_GET_ALARMS(OK, "알림 리스트 조회 성공"), SUCCESS_GET_ALARM(OK, "알림 상세 조회 성공"), SUCCESS_DELETE_ALARM(OK, "알림 삭제 성공"), + SUCCESS_UPDATE_ALARM_STATUS(OK, "알림 상태 업데이트 성공"), SUCCESS_SCHEDULE_ALARM(OK, "알림 예약 발송 성공"); private final HttpStatus status; From 52dd41a3209266b76f53faeed588ae3c044fca83 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Wed, 15 Jan 2025 17:57:49 +0900 Subject: [PATCH 09/31] =?UTF-8?q?[REFACTOR]=20DB=20String=20Data=20to=20Li?= =?UTF-8?q?st=20Converter=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../operation/schedule/converter/StringListConverter.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/schedule/converter/StringListConverter.java b/operation-domain/src/main/java/org/sopt/makers/operation/schedule/converter/StringListConverter.java index 4f0fdc2d..cf6349e5 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/schedule/converter/StringListConverter.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/schedule/converter/StringListConverter.java @@ -1,6 +1,7 @@ package org.sopt.makers.operation.schedule.converter; -import static com.fasterxml.jackson.databind.DeserializationFeature.*; +import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; +import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES; import java.io.IOException; import java.util.List; @@ -9,7 +10,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; +@Converter public class StringListConverter implements AttributeConverter, String> { private static final ObjectMapper mapper = new ObjectMapper() .configure(FAIL_ON_UNKNOWN_PROPERTIES, false) @@ -26,8 +29,7 @@ public String convertToDatabaseColumn(List attribute) { @Override public List convertToEntityAttribute(String dbData) { - TypeReference> typeReference = new TypeReference<>() { - }; + TypeReference> typeReference = new TypeReference<>(){}; try { return mapper.readValue(dbData, typeReference); From 98650d7af08a8b128ca671438449a980eecd584f Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Wed, 15 Jan 2025 18:05:57 +0900 Subject: [PATCH 10/31] =?UTF-8?q?[MODIFY]=20=EC=95=8C=EB=A6=BC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20Response=20DTO=20=ED=95=84=EB=93=9C=EB=AA=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=ED=8C=8C=EB=9D=BC=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=20Entity=20=ED=83=80=EC=9E=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 개편된 Domain Entity로 변경했습니다. --- .../web/alarm/dto/response/AlarmCreateResponse.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmCreateResponse.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmCreateResponse.java index d6e237c2..8c9d961d 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmCreateResponse.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmCreateResponse.java @@ -1,6 +1,6 @@ package org.sopt.makers.operation.web.alarm.dto.response; -import static lombok.AccessLevel.*; +import static lombok.AccessLevel.PRIVATE; import org.sopt.makers.operation.alarm.domain.Alarm; @@ -8,12 +8,12 @@ @Builder(access = PRIVATE) public record AlarmCreateResponse( - long alarmId + long id ) { public static AlarmCreateResponse of(Alarm alarm) { return AlarmCreateResponse.builder() - .alarmId(alarm.getId()) + .id(alarm.getId()) .build(); } } From 9533aaf2df3261e81b79a01f2aebb6fed47ffaff Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Wed, 15 Jan 2025 18:45:27 +0900 Subject: [PATCH 11/31] =?UTF-8?q?[REFACTOR]=20=EC=A6=89=EC=8B=9C/=EC=98=88?= =?UTF-8?q?=EC=95=BD=20=EB=B0=9C=EC=86=A1=20=EC=95=8C=EB=A6=BC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=9A=94=EC=B2=AD=20DTO=20=EB=82=B4=20=EA=B0=9C?= =?UTF-8?q?=ED=8E=B8=20Domain=20Entity=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/AlarmInstantSendRequest.java | 58 +++++++++------- .../dto/request/AlarmScheduleSendRequest.java | 66 ++++++++++++------- 2 files changed, 75 insertions(+), 49 deletions(-) diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmInstantSendRequest.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmInstantSendRequest.java index e852da27..c7d3415e 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmInstantSendRequest.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmInstantSendRequest.java @@ -2,39 +2,47 @@ import jakarta.validation.constraints.NotNull; import java.util.List; -import org.sopt.makers.operation.alarm.domain.Alarm; -import org.sopt.makers.operation.alarm.domain.AlarmType; -import org.sopt.makers.operation.alarm.domain.Category; -import org.sopt.makers.operation.alarm.domain.LinkType; -import org.sopt.makers.operation.alarm.domain.Status; -import org.sopt.makers.operation.alarm.domain.TargetType; -import org.sopt.makers.operation.common.domain.Part; + +import org.sopt.makers.operation.alarm.domain.*; +import org.sopt.makers.operation.exception.AlarmException; + +import static org.sopt.makers.operation.code.failure.AlarmFailureCode.INVALID_SEND_INSTANT_REQUEST; public record AlarmInstantSendRequest( - @NotNull Integer createdGeneration, @NotNull String title, @NotNull String content, - @NotNull Category category, - @NotNull TargetType targetType, + @NotNull AlarmCategory category, + @NotNull AlarmTargetType targetType, + AlarmTargetPart part, + Integer createdGeneration, List targetList, - Part part, - LinkType linkType, + AlarmLinkType linkType, String link ) { + private AlarmTarget toTargetEntity() { + return switch (this.targetType) { + case ALL -> this.part.equals(AlarmTargetPart.ALL) + ? AlarmTarget.all() + : AlarmTarget.partialForAll(this.part, this.targetList); + case ACTIVE -> AlarmTarget.partialForActive(this.createdGeneration, this.part, this.targetList); + case CSV -> AlarmTarget.partialForCsv(this.targetList); + default -> throw new AlarmException(INVALID_SEND_INSTANT_REQUEST); + }; + } + + private AlarmContent toContentEntity() { + return switch (this.linkType) { + case WEB -> AlarmContent.withWebLink(this.title, this.content, this.category, this.link); + case APP -> AlarmContent.withAppLink(this.title, this.content, this.category, this.link); + case NONE -> AlarmContent.withoutLink(this.title, this.content, this.category); + default -> throw new AlarmException(INVALID_SEND_INSTANT_REQUEST); + }; + } + public Alarm toEntity() { - return Alarm.builder() - .createdGeneration(this.createdGeneration) - .category(this.category) - .title(this.title) - .content(this.content) - .targetType(this.targetType) - .alarmType(AlarmType.INSTANT) - .link(this.link) - .linkType(linkType) - .part(this.part) - .status(Status.COMPLETED) - .targetList(this.targetList) - .build(); + AlarmTarget targetEntity = this.toTargetEntity(); + AlarmContent contentEntity = this.toContentEntity(); + return Alarm.instant(targetEntity, contentEntity); } } diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleSendRequest.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleSendRequest.java index 8f75bc2a..a8a6a79d 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleSendRequest.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleSendRequest.java @@ -1,43 +1,61 @@ package org.sopt.makers.operation.web.alarm.dto.request; import jakarta.validation.constraints.NotNull; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; import java.util.List; -import org.sopt.makers.operation.alarm.domain.Alarm; -import org.sopt.makers.operation.alarm.domain.AlarmType; -import org.sopt.makers.operation.alarm.domain.Category; -import org.sopt.makers.operation.alarm.domain.LinkType; -import org.sopt.makers.operation.alarm.domain.Status; -import org.sopt.makers.operation.alarm.domain.TargetType; + +import lombok.val; +import org.sopt.makers.operation.alarm.domain.*; +import org.sopt.makers.operation.code.failure.AlarmFailureCode; import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.exception.AlarmException; + +import static org.sopt.makers.operation.code.failure.AlarmFailureCode.INVALID_SEND_SCHEDULED_REQUEST; public record AlarmScheduleSendRequest( - @NotNull Integer createdGeneration, @NotNull String title, @NotNull String content, - @NotNull Category category, - @NotNull TargetType targetType, + @NotNull AlarmCategory category, + @NotNull AlarmTargetType targetType, List targetList, - Part part, - LinkType linkType, + AlarmTargetPart part, + Integer createdGeneration, + AlarmLinkType linkType, String link, @NotNull String postDate, @NotNull String postTime ) { + private AlarmTarget toTargetEntity() { + return switch (this.targetType) { + case ALL -> this.part.equals(AlarmTargetPart.ALL) + ? AlarmTarget.all() + : AlarmTarget.partialForAll(this.part, this.targetList); + case ACTIVE -> AlarmTarget.partialForActive(this.createdGeneration, this.part, this.targetList); + case CSV -> AlarmTarget.partialForCsv(this.targetList); + default -> throw new AlarmException(INVALID_SEND_SCHEDULED_REQUEST); + }; + } + + private AlarmContent toContentEntity() { + return switch (this.linkType) { + case WEB -> AlarmContent.withWebLink(this.title, this.content, this.category, this.link); + case APP -> AlarmContent.withAppLink(this.title, this.content, this.category, this.link); + case NONE -> AlarmContent.withoutLink(this.title, this.content, this.category); + default -> throw new AlarmException(INVALID_SEND_SCHEDULED_REQUEST); + }; + } + public Alarm toEntity() { - return Alarm.builder() - .createdGeneration(this.createdGeneration) - .category(this.category) - .title(this.title) - .content(this.content) - .targetType(this.targetType) - .alarmType(AlarmType.RESERVED) - .link(this.link) - .linkType(linkType) - .part(this.part) - .status(Status.SCHEDULED) - .targetList(this.targetList) - .build(); + AlarmTarget targetEntity = this.toTargetEntity(); + AlarmContent contentEntity = this.toContentEntity(); + val date = LocalDate.parse(postDate, DateTimeFormatter.ISO_LOCAL_DATE); + val time = LocalTime.parse(postTime, DateTimeFormatter.ofPattern("HH:mm")); + return Alarm.scheduled(targetEntity, contentEntity, LocalDateTime.of(date, time)); } } From 2e59cb7fc52a10465b1b3cf11907cd09ff97d78f Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Thu, 16 Jan 2025 20:29:13 +0900 Subject: [PATCH 12/31] =?UTF-8?q?[CHORE]=20Member=20Domain=EC=9D=B8=20Part?= =?UTF-8?q?=20Enum=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/member/dto/response/AttendanceTotalResponseDTO.java | 2 +- .../operation/web/attendnace/api/WebAttendanceApi.java | 2 +- .../web/attendnace/api/WebAttendanceApiController.java | 2 +- .../web/attendnace/service/WebAttendanceService.java | 2 +- .../web/attendnace/service/WebAttendanceServiceImpl.java | 2 +- .../makers/operation/web/lecture/api/WebLectureApi.java | 2 +- .../operation/web/lecture/api/WebLectureApiController.java | 2 +- .../web/lecture/dto/request/LectureCreateRequest.java | 2 +- .../web/lecture/dto/response/LectureGetResponse.java | 2 +- .../web/lecture/dto/response/LectureListGetResponse.java | 2 +- .../operation/web/lecture/service/WebLectureService.java | 2 +- .../web/lecture/service/WebLectureServiceImpl.java | 2 +- .../sopt/makers/operation/web/member/api/WebMemberApi.java | 2 +- .../operation/web/member/api/WebMemberApiController.java | 2 +- .../web/member/dto/response/MemberListGetResponse.java | 2 +- .../operation/web/member/service/WebMemberService.java | 2 +- .../operation/web/member/service/WebMemberServiceImpl.java | 2 +- .../repository/attendance/AttendanceCustomRepository.java | 2 +- .../repository/attendance/AttendanceRepositoryImpl.java | 6 +++--- .../org/sopt/makers/operation/lecture/domain/Lecture.java | 2 +- .../lecture/repository/lecture/LectureCustomRepository.java | 3 +-- .../lecture/repository/lecture/LectureRepositoryImpl.java | 2 +- .../org/sopt/makers/operation/member/domain/Member.java | 1 - .../makers/operation/{common => member}/domain/Part.java | 2 +- .../operation/member/repository/MemberCustomRepository.java | 2 +- .../operation/member/repository/MemberRepositoryImpl.java | 4 ++-- .../operation/attendance/domain/AttendanceGetScoreTest.java | 2 +- .../attendance/domain/AttendanceGetStatusTest.java | 2 +- .../java/org/sopt/makers/operation/dummy/LectureDummy.java | 2 +- .../java/org/sopt/makers/operation/dummy/MemberDummy.java | 2 +- .../operation/client/playground/PlayGroundServer.java | 2 +- .../operation/client/playground/PlayGroundServerImpl.java | 4 ++-- 32 files changed, 35 insertions(+), 37 deletions(-) rename operation-domain/src/main/java/org/sopt/makers/operation/{common => member}/domain/Part.java (84%) diff --git a/operation-api/src/main/java/org/sopt/makers/operation/app/member/dto/response/AttendanceTotalResponseDTO.java b/operation-api/src/main/java/org/sopt/makers/operation/app/member/dto/response/AttendanceTotalResponseDTO.java index 1bf8f22a..74ccea8a 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/app/member/dto/response/AttendanceTotalResponseDTO.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/app/member/dto/response/AttendanceTotalResponseDTO.java @@ -3,7 +3,7 @@ import java.util.List; import lombok.Builder; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.member.domain.Member; import static lombok.AccessLevel.PRIVATE; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/api/WebAttendanceApi.java b/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/api/WebAttendanceApi.java index 1efb6170..3964413e 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/api/WebAttendanceApi.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/api/WebAttendanceApi.java @@ -1,6 +1,6 @@ package org.sopt.makers.operation.web.attendnace.api; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.dto.BaseResponse; import org.sopt.makers.operation.web.attendnace.dto.request.SubAttendanceUpdateRequest; import org.springframework.data.domain.Pageable; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/api/WebAttendanceApiController.java b/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/api/WebAttendanceApiController.java index 062b682d..748d2e0e 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/api/WebAttendanceApiController.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/api/WebAttendanceApiController.java @@ -2,7 +2,7 @@ import static org.sopt.makers.operation.code.success.web.AttendanceSuccessCode.*; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.dto.BaseResponse; import org.sopt.makers.operation.util.ApiResponseUtil; import org.sopt.makers.operation.web.attendnace.dto.request.SubAttendanceUpdateRequest; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/service/WebAttendanceService.java b/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/service/WebAttendanceService.java index affade26..07fb9409 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/service/WebAttendanceService.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/service/WebAttendanceService.java @@ -1,6 +1,6 @@ package org.sopt.makers.operation.web.attendnace.service; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.web.attendnace.dto.request.SubAttendanceUpdateRequest; import org.sopt.makers.operation.web.attendnace.dto.response.AttendanceListByLectureGetResponse; import org.sopt.makers.operation.web.attendnace.dto.response.AttendanceListByMemberGetResponse; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/service/WebAttendanceServiceImpl.java b/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/service/WebAttendanceServiceImpl.java index b64ebca2..8c7e7db9 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/service/WebAttendanceServiceImpl.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/attendnace/service/WebAttendanceServiceImpl.java @@ -4,7 +4,7 @@ import static org.sopt.makers.operation.code.failure.LectureFailureCode.*; import static org.sopt.makers.operation.code.failure.MemberFailureCode.*; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.attendance.domain.SubAttendance; import org.sopt.makers.operation.attendance.repository.attendance.AttendanceRepository; import org.sopt.makers.operation.attendance.repository.subAttendance.SubAttendanceRepository; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/api/WebLectureApi.java b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/api/WebLectureApi.java index 802ff563..5b2e5454 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/api/WebLectureApi.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/api/WebLectureApi.java @@ -1,6 +1,6 @@ package org.sopt.makers.operation.web.lecture.api; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.dto.BaseResponse; import org.sopt.makers.operation.web.lecture.dto.request.SubLectureStartRequest; import org.sopt.makers.operation.web.lecture.dto.request.LectureCreateRequest; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/api/WebLectureApiController.java b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/api/WebLectureApiController.java index 33913f1e..5b5a5a94 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/api/WebLectureApiController.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/api/WebLectureApiController.java @@ -2,7 +2,7 @@ import static org.sopt.makers.operation.code.success.web.LectureSuccessCode.*; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.dto.BaseResponse; import org.sopt.makers.operation.util.ApiResponseUtil; import org.sopt.makers.operation.web.lecture.dto.request.SubLectureStartRequest; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/dto/request/LectureCreateRequest.java b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/dto/request/LectureCreateRequest.java index 17c6f32c..ebd997b3 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/dto/request/LectureCreateRequest.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/dto/request/LectureCreateRequest.java @@ -6,7 +6,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeParseException; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.lecture.domain.Attribute; import org.sopt.makers.operation.lecture.domain.Lecture; import org.sopt.makers.operation.exception.DateTimeParseCustomException; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/dto/response/LectureGetResponse.java b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/dto/response/LectureGetResponse.java index c478c31a..77882e4a 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/dto/response/LectureGetResponse.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/dto/response/LectureGetResponse.java @@ -6,7 +6,7 @@ import java.time.LocalDateTime; import java.util.List; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.lecture.domain.Attribute; import org.sopt.makers.operation.lecture.domain.Lecture; import org.sopt.makers.operation.lecture.domain.LectureStatus; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/dto/response/LectureListGetResponse.java b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/dto/response/LectureListGetResponse.java index f1ef0c0f..3d030c49 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/dto/response/LectureListGetResponse.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/dto/response/LectureListGetResponse.java @@ -4,7 +4,7 @@ import java.util.List; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.lecture.domain.Attribute; import org.sopt.makers.operation.lecture.domain.Lecture; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureService.java b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureService.java index 8fa12dcb..a9a9b180 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureService.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureService.java @@ -1,6 +1,6 @@ package org.sopt.makers.operation.web.lecture.service; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.web.lecture.dto.request.SubLectureStartRequest; import org.sopt.makers.operation.web.lecture.dto.request.LectureCreateRequest; import org.sopt.makers.operation.web.lecture.dto.response.SubLectureStartResponse; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureServiceImpl.java b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureServiceImpl.java index 1ee5c9bf..f3b45514 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureServiceImpl.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureServiceImpl.java @@ -16,7 +16,7 @@ import org.sopt.makers.operation.attendance.repository.subAttendance.SubAttendanceRepository; import org.sopt.makers.operation.client.alarm.alarmServer.AlarmSender; import org.sopt.makers.operation.client.alarm.alarmServer.dto.AlarmSenderRequest; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.config.ValueConfig; import org.sopt.makers.operation.exception.LectureException; import org.sopt.makers.operation.exception.SubLectureException; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/member/api/WebMemberApi.java b/operation-api/src/main/java/org/sopt/makers/operation/web/member/api/WebMemberApi.java index 9801990d..4a0a1f98 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/member/api/WebMemberApi.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/member/api/WebMemberApi.java @@ -1,6 +1,6 @@ package org.sopt.makers.operation.web.member.api; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.dto.BaseResponse; import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/member/api/WebMemberApiController.java b/operation-api/src/main/java/org/sopt/makers/operation/web/member/api/WebMemberApiController.java index 0f39709b..4200f4dc 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/member/api/WebMemberApiController.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/member/api/WebMemberApiController.java @@ -2,7 +2,7 @@ import static org.sopt.makers.operation.code.success.web.MemberSuccessCode.*; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.dto.BaseResponse; import org.sopt.makers.operation.util.ApiResponseUtil; import org.sopt.makers.operation.web.member.service.WebMemberService; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/member/dto/response/MemberListGetResponse.java b/operation-api/src/main/java/org/sopt/makers/operation/web/member/dto/response/MemberListGetResponse.java index 477b28d9..330e52c9 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/member/dto/response/MemberListGetResponse.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/member/dto/response/MemberListGetResponse.java @@ -5,7 +5,7 @@ import java.util.List; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.attendance.domain.AttendanceStatus; import org.sopt.makers.operation.member.domain.Member; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/member/service/WebMemberService.java b/operation-api/src/main/java/org/sopt/makers/operation/web/member/service/WebMemberService.java index 2c8edacb..42485d00 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/member/service/WebMemberService.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/member/service/WebMemberService.java @@ -1,6 +1,6 @@ package org.sopt.makers.operation.web.member.service; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.web.member.dto.response.MemberListGetResponse; import org.springframework.data.domain.Pageable; diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/member/service/WebMemberServiceImpl.java b/operation-api/src/main/java/org/sopt/makers/operation/web/member/service/WebMemberServiceImpl.java index c02a78eb..1ed17188 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/member/service/WebMemberServiceImpl.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/member/service/WebMemberServiceImpl.java @@ -1,6 +1,6 @@ package org.sopt.makers.operation.web.member.service; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.member.repository.MemberRepository; import org.sopt.makers.operation.web.member.dto.response.MemberListGetResponse; import org.springframework.data.domain.Pageable; diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/attendance/repository/attendance/AttendanceCustomRepository.java b/operation-domain/src/main/java/org/sopt/makers/operation/attendance/repository/attendance/AttendanceCustomRepository.java index 2dee226d..9e8ddcd2 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/attendance/repository/attendance/AttendanceCustomRepository.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/attendance/repository/attendance/AttendanceCustomRepository.java @@ -2,7 +2,7 @@ import java.util.List; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.attendance.domain.Attendance; import org.sopt.makers.operation.lecture.domain.Lecture; import org.sopt.makers.operation.member.domain.Member; diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/attendance/repository/attendance/AttendanceRepositoryImpl.java b/operation-domain/src/main/java/org/sopt/makers/operation/attendance/repository/attendance/AttendanceRepositoryImpl.java index 9020a32e..10283ed7 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/attendance/repository/attendance/AttendanceRepositoryImpl.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/attendance/repository/attendance/AttendanceRepositoryImpl.java @@ -1,10 +1,10 @@ package org.sopt.makers.operation.attendance.repository.attendance; -import static com.querydsl.core.types.dsl.Expressions.*; +import static com.querydsl.core.types.dsl.Expressions.stringTemplate; import static java.util.Objects.*; import static org.sopt.makers.operation.attendance.domain.QAttendance.*; import static org.sopt.makers.operation.attendance.domain.QSubAttendance.*; -import static org.sopt.makers.operation.common.domain.Part.*; +import static org.sopt.makers.operation.member.domain.Part.*; import static org.sopt.makers.operation.lecture.domain.QLecture.*; import static org.sopt.makers.operation.lecture.domain.QSubLecture.*; import static org.sopt.makers.operation.member.domain.QMember.*; @@ -15,7 +15,7 @@ import java.util.List; import org.sopt.makers.operation.config.ValueConfig; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.attendance.domain.Attendance; import org.sopt.makers.operation.lecture.domain.Lecture; import org.sopt.makers.operation.lecture.domain.LectureStatus; diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/lecture/domain/Lecture.java b/operation-domain/src/main/java/org/sopt/makers/operation/lecture/domain/Lecture.java index 29befe77..bd7e857b 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/lecture/domain/Lecture.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/lecture/domain/Lecture.java @@ -7,7 +7,7 @@ import java.util.List; import org.sopt.makers.operation.common.domain.BaseEntity; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.attendance.domain.Attendance; import jakarta.persistence.Column; diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/lecture/repository/lecture/LectureCustomRepository.java b/operation-domain/src/main/java/org/sopt/makers/operation/lecture/repository/lecture/LectureCustomRepository.java index 738e1679..3de4beb5 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/lecture/repository/lecture/LectureCustomRepository.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/lecture/repository/lecture/LectureCustomRepository.java @@ -1,9 +1,8 @@ package org.sopt.makers.operation.lecture.repository.lecture; import java.util.List; -import java.util.Optional; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.lecture.domain.Lecture; public interface LectureCustomRepository { diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/lecture/repository/lecture/LectureRepositoryImpl.java b/operation-domain/src/main/java/org/sopt/makers/operation/lecture/repository/lecture/LectureRepositoryImpl.java index 281831ae..4ead62b6 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/lecture/repository/lecture/LectureRepositoryImpl.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/lecture/repository/lecture/LectureRepositoryImpl.java @@ -8,7 +8,7 @@ import java.time.LocalDateTime; import java.util.List; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.lecture.domain.Lecture; import org.sopt.makers.operation.lecture.domain.LectureStatus; import org.springframework.stereotype.Repository; diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/member/domain/Member.java b/operation-domain/src/main/java/org/sopt/makers/operation/member/domain/Member.java index b1f799b7..2109e027 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/member/domain/Member.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/member/domain/Member.java @@ -4,7 +4,6 @@ import java.util.List; import org.sopt.makers.operation.attendance.domain.Attendance; -import org.sopt.makers.operation.common.domain.Part; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/common/domain/Part.java b/operation-domain/src/main/java/org/sopt/makers/operation/member/domain/Part.java similarity index 84% rename from operation-domain/src/main/java/org/sopt/makers/operation/common/domain/Part.java rename to operation-domain/src/main/java/org/sopt/makers/operation/member/domain/Part.java index e39f073c..a50b7740 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/common/domain/Part.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/member/domain/Part.java @@ -1,4 +1,4 @@ -package org.sopt.makers.operation.common.domain; +package org.sopt.makers.operation.member.domain; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/member/repository/MemberCustomRepository.java b/operation-domain/src/main/java/org/sopt/makers/operation/member/repository/MemberCustomRepository.java index 93493bbe..af043ed1 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/member/repository/MemberCustomRepository.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/member/repository/MemberCustomRepository.java @@ -2,7 +2,7 @@ import java.util.List; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.member.domain.Member; import org.springframework.data.domain.Pageable; diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/member/repository/MemberRepositoryImpl.java b/operation-domain/src/main/java/org/sopt/makers/operation/member/repository/MemberRepositoryImpl.java index 4f4a17f8..8e9dae26 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/member/repository/MemberRepositoryImpl.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/member/repository/MemberRepositoryImpl.java @@ -1,12 +1,12 @@ package org.sopt.makers.operation.member.repository; import static java.util.Objects.*; -import static org.sopt.makers.operation.common.domain.Part.*; +import static org.sopt.makers.operation.member.domain.Part.*; import static org.sopt.makers.operation.member.domain.QMember.*; import java.util.List; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.member.domain.Member; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Repository; diff --git a/operation-domain/src/test/java/org/sopt/makers/operation/attendance/domain/AttendanceGetScoreTest.java b/operation-domain/src/test/java/org/sopt/makers/operation/attendance/domain/AttendanceGetScoreTest.java index 3d15bc1d..551bb16e 100644 --- a/operation-domain/src/test/java/org/sopt/makers/operation/attendance/domain/AttendanceGetScoreTest.java +++ b/operation-domain/src/test/java/org/sopt/makers/operation/attendance/domain/AttendanceGetScoreTest.java @@ -4,7 +4,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.dummy.AttendanceDummy; import org.sopt.makers.operation.dummy.LectureDummy; import org.sopt.makers.operation.dummy.MemberDummy; diff --git a/operation-domain/src/test/java/org/sopt/makers/operation/attendance/domain/AttendanceGetStatusTest.java b/operation-domain/src/test/java/org/sopt/makers/operation/attendance/domain/AttendanceGetStatusTest.java index a0877f15..eed7d5af 100644 --- a/operation-domain/src/test/java/org/sopt/makers/operation/attendance/domain/AttendanceGetStatusTest.java +++ b/operation-domain/src/test/java/org/sopt/makers/operation/attendance/domain/AttendanceGetStatusTest.java @@ -4,7 +4,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.dummy.AttendanceDummy; import org.sopt.makers.operation.dummy.LectureDummy; import org.sopt.makers.operation.dummy.MemberDummy; diff --git a/operation-domain/src/test/java/org/sopt/makers/operation/dummy/LectureDummy.java b/operation-domain/src/test/java/org/sopt/makers/operation/dummy/LectureDummy.java index 3527fd4c..f6e6981e 100644 --- a/operation-domain/src/test/java/org/sopt/makers/operation/dummy/LectureDummy.java +++ b/operation-domain/src/test/java/org/sopt/makers/operation/dummy/LectureDummy.java @@ -1,7 +1,7 @@ package org.sopt.makers.operation.dummy; import org.sopt.makers.operation.attendance.domain.Attendance; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.lecture.domain.Attribute; import org.sopt.makers.operation.lecture.domain.Lecture; import org.sopt.makers.operation.lecture.domain.LectureStatus; diff --git a/operation-domain/src/test/java/org/sopt/makers/operation/dummy/MemberDummy.java b/operation-domain/src/test/java/org/sopt/makers/operation/dummy/MemberDummy.java index c27010e9..d18a24d1 100644 --- a/operation-domain/src/test/java/org/sopt/makers/operation/dummy/MemberDummy.java +++ b/operation-domain/src/test/java/org/sopt/makers/operation/dummy/MemberDummy.java @@ -2,7 +2,7 @@ import lombok.Builder; import org.sopt.makers.operation.attendance.domain.Attendance; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.member.domain.Member; import org.sopt.makers.operation.member.domain.ObYb; diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/playground/PlayGroundServer.java b/operation-external/src/main/java/org/sopt/makers/operation/client/playground/PlayGroundServer.java index 9230281e..c2f15036 100644 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/playground/PlayGroundServer.java +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/playground/PlayGroundServer.java @@ -1,7 +1,7 @@ package org.sopt.makers.operation.client.playground; import org.sopt.makers.operation.client.playground.dto.MemberListGetResponse; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; public interface PlayGroundServer { MemberListGetResponse getMembers(int generation, Part part); diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/playground/PlayGroundServerImpl.java b/operation-external/src/main/java/org/sopt/makers/operation/client/playground/PlayGroundServerImpl.java index c48cd3f7..1048c678 100644 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/playground/PlayGroundServerImpl.java +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/playground/PlayGroundServerImpl.java @@ -1,11 +1,11 @@ package org.sopt.makers.operation.client.playground; import static org.sopt.makers.operation.code.failure.AlarmFailureCode.*; -import static org.sopt.makers.operation.common.domain.Part.*; +import static org.sopt.makers.operation.member.domain.Part.*; import static org.springframework.http.HttpMethod.*; import org.sopt.makers.operation.client.playground.dto.MemberListGetResponse; -import org.sopt.makers.operation.common.domain.Part; +import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.config.ValueConfig; import org.sopt.makers.operation.exception.AlarmException; import org.springframework.http.HttpEntity; From 2890d87ee968bf0bf04abba4a8e9c34652105807 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Thu, 16 Jan 2025 20:48:05 +0900 Subject: [PATCH 13/31] =?UTF-8?q?[ADD]=20AlarmLinkType=20Enum=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=ED=95=9C=EA=B8=80=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?`name`=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/sopt/makers/operation/alarm/domain/AlarmLinkType.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmLinkType.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmLinkType.java index 3b451ef2..4f419b5d 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmLinkType.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmLinkType.java @@ -6,5 +6,7 @@ @Getter @AllArgsConstructor public enum AlarmLinkType { - WEB, APP, NONE + WEB("웹"), APP("앱"), NONE("없음") + ; + private final String name; } From 2832efee9b7751ec85e7d002f16b5b7709b25c44 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Thu, 16 Jan 2025 20:49:02 +0900 Subject: [PATCH 14/31] =?UTF-8?q?[ADD]=20Alarm=20Target=20String=20Target?= =?UTF-8?q?=20Id=20List=20=EC=A3=BC=EC=9E=85=20Setter=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/sopt/makers/operation/alarm/domain/AlarmTarget.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTarget.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTarget.java index faad8c20..95189d24 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTarget.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTarget.java @@ -6,6 +6,7 @@ import lombok.Builder; import lombok.Getter; +import lombok.Setter; import lombok.NoArgsConstructor; import lombok.AllArgsConstructor; @@ -35,6 +36,7 @@ public class AlarmTarget { @Column(name = "generation", updatable = false, insertable = false) private Integer generation; + @Setter @Column(name = "targets", columnDefinition = "TEXT", updatable = false) @Convert(converter = StringListConverter.class) private List targetIds; From d4d63a97be355dce89357f174041a83b1328afa3 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Thu, 16 Jan 2025 20:50:28 +0900 Subject: [PATCH 15/31] =?UTF-8?q?[REFACTOR]=20Alarm=20Entity=20=EA=B0=9C?= =?UTF-8?q?=ED=8E=B8=EC=97=90=20=EB=94=B0=EB=A5=B8=20QueryDSL=20=EC=86=8C?= =?UTF-8?q?=EC=8A=A4=20=EC=BD=94=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alarm/repository/AlarmCustomRepository.java | 7 ++++--- .../alarm/repository/AlarmRepositoryImpl.java | 10 +++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/repository/AlarmCustomRepository.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/repository/AlarmCustomRepository.java index 4b329f02..dc5e1269 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/repository/AlarmCustomRepository.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/repository/AlarmCustomRepository.java @@ -1,12 +1,13 @@ package org.sopt.makers.operation.alarm.repository; import java.util.List; + import org.sopt.makers.operation.alarm.domain.Alarm; -import org.sopt.makers.operation.alarm.domain.Status; +import org.sopt.makers.operation.alarm.domain.AlarmStatus; import org.springframework.data.domain.Pageable; public interface AlarmCustomRepository { - List findOrderByCreatedDate(Integer generation, Status status, Pageable pageable); + List findOrderByCreatedDate(Integer generation, AlarmStatus status, Pageable pageable); - int count(Integer generation, Status status); + int count(Integer generation, AlarmStatus status); } diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/repository/AlarmRepositoryImpl.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/repository/AlarmRepositoryImpl.java index 2c6c5456..48041aef 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/repository/AlarmRepositoryImpl.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/repository/AlarmRepositoryImpl.java @@ -8,7 +8,7 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.sopt.makers.operation.alarm.domain.Alarm; -import org.sopt.makers.operation.alarm.domain.Status; +import org.sopt.makers.operation.alarm.domain.AlarmStatus; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Repository; @@ -18,7 +18,7 @@ public class AlarmRepositoryImpl implements AlarmCustomRepository { private final JPAQueryFactory queryFactory; @Override - public List findOrderByCreatedDate(Integer generation, Status status, Pageable pageable) { + public List findOrderByCreatedDate(Integer generation, AlarmStatus status, Pageable pageable) { return queryFactory .selectFrom(alarm) .where( @@ -32,7 +32,7 @@ public List findOrderByCreatedDate(Integer generation, Status status, Pag } @Override - public int count(Integer generation, Status status) { + public int count(Integer generation, AlarmStatus status) { return Math.toIntExact(queryFactory .select(alarm.count()) .from(alarm) @@ -44,10 +44,10 @@ public int count(Integer generation, Status status) { } private BooleanExpression generationEq(Integer generation) { - return nonNull(generation) ? alarm.createdGeneration.eq(generation) : null; + return nonNull(generation) ? alarm.target.generation.eq(generation) : null; } - private BooleanExpression statusEq(Status status) { + private BooleanExpression statusEq(AlarmStatus status) { return nonNull(status) ? alarm.status.eq(status) : null; } } From 6798f4511d160ce7da9e339c47c4825f569a6af4 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Fri, 17 Jan 2025 02:07:21 +0900 Subject: [PATCH 16/31] =?UTF-8?q?[REFACTOR]=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EB=B0=9C=EC=86=A1=20=EC=9A=94=EC=B2=AD=20DTO=20=ED=91=9C?= =?UTF-8?q?=EC=A4=80=ED=99=94=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 쓰임에 따라 슈퍼 타입 Interface `AlarmRequest`를 구현한 후, `InstantAlarmRequest` / `ScheduleAlarmRequest` 구현체를 구현하여 관심사에 따른 관심사 분리 & 타입 안정적으로 사용하도록 했습니다. - 통일성 있는 행위에 대한 메서드를 정의 및 구현할 수 있습니다. - 알림 발송 역할을 담당하는 객체는 메서드는 `AlarmRequest` 타입 객체만 파라미터로 받을 수 있도록 합니다. - 알림 발송 구현체는 `InstantAlarmRequest` / `ScheduleAlarmRequest`만을 활용할 수 있습니다. --- .../service/WebLectureServiceImpl.java | 15 ++++-- .../operation/client/alarm/AlarmManager.java | 24 +++++----- .../operation/client/alarm/AlarmSender.java | 7 +++ .../client/alarm/alarmServer/AlarmSender.java | 7 --- .../client/alarm/dto/AlarmRequest.java | 4 ++ .../client/alarm/dto/InstantAlarmRequest.java | 47 +++++++++++++++++++ .../alarm/dto/ScheduleAlarmRequest.java | 42 +++++++++++++++++ 7 files changed, 123 insertions(+), 23 deletions(-) create mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/AlarmSender.java delete mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/alarmServer/AlarmSender.java create mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/AlarmRequest.java create mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/InstantAlarmRequest.java create mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/ScheduleAlarmRequest.java diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureServiceImpl.java b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureServiceImpl.java index f3b45514..4208070e 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureServiceImpl.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureServiceImpl.java @@ -14,8 +14,8 @@ import org.sopt.makers.operation.attendance.domain.SubAttendance; import org.sopt.makers.operation.attendance.repository.attendance.AttendanceRepository; import org.sopt.makers.operation.attendance.repository.subAttendance.SubAttendanceRepository; -import org.sopt.makers.operation.client.alarm.alarmServer.AlarmSender; -import org.sopt.makers.operation.client.alarm.alarmServer.dto.AlarmSenderRequest; +import org.sopt.makers.operation.client.alarm.AlarmManager; +import org.sopt.makers.operation.client.alarm.dto.InstantAlarmRequest; import org.sopt.makers.operation.member.domain.Part; import org.sopt.makers.operation.config.ValueConfig; import org.sopt.makers.operation.exception.LectureException; @@ -47,7 +47,7 @@ public class WebLectureServiceImpl implements WebLectureService { private final SubAttendanceRepository subAttendanceRepository; private final MemberRepository memberRepository; - private final AlarmSender alarmSender; + private final AlarmManager alarmSender; private final ValueConfig valueConfig; @Override @@ -177,7 +177,14 @@ private Lecture getLectureReadyToEnd(long lectureId) { } private void sendAlarm(Lecture lecture) { - alarmSender.send(AlarmSenderRequest.of(lecture, valueConfig)); + val alarmMessageTitle = lecture.getName() + " " + valueConfig.getALARM_MESSAGE_TITLE(); + val alarmMessageContent = valueConfig.getALARM_MESSAGE_CONTENT(); + val targets = lecture.getAttendances().stream() + .map(attendance -> String.valueOf(attendance.getMember().getPlaygroundId())) + .filter(id -> !id.equals("null")) + .toList(); + val alarmRequest = InstantAlarmRequest.of(alarmMessageTitle, alarmMessageContent, targets); + alarmSender.sendInstant(alarmRequest); } private Lecture getLectureToDelete(long lectureId) { diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/AlarmManager.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/AlarmManager.java index facd07a8..cfed0df0 100644 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/AlarmManager.java +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/AlarmManager.java @@ -1,24 +1,24 @@ package org.sopt.makers.operation.client.alarm; import lombok.RequiredArgsConstructor; -import org.sopt.makers.operation.client.alarm.alarmServer.AlarmSenderImpl; -import org.sopt.makers.operation.client.alarm.alarmServer.dto.AlarmSenderRequest; -import org.sopt.makers.operation.client.alarm.eventBridgeServer.EventBridgeSenderImpl; -import org.sopt.makers.operation.client.alarm.eventBridgeServer.dto.EventBridgeSenderRequest; +import org.sopt.makers.operation.alarm.domain.Alarm; +import org.sopt.makers.operation.client.alarm.dto.InstantAlarmRequest; +import org.sopt.makers.operation.client.alarm.dto.ScheduleAlarmRequest; import org.springframework.stereotype.Component; +import java.util.List; + @Component @RequiredArgsConstructor public class AlarmManager { + private final InstantAlarmSender instantAlarmSender; + private final ScheduleAlarmSender scheduleAlarmSender; - private final AlarmSenderImpl alarmSender; - private final EventBridgeSenderImpl eventBridgeSender; - - public void sendInstantAlarm(AlarmSenderRequest request) { - alarmSender.send(request); + public void sendInstant(InstantAlarmRequest alarmRequest) { + instantAlarmSender.sendAlarm(alarmRequest); } - - public void sendReservedAlarm(EventBridgeSenderRequest request, String postDate, String postTime, Long alarmId) { - eventBridgeSender.scheduleAlarm(request, postDate, postTime, alarmId); + public void sendSchedule(ScheduleAlarmRequest alarmRequest) { + scheduleAlarmSender.sendAlarm(alarmRequest); } + } diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/AlarmSender.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/AlarmSender.java new file mode 100644 index 00000000..d4b14ea1 --- /dev/null +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/AlarmSender.java @@ -0,0 +1,7 @@ +package org.sopt.makers.operation.client.alarm; + +import org.sopt.makers.operation.client.alarm.dto.AlarmRequest; + +interface AlarmSender { + void sendAlarm(AlarmRequest alarmRequest); +} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/alarmServer/AlarmSender.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/alarmServer/AlarmSender.java deleted file mode 100644 index 8ef650d2..00000000 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/alarmServer/AlarmSender.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.sopt.makers.operation.client.alarm.alarmServer; - -import org.sopt.makers.operation.client.alarm.alarmServer.dto.AlarmSenderRequest; - -public interface AlarmSender { - void send(AlarmSenderRequest request); -} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/AlarmRequest.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/AlarmRequest.java new file mode 100644 index 00000000..19fe4831 --- /dev/null +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/AlarmRequest.java @@ -0,0 +1,4 @@ +package org.sopt.makers.operation.client.alarm.dto; + +public interface AlarmRequest { +} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/InstantAlarmRequest.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/InstantAlarmRequest.java new file mode 100644 index 00000000..848f995c --- /dev/null +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/InstantAlarmRequest.java @@ -0,0 +1,47 @@ +package org.sopt.makers.operation.client.alarm.dto; + +import lombok.Builder; +import lombok.val; +import org.sopt.makers.operation.alarm.domain.Alarm; +import org.sopt.makers.operation.alarm.domain.AlarmCategory; +import org.sopt.makers.operation.alarm.domain.AlarmLinkType; +import org.sopt.makers.operation.alarm.domain.AlarmTargetType; + +import java.util.List; + +import static lombok.AccessLevel.PRIVATE; +import static org.sopt.makers.operation.alarm.domain.AlarmCategory.NEWS; + +@Builder(access = PRIVATE) +public record InstantAlarmRequest( + String title, + String content, + AlarmTargetType targetType, + List targets, + AlarmCategory category, + String link, + AlarmLinkType linkType + +) implements AlarmRequest { + public static InstantAlarmRequest of(Alarm alarm) { + val content = alarm.getContent(); + return InstantAlarmRequest.builder() + .targetType(alarm.getTarget().getTargetType()) + .targets(alarm.getTarget().getTargetIds()) + .title(content.getTitle()) + .content(content.getContent()) + .category(content.getCategory()) + .linkType(content.getLinkType()).link(content.getLinkPath()) + .build(); + } + + public static InstantAlarmRequest of(String title, String content, List targetList) { + return InstantAlarmRequest.builder() + .targets(targetList) + .title(title) + .content(content) + .category(NEWS) + .build(); + } + +} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/ScheduleAlarmRequest.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/ScheduleAlarmRequest.java new file mode 100644 index 00000000..9dff1323 --- /dev/null +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/ScheduleAlarmRequest.java @@ -0,0 +1,42 @@ +package org.sopt.makers.operation.client.alarm.dto; + +import lombok.AccessLevel; +import lombok.Builder; +import org.sopt.makers.operation.alarm.domain.Alarm; +import org.sopt.makers.operation.alarm.domain.AlarmCategory; +import org.sopt.makers.operation.alarm.domain.AlarmLinkType; +import org.sopt.makers.operation.alarm.domain.AlarmTargetType; + +import java.time.LocalDateTime; +import java.util.List; + +import static lombok.AccessLevel.PRIVATE; + +@Builder(access = PRIVATE) +public record ScheduleAlarmRequest( + long alarmId, + String title, + String content, + AlarmCategory category, + String link, + AlarmLinkType linkType, + AlarmTargetType targetType, + List targets, + LocalDateTime scheduleDateTime +) implements AlarmRequest { + public static ScheduleAlarmRequest of(Alarm alarm) { + return ScheduleAlarmRequest.builder() + .alarmId(alarm.getId()) + .title(alarm.getContent().getTitle()) + .content(alarm.getContent().getContent()) + .category(alarm.getContent().getCategory()) + .link(alarm.getContent().getLinkPath()) + .linkType(alarm.getContent().getLinkType()) + .targetType(alarm.getTarget().getTargetType()) + .targets(alarm.getTarget().getTargetIds()) + .scheduleDateTime(alarm.getIntendedAt()) + .build(); + } + + public +} From befd8381690346782171674ba76e260e02ba9dcd Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Fri, 17 Jan 2025 02:11:04 +0900 Subject: [PATCH 17/31] =?UTF-8?q?[REFACTOR]=20=EC=98=88=EC=95=BD=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EB=B0=9C=EC=86=A1=20=EC=A0=84=EC=9A=A9=20?= =?UTF-8?q?EventBridge=20=EA=B5=AC=ED=98=84=EC=B2=B4=20=EA=B0=9C=ED=8E=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EventBridge의 경우, 다양한 도메인에서 활용될 수 있기 때문에 이름에 쓰임과 의도를 명확히 표현하기 위해 이름을 수정했습니다. - 이전 구현체 대비 코드 절약이 가능한 소스 코드는 편집했습니다. --- .../alarmServer/dto/AlarmSenderRequest.java | 52 ------------------- .../AlarmScheduleEventBridgeBody.java | 18 +++++++ .../AlarmScheduleEventBridgeHeader.java | 12 +++++ .../AlarmScheduleEventBridgeRequest.java | 13 +++++ .../eventBridgeServer/EventBridgeSender.java | 10 ---- .../dto/EventBridgeSenderRequest.java | 27 ---------- .../dto/EventBridgeSenderRequestBody.java | 18 ------- .../dto/EventBridgeSenderRequestHeader.java | 16 ------ 8 files changed, 43 insertions(+), 123 deletions(-) delete mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/alarmServer/dto/AlarmSenderRequest.java create mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeBody.java create mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeHeader.java create mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeRequest.java delete mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/EventBridgeSender.java delete mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/dto/EventBridgeSenderRequest.java delete mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/dto/EventBridgeSenderRequestBody.java delete mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/dto/EventBridgeSenderRequestHeader.java diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/alarmServer/dto/AlarmSenderRequest.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/alarmServer/dto/AlarmSenderRequest.java deleted file mode 100644 index 225fc992..00000000 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/alarmServer/dto/AlarmSenderRequest.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.sopt.makers.operation.client.alarm.alarmServer.dto; - -import static org.sopt.makers.operation.alarm.domain.Category.NEWS; - -import java.util.List; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.val; -import org.sopt.makers.operation.alarm.domain.Alarm; -import org.sopt.makers.operation.alarm.domain.Category; -import org.sopt.makers.operation.config.ValueConfig; -import org.sopt.makers.operation.lecture.domain.Lecture; - -@Builder(access = AccessLevel.PRIVATE) -public record AlarmSenderRequest( - String title, - String content, - List targetList, - Category attribute, - String link -) { - - public static AlarmSenderRequest of(Alarm alarm, List targetList) { - return AlarmSenderRequest.builder() - .title(alarm.getTitle()) - .content(alarm.getContent()) - .targetList(targetList) - .attribute(alarm.getCategory()) - .link(alarm.getLink()) - .build(); - } - - public static AlarmSenderRequest of(Lecture lecture, ValueConfig valueConfig) { - val title = lecture.getName() + " " + valueConfig.getALARM_MESSAGE_TITLE(); - val content = valueConfig.getALARM_MESSAGE_CONTENT(); - val targetList = getTargetsFromLecture(lecture); - return AlarmSenderRequest.builder() - .title(title) - .content(content) - .targetList(targetList) - .attribute(NEWS) - .build(); - } - - private static List getTargetsFromLecture(Lecture lecture) { - return lecture.getAttendances().stream() - .map(attendance -> String.valueOf(attendance.getMember().getPlaygroundId())) - .filter(id -> !id.equals("null")) - .toList(); - } - -} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeBody.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeBody.java new file mode 100644 index 00000000..03dbe163 --- /dev/null +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeBody.java @@ -0,0 +1,18 @@ +package org.sopt.makers.operation.client.alarm.dto.eventbridge; + +import java.util.List; + +import lombok.Builder; +import org.sopt.makers.operation.alarm.domain.AlarmCategory; + +@Builder +public record AlarmScheduleEventBridgeBody( + long alarmId, + List userIds, + String title, + String content, + AlarmCategory category, + String deepLink, + String webLink +) { +} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeHeader.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeHeader.java new file mode 100644 index 00000000..12e85d9b --- /dev/null +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeHeader.java @@ -0,0 +1,12 @@ +package org.sopt.makers.operation.client.alarm.dto.eventbridge; + +import lombok.Builder; + +@Builder +public record AlarmScheduleEventBridgeHeader( + String action, + String xApiKey, + String transactionId, + String service +) { +} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeRequest.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeRequest.java new file mode 100644 index 00000000..e491c1e6 --- /dev/null +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeRequest.java @@ -0,0 +1,13 @@ +package org.sopt.makers.operation.client.alarm.dto.eventbridge; + +public record AlarmScheduleEventBridgeRequest( + AlarmScheduleEventBridgeHeader header, + AlarmScheduleEventBridgeBody body +) { + public static AlarmScheduleEventBridgeRequest of( + AlarmScheduleEventBridgeHeader header, + AlarmScheduleEventBridgeBody body + ) { + return new AlarmScheduleEventBridgeRequest(header, body); + } +} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/EventBridgeSender.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/EventBridgeSender.java deleted file mode 100644 index 1542906b..00000000 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/EventBridgeSender.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.sopt.makers.operation.client.alarm.eventBridgeServer; - - -import org.sopt.makers.operation.client.alarm.eventBridgeServer.dto.EventBridgeSenderRequest; - -public interface EventBridgeSender { - - void scheduleAlarm(EventBridgeSenderRequest request, String postDate, String postTime, Long alarmId); - -} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/dto/EventBridgeSenderRequest.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/dto/EventBridgeSenderRequest.java deleted file mode 100644 index c22f37a1..00000000 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/dto/EventBridgeSenderRequest.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.sopt.makers.operation.client.alarm.eventBridgeServer.dto; - -import java.util.List; -import lombok.val; -import org.sopt.makers.operation.alarm.domain.Category; - -public record EventBridgeSenderRequest( - EventBridgeSenderRequestHeader header, - EventBridgeSenderRequestBody body -) { - public static EventBridgeSenderRequest of( - EventBridgeSenderRequestHeader header, - EventBridgeSenderRequestBody body - ) { - return new EventBridgeSenderRequest(header, body); - } - - public static EventBridgeSenderRequest of( - String xApiKey, String service, String action, - List userIds, String title, String content, Category category, String deepLink, String webLink - ) { - val header = EventBridgeSenderRequestHeader.of(xApiKey, action, service); - val body = EventBridgeSenderRequestBody.of(userIds, title, content, category, deepLink, - webLink); - return new EventBridgeSenderRequest(header, body); - } -} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/dto/EventBridgeSenderRequestBody.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/dto/EventBridgeSenderRequestBody.java deleted file mode 100644 index 716eced9..00000000 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/dto/EventBridgeSenderRequestBody.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.sopt.makers.operation.client.alarm.eventBridgeServer.dto; - -import java.util.List; -import org.sopt.makers.operation.alarm.domain.Category; - -public record EventBridgeSenderRequestBody( - List userIds, - String title, - String content, - Category category, - String deepLink, - String webLink -) { - public static EventBridgeSenderRequestBody of(List userIds, String title, String content, Category category, - String deepLink, String webLink) { - return new EventBridgeSenderRequestBody(userIds, title, content, category, deepLink, webLink); - } -} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/dto/EventBridgeSenderRequestHeader.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/dto/EventBridgeSenderRequestHeader.java deleted file mode 100644 index ce7c997b..00000000 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/dto/EventBridgeSenderRequestHeader.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.sopt.makers.operation.client.alarm.eventBridgeServer.dto; - -import java.util.UUID; -import lombok.val; - -public record EventBridgeSenderRequestHeader( - String action, - String xApiKey, - String transactionId, - String service -) { - public static EventBridgeSenderRequestHeader of(String xApiKey, String action, String service) { - val transactionId = UUID.randomUUID().toString(); - return new EventBridgeSenderRequestHeader(action, xApiKey, transactionId, service); - } -} From e626318712fe438f192cf6a24357f7a7fb405afc Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Fri, 17 Jan 2025 02:18:29 +0900 Subject: [PATCH 18/31] =?UTF-8?q?[REFACTOR]=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EC=A6=89=EC=8B=9C=20=EB=B0=9C=EC=86=A1/=EC=98=88=EC=95=BD=20?= =?UTF-8?q?=EB=B0=9C=EC=86=A1=20=EA=B5=AC=ED=98=84=EC=B2=B4=20=EA=B0=9C?= =?UTF-8?q?=ED=8E=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/alarm/InstantAlarmSender.java | 90 +++++++++++ .../client/alarm/ScheduleAlarmSender.java | 142 ++++++++++++++++++ .../alarm/alarmServer/AlarmSenderImpl.java | 91 ----------- .../alarm/dto/ScheduleAlarmRequest.java | 2 - .../EventBridgeSenderImpl.java | 102 ------------- 5 files changed, 232 insertions(+), 195 deletions(-) create mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/InstantAlarmSender.java create mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/ScheduleAlarmSender.java delete mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/alarmServer/AlarmSenderImpl.java delete mode 100644 operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/EventBridgeSenderImpl.java diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/InstantAlarmSender.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/InstantAlarmSender.java new file mode 100644 index 00000000..24ad1698 --- /dev/null +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/InstantAlarmSender.java @@ -0,0 +1,90 @@ +package org.sopt.makers.operation.client.alarm; + +import lombok.RequiredArgsConstructor; +import lombok.val; +import org.sopt.makers.operation.alarm.domain.AlarmLinkType; +import org.sopt.makers.operation.alarm.domain.AlarmTargetType; +import org.sopt.makers.operation.client.alarm.dto.AlarmRequest; +import org.sopt.makers.operation.client.alarm.dto.InstantAlarmRequest; +import org.sopt.makers.operation.config.ValueConfig; +import org.sopt.makers.operation.exception.AlarmException; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Component; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; +import org.springframework.web.client.RestTemplate; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static java.util.UUID.randomUUID; +import static org.sopt.makers.operation.code.failure.AlarmFailureCode.FAIL_SEND_ALARM; +import static org.springframework.http.MediaType.APPLICATION_JSON; + +@Component +@RequiredArgsConstructor +class InstantAlarmSender implements AlarmSender{ + private final RestTemplate restTemplate; + private final ValueConfig valueConfig; + + @Override + public void sendAlarm(AlarmRequest alarmRequest) { + InstantAlarmRequest instantRequest = (InstantAlarmRequest) alarmRequest; + try { + val host = valueConfig.getNOTIFICATION_URL(); + val body = generateBody(instantRequest); + val headers = generateHeader(instantRequest); + val request = new HttpEntity<>(body, headers); + + restTemplate.postForEntity(host, request, InstantAlarmRequest.class); + } catch (HttpServerErrorException | HttpClientErrorException e) { + throw new AlarmException(FAIL_SEND_ALARM); + } + } + + private Map generateBody(InstantAlarmRequest instantRequest) { + val body = new HashMap<>(); + + putRequiredAttributes(instantRequest, body); + putOptionalAttributes(instantRequest, body); + + return body; + } + + private static void putRequiredAttributes(InstantAlarmRequest instantRequest, HashMap body) { + body.put("title", instantRequest.title()); + body.put("content", instantRequest.content()); + body.put("category", instantRequest.category()); + } + + private static void putOptionalAttributes(InstantAlarmRequest instantRequest, HashMap body) { + if (!instantRequest.targetType().equals(AlarmTargetType.ALL)) { + body.put("userIds", instantRequest.targets()); + } + + if (instantRequest.linkType().equals(AlarmLinkType.WEB)) { + body.put("webLink", instantRequest.link()); + } else if (instantRequest.linkType().equals(AlarmLinkType.APP)) { + body.put("appLink", instantRequest.link()); + } + } + + private HttpHeaders generateHeader(InstantAlarmRequest instantRequest) { + val headers = new HttpHeaders(); + val apiKey = valueConfig.getNOTIFICATION_KEY(); + + headers.setContentType(APPLICATION_JSON); + headers.setAccept(Collections.singletonList(APPLICATION_JSON)); + + String actionValue = instantRequest.targetType().getAction().getValue(); + headers.add("action", actionValue); + headers.add("transactionId", randomUUID().toString()); + headers.add("service", "operation"); + headers.add("x-api-key", apiKey); + + return headers; + } + +} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/ScheduleAlarmSender.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/ScheduleAlarmSender.java new file mode 100644 index 00000000..2722143f --- /dev/null +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/ScheduleAlarmSender.java @@ -0,0 +1,142 @@ +package org.sopt.makers.operation.client.alarm; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import lombok.val; +import org.sopt.makers.operation.alarm.domain.AlarmLinkType; +import org.sopt.makers.operation.client.alarm.dto.AlarmRequest; +import org.sopt.makers.operation.client.alarm.dto.ScheduleAlarmRequest; +import org.sopt.makers.operation.client.alarm.dto.eventbridge.AlarmScheduleEventBridgeRequest; +import org.sopt.makers.operation.client.alarm.dto.eventbridge.AlarmScheduleEventBridgeBody; +import org.sopt.makers.operation.client.alarm.dto.eventbridge.AlarmScheduleEventBridgeHeader; +import org.sopt.makers.operation.code.failure.AlarmFailureCode; +import org.sopt.makers.operation.config.ValueConfig; +import org.sopt.makers.operation.exception.AlarmException; +import org.springframework.stereotype.Component; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.scheduler.SchedulerClient; +import software.amazon.awssdk.services.scheduler.model.CreateScheduleRequest; +import software.amazon.awssdk.services.scheduler.model.FlexibleTimeWindow; +import software.amazon.awssdk.services.scheduler.model.FlexibleTimeWindowMode; +import software.amazon.awssdk.services.scheduler.model.Target; + +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.UUID; + +@Component +@RequiredArgsConstructor +class ScheduleAlarmSender implements AlarmSender{ + private final ValueConfig valueConfig; + private SchedulerClient schedulerClient; + private ObjectMapper objectMapper; + + @PostConstruct + private void init() { + val awsCredentials = AwsBasicCredentials.create(valueConfig.getAccessKey(), + valueConfig.getSecretKey()); + this.schedulerClient = SchedulerClient.builder() + .region(Region.AP_NORTHEAST_2) + .credentialsProvider(StaticCredentialsProvider.create(awsCredentials)) + .build(); + this.objectMapper = new ObjectMapper(); + } + + @Override + public void sendAlarm(AlarmRequest alarmRequest) { + ScheduleAlarmRequest scheduleRequest = (ScheduleAlarmRequest) alarmRequest; + try { + val name = generateEventName(scheduleRequest); + val cronExpression = generateScheduleCronExpression(scheduleRequest); + + val eventJson = generateEventJson(scheduleRequest); + val target = generateEventTarget(eventJson); + + val createScheduleRequest = generateEvent(name, target, cronExpression); + schedulerClient.createSchedule(createScheduleRequest); + } catch (Exception e) { + e.printStackTrace(); + throw new AlarmException(AlarmFailureCode.FAIL_SCHEDULE_ALARM); + } + } + + private CreateScheduleRequest generateEvent(String eventName, Target eventTarget, String eventCronExpression) { + return CreateScheduleRequest.builder() + .name(eventName) + .target(eventTarget) + .scheduleExpression(eventCronExpression) + .actionAfterCompletion("DELETE") + .flexibleTimeWindow(FlexibleTimeWindow.builder() + .mode(FlexibleTimeWindowMode.OFF) + .build()) + .build(); + } + + private Target generateEventTarget(String eventJson) { + return Target.builder() + .roleArn(valueConfig.getEventBridgeRoleArn()) + .arn(valueConfig.getNotificationLambdaArn()) + .input(eventJson) + .build(); + } + + private String generateEventName(ScheduleAlarmRequest request) { + val dateData = request.scheduleDateTime().toLocalDate().format(DateTimeFormatter.ISO_DATE); + val timeData = request.scheduleDateTime().toLocalTime().format(DateTimeFormatter.ofPattern("HH-mm")); + + return String.format("%s_%s_%d", dateData, timeData, request.alarmId()); + } + + private String generateScheduleCronExpression(ScheduleAlarmRequest request) { + try { + val localDateTime = request.scheduleDateTime(); + val utcDateTime = localDateTime.atZone(ZoneId.systemDefault()) + .withZoneSameInstant(ZoneId.of("UTC")); + + return String.format("cron(%d %d %d %d ? %d)", + utcDateTime.getMinute(), + utcDateTime.getHour(), + utcDateTime.getDayOfMonth(), + utcDateTime.getMonthValue(), + utcDateTime.getYear()); + } catch (Exception e) { + throw new AlarmException(AlarmFailureCode.INVALID_SCHEDULE_ALARM_FORMAT); + } + } + + private String generateEventJson(ScheduleAlarmRequest request) throws JsonProcessingException { + val eventBody = convertToEventBridgeBody(request); + val eventHeader = convertToEventBridgeHeader(request); + + val eventBridgeRequest = AlarmScheduleEventBridgeRequest.of(eventHeader, eventBody); + return String.format("{\"detail\": %s}", objectMapper.writeValueAsString(eventBridgeRequest)); + } + + private AlarmScheduleEventBridgeHeader convertToEventBridgeHeader(ScheduleAlarmRequest request) { + return AlarmScheduleEventBridgeHeader.builder() + .action(request.targetType().getAction().getValue()) + .xApiKey(valueConfig.getNOTIFICATION_KEY()) + .transactionId(UUID.randomUUID().toString()) + .service(valueConfig.getNOTIFICATION_HEADER_SERVICE()) + .build(); + } + + private AlarmScheduleEventBridgeBody convertToEventBridgeBody(ScheduleAlarmRequest request) { + val deepLink = request.linkType().equals(AlarmLinkType.APP) ? request.link() : null; + val webLink = request.linkType().equals(AlarmLinkType.WEB) ? request.link() : null; + return AlarmScheduleEventBridgeBody.builder() + .alarmId(request.alarmId()) + .userIds(request.targets()) + .title(request.title()) + .content(request.content()) + .category(request.category()) + .deepLink(deepLink) + .webLink(webLink) + .build(); + } + +} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/alarmServer/AlarmSenderImpl.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/alarmServer/AlarmSenderImpl.java deleted file mode 100644 index 3583effb..00000000 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/alarmServer/AlarmSenderImpl.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.sopt.makers.operation.client.alarm.alarmServer; - -import static java.util.Objects.nonNull; -import static java.util.UUID.randomUUID; -import static org.sopt.makers.operation.code.failure.AlarmFailureCode.FAIL_SEND_ALARM; -import static org.springframework.http.MediaType.APPLICATION_JSON; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import lombok.RequiredArgsConstructor; -import lombok.val; -import org.sopt.makers.operation.client.alarm.alarmServer.dto.AlarmSenderRequest; -import org.sopt.makers.operation.config.ValueConfig; -import org.sopt.makers.operation.exception.AlarmException; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.stereotype.Component; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.HttpServerErrorException; -import org.springframework.web.client.RestTemplate; - -@Component -@RequiredArgsConstructor -public class AlarmSenderImpl implements AlarmSender { - - private final RestTemplate restTemplate; - private final ValueConfig valueConfig; - - @Override - public void send(AlarmSenderRequest request) { - try { - val host = valueConfig.getNOTIFICATION_URL(); - val entity = getEntity(request); - restTemplate.postForEntity(host, entity, AlarmSenderRequest.class); - } catch (HttpServerErrorException | HttpClientErrorException e) { - throw new AlarmException(FAIL_SEND_ALARM); - } - } - - private HttpEntity> getEntity(AlarmSenderRequest request) { - val alarmRequest = getAlarmRequest(request); - val headers = getHeaders(); - return new HttpEntity<>(alarmRequest, headers); - } - - private Map getAlarmRequest(AlarmSenderRequest request) { - val alarmRequest = new HashMap<>(); - val link = request.link(); - val linkKey = getLinkKey(link); - - if (!linkKey.isEmpty()) { - alarmRequest.put(linkKey, link); - } - - alarmRequest.put("userIds", request.targetList()); - alarmRequest.put("title", request.title()); - alarmRequest.put("content", request.content()); - alarmRequest.put("category", request.attribute()); - - return alarmRequest; - } - - private String getLinkKey(String link) { - val appLinkList = valueConfig.getAPP_LINK_LIST(); - val webLinkList = valueConfig.getWEB_LINK_LIST(); - - if (nonNull(link)) { - if (appLinkList.contains(link)) { - return "appLink"; - } else if (webLinkList.contains(link)) { - return "webLink"; - } - } - return ""; - } - - private HttpHeaders getHeaders() { - val headers = new HttpHeaders(); - val key = valueConfig.getNOTIFICATION_KEY(); - - headers.setContentType(APPLICATION_JSON); - headers.setAccept(Collections.singletonList(APPLICATION_JSON)); - headers.add("action", "send"); - headers.add("transactionId", randomUUID().toString()); - headers.add("service", "operation"); - headers.add("x-api-key", key); - - return headers; - } -} diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/ScheduleAlarmRequest.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/ScheduleAlarmRequest.java index 9dff1323..7783e3cf 100644 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/ScheduleAlarmRequest.java +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/ScheduleAlarmRequest.java @@ -37,6 +37,4 @@ public static ScheduleAlarmRequest of(Alarm alarm) { .scheduleDateTime(alarm.getIntendedAt()) .build(); } - - public } diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/EventBridgeSenderImpl.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/EventBridgeSenderImpl.java deleted file mode 100644 index beaf7c7a..00000000 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/eventBridgeServer/EventBridgeSenderImpl.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.sopt.makers.operation.client.alarm.eventBridgeServer; - -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.annotation.PostConstruct; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import lombok.RequiredArgsConstructor; -import lombok.val; -import org.sopt.makers.operation.client.alarm.eventBridgeServer.dto.EventBridgeSenderRequest; -import org.sopt.makers.operation.code.failure.AlarmFailureCode; -import org.sopt.makers.operation.config.ValueConfig; -import org.sopt.makers.operation.exception.AlarmException; -import org.springframework.stereotype.Component; -import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; -import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.scheduler.SchedulerClient; -import software.amazon.awssdk.services.scheduler.model.CreateScheduleRequest; -import software.amazon.awssdk.services.scheduler.model.FlexibleTimeWindow; -import software.amazon.awssdk.services.scheduler.model.FlexibleTimeWindowMode; -import software.amazon.awssdk.services.scheduler.model.Target; - -@Component -@RequiredArgsConstructor -public class EventBridgeSenderImpl implements EventBridgeSender { - - private SchedulerClient schedulerClient; - private final ValueConfig valueConfig; - private ObjectMapper objectMapper; - - @PostConstruct - private void init() { - val awsCredentials = AwsBasicCredentials.create(valueConfig.getAccessKey(), - valueConfig.getSecretKey()); - this.schedulerClient = SchedulerClient.builder() - .region(Region.AP_NORTHEAST_2) - .credentialsProvider(StaticCredentialsProvider.create(awsCredentials)) - .build(); - this.objectMapper = new ObjectMapper(); - } - - @Override - public void scheduleAlarm(EventBridgeSenderRequest request, String postDate, String postTime, Long alarmId) { - try { - val eventJson = String.format("{\"detail\": %s}", objectMapper.writeValueAsString(request)); - val formattedDate = formatCronExpression(postDate, postTime); - val scheduleName = createScheduleName(postDate, postTime, alarmId); - val target = createEventBridgeTarget(eventJson); - val createScheduleRequest = createScheduleRequest(target, scheduleName, formattedDate); - schedulerClient.createSchedule(createScheduleRequest); - } catch (Exception e) { - e.printStackTrace(); - throw new AlarmException(AlarmFailureCode.FAIL_SCHEDULE_ALARM); - } - } - - private String formatCronExpression(String postDate, String postTime) { - try { - val dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); - val localDateTime = LocalDateTime.parse(postDate + " " + postTime, dateFormatter); - - val utcDateTime = localDateTime.atZone(ZoneId.systemDefault()) - .withZoneSameInstant(ZoneId.of("UTC")); - - return String.format("cron(%d %d %d %d ? %d)", - utcDateTime.getMinute(), - utcDateTime.getHour(), - utcDateTime.getDayOfMonth(), - utcDateTime.getMonthValue(), - utcDateTime.getYear()); - } catch (Exception e) { - throw new AlarmException(AlarmFailureCode.INVALID_SCHEDULE_ALARM_FORMAT); - } - } - - private String createScheduleName(String postDate, String postTime, Long alarmId) { - val formattedTime = postTime.replace(":", "-"); - return String.format("%s_%s_%d", postDate, formattedTime, alarmId); - } - - private Target createEventBridgeTarget(String eventJson) { - return Target.builder() - .roleArn(valueConfig.getEventBridgeRoleArn()) - .arn(valueConfig.getNotificationLambdaArn()) - .input(eventJson) - .build(); - } - - private CreateScheduleRequest createScheduleRequest(Target target, String scheduleName, String formattedDate) { - return CreateScheduleRequest.builder() - .name(scheduleName) - .scheduleExpression(formattedDate) - .target(target) - .actionAfterCompletion("DELETE") - .flexibleTimeWindow(FlexibleTimeWindow.builder() - .mode(FlexibleTimeWindowMode.OFF) - .build()) - .build(); - } -} - From 3a21d94284d2244427439ffab48975d2fceda143 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Fri, 17 Jan 2025 02:25:01 +0900 Subject: [PATCH 19/31] =?UTF-8?q?[CHORE]=20Success/Failure=20Code=20?= =?UTF-8?q?=EA=B0=9C=ED=96=89=20=EB=B0=8F=20=EC=A3=BC=EC=84=9D=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 --- .../code/failure/AlarmFailureCode.java | 14 +++++++++---- .../code/success/web/AlarmSuccessCode.java | 20 ++++++++++++------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/operation-common/src/main/java/org/sopt/makers/operation/code/failure/AlarmFailureCode.java b/operation-common/src/main/java/org/sopt/makers/operation/code/failure/AlarmFailureCode.java index d47be86c..d5ed7176 100644 --- a/operation-common/src/main/java/org/sopt/makers/operation/code/failure/AlarmFailureCode.java +++ b/operation-common/src/main/java/org/sopt/makers/operation/code/failure/AlarmFailureCode.java @@ -10,13 +10,19 @@ @RequiredArgsConstructor @Getter public enum AlarmFailureCode implements FailureCode { - FAIL_SEND_ALARM(BAD_REQUEST, "알림 즉시 발송에 실패하였습니다."), - FAIL_SCHEDULE_ALARM(BAD_REQUEST, "알림 예약 발송에 실패하였습니다."), - INVALID_ALARM(NOT_FOUND, "알림이 존재하지 않습니다."), + // 400 + INVALID_SEND_INSTANT_REQUEST(BAD_REQUEST, "유효하지 않은 요청 키/값이 존재합니다."), + INVALID_SEND_SCHEDULED_REQUEST(BAD_REQUEST, "유효하지 않은 요청 키/값이 존재합니다."), INVALID_LINK(BAD_REQUEST, "지원하지 않는 링크입니다."), FAIL_INACTIVE_USERS(BAD_REQUEST, "비활동 유저 불러오기에 실패하였습니다."), INVALID_ALARM_TARGET_TYPE(BAD_REQUEST, "올바르지 않은 알림 타겟 타입입니다."), - INVALID_SCHEDULE_ALARM_FORMAT(BAD_REQUEST, "알림 예약 시간 포맷이 맞지 않습니다."); + INVALID_SCHEDULE_ALARM_FORMAT(BAD_REQUEST, "알림 예약 시간 포맷이 맞지 않습니다."), + FAIL_SEND_ALARM(BAD_REQUEST, "알림 즉시 발송에 실패하였습니다."), + FAIL_SCHEDULE_ALARM(BAD_REQUEST, "알림 예약 발송에 실패하였습니다."), + + // 404 + NOT_FOUND_ALARM(NOT_FOUND, "알림이 존재하지 않습니다."), + ; private final HttpStatus status; private final String message; diff --git a/operation-common/src/main/java/org/sopt/makers/operation/code/success/web/AlarmSuccessCode.java b/operation-common/src/main/java/org/sopt/makers/operation/code/success/web/AlarmSuccessCode.java index a2de6dc0..1e82f651 100644 --- a/operation-common/src/main/java/org/sopt/makers/operation/code/success/web/AlarmSuccessCode.java +++ b/operation-common/src/main/java/org/sopt/makers/operation/code/success/web/AlarmSuccessCode.java @@ -1,21 +1,27 @@ package org.sopt.makers.operation.code.success.web; -import static org.springframework.http.HttpStatus.OK; - import lombok.Getter; import lombok.RequiredArgsConstructor; import org.sopt.makers.operation.code.success.SuccessCode; import org.springframework.http.HttpStatus; +import static org.springframework.http.HttpStatus.*; + @RequiredArgsConstructor @Getter public enum AlarmSuccessCode implements SuccessCode { - SUCCESS_SEND_ALARM(OK, "알림 즉시 발송 성공"), - SUCCESS_GET_ALARMS(OK, "알림 리스트 조회 성공"), + // 200 SUCCESS_GET_ALARM(OK, "알림 상세 조회 성공"), - SUCCESS_DELETE_ALARM(OK, "알림 삭제 성공"), - SUCCESS_UPDATE_ALARM_STATUS(OK, "알림 상태 업데이트 성공"), - SUCCESS_SCHEDULE_ALARM(OK, "알림 예약 발송 성공"); + SUCCESS_GET_ALARMS(OK, "알림 리스트 조회 성공"), + + // 201 + SUCCESS_SEND_ALARM(CREATED, "알림 즉시 발송 성공"), + SUCCESS_SCHEDULE_ALARM(CREATED, "알림 예약 발송 성공"), + + // 204 + SUCCESS_UPDATE_ALARM_STATUS(NO_CONTENT, "알림 상태 업데이트 성공"), + SUCCESS_DELETE_ALARM(NO_CONTENT, "알림 삭제 성공"), + ; private final HttpStatus status; private final String message; From f0741af76747e276c379e4076fd44e2887c61376 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Fri, 17 Jan 2025 02:29:01 +0900 Subject: [PATCH 20/31] =?UTF-8?q?[FIX]=20API=20=EC=9A=94=EC=B2=AD/?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20DTO=20=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/AlarmScheduleSendRequest.java | 14 ++-- .../alarm/dto/response/AlarmGetResponse.java | 74 +++++++++++++------ .../dto/response/AlarmListGetResponse.java | 50 +++++++------ 3 files changed, 85 insertions(+), 53 deletions(-) diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleSendRequest.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleSendRequest.java index a8a6a79d..b79054af 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleSendRequest.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleSendRequest.java @@ -9,12 +9,14 @@ import java.util.List; import lombok.val; -import org.sopt.makers.operation.alarm.domain.*; -import org.sopt.makers.operation.code.failure.AlarmFailureCode; -import org.sopt.makers.operation.common.domain.Part; -import org.sopt.makers.operation.exception.AlarmException; -import static org.sopt.makers.operation.code.failure.AlarmFailureCode.INVALID_SEND_SCHEDULED_REQUEST; +import org.sopt.makers.operation.alarm.domain.Alarm; +import org.sopt.makers.operation.alarm.domain.AlarmTarget; +import org.sopt.makers.operation.alarm.domain.AlarmContent; +import org.sopt.makers.operation.alarm.domain.AlarmCategory; +import org.sopt.makers.operation.alarm.domain.AlarmTargetType; +import org.sopt.makers.operation.alarm.domain.AlarmTargetPart; +import org.sopt.makers.operation.alarm.domain.AlarmLinkType; public record AlarmScheduleSendRequest( @@ -37,7 +39,6 @@ private AlarmTarget toTargetEntity() { : AlarmTarget.partialForAll(this.part, this.targetList); case ACTIVE -> AlarmTarget.partialForActive(this.createdGeneration, this.part, this.targetList); case CSV -> AlarmTarget.partialForCsv(this.targetList); - default -> throw new AlarmException(INVALID_SEND_SCHEDULED_REQUEST); }; } @@ -46,7 +47,6 @@ private AlarmContent toContentEntity() { case WEB -> AlarmContent.withWebLink(this.title, this.content, this.category, this.link); case APP -> AlarmContent.withAppLink(this.title, this.content, this.category, this.link); case NONE -> AlarmContent.withoutLink(this.title, this.content, this.category); - default -> throw new AlarmException(INVALID_SEND_SCHEDULED_REQUEST); }; } diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmGetResponse.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmGetResponse.java index 34bbdd56..049bf9be 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmGetResponse.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmGetResponse.java @@ -1,48 +1,74 @@ package org.sopt.makers.operation.web.alarm.dto.response; import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; -import static java.util.Objects.nonNull; import static lombok.AccessLevel.PRIVATE; import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Builder; -import org.sopt.makers.operation.alarm.domain.Alarm; -import org.sopt.makers.operation.alarm.domain.Category; -import org.sopt.makers.operation.alarm.domain.LinkType; -import org.sopt.makers.operation.alarm.domain.TargetType; -import org.sopt.makers.operation.common.domain.Part; +import lombok.val; +import org.sopt.makers.operation.alarm.domain.*; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Objects; @Builder(access = PRIVATE) public record AlarmGetResponse( - Category category, + String status, + String sendType, + String targetType, + String targetPart, + @JsonInclude(value = NON_NULL) + Integer targetGeneration, + String createDate, + String createTime, + String intendDate, + String intendTime, + @JsonInclude(value = NON_NULL) + String sendDate, @JsonInclude(value = NON_NULL) - String part, - TargetType targetType, + String sendTime, String title, String content, + String category, String link, - LinkType linkType, - String createdAt, - @JsonInclude(value = NON_NULL) - String sendAt + String linkType ) { + private static final String RESPONSE_DATE_FORMAT = "yyyy-MM-dd"; + private static final String RESPONSE_TIME_FORMAT = "HH:mm"; public static AlarmGetResponse of(Alarm alarm) { + val alarmContent = alarm.getContent(); + val alarmTarget = alarm.getTarget(); + val createdAt = alarm.getCreatedDate(); + val intendedAt = alarm.getIntendedAt(); + val sendAt = alarm.getSendAt(); return AlarmGetResponse.builder() - .category(alarm.getCategory()) - .part(getPartName(alarm.getPart())) - .targetType(alarm.getTargetType()) - .title(alarm.getTitle()) - .content(alarm.getContent()) - .link(alarm.getLink()) - .linkType(alarm.getLinkType()) - .createdAt(alarm.getCreatedDate().toString()) - .sendAt(alarm.getSendAt()) + .status(alarm.getStatus().getDescription()) + .sendType(alarm.getType().getDescription()) + .targetType(alarmTarget.getTargetType().getName()) + .targetPart(alarmTarget.getTargetPart().getName()) + .targetGeneration(alarmTarget.getGeneration()) + .createDate(covertToDate(createdAt)).createTime(covertToTime(createdAt)) + .intendDate(covertToDate(intendedAt)).intendTime(covertToTime(intendedAt)) + .sendDate(covertToDate(sendAt)).sendTime(covertToTime(sendAt)) + .category(alarmContent.getCategory().getName()) + .title(alarmContent.getTitle()).content(alarmContent.getContent()) + .link(alarmContent.getLinkPath()).linkType(alarmContent.getLinkType().getName()) .build(); } - private static String getPartName(Part part) { - return nonNull(part) ? part.getName() : null; + private static String covertToDate(LocalDateTime dateTime) { + if (Objects.isNull(dateTime)){ + return null; + } + return dateTime.toLocalDate().format(DateTimeFormatter.ofPattern(RESPONSE_DATE_FORMAT)); } + private static String covertToTime(LocalDateTime dateTime) { + if (Objects.isNull(dateTime)){ + return null; + } + return dateTime.toLocalTime().format(DateTimeFormatter.ofPattern(RESPONSE_TIME_FORMAT)); + } } diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmListGetResponse.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmListGetResponse.java index 31e1e7fe..4d1d84f2 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmListGetResponse.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmListGetResponse.java @@ -1,15 +1,16 @@ package org.sopt.makers.operation.web.alarm.dto.response; import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; -import static java.util.Objects.nonNull; import static lombok.AccessLevel.PRIVATE; import com.fasterxml.jackson.annotation.JsonInclude; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.List; import lombok.Builder; +import lombok.val; import org.sopt.makers.operation.alarm.domain.Alarm; -import org.sopt.makers.operation.alarm.domain.Status; -import org.sopt.makers.operation.common.domain.Part; @Builder(access = PRIVATE) public record AlarmListGetResponse( @@ -18,42 +19,47 @@ public record AlarmListGetResponse( ) { public static AlarmListGetResponse of(List alarmList, int totalCount) { + val alarms = alarmList.stream().map(AlarmResponse::of).toList(); return AlarmListGetResponse.builder() - .alarms(alarmList.stream().map(AlarmResponse::of).toList()) + .alarms(alarms) .totalCount(totalCount) .build(); } @Builder(access = PRIVATE) private record AlarmResponse( - long alarmId, + long id, + String status, + String sendType, + String targetType, @JsonInclude(value = NON_NULL) - String part, + String targetPart, String category, - String title, - String content, + String intendAt, @JsonInclude(value = NON_NULL) String sendAt, - String alarmType, - Status status + String title, + String content ) { + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd hh:mm"); + private static String covertToResponseDateTime(LocalDateTime dateTime) { + return dateTime.format(DATE_TIME_FORMATTER); + } private static AlarmResponse of(Alarm alarm) { return AlarmResponse.builder() - .alarmId(alarm.getId()) - .part(getPartName(alarm.getPart())) - .category(alarm.getCategory().getName()) - .title(alarm.getTitle()) - .content(alarm.getContent()) - .sendAt(alarm.getSendAt()) - .alarmType(alarm.getAlarmType().getDescription()) - .status(alarm.getStatus()) + .id(alarm.getId()) + .status(alarm.getStatus().getDescription()) + .sendType(alarm.getType().getDescription()) + .targetType(alarm.getTarget().getTargetType().getName()) + .targetPart(alarm.getTarget().getTargetPart().getName()) + .category(alarm.getContent().getCategory().getName()) + .intendAt(covertToResponseDateTime(alarm.getIntendedAt())) + .sendAt(covertToResponseDateTime(alarm.getSendAt())) + .title(alarm.getContent().getTitle()) + .content(alarm.getContent().getContent()) .build(); } - private static String getPartName(Part part) { - return nonNull(part) ? part.getName() : null; - } - } } From 483d024eb8531387bdb538d6761179c7e8cb833f Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Fri, 17 Jan 2025 02:30:00 +0900 Subject: [PATCH 21/31] =?UTF-8?q?[FIX]=20Alarm=20API=20=EC=8A=A4=ED=8E=99?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20DTO=20?= =?UTF-8?q?=EB=B0=8F=20Service=20Layer=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=20=ED=83=80=EC=9E=85=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../operation/web/alarm/api/AlarmApiController.java | 8 ++++---- .../alarm/dto/request/AlarmInstantSendRequest.java | 13 +++++++------ .../operation/web/alarm/service/AlarmService.java | 12 ++++++++---- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java index 4602d031..8b8966e3 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java @@ -37,15 +37,15 @@ public class AlarmApiController implements AlarmApi { @Override @PostMapping("/send") public ResponseEntity> sendInstantAlarm(@Valid AlarmInstantSendRequest request) { - alarmService.sendInstantAlarm(request); - return ApiResponseUtil.success(SUCCESS_SEND_ALARM); + val result = alarmService.sendInstantAlarm(request); + return ApiResponseUtil.success(SUCCESS_SEND_ALARM , result); } @Override @PostMapping("/schedule") public ResponseEntity> sendScheduleAlarm(@Valid AlarmScheduleSendRequest request) { - alarmService.sendScheduleAlarm(request); - return ApiResponseUtil.success(SUCCESS_SCHEDULE_ALARM); + val result = alarmService.sendScheduleAlarm(request); + return ApiResponseUtil.success(SUCCESS_SCHEDULE_ALARM, result); } @Override diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmInstantSendRequest.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmInstantSendRequest.java index c7d3415e..27665f9c 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmInstantSendRequest.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmInstantSendRequest.java @@ -3,10 +3,13 @@ import jakarta.validation.constraints.NotNull; import java.util.List; -import org.sopt.makers.operation.alarm.domain.*; -import org.sopt.makers.operation.exception.AlarmException; - -import static org.sopt.makers.operation.code.failure.AlarmFailureCode.INVALID_SEND_INSTANT_REQUEST; +import org.sopt.makers.operation.alarm.domain.Alarm; +import org.sopt.makers.operation.alarm.domain.AlarmTarget; +import org.sopt.makers.operation.alarm.domain.AlarmContent; +import org.sopt.makers.operation.alarm.domain.AlarmCategory; +import org.sopt.makers.operation.alarm.domain.AlarmTargetType; +import org.sopt.makers.operation.alarm.domain.AlarmTargetPart; +import org.sopt.makers.operation.alarm.domain.AlarmLinkType; public record AlarmInstantSendRequest( @NotNull String title, @@ -27,7 +30,6 @@ private AlarmTarget toTargetEntity() { : AlarmTarget.partialForAll(this.part, this.targetList); case ACTIVE -> AlarmTarget.partialForActive(this.createdGeneration, this.part, this.targetList); case CSV -> AlarmTarget.partialForCsv(this.targetList); - default -> throw new AlarmException(INVALID_SEND_INSTANT_REQUEST); }; } @@ -36,7 +38,6 @@ private AlarmContent toContentEntity() { case WEB -> AlarmContent.withWebLink(this.title, this.content, this.category, this.link); case APP -> AlarmContent.withAppLink(this.title, this.content, this.category, this.link); case NONE -> AlarmContent.withoutLink(this.title, this.content, this.category); - default -> throw new AlarmException(INVALID_SEND_INSTANT_REQUEST); }; } diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmService.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmService.java index 732e5fdc..188df11d 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmService.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmService.java @@ -1,19 +1,23 @@ package org.sopt.makers.operation.web.alarm.service; -import org.sopt.makers.operation.alarm.domain.Status; +import org.sopt.makers.operation.alarm.domain.AlarmStatus; + import org.sopt.makers.operation.web.alarm.dto.request.AlarmInstantSendRequest; import org.sopt.makers.operation.web.alarm.dto.request.AlarmScheduleSendRequest; + +import org.sopt.makers.operation.web.alarm.dto.response.AlarmCreateResponse; import org.sopt.makers.operation.web.alarm.dto.response.AlarmGetResponse; import org.sopt.makers.operation.web.alarm.dto.response.AlarmListGetResponse; + import org.springframework.data.domain.Pageable; public interface AlarmService { - void sendInstantAlarm(AlarmInstantSendRequest requestDTO); + AlarmCreateResponse sendInstantAlarm(AlarmInstantSendRequest requestDTO); - void sendScheduleAlarm(AlarmScheduleSendRequest request); + AlarmCreateResponse sendScheduleAlarm(AlarmScheduleSendRequest request); - AlarmListGetResponse getAlarms(Integer generation, Status status, Pageable pageable); + AlarmListGetResponse getAlarms(Integer generation, AlarmStatus status, Pageable pageable); AlarmGetResponse getAlarm(long alarmId); From 84aa953b1f31d2d7e225a2714f89db3257954cda Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Fri, 17 Jan 2025 02:31:48 +0900 Subject: [PATCH 22/31] =?UTF-8?q?[CHORE]=20Alarm=20Service=20Layer=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=20=EA=B3=BC=EC=A0=95=20=EB=82=B4=20=EC=9E=90?= =?UTF-8?q?=EC=9E=98=ED=95=9C=20Enum=20=EB=A9=94=EC=84=9C=EB=93=9C=20=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../operation/alarm/domain/AlarmSendAction.java | 11 +++++++++-- .../operation/alarm/domain/AlarmTargetPart.java | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmSendAction.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmSendAction.java index 655c09fa..07456eb2 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmSendAction.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmSendAction.java @@ -1,6 +1,13 @@ package org.sopt.makers.operation.alarm.domain; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor public enum AlarmSendAction { - SEND, - SEND_ALL, + SEND("send"), + SEND_ALL("sendAll"), + ; + private final String value; } diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTargetPart.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTargetPart.java index d222664d..0566681b 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTargetPart.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTargetPart.java @@ -2,8 +2,11 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; +import org.sopt.makers.operation.exception.AlarmException; +import org.sopt.makers.operation.member.domain.Part; import static lombok.AccessLevel.PRIVATE; +import static org.sopt.makers.operation.code.failure.AlarmFailureCode.INVALID_ALARM_TARGET_TYPE; @Getter @RequiredArgsConstructor(access = PRIVATE) @@ -19,4 +22,17 @@ public enum AlarmTargetPart { ; private final String name; + + public Part toPartDomain() { + return switch (this) { + case ALL -> Part.ALL; + case PLAN -> Part.PLAN; + case DESIGN -> Part.DESIGN; + case ANDROID -> Part.ANDROID; + case iOS -> Part.IOS; + case WEB -> Part.WEB; + case SERVER -> Part.SERVER; + default -> throw new AlarmException(INVALID_ALARM_TARGET_TYPE); + }; + } } From 06e843372afa592e14099531717aeee8a607e354 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Fri, 17 Jan 2025 02:34:52 +0900 Subject: [PATCH 23/31] =?UTF-8?q?[REFACTOR]=20=EB=B3=80=EA=B2=BD=EB=90=9C?= =?UTF-8?q?=20=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81=20?= =?UTF-8?q?Service=20Layer=20=EC=88=98=EC=A0=95=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/alarm/service/AlarmServiceImpl.java | 117 +++++++----------- 1 file changed, 48 insertions(+), 69 deletions(-) diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmServiceImpl.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmServiceImpl.java index 9d79954c..a4bfa703 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmServiceImpl.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmServiceImpl.java @@ -1,33 +1,33 @@ package org.sopt.makers.operation.web.alarm.service; -import static org.sopt.makers.operation.code.failure.AlarmFailureCode.INVALID_ALARM; +import static org.sopt.makers.operation.code.failure.AlarmFailureCode.NOT_FOUND_ALARM; import static org.sopt.makers.operation.code.failure.AlarmFailureCode.INVALID_ALARM_TARGET_TYPE; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Objects; import lombok.RequiredArgsConstructor; import lombok.val; + import org.sopt.makers.operation.alarm.domain.Alarm; -import org.sopt.makers.operation.alarm.domain.LinkType; -import org.sopt.makers.operation.alarm.domain.Status; -import org.sopt.makers.operation.alarm.domain.TargetType; +import org.sopt.makers.operation.alarm.domain.AlarmStatus; +import org.sopt.makers.operation.alarm.domain.AlarmTarget; +import org.sopt.makers.operation.alarm.domain.AlarmTargetType; import org.sopt.makers.operation.alarm.repository.AlarmRepository; -import org.sopt.makers.operation.client.alarm.AlarmManager; -import org.sopt.makers.operation.client.alarm.alarmServer.dto.AlarmSenderRequest; -import org.sopt.makers.operation.client.alarm.eventBridgeServer.dto.EventBridgeSenderRequest; -import org.sopt.makers.operation.common.domain.Part; -import org.sopt.makers.operation.config.ValueConfig; -import org.sopt.makers.operation.exception.AlarmException; +import org.sopt.makers.operation.client.alarm.dto.InstantAlarmRequest; +import org.sopt.makers.operation.client.alarm.dto.ScheduleAlarmRequest; import org.sopt.makers.operation.member.domain.Member; import org.sopt.makers.operation.member.repository.MemberRepository; + +import org.sopt.makers.operation.config.ValueConfig; +import org.sopt.makers.operation.client.alarm.AlarmManager; +import org.sopt.makers.operation.exception.AlarmException; + import org.sopt.makers.operation.web.alarm.dto.request.AlarmInstantSendRequest; import org.sopt.makers.operation.web.alarm.dto.request.AlarmScheduleSendRequest; import org.sopt.makers.operation.web.alarm.dto.response.AlarmGetResponse; +import org.sopt.makers.operation.web.alarm.dto.response.AlarmCreateResponse; import org.sopt.makers.operation.web.alarm.dto.response.AlarmListGetResponse; + import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -43,46 +43,30 @@ public class AlarmServiceImpl implements AlarmService { @Override @Transactional - public void sendInstantAlarm(AlarmInstantSendRequest request) { - val savedAlarm = alarmRepository.save(request.toEntity()); - val targets = getTargets(savedAlarm); - alarmManager.sendInstantAlarm(AlarmSenderRequest.of(savedAlarm, targets)); - savedAlarm.updateToSent(formatSendAt(LocalDateTime.now())); + public AlarmCreateResponse sendInstantAlarm(AlarmInstantSendRequest request) { + val alarm = request.toEntity(); + val alarmTarget = alarm.getTarget(); + alarmTarget.setTargetIds(extractTargetIds(alarmTarget)); + val savedAlarm = alarmRepository.save(alarm); + + val alarmRequest = InstantAlarmRequest.of(savedAlarm); + alarmManager.sendInstant(alarmRequest); + + return AlarmCreateResponse.of(savedAlarm); } @Override @Transactional - public void sendScheduleAlarm(AlarmScheduleSendRequest request) { - val savedAlarm = alarmRepository.save(request.toEntity()); - val targets = getTargets(savedAlarm); - val sendAt = parseDateTime(request.postDate(), request.postTime()); - savedAlarm.updateToSent(formatSendAt(sendAt)); - - val linkType = request.linkType(); - val webLink = linkType == LinkType.WEB ? request.link() : null; - val deepLink = linkType == LinkType.APP ? request.link() : null; - - val eventBridgeRequest = EventBridgeSenderRequest.of( - valueConfig.getNOTIFICATION_KEY(), - valueConfig.getNOTIFICATION_HEADER_SERVICE(), - request.targetType().getAction(), - targets, - request.title(), - request.content(), - request.category(), - deepLink, - webLink - ); - - alarmManager.sendReservedAlarm(eventBridgeRequest, request.postDate(), request.postTime(), savedAlarm.getId()); - } + public AlarmCreateResponse sendScheduleAlarm(AlarmScheduleSendRequest request) { + val alarm = request.toEntity(); + val alarmTarget = alarm.getTarget(); + alarmTarget.setTargetIds(extractTargetIds(alarmTarget)); + val savedAlarm = alarmRepository.save(alarm); - @Override - @Transactional(readOnly = true) - public AlarmListGetResponse getAlarms(Integer generation, Status status, Pageable pageable) { - val alarms = alarmRepository.findOrderByCreatedDate(generation, status, pageable); - val totalCount = alarmRepository.count(generation, status); - return AlarmListGetResponse.of(alarms, totalCount); + val scheduleAlarmRequest = ScheduleAlarmRequest.of(savedAlarm); + alarmManager.sendSchedule(scheduleAlarmRequest); + + return AlarmCreateResponse.of(savedAlarm); } @Override @@ -92,6 +76,14 @@ public AlarmGetResponse getAlarm(long alarmId) { return AlarmGetResponse.of(alarm); } + @Override + @Transactional(readOnly = true) + public AlarmListGetResponse getAlarms(Integer generation, AlarmStatus status, Pageable pageable) { + val alarms = alarmRepository.findOrderByCreatedDate(generation, status, pageable); + val totalCount = alarmRepository.count(generation, status); + return AlarmListGetResponse.of(alarms, totalCount); + } + @Override @Transactional public void deleteAlarm(long alarmId) { @@ -101,37 +93,24 @@ public void deleteAlarm(long alarmId) { private Alarm findAlarm(long id) { return alarmRepository.findById(id) - .orElseThrow(() -> new AlarmException(INVALID_ALARM)); + .orElseThrow(() -> new AlarmException(NOT_FOUND_ALARM)); } - private List getTargets(Alarm alarm) { - return alarm.hasTargets() - ? alarm.getTargetList() - : getTargetsByActivityAndPart(alarm.getTargetType(), alarm.getPart()); - } + private List extractTargetIds(AlarmTarget target) { + val targetType = target.getTargetType(); + if (targetType.equals(AlarmTargetType.CSV)) { + return target.getTargetIds(); + } - private List getTargetsByActivityAndPart(TargetType targetType, Part part) { val members = switch (targetType) { - case ACTIVE -> memberRepository.find(valueConfig.getGENERATION(), part); case ALL -> memberRepository.findAll(); + case ACTIVE -> memberRepository.find(valueConfig.getGENERATION(), target.getTargetPart().toPartDomain()); default -> throw new AlarmException(INVALID_ALARM_TARGET_TYPE); }; - return members.stream() .map(Member::getPlaygroundId) .filter(Objects::nonNull) .map(String::valueOf) .toList(); } - - private LocalDateTime parseDateTime(String postDate, String postTime) { - val date = LocalDate.parse(postDate, DateTimeFormatter.ISO_LOCAL_DATE); - val time = LocalTime.parse(postTime, DateTimeFormatter.ofPattern("HH:mm")); - return LocalDateTime.of(date, time); - } - - private String formatSendAt(LocalDateTime dateTime) { - val formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"); - return dateTime.format(formatter); - } } From 51ea667bd7ac9fb5c1b3f04ef13753a800eff291 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Fri, 17 Jan 2025 16:10:28 +0900 Subject: [PATCH 24/31] =?UTF-8?q?[FIX]=20=ED=91=B8=EC=8B=9C=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EC=84=9C=EB=B2=84=20=EC=9A=94=EA=B5=AC=20=EC=8A=A4?= =?UTF-8?q?=ED=8E=99=EC=97=90=20=EB=A7=9E=EC=B6=98=20EventBridge=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20DTO=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../makers/operation/client/alarm/ScheduleAlarmSender.java | 2 +- .../alarm/dto/eventbridge/AlarmScheduleEventBridgeBody.java | 1 - .../alarm/dto/eventbridge/AlarmScheduleEventBridgeHeader.java | 3 ++- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/ScheduleAlarmSender.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/ScheduleAlarmSender.java index 2722143f..fca21f99 100644 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/ScheduleAlarmSender.java +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/ScheduleAlarmSender.java @@ -118,6 +118,7 @@ private String generateEventJson(ScheduleAlarmRequest request) throws JsonProces private AlarmScheduleEventBridgeHeader convertToEventBridgeHeader(ScheduleAlarmRequest request) { return AlarmScheduleEventBridgeHeader.builder() + .alarmId(request.alarmId()) .action(request.targetType().getAction().getValue()) .xApiKey(valueConfig.getNOTIFICATION_KEY()) .transactionId(UUID.randomUUID().toString()) @@ -129,7 +130,6 @@ private AlarmScheduleEventBridgeBody convertToEventBridgeBody(ScheduleAlarmReque val deepLink = request.linkType().equals(AlarmLinkType.APP) ? request.link() : null; val webLink = request.linkType().equals(AlarmLinkType.WEB) ? request.link() : null; return AlarmScheduleEventBridgeBody.builder() - .alarmId(request.alarmId()) .userIds(request.targets()) .title(request.title()) .content(request.content()) diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeBody.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeBody.java index 03dbe163..c84deb0c 100644 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeBody.java +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeBody.java @@ -7,7 +7,6 @@ @Builder public record AlarmScheduleEventBridgeBody( - long alarmId, List userIds, String title, String content, diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeHeader.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeHeader.java index 12e85d9b..89e12495 100644 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeHeader.java +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/eventbridge/AlarmScheduleEventBridgeHeader.java @@ -7,6 +7,7 @@ public record AlarmScheduleEventBridgeHeader( String action, String xApiKey, String transactionId, - String service + String service, + long alarmId ) { } From 780fd5596d77bc619cbc73a12bdf50fbbce761fe Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Fri, 17 Jan 2025 16:16:21 +0900 Subject: [PATCH 25/31] =?UTF-8?q?[FIX]=20=ED=91=B8=EC=8B=9C=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EC=84=9C=EB=B2=84=20=EC=9A=94=EA=B5=AC=20=EC=8A=A4?= =?UTF-8?q?=ED=8E=99=EC=97=90=20=EB=A7=9E=EC=B6=98=20Web=20Hook=20?= =?UTF-8?q?=EC=88=98=EC=8B=A0=20Response=20DTO=20=EB=B0=98=EC=98=81=20?= =?UTF-8?q?=EB=B0=8F=20=EC=88=98=EC=8B=A0=20API=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../operation/web/alarm/api/AlarmApi.java | 3 ++- .../web/alarm/api/AlarmApiController.java | 17 +++++++---------- .../AlarmScheduleStatusUpdateRequest.java | 10 ++++++++++ .../web/alarm/service/AlarmService.java | 3 +++ 4 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleStatusUpdateRequest.java diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApi.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApi.java index 480f4900..a11f21b9 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApi.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApi.java @@ -6,6 +6,7 @@ import org.sopt.makers.operation.dto.BaseResponse; import org.sopt.makers.operation.web.alarm.dto.request.AlarmInstantSendRequest; import org.sopt.makers.operation.web.alarm.dto.request.AlarmScheduleSendRequest; +import org.sopt.makers.operation.web.alarm.dto.request.AlarmScheduleStatusUpdateRequest; import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; @@ -138,5 +139,5 @@ ResponseEntity> getAlarms( ) } ) - ResponseEntity> updateAlarmStatus(@PathVariable long alarmId); + ResponseEntity> updateAlarmStatus(@PathVariable long alarmId, @RequestBody AlarmScheduleStatusUpdateRequest updateRequest); } diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java index 8b8966e3..c95a40fe 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java @@ -15,17 +15,11 @@ import org.sopt.makers.operation.util.ApiResponseUtil; import org.sopt.makers.operation.web.alarm.dto.request.AlarmInstantSendRequest; import org.sopt.makers.operation.web.alarm.dto.request.AlarmScheduleSendRequest; +import org.sopt.makers.operation.web.alarm.dto.request.AlarmScheduleStatusUpdateRequest; import org.sopt.makers.operation.web.alarm.service.AlarmService; import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequiredArgsConstructor @@ -75,8 +69,11 @@ public ResponseEntity> deleteAlarm(@PathVariable long alarmId) { @Override @PatchMapping("/{alarmId}") - public ResponseEntity> updateAlarmStatus(@PathVariable long alarmId) { - + public ResponseEntity> updateAlarmStatus( + @PathVariable long alarmId, + @RequestBody AlarmScheduleStatusUpdateRequest updateRequest + ) { + alarmService.updateScheduleAlarm(alarmId, updateRequest); return ApiResponseUtil.success(SUCCESS_UPDATE_ALARM_STATUS); } diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleStatusUpdateRequest.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleStatusUpdateRequest.java new file mode 100644 index 00000000..4ed5147c --- /dev/null +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleStatusUpdateRequest.java @@ -0,0 +1,10 @@ +package org.sopt.makers.operation.web.alarm.dto.request; + +import jakarta.validation.constraints.NotNull; + +import java.time.LocalDateTime; + +public record AlarmScheduleStatusUpdateRequest( + @NotNull LocalDateTime sendAt +) { +} diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmService.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmService.java index 188df11d..d967cee2 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmService.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmService.java @@ -5,6 +5,7 @@ import org.sopt.makers.operation.web.alarm.dto.request.AlarmInstantSendRequest; import org.sopt.makers.operation.web.alarm.dto.request.AlarmScheduleSendRequest; +import org.sopt.makers.operation.web.alarm.dto.request.AlarmScheduleStatusUpdateRequest; import org.sopt.makers.operation.web.alarm.dto.response.AlarmCreateResponse; import org.sopt.makers.operation.web.alarm.dto.response.AlarmGetResponse; import org.sopt.makers.operation.web.alarm.dto.response.AlarmListGetResponse; @@ -21,5 +22,7 @@ public interface AlarmService { AlarmGetResponse getAlarm(long alarmId); + void updateScheduleAlarm(long alarmId, AlarmScheduleStatusUpdateRequest request); + void deleteAlarm(long alarmId); } From b77561e3520fcd2044d935ea0a95f6828ef5b5e0 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Fri, 17 Jan 2025 16:17:58 +0900 Subject: [PATCH 26/31] =?UTF-8?q?[REFACTOR]=20Alarm=20Entity=20=EC=8B=A4?= =?UTF-8?q?=EC=A0=9C=20=EC=A0=84=EC=86=A1=20=EC=8B=9C=EC=A0=90=20=EA=B0=92?= =?UTF-8?q?(`sendAt`)=20=EA=B8=B0=EC=A4=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 본 어플리케이션 서버 기준(`LocalDateTime.now()`) 등록되는 구조를 실제 알림서버에서 성공한 시점이 등록되는 구조로 변경했습니다. --- .../java/org/sopt/makers/operation/alarm/domain/Alarm.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Alarm.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Alarm.java index 25af4d5c..c8d9acc2 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Alarm.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/Alarm.java @@ -69,9 +69,9 @@ public static Alarm scheduled(AlarmTarget target, AlarmContent content, LocalDat .build(); } - public void updateStatusToComplete() { + public void updateStatusToComplete(LocalDateTime successAt) { this.status = AlarmStatus.COMPLETED; - this.sendAt = LocalDateTime.now(); + this.sendAt = successAt; } } From 53335ef4b0019abef84ac4b83582f469454f8cef Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Fri, 17 Jan 2025 16:18:24 +0900 Subject: [PATCH 27/31] =?UTF-8?q?[FEAT]=20=EC=98=88=EC=95=BD=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EC=83=81=ED=83=9C=20=EB=B0=8F=20=EC=A0=84=EC=86=A1?= =?UTF-8?q?=20=EC=8B=9C=EA=B0=84=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?Service=20Layer=20=EB=A9=94=EC=84=9C=EB=93=9C=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 --- .../operation/web/alarm/service/AlarmServiceImpl.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmServiceImpl.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmServiceImpl.java index a4bfa703..e90a6a1e 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmServiceImpl.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmServiceImpl.java @@ -24,6 +24,7 @@ import org.sopt.makers.operation.web.alarm.dto.request.AlarmInstantSendRequest; import org.sopt.makers.operation.web.alarm.dto.request.AlarmScheduleSendRequest; +import org.sopt.makers.operation.web.alarm.dto.request.AlarmScheduleStatusUpdateRequest; import org.sopt.makers.operation.web.alarm.dto.response.AlarmGetResponse; import org.sopt.makers.operation.web.alarm.dto.response.AlarmCreateResponse; import org.sopt.makers.operation.web.alarm.dto.response.AlarmListGetResponse; @@ -91,6 +92,12 @@ public void deleteAlarm(long alarmId) { alarmRepository.delete(alarm); } + @Override + public void updateScheduleAlarm(long alarmId, AlarmScheduleStatusUpdateRequest request) { + val alarm = findAlarm(alarmId); + alarm.updateStatusToComplete(request.sendAt()); + } + private Alarm findAlarm(long id) { return alarmRepository.findById(id) .orElseThrow(() -> new AlarmException(NOT_FOUND_ALARM)); From c9978e0b958e18aa7564bfc8cca1494b65582262 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Sat, 18 Jan 2025 19:27:00 +0900 Subject: [PATCH 28/31] =?UTF-8?q?[FIX]=20=EC=A6=89=EC=8B=9C/=EC=98=88?= =?UTF-8?q?=EC=95=BD=20=EC=95=8C=EB=A6=BC=20=EB=B0=9C=EC=86=A1=20POST=20AP?= =?UTF-8?q?I=20`@RequestBody`=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../operation/web/alarm/api/AlarmApiController.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java index c95a40fe..de920e5b 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/api/AlarmApiController.java @@ -30,14 +30,18 @@ public class AlarmApiController implements AlarmApi { @Override @PostMapping("/send") - public ResponseEntity> sendInstantAlarm(@Valid AlarmInstantSendRequest request) { + public ResponseEntity> sendInstantAlarm( + @Valid @RequestBody AlarmInstantSendRequest request + ) { val result = alarmService.sendInstantAlarm(request); - return ApiResponseUtil.success(SUCCESS_SEND_ALARM , result); + return ApiResponseUtil.success(SUCCESS_SEND_ALARM, result); } @Override @PostMapping("/schedule") - public ResponseEntity> sendScheduleAlarm(@Valid AlarmScheduleSendRequest request) { + public ResponseEntity> sendScheduleAlarm( + @Valid @RequestBody AlarmScheduleSendRequest request + ) { val result = alarmService.sendScheduleAlarm(request); return ApiResponseUtil.success(SUCCESS_SCHEDULE_ALARM, result); } From 42ffa6a33e01c521828476468dac0ad345da032a Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Sat, 18 Jan 2025 19:41:46 +0900 Subject: [PATCH 29/31] =?UTF-8?q?[REFACTOR]=20Request/Response=EC=97=90=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EB=90=98=EB=8A=94=20DateTime=20Format=20?= =?UTF-8?q?=EC=83=81=EC=88=98=20=EC=84=A0=EC=96=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alarm/dto/request/AlarmScheduleSendRequest.java | 6 ++++-- .../web/alarm/dto/response/AlarmGetResponse.java | 12 +++++++----- .../web/alarm/dto/response/AlarmListGetResponse.java | 6 ++++-- .../makers/operation/constant/AlarmConstant.java | 5 +++++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleSendRequest.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleSendRequest.java index b79054af..1916cd38 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleSendRequest.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/request/AlarmScheduleSendRequest.java @@ -18,6 +18,8 @@ import org.sopt.makers.operation.alarm.domain.AlarmTargetPart; import org.sopt.makers.operation.alarm.domain.AlarmLinkType; +import static org.sopt.makers.operation.constant.AlarmConstant.ALARM_REQUEST_DATE_FORMAT; +import static org.sopt.makers.operation.constant.AlarmConstant.ALARM_REQUEST_TIME_FORMAT; public record AlarmScheduleSendRequest( @NotNull String title, @@ -53,8 +55,8 @@ private AlarmContent toContentEntity() { public Alarm toEntity() { AlarmTarget targetEntity = this.toTargetEntity(); AlarmContent contentEntity = this.toContentEntity(); - val date = LocalDate.parse(postDate, DateTimeFormatter.ISO_LOCAL_DATE); - val time = LocalTime.parse(postTime, DateTimeFormatter.ofPattern("HH:mm")); + val date = LocalDate.parse(postDate, DateTimeFormatter.ofPattern(ALARM_REQUEST_DATE_FORMAT)); + val time = LocalTime.parse(postTime, DateTimeFormatter.ofPattern(ALARM_REQUEST_TIME_FORMAT)); return Alarm.scheduled(targetEntity, contentEntity, LocalDateTime.of(date, time)); } } diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmGetResponse.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmGetResponse.java index 049bf9be..93cf479b 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmGetResponse.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmGetResponse.java @@ -2,11 +2,13 @@ import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; import static lombok.AccessLevel.PRIVATE; +import static org.sopt.makers.operation.constant.AlarmConstant.ALARM_RESPONSE_DATE_FORMAT; +import static org.sopt.makers.operation.constant.AlarmConstant.ALARM_RESPONSE_TIME_FORMAT; import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Builder; import lombok.val; -import org.sopt.makers.operation.alarm.domain.*; +import org.sopt.makers.operation.alarm.domain.Alarm; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -34,8 +36,6 @@ public record AlarmGetResponse( String link, String linkType ) { - private static final String RESPONSE_DATE_FORMAT = "yyyy-MM-dd"; - private static final String RESPONSE_TIME_FORMAT = "HH:mm"; public static AlarmGetResponse of(Alarm alarm) { val alarmContent = alarm.getContent(); @@ -62,13 +62,15 @@ private static String covertToDate(LocalDateTime dateTime) { if (Objects.isNull(dateTime)){ return null; } - return dateTime.toLocalDate().format(DateTimeFormatter.ofPattern(RESPONSE_DATE_FORMAT)); + return dateTime.toLocalDate() + .format(DateTimeFormatter.ofPattern(ALARM_RESPONSE_DATE_FORMAT)); } private static String covertToTime(LocalDateTime dateTime) { if (Objects.isNull(dateTime)){ return null; } - return dateTime.toLocalTime().format(DateTimeFormatter.ofPattern(RESPONSE_TIME_FORMAT)); + return dateTime.toLocalTime() + .format(DateTimeFormatter.ofPattern(ALARM_RESPONSE_TIME_FORMAT)); } } diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmListGetResponse.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmListGetResponse.java index 4d1d84f2..af9babc9 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmListGetResponse.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/dto/response/AlarmListGetResponse.java @@ -2,6 +2,7 @@ import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; import static lombok.AccessLevel.PRIVATE; +import static org.sopt.makers.operation.constant.AlarmConstant.*; import com.fasterxml.jackson.annotation.JsonInclude; @@ -11,6 +12,7 @@ import lombok.Builder; import lombok.val; import org.sopt.makers.operation.alarm.domain.Alarm; +import org.sopt.makers.operation.constant.AlarmConstant; @Builder(access = PRIVATE) public record AlarmListGetResponse( @@ -41,10 +43,10 @@ private record AlarmResponse( String title, String content ) { - private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd hh:mm"); + private static final String DATETIME_FORMAT = String.join(" ", ALARM_RESPONSE_DATE_FORMAT, ALARM_RESPONSE_TIME_FORMAT); private static String covertToResponseDateTime(LocalDateTime dateTime) { - return dateTime.format(DATE_TIME_FORMATTER); + return dateTime.format(DateTimeFormatter.ofPattern(DATETIME_FORMAT)); } private static AlarmResponse of(Alarm alarm) { return AlarmResponse.builder() diff --git a/operation-common/src/main/java/org/sopt/makers/operation/constant/AlarmConstant.java b/operation-common/src/main/java/org/sopt/makers/operation/constant/AlarmConstant.java index 4c409e63..7082425b 100644 --- a/operation-common/src/main/java/org/sopt/makers/operation/constant/AlarmConstant.java +++ b/operation-common/src/main/java/org/sopt/makers/operation/constant/AlarmConstant.java @@ -19,6 +19,11 @@ public final class AlarmConstant { "home/soptamp/current-generation-ranking" ); + public static final String ALARM_REQUEST_DATE_FORMAT = "yyyy-MM-dd"; + public static final String ALARM_REQUEST_TIME_FORMAT = "HH:mm"; + public static final String ALARM_RESPONSE_DATE_FORMAT = "yyyy-MM-dd"; + public static final String ALARM_RESPONSE_TIME_FORMAT = "HH:mm"; + public static boolean isSupportedAppLink(String link) { return SUPPORTED_APP_LINK.contains(link); } From 4eeb48c3f38e1361a821a7f4edbd8f82c20e7675 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Sat, 18 Jan 2025 19:56:20 +0900 Subject: [PATCH 30/31] =?UTF-8?q?[CHORE]=20=EC=BD=94=EB=93=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [참고 PR](https://github.com/sopt-makers/sopt-operation-backend/pull/306) --- .../web/alarm/service/AlarmServiceImpl.java | 6 ++++-- .../lecture/service/WebLectureServiceImpl.java | 10 ++++++---- .../client/alarm/InstantAlarmSender.java | 18 +++++++++--------- .../client/alarm/ScheduleAlarmSender.java | 9 +++++---- .../client/alarm/dto/InstantAlarmRequest.java | 1 + 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmServiceImpl.java b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmServiceImpl.java index e90a6a1e..908f5d29 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmServiceImpl.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/alarm/service/AlarmServiceImpl.java @@ -47,12 +47,13 @@ public class AlarmServiceImpl implements AlarmService { public AlarmCreateResponse sendInstantAlarm(AlarmInstantSendRequest request) { val alarm = request.toEntity(); val alarmTarget = alarm.getTarget(); + alarmTarget.setTargetIds(extractTargetIds(alarmTarget)); - val savedAlarm = alarmRepository.save(alarm); + val savedAlarm = alarmRepository.save(alarm); val alarmRequest = InstantAlarmRequest.of(savedAlarm); - alarmManager.sendInstant(alarmRequest); + alarmManager.sendInstant(alarmRequest); return AlarmCreateResponse.of(savedAlarm); } @@ -93,6 +94,7 @@ public void deleteAlarm(long alarmId) { } @Override + @Transactional public void updateScheduleAlarm(long alarmId, AlarmScheduleStatusUpdateRequest request) { val alarm = findAlarm(alarmId); alarm.updateStatusToComplete(request.sendAt()); diff --git a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureServiceImpl.java b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureServiceImpl.java index 4208070e..21b9360a 100644 --- a/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureServiceImpl.java +++ b/operation-api/src/main/java/org/sopt/makers/operation/web/lecture/service/WebLectureServiceImpl.java @@ -40,6 +40,8 @@ @RequiredArgsConstructor @Transactional(readOnly = true) public class WebLectureServiceImpl implements WebLectureService { + public static final String NULL = "null"; + public static final String WHITE_SPACE = " "; private final LectureRepository lectureRepository; private final SubLectureRepository subLectureRepository; @@ -47,7 +49,7 @@ public class WebLectureServiceImpl implements WebLectureService { private final SubAttendanceRepository subAttendanceRepository; private final MemberRepository memberRepository; - private final AlarmManager alarmSender; + private final AlarmManager alarmManager; private final ValueConfig valueConfig; @Override @@ -177,14 +179,14 @@ private Lecture getLectureReadyToEnd(long lectureId) { } private void sendAlarm(Lecture lecture) { - val alarmMessageTitle = lecture.getName() + " " + valueConfig.getALARM_MESSAGE_TITLE(); + val alarmMessageTitle = String.join(WHITE_SPACE, lecture.getName(), valueConfig.getALARM_MESSAGE_TITLE()); val alarmMessageContent = valueConfig.getALARM_MESSAGE_CONTENT(); val targets = lecture.getAttendances().stream() .map(attendance -> String.valueOf(attendance.getMember().getPlaygroundId())) - .filter(id -> !id.equals("null")) + .filter(id -> !id.equals(NULL)) .toList(); val alarmRequest = InstantAlarmRequest.of(alarmMessageTitle, alarmMessageContent, targets); - alarmSender.sendInstant(alarmRequest); + alarmManager.sendInstant(alarmRequest); } private Lecture getLectureToDelete(long lectureId) { diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/InstantAlarmSender.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/InstantAlarmSender.java index 24ad1698..db24b6b0 100644 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/InstantAlarmSender.java +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/InstantAlarmSender.java @@ -31,7 +31,7 @@ class InstantAlarmSender implements AlarmSender{ @Override public void sendAlarm(AlarmRequest alarmRequest) { - InstantAlarmRequest instantRequest = (InstantAlarmRequest) alarmRequest; + val instantRequest = (InstantAlarmRequest) alarmRequest; try { val host = valueConfig.getNOTIFICATION_URL(); val body = generateBody(instantRequest); @@ -46,10 +46,8 @@ public void sendAlarm(AlarmRequest alarmRequest) { private Map generateBody(InstantAlarmRequest instantRequest) { val body = new HashMap<>(); - putRequiredAttributes(instantRequest, body); putOptionalAttributes(instantRequest, body); - return body; } @@ -60,13 +58,16 @@ private static void putRequiredAttributes(InstantAlarmRequest instantRequest, Ha } private static void putOptionalAttributes(InstantAlarmRequest instantRequest, HashMap body) { - if (!instantRequest.targetType().equals(AlarmTargetType.ALL)) { + val isTargetAll = instantRequest.targetType().equals(AlarmTargetType.ALL); + val isWebLink = instantRequest.linkType().equals(AlarmLinkType.WEB); + val isAppLink = instantRequest.linkType().equals(AlarmLinkType.APP); + + if (!isTargetAll) { body.put("userIds", instantRequest.targets()); } - - if (instantRequest.linkType().equals(AlarmLinkType.WEB)) { + if (isWebLink) { body.put("webLink", instantRequest.link()); - } else if (instantRequest.linkType().equals(AlarmLinkType.APP)) { + } else if (isAppLink) { body.put("appLink", instantRequest.link()); } } @@ -74,16 +75,15 @@ private static void putOptionalAttributes(InstantAlarmRequest instantRequest, Ha private HttpHeaders generateHeader(InstantAlarmRequest instantRequest) { val headers = new HttpHeaders(); val apiKey = valueConfig.getNOTIFICATION_KEY(); + val actionValue = instantRequest.targetType().getAction().getValue(); headers.setContentType(APPLICATION_JSON); headers.setAccept(Collections.singletonList(APPLICATION_JSON)); - String actionValue = instantRequest.targetType().getAction().getValue(); headers.add("action", actionValue); headers.add("transactionId", randomUUID().toString()); headers.add("service", "operation"); headers.add("x-api-key", apiKey); - return headers; } diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/ScheduleAlarmSender.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/ScheduleAlarmSender.java index fca21f99..5b2979c3 100644 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/ScheduleAlarmSender.java +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/ScheduleAlarmSender.java @@ -28,6 +28,9 @@ import java.time.format.DateTimeFormatter; import java.util.UUID; +import static org.sopt.makers.operation.constant.AlarmConstant.ALARM_REQUEST_DATE_FORMAT; +import static org.sopt.makers.operation.constant.AlarmConstant.ALARM_REQUEST_TIME_FORMAT; + @Component @RequiredArgsConstructor class ScheduleAlarmSender implements AlarmSender{ @@ -52,7 +55,6 @@ public void sendAlarm(AlarmRequest alarmRequest) { try { val name = generateEventName(scheduleRequest); val cronExpression = generateScheduleCronExpression(scheduleRequest); - val eventJson = generateEventJson(scheduleRequest); val target = generateEventTarget(eventJson); @@ -85,9 +87,8 @@ private Target generateEventTarget(String eventJson) { } private String generateEventName(ScheduleAlarmRequest request) { - val dateData = request.scheduleDateTime().toLocalDate().format(DateTimeFormatter.ISO_DATE); - val timeData = request.scheduleDateTime().toLocalTime().format(DateTimeFormatter.ofPattern("HH-mm")); - + val dateData = request.scheduleDateTime().toLocalDate().format(DateTimeFormatter.ofPattern(ALARM_REQUEST_DATE_FORMAT)); + val timeData = request.scheduleDateTime().toLocalTime().format(DateTimeFormatter.ofPattern(ALARM_REQUEST_TIME_FORMAT)); return String.format("%s_%s_%d", dateData, timeData, request.alarmId()); } diff --git a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/InstantAlarmRequest.java b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/InstantAlarmRequest.java index 848f995c..aeaec3da 100644 --- a/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/InstantAlarmRequest.java +++ b/operation-external/src/main/java/org/sopt/makers/operation/client/alarm/dto/InstantAlarmRequest.java @@ -23,6 +23,7 @@ public record InstantAlarmRequest( AlarmLinkType linkType ) implements AlarmRequest { + public static InstantAlarmRequest of(Alarm alarm) { val content = alarm.getContent(); return InstantAlarmRequest.builder() From 19b12b456c112bc1f9d0a96d0ef1f9b1c80d022c Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Sun, 19 Jan 2025 15:41:21 +0900 Subject: [PATCH 31/31] =?UTF-8?q?[FIX]=20AlarmTarget=20Enum=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20`@Enumerated`=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sopt/makers/operation/alarm/domain/AlarmTarget.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTarget.java b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTarget.java index 95189d24..d54165a0 100644 --- a/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTarget.java +++ b/operation-domain/src/main/java/org/sopt/makers/operation/alarm/domain/AlarmTarget.java @@ -1,8 +1,6 @@ package org.sopt.makers.operation.alarm.domain; -import jakarta.persistence.Column; -import jakarta.persistence.Convert; -import jakarta.persistence.Embeddable; +import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; @@ -25,12 +23,15 @@ public class AlarmTarget { @Column(name = "action", nullable = false, updatable = false, insertable = false) + @Enumerated(EnumType.STRING) private AlarmSendAction sendAction; @Column(name = "part", nullable = false, updatable = false, insertable = false) + @Enumerated(EnumType.STRING) private AlarmTargetPart targetPart; @Column(name = "target_type", nullable = false, updatable = false, insertable = false) + @Enumerated(EnumType.STRING) private AlarmTargetType targetType; @Column(name = "generation", updatable = false, insertable = false)