From 1e2e4fe45d400e03f4408d64d839578242df317e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Sat, 20 Jun 2026 23:56:24 +0900 Subject: [PATCH 1/9] =?UTF-8?q?:sparkles:=20feat:=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EA=B5=AC=EC=A1=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/NotificationRequest.java | 4 ++++ .../dto/response/NotificationResponse.java | 4 ++++ .../mapper/NotificationConverter.java | 4 ++++ .../notification/domain/constant/.gitkeep | 0 .../domain/service/NotificationService.java | 4 ++++ .../service/NotificationServiceImpl.java | 9 +++++++++ .../exception/NotificationException.java | 10 ++++++++++ .../exception/code/NotificationErrorCode.java | 18 ++++++++++++++++++ .../presentation/NotificationController.java | 12 ++++++++++++ .../docs/NotificationControllerDocs.java | 4 ++++ 10 files changed, 69 insertions(+) create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/application/dto/request/NotificationRequest.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/application/dto/response/NotificationResponse.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/application/mapper/NotificationConverter.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/constant/.gitkeep create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/service/NotificationService.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/service/NotificationServiceImpl.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/exception/NotificationException.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/exception/code/NotificationErrorCode.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/presentation/NotificationController.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/presentation/docs/NotificationControllerDocs.java diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/application/dto/request/NotificationRequest.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/application/dto/request/NotificationRequest.java new file mode 100644 index 00000000..a13b2f84 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/application/dto/request/NotificationRequest.java @@ -0,0 +1,4 @@ +package com.whereyouad.WhereYouAd.domains.notification.application.dto.request; + +public class NotificationRequest { +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/application/dto/response/NotificationResponse.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/application/dto/response/NotificationResponse.java new file mode 100644 index 00000000..fbd0cee4 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/application/dto/response/NotificationResponse.java @@ -0,0 +1,4 @@ +package com.whereyouad.WhereYouAd.domains.notification.application.dto.response; + +public class NotificationResponse { +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/application/mapper/NotificationConverter.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/application/mapper/NotificationConverter.java new file mode 100644 index 00000000..a8936e79 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/application/mapper/NotificationConverter.java @@ -0,0 +1,4 @@ +package com.whereyouad.WhereYouAd.domains.notification.application.mapper; + +public class NotificationConverter { +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/constant/.gitkeep b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/constant/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/service/NotificationService.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/service/NotificationService.java new file mode 100644 index 00000000..2eaea0bd --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/service/NotificationService.java @@ -0,0 +1,4 @@ +package com.whereyouad.WhereYouAd.domains.notification.domain.service; + +public interface NotificationService { +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/service/NotificationServiceImpl.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/service/NotificationServiceImpl.java new file mode 100644 index 00000000..a047e910 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/service/NotificationServiceImpl.java @@ -0,0 +1,9 @@ +package com.whereyouad.WhereYouAd.domains.notification.domain.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class NotificationServiceImpl { +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/exception/NotificationException.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/exception/NotificationException.java new file mode 100644 index 00000000..fb8d18d7 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/exception/NotificationException.java @@ -0,0 +1,10 @@ +package com.whereyouad.WhereYouAd.domains.notification.exception; + +import com.whereyouad.WhereYouAd.global.exception.AppException; +import com.whereyouad.WhereYouAd.global.exception.BaseErrorCode; + +public class NotificationException extends AppException { + public NotificationException(BaseErrorCode code) { + super(code); + } +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/exception/code/NotificationErrorCode.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/exception/code/NotificationErrorCode.java new file mode 100644 index 00000000..d9b1000c --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/exception/code/NotificationErrorCode.java @@ -0,0 +1,18 @@ +package com.whereyouad.WhereYouAd.domains.notification.exception.code; + +import com.whereyouad.WhereYouAd.global.exception.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum NotificationErrorCode implements BaseErrorCode { + + , + ; + + private final HttpStatus httpStatus; + private final String code; + private final String message; +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/presentation/NotificationController.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/presentation/NotificationController.java new file mode 100644 index 00000000..4ffe3890 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/presentation/NotificationController.java @@ -0,0 +1,12 @@ +package com.whereyouad.WhereYouAd.domains.notification.presentation; + +import com.whereyouad.WhereYouAd.domains.notification.presentation.docs.NotificationControllerDocs; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/notification") +@RequiredArgsConstructor +public class NotificationController implements NotificationControllerDocs { +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/presentation/docs/NotificationControllerDocs.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/presentation/docs/NotificationControllerDocs.java new file mode 100644 index 00000000..b4a32165 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/presentation/docs/NotificationControllerDocs.java @@ -0,0 +1,4 @@ +package com.whereyouad.WhereYouAd.domains.notification.presentation.docs; + +public interface NotificationControllerDocs { +} From cf4b35f0dd9582806d9429bf04c2ede1ed925c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Sat, 20 Jun 2026 23:56:43 +0900 Subject: [PATCH 2/9] =?UTF-8?q?:sparkles:=20feat:=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=97=94=ED=8B=B0=ED=8B=B0=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 --- .../persistence/entity/Notification.java | 45 +++++++++++++++++ .../entity/OrgMemberNotificationSetting.java | 48 +++++++++++++++++++ .../persistence/entity/UserNotification.java | 38 +++++++++++++++ .../repository/NotificationRepository.java | 7 +++ ...rgMemberNotificationSettingRepository.java | 7 +++ .../UserNotificationRepository.java | 7 +++ 6 files changed, 152 insertions(+) create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/Notification.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgMemberNotificationSetting.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/UserNotification.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/NotificationRepository.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/OrgMemberNotificationSettingRepository.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/UserNotificationRepository.java diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/Notification.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/Notification.java new file mode 100644 index 00000000..2d9cc60e --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/Notification.java @@ -0,0 +1,45 @@ +package com.whereyouad.WhereYouAd.domains.notification.persistence.entity; + +import com.whereyouad.WhereYouAd.domains.organization.persistence.entity.Organization; +import jakarta.persistence.*; +import lombok.*; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "notification") +@EntityListeners(AuditingEntityListener.class) +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Notification { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "notification_id") + private Long id; + + @Column(name = "title", nullable = false, length = 200) + private String title; + + @Column(name = "message", nullable = false, length = 2000) + private String message; + + @Column(name = "link_url", length = 1024) + private String linkUrl; + + @Column(name = "metadata_json", length = 4000) + private String metadataJson; + + @CreatedDate + @Column(name = "created_at", updatable = false) + private LocalDateTime createdAt; + + // 연관 관계 + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "org_id", nullable = false) + private Organization organization; +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgMemberNotificationSetting.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgMemberNotificationSetting.java new file mode 100644 index 00000000..28a9234c --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgMemberNotificationSetting.java @@ -0,0 +1,48 @@ +package com.whereyouad.WhereYouAd.domains.notification.persistence.entity; + +import com.whereyouad.WhereYouAd.domains.organization.persistence.entity.OrgMember; +import com.whereyouad.WhereYouAd.global.common.BaseEntity; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Table(name = "org_member_notification_setting") +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class OrgMemberNotificationSetting extends BaseEntity { + + @Id + @Column(name = "membership_id") + private Long membershipId; + + @OneToOne(fetch = FetchType.LAZY) + @MapsId // PK == FK(식별 관계) + @JoinColumn(name = "membership_id") + private OrgMember orgMember; + + @Column(name = "is_master_enabled", nullable = false) + private boolean isMasterEnabled; + + @Column(name = "is_browser_push_enabled", nullable = false) + private boolean isBrowserPushEnabled; + + @Column(name = "is_email_enabled", nullable = false) + private boolean isEmailEnabled; + + @Column(name = "is_slack_enabled", nullable = false) + private boolean isSlackEnabled; + + @Column(name = "slack_webhook_url", length = 255) + private String slackWebhookUrl; + + @Column(name = "alert_budget_80", nullable = false) + private boolean alertBudget80; + + @Column(name = "alert_budget_100", nullable = false) + private boolean alertBudget100; + + @Column(name = "alert_rapid_clicks", nullable = false) + private boolean alertRapidClicks; +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/UserNotification.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/UserNotification.java new file mode 100644 index 00000000..52e3b9d5 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/UserNotification.java @@ -0,0 +1,38 @@ +package com.whereyouad.WhereYouAd.domains.notification.persistence.entity; + +import com.whereyouad.WhereYouAd.domains.user.persistence.entity.User; +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.annotations.ColumnDefault; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "user_notification") +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class UserNotification { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_notification_id") + private Long id; + + @ColumnDefault("false") + @Column(name = "is_read", nullable = false) + private boolean isRead; + + @Column(name = "read_at") + private LocalDateTime readAt; + + // 연관관계 + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "notification_id", nullable = false) + private Notification notification; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/NotificationRepository.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/NotificationRepository.java new file mode 100644 index 00000000..20aa94fe --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/NotificationRepository.java @@ -0,0 +1,7 @@ +package com.whereyouad.WhereYouAd.domains.notification.persistence.repository; + +import com.whereyouad.WhereYouAd.domains.notification.persistence.entity.Notification; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface NotificationRepository extends JpaRepository { +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/OrgMemberNotificationSettingRepository.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/OrgMemberNotificationSettingRepository.java new file mode 100644 index 00000000..2ba139d8 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/OrgMemberNotificationSettingRepository.java @@ -0,0 +1,7 @@ +package com.whereyouad.WhereYouAd.domains.notification.persistence.repository; + +import com.whereyouad.WhereYouAd.domains.notification.persistence.entity.OrgMemberNotificationSetting; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface OrgMemberNotificationSettingRepository extends JpaRepository { +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/UserNotificationRepository.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/UserNotificationRepository.java new file mode 100644 index 00000000..035b6f84 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/UserNotificationRepository.java @@ -0,0 +1,7 @@ +package com.whereyouad.WhereYouAd.domains.notification.persistence.repository; + +import com.whereyouad.WhereYouAd.domains.notification.persistence.entity.UserNotification; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserNotificationRepository extends JpaRepository { +} From 25b55de3cf214d6e125d1f470511ce74f85889ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Sun, 21 Jun 2026 00:20:58 +0900 Subject: [PATCH 3/9] =?UTF-8?q?:recycle:=20refactor:=20=EC=8A=AC=EB=9E=99?= =?UTF-8?q?=20=EC=9B=B9=ED=9B=85=20URL=EC=9D=84=20=EC=A1=B0=EC=A7=81=20?= =?UTF-8?q?=EB=A0=88=EB=B2=A8=EB=A1=9C=20=EB=B6=84=EB=A6=AC=ED=95=98?= =?UTF-8?q?=EA=B3=A0=20=EB=94=94=EC=8A=A4=EC=BD=94=EB=93=9C=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/OrgMemberNotificationSetting.java | 4 +-- .../entity/OrgNotificationSetting.java | 30 +++++++++++++++++++ .../OrgNotificationSettingRepository.java | 7 +++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgNotificationSetting.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/OrgNotificationSettingRepository.java diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgMemberNotificationSetting.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgMemberNotificationSetting.java index 28a9234c..8deda0cd 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgMemberNotificationSetting.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgMemberNotificationSetting.java @@ -34,8 +34,8 @@ public class OrgMemberNotificationSetting extends BaseEntity { @Column(name = "is_slack_enabled", nullable = false) private boolean isSlackEnabled; - @Column(name = "slack_webhook_url", length = 255) - private String slackWebhookUrl; + @Column(name = "is_discord_enabled", nullable = false) + private boolean isDiscordEnabled; @Column(name = "alert_budget_80", nullable = false) private boolean alertBudget80; diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgNotificationSetting.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgNotificationSetting.java new file mode 100644 index 00000000..b3d910b3 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgNotificationSetting.java @@ -0,0 +1,30 @@ +package com.whereyouad.WhereYouAd.domains.notification.persistence.entity; + +import com.whereyouad.WhereYouAd.domains.organization.persistence.entity.Organization; +import com.whereyouad.WhereYouAd.global.common.BaseEntity; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Table(name = "org_notification_setting") +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class OrgNotificationSetting extends BaseEntity { + + @Id + @Column(name = "org_id") + private Long orgId; + + @OneToOne(fetch = FetchType.LAZY) + @MapsId // PK == FK(식별 관계) + @JoinColumn(name = "org_id") + private Organization organization; + + @Column(name = "slack_webhook_url", length = 512) + private String slackWebhookUrl; + + @Column(name = "discord_webhook_url", length = 512) + private String discordWebhookUrl; +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/OrgNotificationSettingRepository.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/OrgNotificationSettingRepository.java new file mode 100644 index 00000000..eb4ca8f6 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/OrgNotificationSettingRepository.java @@ -0,0 +1,7 @@ +package com.whereyouad.WhereYouAd.domains.notification.persistence.repository; + +import com.whereyouad.WhereYouAd.domains.notification.persistence.entity.OrgNotificationSetting; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface OrgNotificationSettingRepository extends JpaRepository { +} From b5578bf4d09f6604d95124483042127d16c69885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Sun, 21 Jun 2026 00:50:29 +0900 Subject: [PATCH 4/9] =?UTF-8?q?:bug:=20fix:=20NotificationServiceImpl=20im?= =?UTF-8?q?plements=20NotificationService=20=EB=88=84=EB=9D=BD=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification/domain/service/NotificationServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/service/NotificationServiceImpl.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/service/NotificationServiceImpl.java index a047e910..158e92a5 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/service/NotificationServiceImpl.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/service/NotificationServiceImpl.java @@ -5,5 +5,5 @@ @Service @RequiredArgsConstructor -public class NotificationServiceImpl { +public class NotificationServiceImpl implements NotificationService { } From 29e86eb0711ef05f2869c15ba2adc9f0ff09f11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Sun, 21 Jun 2026 00:51:31 +0900 Subject: [PATCH 5/9] =?UTF-8?q?:bug:=20fix:=20NotificationErrorCode=20enum?= =?UTF-8?q?=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20=EC=89=BC=ED=91=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification/exception/code/NotificationErrorCode.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/exception/code/NotificationErrorCode.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/exception/code/NotificationErrorCode.java index d9b1000c..8cb99c55 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/exception/code/NotificationErrorCode.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/exception/code/NotificationErrorCode.java @@ -9,7 +9,6 @@ @AllArgsConstructor public enum NotificationErrorCode implements BaseErrorCode { - , ; private final HttpStatus httpStatus; From e221a8bb58ef9b3f3d34b01d9acfae80f0b9a55e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Sun, 21 Jun 2026 16:30:46 +0900 Subject: [PATCH 6/9] =?UTF-8?q?:sparkles:=20feat:=20OrgMemberNotificationS?= =?UTF-8?q?etting=EC=97=90=20=EC=9D=BC=EC=9D=BC=20=EC=98=88=EC=82=B0=2050%?= =?UTF-8?q?=20=EC=95=8C=EB=A6=BC=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 --- .../persistence/entity/OrgMemberNotificationSetting.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgMemberNotificationSetting.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgMemberNotificationSetting.java index 8deda0cd..349be66e 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgMemberNotificationSetting.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/OrgMemberNotificationSetting.java @@ -37,6 +37,9 @@ public class OrgMemberNotificationSetting extends BaseEntity { @Column(name = "is_discord_enabled", nullable = false) private boolean isDiscordEnabled; + @Column(name = "alert_budget_50", nullable = false) + private boolean alertBudget50; + @Column(name = "alert_budget_80", nullable = false) private boolean alertBudget80; From 2f56e43c344d4fb09d31ea74d76fcd8487c4b9dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Tue, 23 Jun 2026 21:31:24 +0900 Subject: [PATCH 7/9] =?UTF-8?q?:sparkles:=20feat:=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EB=B0=9C=EC=86=A1=20=EC=9D=B4=EB=A0=A5=20=EC=B6=94=EC=A0=81?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20NotificationDelivery=20?= =?UTF-8?q?=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/constant/DeliveryChannel.java | 9 +++ .../domain/constant/DeliveryStatus.java | 7 ++ .../entity/NotificationDelivery.java | 65 +++++++++++++++++++ .../NotificationDeliveryRepository.java | 9 +++ 4 files changed, 90 insertions(+) create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/constant/DeliveryChannel.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/constant/DeliveryStatus.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/NotificationDelivery.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/NotificationDeliveryRepository.java diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/constant/DeliveryChannel.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/constant/DeliveryChannel.java new file mode 100644 index 00000000..6e8bebcc --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/constant/DeliveryChannel.java @@ -0,0 +1,9 @@ +package com.whereyouad.WhereYouAd.domains.notification.domain.constant; + +public enum DeliveryChannel { + EMAIL, + SLACK, + DISCORD, + BROWSER_PUSH, + IN_APP +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/constant/DeliveryStatus.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/constant/DeliveryStatus.java new file mode 100644 index 00000000..922a82e2 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/domain/constant/DeliveryStatus.java @@ -0,0 +1,7 @@ +package com.whereyouad.WhereYouAd.domains.notification.domain.constant; + +public enum DeliveryStatus { + PENDING, + SUCCESS, + FAILED +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/NotificationDelivery.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/NotificationDelivery.java new file mode 100644 index 00000000..05646047 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/NotificationDelivery.java @@ -0,0 +1,65 @@ +package com.whereyouad.WhereYouAd.domains.notification.persistence.entity; + +import com.whereyouad.WhereYouAd.domains.notification.domain.constant.DeliveryChannel; +import com.whereyouad.WhereYouAd.domains.notification.domain.constant.DeliveryStatus; +import com.whereyouad.WhereYouAd.domains.user.persistence.entity.User; +import com.whereyouad.WhereYouAd.global.common.BaseEntity; +import jakarta.persistence.*; +import lombok.*; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "notification_delivery") +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class NotificationDelivery extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "delivery_id") + private Long id; + + @Enumerated(EnumType.STRING) + @Column(name = "channel", nullable = false, length = 20) + private DeliveryChannel channel; + + @Enumerated(EnumType.STRING) + @Column(name = "status", nullable = false, length = 10) + private DeliveryStatus status; + + @Column(name = "sent_at") + private LocalDateTime sentAt; + + @Column(name = "failed_at") + private LocalDateTime failedAt; + + @Column(name = "failure_reason", length = 500) + private String failureReason; + + @Builder.Default + @Column(name = "retry_count", nullable = false) + private int retryCount = 0; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "notification_id", nullable = false) + private Notification notification; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; + + public void markSuccess() { + this.status = DeliveryStatus.SUCCESS; + this.sentAt = LocalDateTime.now(); + } + + public void markFailed(String reason) { + this.status = DeliveryStatus.FAILED; + this.failedAt = LocalDateTime.now(); + this.failureReason = reason; + this.retryCount++; + } +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/NotificationDeliveryRepository.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/NotificationDeliveryRepository.java new file mode 100644 index 00000000..0db71843 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/repository/NotificationDeliveryRepository.java @@ -0,0 +1,9 @@ +package com.whereyouad.WhereYouAd.domains.notification.persistence.repository; + +import com.whereyouad.WhereYouAd.domains.notification.persistence.entity.NotificationDelivery; +import org.springframework.data.jpa.repository.JpaRepository; + + +public interface NotificationDeliveryRepository extends JpaRepository { + +} From 59ce79c5de09adf6d039db8a6afe066366a61a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Wed, 24 Jun 2026 10:57:56 +0900 Subject: [PATCH 8/9] =?UTF-8?q?:recycle:=20refactor:=20NotificationDeliver?= =?UTF-8?q?y=20=EC=97=B0=EA=B4=80=EA=B4=80=EA=B3=84=EB=A5=BC=20User?= =?UTF-8?q?=EC=97=90=EC=84=9C=20OrgMember=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../persistence/entity/NotificationDelivery.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/NotificationDelivery.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/NotificationDelivery.java index 05646047..7143012b 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/NotificationDelivery.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/NotificationDelivery.java @@ -2,7 +2,7 @@ import com.whereyouad.WhereYouAd.domains.notification.domain.constant.DeliveryChannel; import com.whereyouad.WhereYouAd.domains.notification.domain.constant.DeliveryStatus; -import com.whereyouad.WhereYouAd.domains.user.persistence.entity.User; +import com.whereyouad.WhereYouAd.domains.organization.persistence.entity.OrgMember; import com.whereyouad.WhereYouAd.global.common.BaseEntity; import jakarta.persistence.*; import lombok.*; @@ -48,8 +48,8 @@ public class NotificationDelivery extends BaseEntity { private Notification notification; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id", nullable = false) - private User user; + @JoinColumn(name = "membership_id", nullable = false) + private OrgMember orgMember; public void markSuccess() { this.status = DeliveryStatus.SUCCESS; From ebca70f08ad1f8662aa644d8e22e56c2aaa61d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Wed, 24 Jun 2026 10:59:01 +0900 Subject: [PATCH 9/9] =?UTF-8?q?:bug:=20fix:=20NotificationDelivery=20statu?= =?UTF-8?q?s=20=ED=95=84=EB=93=9C=20=EA=B8=B0=EB=B3=B8=EA=B0=92=20PENDING?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification/persistence/entity/NotificationDelivery.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/NotificationDelivery.java b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/NotificationDelivery.java index 7143012b..fab4f69a 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/NotificationDelivery.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/notification/persistence/entity/NotificationDelivery.java @@ -26,9 +26,10 @@ public class NotificationDelivery extends BaseEntity { @Column(name = "channel", nullable = false, length = 20) private DeliveryChannel channel; + @Builder.Default @Enumerated(EnumType.STRING) @Column(name = "status", nullable = false, length = 10) - private DeliveryStatus status; + private DeliveryStatus status = DeliveryStatus.PENDING; @Column(name = "sent_at") private LocalDateTime sentAt;