From 04382b936943947518a9b00a902add6d531b1678 Mon Sep 17 00:00:00 2001 From: HeWillGoTillTheEnd Date: Wed, 23 Apr 2025 21:05:42 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[Fix]=20=EC=95=8C=EB=9E=8C=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EB=A7=8C=EB=93=A4=20=EB=95=8C=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=EC=A0=9D=ED=8A=B8=EB=AA=85=20=EB=94=B0=EC=98=B4?= =?UTF-8?q?=ED=91=9C=EB=A1=9C=20=EA=B0=90=EC=8B=B8=EA=B8=B0,=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0=20API=20?= =?UTF-8?q?=EC=84=A4=EB=AA=85=20=EC=88=98=EC=A0=95=20send-alarm=20@Request?= =?UTF-8?q?Param=20->=20@RequestHeader=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devpals/domain/user/controller/UserAlarmController.java | 4 ++-- .../kr/backend/devpals/domain/user/service/AlarmService.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/controller/UserAlarmController.java b/src/main/java/hs/kr/backend/devpals/domain/user/controller/UserAlarmController.java index 89d65d6a..d2943827 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/user/controller/UserAlarmController.java +++ b/src/main/java/hs/kr/backend/devpals/domain/user/controller/UserAlarmController.java @@ -25,7 +25,7 @@ public class UserAlarmController { private final AlarmService alarmService; @GetMapping("/alarm") - @Operation(summary = "알림 가져오기", description = "알림을 가져옵니다(해당 api 구현된것이 아닙니다 테스트용도로 만들었어요!)") + @Operation(summary = "알림 가져오기", description = "알림을 가져옵니다(현재 시범운영중입니다 필요한 데이터가 더 있을경우 말씀주세요)") @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "알림 가져오기 성공") @io.swagger.v3.oas.annotations.responses.ApiResponse( responseCode = "400", @@ -72,7 +72,7 @@ public ResponseEntity> deleteUserAlarm(@RequestHeader("Autho ) ) @GetMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE) - public SseEmitter connect(@RequestParam("Authorization") String token) { + public SseEmitter connect(@RequestHeader("Authorization") String token) { return alarmService.createEmitter(token); } diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/service/AlarmService.java b/src/main/java/hs/kr/backend/devpals/domain/user/service/AlarmService.java index 47ec170c..bf99a45c 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/user/service/AlarmService.java +++ b/src/main/java/hs/kr/backend/devpals/domain/user/service/AlarmService.java @@ -95,13 +95,13 @@ public void sendAlarm(ProjectEntity project, ApplicantEntity applicant, AlramFil } private String makeMessage(ProjectEntity project,ApplicantEntity applicant) { - return project.getTitle()+" 프로젝트에 "+ applicant.getUser().getNickname() + "님이 지원하셨습니다."; + return "\""+project.getTitle()+"\" 프로젝트에 "+ applicant.getUser().getNickname() + "님이 지원하셨습니다."; } private String makeMessage(ApplicantEntity applicant) { String result = applicant.getStatus().equals(ApplicantStatus.ACCEPTED) ? "합격" : "불합격"; - return "지원자님은 "+applicant.getProject().getTitle()+" 프로젝트에 "+ result +" 하셨습니다."; + return "지원자님은 \""+applicant.getProject().getTitle()+"\" 프로젝트에 "+ result +" 하셨습니다."; } // 특정 사용자에게 알림 전송 From 699da94db3fc6be961b9e0074b56b5d796fe09b4 Mon Sep 17 00:00:00 2001 From: HeWillGoTillTheEnd Date: Thu, 24 Apr 2025 02:13:17 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[Feat]=20=EB=8C=93=EA=B8=80,=20=EB=8C=80?= =?UTF-8?q?=EB=8C=93=EA=B8=80=20=EC=95=8C=EB=9E=8C=20=EC=B6=94=EA=B0=80,?= =?UTF-8?q?=20=EC=95=8C=EB=A6=BC=20=ED=85=8C=EC=9D=B4=EB=B8=94=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EB=B3=80=EA=B2=BD,=20=EC=95=8C=EB=9E=8C=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/project/service/ApplyService.java | 4 +- .../service/ProjectCommentService.java | 4 + .../project/service/ProjectService.java | 6 +- .../devpals/domain/user/dto/AlarmDto.java | 17 ++-- .../domain/user/dto/CommentAlarmDto.java | 27 +++++++ .../domain/user/entity/AlramEntity.java | 61 -------------- .../domain/user/entity/alarm/AlarmEntity.java | 56 +++++++++++++ .../entity/alarm/ApplicantAlarmEntity.java | 36 +++++++++ .../user/entity/alarm/CommentAlarmEntity.java | 55 +++++++++++++ .../user/entity/alarm/ProjectAlarmEntity.java | 36 +++++++++ .../alarm/constants/AlarmFilterConstants.java | 11 +++ .../user/repository/AlarmRepository.java | 13 +-- .../domain/user/service/AlarmService.java | 81 ++++++++++++------- .../domain/user/service/UserAlarmService.java | 28 ++++--- .../{AlramFilter.java => AlarmFilter.java} | 16 ++-- 15 files changed, 326 insertions(+), 125 deletions(-) create mode 100644 src/main/java/hs/kr/backend/devpals/domain/user/dto/CommentAlarmDto.java delete mode 100644 src/main/java/hs/kr/backend/devpals/domain/user/entity/AlramEntity.java create mode 100644 src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/AlarmEntity.java create mode 100644 src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ApplicantAlarmEntity.java create mode 100644 src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/CommentAlarmEntity.java create mode 100644 src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ProjectAlarmEntity.java create mode 100644 src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.java rename src/main/java/hs/kr/backend/devpals/global/common/enums/{AlramFilter.java => AlarmFilter.java} (73%) diff --git a/src/main/java/hs/kr/backend/devpals/domain/project/service/ApplyService.java b/src/main/java/hs/kr/backend/devpals/domain/project/service/ApplyService.java index 7b22e54d..55e48ab4 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/project/service/ApplyService.java +++ b/src/main/java/hs/kr/backend/devpals/domain/project/service/ApplyService.java @@ -11,7 +11,7 @@ import hs.kr.backend.devpals.domain.user.repository.UserRepository; import hs.kr.backend.devpals.domain.user.service.AlarmService; import hs.kr.backend.devpals.global.common.ApiResponse; -import hs.kr.backend.devpals.global.common.enums.AlramFilter; +import hs.kr.backend.devpals.global.common.enums.AlarmFilter; import hs.kr.backend.devpals.global.common.enums.ApplicantStatus; import hs.kr.backend.devpals.global.exception.CustomException; import hs.kr.backend.devpals.global.exception.ErrorException; @@ -52,7 +52,7 @@ public ResponseEntity> projectApply(Long projectId, ProjectA ApplicantEntity applicant = ApplicantEntity.createApplicant(user, project, request); applicantRepository.save(applicant); - alarmService.sendAlarm(project,applicant, AlramFilter.APPLICANT_CHECK); + alarmService.sendAlarm(project,applicant); return ResponseEntity.ok(new ApiResponse<>(true, "프로젝트 지원 되었습니다." , null)); } diff --git a/src/main/java/hs/kr/backend/devpals/domain/project/service/ProjectCommentService.java b/src/main/java/hs/kr/backend/devpals/domain/project/service/ProjectCommentService.java index 48a97a00..9b0e058a 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/project/service/ProjectCommentService.java +++ b/src/main/java/hs/kr/backend/devpals/domain/project/service/ProjectCommentService.java @@ -10,6 +10,7 @@ import hs.kr.backend.devpals.domain.project.repository.RecommentRepository; import hs.kr.backend.devpals.domain.user.entity.UserEntity; import hs.kr.backend.devpals.domain.user.repository.UserRepository; +import hs.kr.backend.devpals.domain.user.service.AlarmService; import hs.kr.backend.devpals.global.common.ApiResponse; import hs.kr.backend.devpals.global.exception.CustomException; import hs.kr.backend.devpals.global.exception.ErrorException; @@ -28,6 +29,7 @@ @RequiredArgsConstructor public class ProjectCommentService { private final JwtTokenValidator jwtTokenValidator; + private final AlarmService alarmService; private final CommentRepoisitory commentRepoisitory; private final RecommentRepository recommentRepository; private final ProjectRepository projectRepository; @@ -43,6 +45,7 @@ public ResponseEntity> writeComment(String token, Long proje CommentEntity comment = CommentEntity.from(dto, project, user); commentRepoisitory.save(comment); + alarmService.sendAlarm(comment,project,user); return ResponseEntity.ok(new ApiResponse<>(true, "댓글 작성 성공", null)); } @@ -124,6 +127,7 @@ public ResponseEntity> writeRecomment(String token, Long pro RecommentEntity recomment = RecommentEntity.from(dto, project, user, comment); recommentRepository.save(recomment); + alarmService.sendAlarm(recomment,comment,project); return ResponseEntity.ok(new ApiResponse<>(true, "대댓글 작성 성공", null)); } diff --git a/src/main/java/hs/kr/backend/devpals/domain/project/service/ProjectService.java b/src/main/java/hs/kr/backend/devpals/domain/project/service/ProjectService.java index d3131baf..606461b8 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/project/service/ProjectService.java +++ b/src/main/java/hs/kr/backend/devpals/domain/project/service/ProjectService.java @@ -14,7 +14,7 @@ import hs.kr.backend.devpals.domain.user.repository.UserRepository; import hs.kr.backend.devpals.domain.user.service.AlarmService; import hs.kr.backend.devpals.global.common.ApiResponse; -import hs.kr.backend.devpals.global.common.enums.AlramFilter; +import hs.kr.backend.devpals.global.common.enums.AlarmFilter; import hs.kr.backend.devpals.global.common.enums.ApplicantStatus; import hs.kr.backend.devpals.global.exception.CustomException; import hs.kr.backend.devpals.global.exception.ErrorException; @@ -190,7 +190,7 @@ public ResponseEntity> closeProject(Long proje MethodTypeResponse methodTypeResponse = projectFacade.getMethodTypeResponse(project.getMethodTypeId()); - alarmService.sendAlarm(applicants,AlramFilter.APPLIED_PROJECTS,projectId); + alarmService.sendAlarm(applicants,project); return ResponseEntity.ok(new ApiResponse<>(true, "프로젝트 모집 종료 성공", ProjectCloseResponse.fromEntity(project, methodTypeResponse))); } @@ -217,7 +217,7 @@ public CompletableFuture closeProject(List projects) { projects.forEach(project -> { List applicants = projectApplicantsMap.get(project); authEmailService.sendEmailsAsync(applicants, project); - alarmService.sendAlarm(applicants,AlramFilter.APPLIED_PROJECTS, project.getId()); + alarmService.sendAlarm(applicants, project); }); }, emailExecutor)); } diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/dto/AlarmDto.java b/src/main/java/hs/kr/backend/devpals/domain/user/dto/AlarmDto.java index b2e415c1..1b9e8458 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/user/dto/AlarmDto.java +++ b/src/main/java/hs/kr/backend/devpals/domain/user/dto/AlarmDto.java @@ -1,7 +1,9 @@ package hs.kr.backend.devpals.domain.user.dto; -import hs.kr.backend.devpals.domain.user.entity.AlramEntity; -import hs.kr.backend.devpals.global.common.enums.AlramFilter; +import hs.kr.backend.devpals.domain.user.entity.alarm.AlarmEntity; +import hs.kr.backend.devpals.domain.user.entity.alarm.ApplicantAlarmEntity; +import hs.kr.backend.devpals.domain.user.entity.alarm.CommentAlarmEntity; +import hs.kr.backend.devpals.domain.user.entity.alarm.ProjectAlarmEntity; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -21,14 +23,19 @@ public class AlarmDto { private Integer alarmFilterId; private LocalDateTime createdAt; - public static AlarmDto fromEntity(AlramEntity entity) { + public static AlarmDto fromEntity(AlarmEntity entity) { + if (entity instanceof CommentAlarmEntity) { + return new CommentAlarmDto((CommentAlarmEntity) entity); + } return AlarmDto.builder() .id(entity.getId()) - .routingId(entity.getProject().getId()) + .routingId(entity.getRoutingId()) .content(entity.getContent()) .enabled(entity.isEnabled()) - .alarmFilterId(entity.getAlramFilter().getValue()) + .alarmFilterId(entity.getAlarmFilterIntValue()) .createdAt(entity.getCreatedAt()) .build(); } + + } diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/dto/CommentAlarmDto.java b/src/main/java/hs/kr/backend/devpals/domain/user/dto/CommentAlarmDto.java new file mode 100644 index 00000000..ddc355cc --- /dev/null +++ b/src/main/java/hs/kr/backend/devpals/domain/user/dto/CommentAlarmDto.java @@ -0,0 +1,27 @@ +package hs.kr.backend.devpals.domain.user.dto; + +import hs.kr.backend.devpals.domain.user.entity.alarm.CommentAlarmEntity; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class CommentAlarmDto extends AlarmDto{ + + private Boolean replier; + private Long reCommentUserId; + + public CommentAlarmDto(CommentAlarmEntity entity) { + super(entity.getId(), entity.getRoutingId(), entity.getContent(), entity.isEnabled(), entity.getAlarmFilterIntValue(), entity.getCreatedAt()); + this.replier = entity.getReplier(); + this.reCommentUserId = getReCommentUserIdIfNotNull(entity); + } + + //대댓글이 존재하면 유저id 반환 없으면 0 반환 + private Long getReCommentUserIdIfNotNull(CommentAlarmEntity entity) { + if(entity.getRecomment() != null) return entity.getRecomment().getUser().getId(); + else return 0L; + } +} diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/entity/AlramEntity.java b/src/main/java/hs/kr/backend/devpals/domain/user/entity/AlramEntity.java deleted file mode 100644 index bb1129c5..00000000 --- a/src/main/java/hs/kr/backend/devpals/domain/user/entity/AlramEntity.java +++ /dev/null @@ -1,61 +0,0 @@ -package hs.kr.backend.devpals.domain.user.entity; - -import hs.kr.backend.devpals.domain.project.entity.ApplicantEntity; -import hs.kr.backend.devpals.domain.project.entity.ProjectEntity; -import hs.kr.backend.devpals.global.common.enums.AlramFilter; -import jakarta.persistence.*; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.time.LocalDateTime; - -@Entity -@Getter -@NoArgsConstructor -@Table(name = "Alram") -public class AlramEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "project_id", nullable = false) - private ProjectEntity project; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id", nullable = false) - private UserEntity user; - - - @Column(length = 255) - private String content; - - @Column(nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE") - private boolean enabled; - - @Column - private Long routingId; //AlarmFilter마다 - - @Enumerated(EnumType.STRING) - private AlramFilter alramFilter; - - @Column(updatable = false) - private LocalDateTime createdAt = LocalDateTime.now(); - - public AlramEntity(ApplicantEntity applicant, String content, AlramFilter alramFilter,Long routingId) { - this.project = applicant.getProject(); - this.user = applicant.getUser(); - this.content = content; - this.routingId = routingId; - this.enabled = false; - this.alramFilter = alramFilter; - } - public AlramEntity(ProjectEntity project,UserEntity author, String content, AlramFilter alramFilter,Long routingId) { - this.project = project; - this.user = author; - this.content = content; - this.routingId = routingId; - this.enabled = false; - this.alramFilter = alramFilter; - } -} diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/AlarmEntity.java b/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/AlarmEntity.java new file mode 100644 index 00000000..7bbd8056 --- /dev/null +++ b/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/AlarmEntity.java @@ -0,0 +1,56 @@ +package hs.kr.backend.devpals.domain.user.entity.alarm; + +import hs.kr.backend.devpals.domain.project.entity.ApplicantEntity; +import hs.kr.backend.devpals.domain.project.entity.CommentEntity; +import hs.kr.backend.devpals.domain.project.entity.ProjectEntity; +import hs.kr.backend.devpals.domain.user.entity.UserEntity; +import hs.kr.backend.devpals.global.common.enums.AlarmFilter; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor +@Inheritance(strategy = InheritanceType.JOINED) +@DiscriminatorColumn(name = "ALARM_FILTER", + discriminatorType = DiscriminatorType.STRING) + +@Table(name = "Alarm") +public abstract class AlarmEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "receiver_id", nullable = false) + private UserEntity receiver; + + + @Column(length = 255) + private String content; + + @Column(nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE") + private boolean enabled = false; + + @Column + private Long routingId; //AlarmFilter마다 + + +// @Enumerated(EnumType.STRING) +// private AlarmFilter alarmFilter; + + @Column(updatable = false) + private LocalDateTime createdAt = LocalDateTime.now(); + + public AlarmEntity(UserEntity receiver, String content, Long routingId) { + this.receiver = receiver; + this.content = content; + this.routingId = routingId; + } + + public abstract Integer getAlarmFilterIntValue(); +} diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ApplicantAlarmEntity.java b/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ApplicantAlarmEntity.java new file mode 100644 index 00000000..d5778d50 --- /dev/null +++ b/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ApplicantAlarmEntity.java @@ -0,0 +1,36 @@ +package hs.kr.backend.devpals.domain.user.entity.alarm; + +import hs.kr.backend.devpals.domain.project.entity.ApplicantEntity; +import hs.kr.backend.devpals.domain.project.entity.ProjectEntity; +import jakarta.persistence.*; +import lombok.NoArgsConstructor; + +import static hs.kr.backend.devpals.domain.user.entity.alarm.constants.AlarmFilterConstants.APPLIED_PROJECTS; +import static hs.kr.backend.devpals.domain.user.entity.alarm.constants.AlarmFilterConstants.APPLIED_PROJECT_INT_VALUE; + +@Entity +@DiscriminatorValue(APPLIED_PROJECTS) +@NoArgsConstructor +@Table(name = "ApplicantAlarm") // 테이블 이름 지정 +public class ApplicantAlarmEntity extends AlarmEntity { + //"지원한 프로젝트" 알람 (지원 결과) + //공고 지원자가 지원한 프로젝트에 합격, 불합격 여부를 전달하는 알람 + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "project_id", nullable = false) + private ProjectEntity project; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "applicant_id", nullable = false) + private ApplicantEntity applicant; + + public ApplicantAlarmEntity(ApplicantEntity applicantEntity, String content, ProjectEntity project) { + super(applicantEntity.getUser(),content,project.getId()); + this.project = project; + this.applicant = applicantEntity; + + } + + public Integer getAlarmFilterIntValue() { + return APPLIED_PROJECT_INT_VALUE; + } +} diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/CommentAlarmEntity.java b/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/CommentAlarmEntity.java new file mode 100644 index 00000000..a61ed531 --- /dev/null +++ b/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/CommentAlarmEntity.java @@ -0,0 +1,55 @@ +package hs.kr.backend.devpals.domain.user.entity.alarm; + +import hs.kr.backend.devpals.domain.project.entity.CommentEntity; +import hs.kr.backend.devpals.domain.project.entity.ProjectEntity; +import hs.kr.backend.devpals.domain.project.entity.RecommentEntity; +import hs.kr.backend.devpals.domain.user.entity.UserEntity; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import static hs.kr.backend.devpals.domain.user.entity.alarm.constants.AlarmFilterConstants.*; + +@Entity +@DiscriminatorValue(COMMENT_AND_REPLY) +@NoArgsConstructor +@Getter +@Table(name = "CommentAlarm") // 테이블 이름 지정 +public class CommentAlarmEntity extends AlarmEntity { +// 댓글 알람 -> 공고에 댓글을 달았을 시, 댓글에 답변을 달았을 시 전달되는 알람 + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "project_id", nullable = false) + private ProjectEntity project; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "comment_id", nullable = false) + private CommentEntity comment; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "recomment_id") + private RecommentEntity recomment; + + @Column + private Boolean replier; + + //공고에 댓글 달았을 시 공고 게시자에게 알람 전송 + public CommentAlarmEntity(CommentEntity comment, String content, ProjectEntity project, UserEntity projectAuthor) { + super(projectAuthor,content,project.getId()); + this.comment = comment; + this.project = project; + this.replier = false; + } + + public CommentAlarmEntity(CommentEntity comment, String content, ProjectEntity project, RecommentEntity recomment,UserEntity receiver) { + super(receiver,content,project.getId()); + this.comment = comment; + this.project = project; + this.recomment = recomment; + this.replier = true; + } + + public Integer getAlarmFilterIntValue() { + return COMMENT_AND_REPLY_INT_VALUE; + } +} diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ProjectAlarmEntity.java b/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ProjectAlarmEntity.java new file mode 100644 index 00000000..a93cc95b --- /dev/null +++ b/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ProjectAlarmEntity.java @@ -0,0 +1,36 @@ +package hs.kr.backend.devpals.domain.user.entity.alarm; + +import hs.kr.backend.devpals.domain.project.entity.ApplicantEntity; +import hs.kr.backend.devpals.domain.project.entity.ProjectEntity; +import hs.kr.backend.devpals.domain.user.entity.UserEntity; +import jakarta.persistence.*; +import lombok.NoArgsConstructor; + +import static hs.kr.backend.devpals.domain.user.entity.alarm.constants.AlarmFilterConstants.*; + +@Entity +@DiscriminatorValue(APPLICANT_CHECK) +@NoArgsConstructor +@Table(name = "ProjectAlarm") // 테이블 이름 지정 +public class ProjectAlarmEntity extends AlarmEntity{ +//공고에 지원자가 지원할 시 공고생성자가 수신받는 알림 + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "project_id", nullable = false) + private ProjectEntity project; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "applicant_id", nullable = false) + private ApplicantEntity applicant; + + + public ProjectAlarmEntity(ProjectEntity project, UserEntity author, String content,ApplicantEntity applicant) { + super(author,content, project.getId()); + this.project = project; + this.applicant = applicant; + } + + public Integer getAlarmFilterIntValue() { + return APPLICANT_CHECK_INT_VALUE; + } +} diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.java b/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.java new file mode 100644 index 00000000..5291fe3f --- /dev/null +++ b/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.java @@ -0,0 +1,11 @@ +package hs.kr.backend.devpals.domain.user.entity.alarm.constants; + +public class AlarmFilterConstants { + public static final String APPLIED_PROJECTS = "APPLIED_PROJECTS"; + public static final String APPLICANT_CHECK = "APPLICANT_CHECK"; + public static final String COMMENT_AND_REPLY = "COMMENT_AND_REPLY"; + public static final int APPLIED_PROJECT_INT_VALUE = 1; + public static final int APPLICANT_CHECK_INT_VALUE = 1; + public static final int COMMENT_AND_REPLY_INT_VALUE = 1; + +} diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/repository/AlarmRepository.java b/src/main/java/hs/kr/backend/devpals/domain/user/repository/AlarmRepository.java index 964757fc..865dcefb 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/user/repository/AlarmRepository.java +++ b/src/main/java/hs/kr/backend/devpals/domain/user/repository/AlarmRepository.java @@ -1,6 +1,6 @@ package hs.kr.backend.devpals.domain.user.repository; -import hs.kr.backend.devpals.domain.user.entity.AlramEntity; +import hs.kr.backend.devpals.domain.user.entity.alarm.AlarmEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; @@ -12,13 +12,14 @@ import java.util.Optional; @Repository -public interface AlarmRepository extends JpaRepository { - List findByUserId(Long userId); +public interface AlarmRepository extends JpaRepository { + @Query("SELECT a FROM AlarmEntity a WHERE a.receiver.id = :receiverId") + List findByReceiverId(@Param("receiverId") Long receiverId); - @Query("SELECT a FROM AlramEntity a WHERE a.user.id = :userId AND a.id = :alarmId") - Optional findByUserIdAndAlarmId(@Param("userId") Long userId, @Param("alarmId") Long alarmId); + @Query("SELECT a FROM AlarmEntity a WHERE a.receiver.id = :receiverId AND a.id = :alarmId") + Optional findByUserIdAndAlarmId(@Param("receiverId") Long receiverId, @Param("alarmId") Long alarmId); @Modifying - @Query("DELETE FROM AlramEntity a WHERE a.createdAt < :threshold AND a.alramFilter <> 'APPLIED_PROJECTS'") + @Query("DELETE FROM AlarmEntity a WHERE a.createdAt < :threshold AND TYPE(a) <> ApplicantAlarmEntity") void deleteAllOlderThanExceptApplied(@Param("threshold") LocalDateTime threshold); } diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/service/AlarmService.java b/src/main/java/hs/kr/backend/devpals/domain/user/service/AlarmService.java index 1c5fb088..48675d6f 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/user/service/AlarmService.java +++ b/src/main/java/hs/kr/backend/devpals/domain/user/service/AlarmService.java @@ -1,15 +1,18 @@ package hs.kr.backend.devpals.domain.user.service; import hs.kr.backend.devpals.domain.project.entity.ApplicantEntity; +import hs.kr.backend.devpals.domain.project.entity.CommentEntity; import hs.kr.backend.devpals.domain.project.entity.ProjectEntity; +import hs.kr.backend.devpals.domain.project.entity.RecommentEntity; import hs.kr.backend.devpals.domain.project.repository.ProjectRepository; -import hs.kr.backend.devpals.domain.user.dto.UserAlarmDto; -import hs.kr.backend.devpals.domain.user.entity.AlramEntity; +import hs.kr.backend.devpals.domain.user.entity.alarm.AlarmEntity; import hs.kr.backend.devpals.domain.user.entity.UserEntity; +import hs.kr.backend.devpals.domain.user.entity.alarm.ApplicantAlarmEntity; +import hs.kr.backend.devpals.domain.user.entity.alarm.CommentAlarmEntity; +import hs.kr.backend.devpals.domain.user.entity.alarm.ProjectAlarmEntity; import hs.kr.backend.devpals.domain.user.repository.AlarmRepository; import hs.kr.backend.devpals.domain.user.repository.UserRepository; import hs.kr.backend.devpals.global.common.ApiResponse; -import hs.kr.backend.devpals.global.common.enums.AlramFilter; import hs.kr.backend.devpals.global.common.enums.ApplicantStatus; import hs.kr.backend.devpals.global.exception.CustomException; import hs.kr.backend.devpals.global.exception.ErrorException; @@ -23,11 +26,9 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import java.io.IOException; -import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; @Service @@ -56,18 +57,6 @@ public SseEmitter createEmitter(String token) { return emitter; } - // 지원 결과 알람 전송 - public void sendAlarm(List applicants, AlramFilter alramFilter,Long routingId){ - List alramEntities = applicants.stream() - .map(a -> new AlramEntity(a, makeMessage(a), alramFilter,routingId)) - .toList(); - - List savedAlarmEntities = alarmRepository.saveAll(alramEntities); - - savedAlarmEntities.forEach(a -> - sendToUser(a.getUser().getId(), a) - ); - } //테스트용 로직입니다 추후 삭제하겠습니다. public ResponseEntity> sendAlarmTest(String token, Integer alarmFilterId){ @@ -86,36 +75,75 @@ public ResponseEntity> sendAlarmTest(String token, Integer a return new ResponseEntity<>(new ApiResponse(true, "ok","테스트 메시지 입니다. 메시지는 따로 저장되지 않습니다."), HttpStatus.OK); } + // 프로젝트 지원 결과 알람 전송 + public void sendAlarm(List applicants, ProjectEntity project){ + List alarmEntities = applicants.stream() + .map(a -> new ApplicantAlarmEntity(a, makeMessage(a),project)) + .toList(); + + List savedAlarmEntities = alarmRepository.saveAll(alarmEntities); + + savedAlarmEntities.forEach(a -> + sendToUser(a.getReceiver().getId(), a) + ); + } //프로젝트 지원 신청시 프로젝트 작성자에게 알림전송 - public void sendAlarm(ProjectEntity project, ApplicantEntity applicant, AlramFilter alramFilter) { + public void sendAlarm(ProjectEntity project, ApplicantEntity applicant) { UserEntity author = userRepository.findById(project.getUserId()).orElseThrow(() -> new CustomException(ErrorException.USER_NOT_FOUND)); String content = makeMessage(project, applicant); - AlramEntity saved = alarmRepository.save(new AlramEntity(project, author, content, alramFilter,project.getId())); + AlarmEntity saved = alarmRepository.save(new ProjectAlarmEntity(project, author, content,applicant)); sendToUser(author.getId(),saved); } + //대댓글 작성시 댓글 작성자에게 알림 전송 + public void sendAlarm(RecommentEntity recomment, CommentEntity comment, ProjectEntity project) { + String content = makeMessage(project, recomment); + UserEntity receiver = comment.getUser(); + CommentAlarmEntity commentAlarmEntity = new CommentAlarmEntity(comment, content, project, recomment,receiver); + AlarmEntity saved = alarmRepository.save(commentAlarmEntity); + sendToUser(receiver.getId(),saved); + } + + + //댓글 작성시 프로젝트 작성자에게 알림 전송 + public void sendAlarm(CommentEntity comment, ProjectEntity project, UserEntity commenter) { + String content = makeMessage(project, commenter); + UserEntity receiver = userRepository.findById(project.getUserId()).orElseThrow(() -> new CustomException(ErrorException.USER_NOT_FOUND)); + CommentAlarmEntity commentAlarmEntity = new CommentAlarmEntity(comment, content, project, receiver); + AlarmEntity saved = alarmRepository.save(commentAlarmEntity); + sendToUser(project.getUserId(),saved); + } + private String makeMessage(ProjectEntity project,ApplicantEntity applicant) { - return "\""+project.getTitle()+"\" 프로젝트에 "+ applicant.getUser().getNickname() + "님이 지원하셨습니다."; + return "모집중인 '"+project.getTitle()+ "'에 " + applicant.getUser().getNickname() + " 님이 지원하셨습니다."; + } + + private String makeMessage(ProjectEntity project,UserEntity commenter) { + return "'"+project.getTitle()+ "'에 " + commenter.getNickname() + " 님의 댓글이 달렸습니다"; } private String makeMessage(ApplicantEntity applicant) { String result = applicant.getStatus().equals(ApplicantStatus.ACCEPTED) ? "합격" : "불합격"; - return "지원자님은 \""+applicant.getProject().getTitle()+"\" 프로젝트에 "+ result +" 하셨습니다."; + return "내가 지원한 '"+applicant.getProject().getTitle()+"'에 "+ result +"하셨습니다."; + } + + private String makeMessage(ProjectEntity project, RecommentEntity recomment) { + return "'"+project.getTitle()+ "'에 작성자의 답변이 달렸습니다."; } // 특정 사용자에게 알림 전송 - private void sendToUser(Long userId, AlramEntity alramEntity) { + private void sendToUser(Long userId, AlarmEntity alarmEntity) { SseEmitter emitter = emitters.get(userId); if (emitter != null) { try { emitter.send(SseEmitter.event() .name("alarm") .data(Map.of( - "message", alramEntity.getContent(), - "createAt",alramEntity.getCreatedAt(), - "alarmFilterId",alramEntity.getAlramFilter().getValue(), - "routingId",alramEntity.getRoutingId() + "message", alarmEntity.getContent(), + "createAt", alarmEntity.getCreatedAt(), + "alarmFilterId", alarmEntity.getAlarmFilterIntValue(), + "routingId", alarmEntity.getRoutingId() ))); } catch (IOException e) { log.error("Error sending SSE to user {}: {}", userId, e.getMessage()); @@ -158,5 +186,4 @@ public void cleanupExpiredEmitters() { }); } - } diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/service/UserAlarmService.java b/src/main/java/hs/kr/backend/devpals/domain/user/service/UserAlarmService.java index d0b8c876..08887e65 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/user/service/UserAlarmService.java +++ b/src/main/java/hs/kr/backend/devpals/domain/user/service/UserAlarmService.java @@ -1,14 +1,15 @@ package hs.kr.backend.devpals.domain.user.service; import hs.kr.backend.devpals.domain.user.dto.AlarmDto; -import hs.kr.backend.devpals.domain.user.entity.AlramEntity; +import hs.kr.backend.devpals.domain.user.entity.alarm.AlarmEntity; import hs.kr.backend.devpals.domain.user.repository.AlarmRepository; import hs.kr.backend.devpals.global.common.ApiResponse; -import hs.kr.backend.devpals.global.common.enums.AlramFilter; +import hs.kr.backend.devpals.global.common.enums.AlarmFilter; import hs.kr.backend.devpals.global.exception.CustomException; import hs.kr.backend.devpals.global.exception.ErrorException; import hs.kr.backend.devpals.global.jwt.JwtTokenValidator; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,6 +20,7 @@ @Service @RequiredArgsConstructor +@Slf4j public class UserAlarmService { private final JwtTokenValidator jwtTokenValidator; @@ -28,21 +30,21 @@ public class UserAlarmService { public ResponseEntity>> getUserAlarm(String token, Integer filterVal) { Long userId = jwtTokenValidator.getUserId(token); - List cachedAlrams = alarmMyCache.get(userId); - if (cachedAlrams == null) { - cachedAlrams = alarmRepository.findByUserId(userId).stream() + List cachedAlarms = alarmMyCache.get(userId); + if (cachedAlarms == null) { + cachedAlarms = alarmRepository.findByReceiverId(userId).stream() .map(AlarmDto::fromEntity) .collect(Collectors.toList()); - alarmMyCache.put(userId, cachedAlrams); + alarmMyCache.put(userId, cachedAlarms); } - if(!AlramFilter.isValid(filterVal)) + if(!AlarmFilter.isValid(filterVal)) throw new CustomException(ErrorException.ALARM_FILTER_NOT_FOUND); - List filtered = (Objects.equals(filterVal, AlramFilter.ALL.getValue())) - ? cachedAlrams - : cachedAlrams.stream() + List filtered = (Objects.equals(filterVal, AlarmFilter.ALL.getValue())) + ? cachedAlarms + : cachedAlarms.stream() .filter(a -> Objects.equals(a.getAlarmFilterId(), filterVal)) .toList(); @@ -60,11 +62,11 @@ public void deleteAlarmOneWeekBefore(){ public ResponseEntity> deleteAlarm(String token, Long alarmId) { Long userId = jwtTokenValidator.getUserId(token); - AlramEntity alramEntity + AlarmEntity alarmEntity = alarmRepository.findByUserIdAndAlarmId(userId, alarmId).orElseThrow(() -> new CustomException(ErrorException.ALARM_NOT_FOUND)); - if(alramEntity.getAlramFilter().equals(AlramFilter.APPLIED_PROJECTS)) + if(alarmEntity.getAlarmFilterIntValue().equals(AlarmFilter.APPLIED_PROJECTS.getValue())) throw new CustomException(ErrorException.CAN_NOT_DELETE_ALARM); - alarmRepository.delete(alramEntity); + alarmRepository.delete(alarmEntity); ApiResponse response = new ApiResponse<>(true, "알람 삭제 성공", null); return ResponseEntity.ok(response); } diff --git a/src/main/java/hs/kr/backend/devpals/global/common/enums/AlramFilter.java b/src/main/java/hs/kr/backend/devpals/global/common/enums/AlarmFilter.java similarity index 73% rename from src/main/java/hs/kr/backend/devpals/global/common/enums/AlramFilter.java rename to src/main/java/hs/kr/backend/devpals/global/common/enums/AlarmFilter.java index ce1f42c9..47bdb312 100644 --- a/src/main/java/hs/kr/backend/devpals/global/common/enums/AlramFilter.java +++ b/src/main/java/hs/kr/backend/devpals/global/common/enums/AlarmFilter.java @@ -9,7 +9,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -public enum AlramFilter { +public enum AlarmFilter { ALL("전체",0), APPLIED_PROJECTS("지원한 프로젝트",1), APPLICANT_CHECK("지원자 확인",2), @@ -18,11 +18,11 @@ public enum AlramFilter { private final String displayName; private final Integer value; - private static final Map VALUE_MAP = - Arrays.stream(AlramFilter.values()) - .collect(Collectors.toMap(AlramFilter::getValue, f -> f)); + private static final Map VALUE_MAP = + Arrays.stream(AlarmFilter.values()) + .collect(Collectors.toMap(AlarmFilter::getValue, f -> f)); - AlramFilter(String displayName,Integer value) { + AlarmFilter(String displayName, Integer value) { this.displayName = displayName; this.value = value; } @@ -37,14 +37,14 @@ public Integer getValue() { } @JsonCreator - public static AlramFilter fromDisplayName(String value) { - return Stream.of(AlramFilter.values()) + public static AlarmFilter fromDisplayName(String value) { + return Stream.of(AlarmFilter.values()) .filter(filter -> filter.displayName.equals(value)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("Invalid filter name: " + value)); } - public static Optional fromValue(Integer value) { + public static Optional fromValue(Integer value) { return Optional.ofNullable(VALUE_MAP.get(value)); } From 4e32c834164f989373fb6d7614ef4b0d330a73c7 Mon Sep 17 00:00:00 2001 From: HeWillGoTillTheEnd Date: Thu, 24 Apr 2025 02:27:06 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[Fix]=20=EC=BD=94=EB=93=9C=EB=9E=98?= =?UTF-8?q?=EB=B9=97=20=EB=82=B4=EC=9A=A9=20=EB=B0=98=EC=98=81=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/hs/kr/backend/devpals/domain/user/dto/AlarmDto.java | 4 ++-- .../kr/backend/devpals/domain/user/dto/CommentAlarmDto.java | 2 +- .../user/entity/alarm/constants/AlarmFilterConstants.java | 4 ++-- .../devpals/domain/user/repository/AlarmRepository.java | 2 +- .../backend/devpals/domain/user/service/UserAlarmService.java | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/dto/AlarmDto.java b/src/main/java/hs/kr/backend/devpals/domain/user/dto/AlarmDto.java index 1b9e8458..9692d77e 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/user/dto/AlarmDto.java +++ b/src/main/java/hs/kr/backend/devpals/domain/user/dto/AlarmDto.java @@ -1,9 +1,8 @@ package hs.kr.backend.devpals.domain.user.dto; import hs.kr.backend.devpals.domain.user.entity.alarm.AlarmEntity; -import hs.kr.backend.devpals.domain.user.entity.alarm.ApplicantAlarmEntity; import hs.kr.backend.devpals.domain.user.entity.alarm.CommentAlarmEntity; -import hs.kr.backend.devpals.domain.user.entity.alarm.ProjectAlarmEntity; +import hs.kr.backend.devpals.domain.user.dto.CommentAlarmDto; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -24,6 +23,7 @@ public class AlarmDto { private LocalDateTime createdAt; public static AlarmDto fromEntity(AlarmEntity entity) { + //TODO: 추후 타입에 따라 전달하는 데이터가 다를 수 있으므로 ApplicantAlarmDto, ProjectAlarmDto 작성 가능성여부 검토필요 if (entity instanceof CommentAlarmEntity) { return new CommentAlarmDto((CommentAlarmEntity) entity); } diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/dto/CommentAlarmDto.java b/src/main/java/hs/kr/backend/devpals/domain/user/dto/CommentAlarmDto.java index ddc355cc..ee077702 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/user/dto/CommentAlarmDto.java +++ b/src/main/java/hs/kr/backend/devpals/domain/user/dto/CommentAlarmDto.java @@ -21,7 +21,7 @@ public CommentAlarmDto(CommentAlarmEntity entity) { //대댓글이 존재하면 유저id 반환 없으면 0 반환 private Long getReCommentUserIdIfNotNull(CommentAlarmEntity entity) { - if(entity.getRecomment() != null) return entity.getRecomment().getUser().getId(); + if(entity.getRecomment() != null && entity.getRecomment().getUser() != null) return entity.getRecomment().getUser().getId(); else return 0L; } } diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.java b/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.java index 5291fe3f..5f1029f5 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.java +++ b/src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.java @@ -5,7 +5,7 @@ public class AlarmFilterConstants { public static final String APPLICANT_CHECK = "APPLICANT_CHECK"; public static final String COMMENT_AND_REPLY = "COMMENT_AND_REPLY"; public static final int APPLIED_PROJECT_INT_VALUE = 1; - public static final int APPLICANT_CHECK_INT_VALUE = 1; - public static final int COMMENT_AND_REPLY_INT_VALUE = 1; + public static final int APPLICANT_CHECK_INT_VALUE = 2; + public static final int COMMENT_AND_REPLY_INT_VALUE = 3; } diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/repository/AlarmRepository.java b/src/main/java/hs/kr/backend/devpals/domain/user/repository/AlarmRepository.java index 865dcefb..6ae1bbac 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/user/repository/AlarmRepository.java +++ b/src/main/java/hs/kr/backend/devpals/domain/user/repository/AlarmRepository.java @@ -17,7 +17,7 @@ public interface AlarmRepository extends JpaRepository { List findByReceiverId(@Param("receiverId") Long receiverId); @Query("SELECT a FROM AlarmEntity a WHERE a.receiver.id = :receiverId AND a.id = :alarmId") - Optional findByUserIdAndAlarmId(@Param("receiverId") Long receiverId, @Param("alarmId") Long alarmId); + Optional findByReceiverIdAndAlarmId(@Param("receiverId") Long receiverId, @Param("alarmId") Long alarmId); @Modifying @Query("DELETE FROM AlarmEntity a WHERE a.createdAt < :threshold AND TYPE(a) <> ApplicantAlarmEntity") diff --git a/src/main/java/hs/kr/backend/devpals/domain/user/service/UserAlarmService.java b/src/main/java/hs/kr/backend/devpals/domain/user/service/UserAlarmService.java index 08887e65..34b5ec89 100644 --- a/src/main/java/hs/kr/backend/devpals/domain/user/service/UserAlarmService.java +++ b/src/main/java/hs/kr/backend/devpals/domain/user/service/UserAlarmService.java @@ -63,7 +63,7 @@ public void deleteAlarmOneWeekBefore(){ public ResponseEntity> deleteAlarm(String token, Long alarmId) { Long userId = jwtTokenValidator.getUserId(token); AlarmEntity alarmEntity - = alarmRepository.findByUserIdAndAlarmId(userId, alarmId).orElseThrow(() -> new CustomException(ErrorException.ALARM_NOT_FOUND)); + = alarmRepository.findByReceiverIdAndAlarmId(userId, alarmId).orElseThrow(() -> new CustomException(ErrorException.ALARM_NOT_FOUND)); if(alarmEntity.getAlarmFilterIntValue().equals(AlarmFilter.APPLIED_PROJECTS.getValue())) throw new CustomException(ErrorException.CAN_NOT_DELETE_ALARM); alarmRepository.delete(alarmEntity);