diff --git a/gotcha-domain/src/main/java/gotcha_domain/notification/Notification.java b/gotcha-domain/src/main/java/gotcha_domain/notification/Notification.java index 3f3243bb..0a63a26f 100644 --- a/gotcha-domain/src/main/java/gotcha_domain/notification/Notification.java +++ b/gotcha-domain/src/main/java/gotcha_domain/notification/Notification.java @@ -4,6 +4,8 @@ import gotcha_domain.user.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -31,15 +33,19 @@ public class Notification extends BaseTimeEntity { @Column(columnDefinition = "TEXT") private String content; + @Enumerated(EnumType.STRING) + private NotificationType type; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User writer; @Builder - public Notification(String title, String content, User writer){ + public Notification(String title, String content, User writer, NotificationType type){ this.title = title; this.content = content; this.writer = writer; + this.type = type; } public void update(NotificationReq req){ diff --git a/gotcha-domain/src/main/java/gotcha_domain/notification/NotificationReq.java b/gotcha-domain/src/main/java/gotcha_domain/notification/NotificationReq.java index aa4e852d..ecce46a9 100644 --- a/gotcha-domain/src/main/java/gotcha_domain/notification/NotificationReq.java +++ b/gotcha-domain/src/main/java/gotcha_domain/notification/NotificationReq.java @@ -18,6 +18,7 @@ public Notification toEntity(User writer) { title(title). content(content). writer(writer). + type(NotificationType.UPDATE). build(); } } \ No newline at end of file diff --git a/gotcha-domain/src/main/java/gotcha_domain/notification/NotificationType.java b/gotcha-domain/src/main/java/gotcha_domain/notification/NotificationType.java new file mode 100644 index 00000000..fe5324f9 --- /dev/null +++ b/gotcha-domain/src/main/java/gotcha_domain/notification/NotificationType.java @@ -0,0 +1,5 @@ +package gotcha_domain.notification; + +public enum NotificationType { + EVENT, UPDATE +} diff --git a/gotcha/src/main/java/Gotcha/domain/notification/api/NotificationApi.java b/gotcha/src/main/java/Gotcha/domain/notification/api/NotificationApi.java index 75b64b5f..b89b8c29 100644 --- a/gotcha/src/main/java/Gotcha/domain/notification/api/NotificationApi.java +++ b/gotcha/src/main/java/Gotcha/domain/notification/api/NotificationApi.java @@ -2,6 +2,7 @@ import Gotcha.domain.notification.dto.NotificationSortType; +import gotcha_domain.notification.NotificationType; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.ExampleObject; @@ -11,12 +12,21 @@ import jakarta.validation.constraints.Min; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.web.bind.annotation.RequestParam; @Tag(name = "[공지사항 API]", description = "공지사항 관련 API") public interface NotificationApi { - @Operation(summary = "공지사항 목록", description = "공지사항 목록을 조회하는 API. Keyword로 검색 및 정렬 가능.") + @Operation(summary = "공지사항 목록", description = "공지사항 목록을 조회하는 API. Keyword, Type으로 검색 및 정렬 가능.", + parameters = { + @Parameter(name = "keyword", description = "검색할 제목 키워드", example = "점검"), + @Parameter(name = "type", description = "알림 타입", schema = @Schema(implementation = NotificationType.class), example = "UPDATE"), + @Parameter(name = "page", description = "페이지 번호 (0부터 시작)", example = "0"), + @Parameter(name = "sort", description = "정렬 방식", schema = @Schema(implementation = NotificationSortType.class), example = "DATE_DESC") + } + ) @ApiResponses({ @ApiResponse( responseCode = "200", description = "공지사항 목록 조회 성공", @@ -74,9 +84,10 @@ public interface NotificationApi { ) }) - ResponseEntity getNotifications(@RequestParam(value = "keyword", required = false) String keyword, - @RequestParam(value = "page",defaultValue = "0") @Min(0) Integer page, - @RequestParam(value = "sort", defaultValue = "DATE_DESC") NotificationSortType sort); + public ResponseEntity getNotifications(@RequestParam(value = "keyword", required = false) String keyword, + @RequestParam(value = "type", required = false) NotificationType type, + @RequestParam(value = "page", defaultValue = "0") @Min(0) Integer page, + @RequestParam(value = "sort", defaultValue = "DATE_DESC") NotificationSortType sort); @@ -89,6 +100,7 @@ ResponseEntity getNotifications(@RequestParam(value = "keyword", required = f { "title": "걍 공지사항이다", "content": "걍 공지사항이다 인마", + "type": "EVENT", "createdAt": "2025-03-27T16:13:32", "modifiedAt": "2025-11-16T16:13:32", "writer": "묘묘" diff --git a/gotcha/src/main/java/Gotcha/domain/notification/controller/NotificationController.java b/gotcha/src/main/java/Gotcha/domain/notification/controller/NotificationController.java index 02242214..4b256141 100644 --- a/gotcha/src/main/java/Gotcha/domain/notification/controller/NotificationController.java +++ b/gotcha/src/main/java/Gotcha/domain/notification/controller/NotificationController.java @@ -5,12 +5,17 @@ import Gotcha.domain.notification.dto.NotificationSortType; import Gotcha.domain.notification.dto.NotificationSummaryRes; import Gotcha.domain.notification.service.NotificationService; +import gotcha_domain.notification.NotificationType; import jakarta.validation.constraints.Min; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor @@ -23,9 +28,10 @@ public class NotificationController implements NotificationApi { @Override @GetMapping public ResponseEntity getNotifications(@RequestParam(value = "keyword", required = false) String keyword, - @RequestParam(value = "page", defaultValue = "0") @Min(0) Integer page, - @RequestParam(value = "sort", defaultValue = "DATE_DESC") NotificationSortType sort){ - Page notifications = notificationService.getNotifications(keyword, page, sort); + @RequestParam(value = "type", required = false) NotificationType type, + @RequestParam(value = "page", defaultValue = "0") @Min(0) Integer page, + @RequestParam(value = "sort", defaultValue = "DATE_DESC") NotificationSortType sort) { + Page notifications = notificationService.getNotifications(keyword, type, page, sort); return ResponseEntity.status(HttpStatus.OK).body(notifications); } diff --git a/gotcha/src/main/java/Gotcha/domain/notification/dto/NotificationRes.java b/gotcha/src/main/java/Gotcha/domain/notification/dto/NotificationRes.java index d1c55339..a35272ea 100644 --- a/gotcha/src/main/java/Gotcha/domain/notification/dto/NotificationRes.java +++ b/gotcha/src/main/java/Gotcha/domain/notification/dto/NotificationRes.java @@ -2,12 +2,14 @@ import gotcha_domain.notification.Notification; +import gotcha_domain.notification.NotificationType; import java.time.LocalDateTime; public record NotificationRes( String title, String content, + NotificationType type, LocalDateTime createdAt, LocalDateTime modifiedAt, String writer @@ -16,6 +18,7 @@ public static NotificationRes fromEntity(Notification noti) { return new NotificationRes( noti.getTitle(), noti.getContent(), + noti.getType(), noti.getCreatedAt(), noti.getModifiedAt(), noti.getWriter().getNickname() diff --git a/gotcha/src/main/java/Gotcha/domain/notification/repository/NotificationRepository.java b/gotcha/src/main/java/Gotcha/domain/notification/repository/NotificationRepository.java index 533128ce..1c9c8022 100644 --- a/gotcha/src/main/java/Gotcha/domain/notification/repository/NotificationRepository.java +++ b/gotcha/src/main/java/Gotcha/domain/notification/repository/NotificationRepository.java @@ -1,10 +1,12 @@ package Gotcha.domain.notification.repository; import gotcha_domain.notification.Notification; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.domain.Pageable; +import gotcha_domain.notification.NotificationType; import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; public interface NotificationRepository extends JpaRepository { Page findByTitleContainingIgnoreCase(String keyword, Pageable pageable); + Page findByTypeAndTitleContainingIgnoreCase(NotificationType type, String keyword, Pageable pageable); } diff --git a/gotcha/src/main/java/Gotcha/domain/notification/service/NotificationService.java b/gotcha/src/main/java/Gotcha/domain/notification/service/NotificationService.java index f2127a3f..2634ff1b 100644 --- a/gotcha/src/main/java/Gotcha/domain/notification/service/NotificationService.java +++ b/gotcha/src/main/java/Gotcha/domain/notification/service/NotificationService.java @@ -7,6 +7,7 @@ import Gotcha.domain.notification.repository.NotificationRepository; import gotcha_common.exception.CustomException; import gotcha_domain.notification.Notification; +import gotcha_domain.notification.NotificationType; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -25,10 +26,18 @@ public class NotificationService { @Transactional(readOnly = true) - public Page getNotifications(String keyword, Integer page, NotificationSortType sort){ + public Page getNotifications(String keyword, NotificationType type, Integer page, NotificationSortType sort){ Pageable pageable = PageRequest.of(page, NOTIS_PER_PAGE, sort.getSort()); - Page notifications = notificationRepository.findByTitleContainingIgnoreCase(keyword, pageable); + Page notifications; + if (keyword == null) keyword = ""; + if (type != null) { + notifications = notificationRepository + .findByTypeAndTitleContainingIgnoreCase(type, keyword, pageable); + } else { + notifications = notificationRepository + .findByTitleContainingIgnoreCase(keyword, pageable); + } return notifications.map(NotificationSummaryRes::fromEntity); }