-
Notifications
You must be signed in to change notification settings - Fork 0
[feat] 알림센터 조회 api 개발 #305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4a376c8
8b8085e
474a23a
851d29f
2254190
f616f09
16e5744
dcf9d6f
981bf81
450b5e3
9f3d389
63b93e8
c53b2bc
d76c0b2
dbc53e9
20fc36b
a688492
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,20 +7,25 @@ | |
| import konkuk.thip.common.security.annotation.UserId; | ||
| import konkuk.thip.common.swagger.annotation.ExceptionDescription; | ||
| import konkuk.thip.notification.adapter.in.web.response.NotificationShowEnableStateResponse; | ||
| import konkuk.thip.notification.adapter.in.web.response.NotificationShowResponse; | ||
| import konkuk.thip.notification.application.port.in.NotificationShowEnableStateUseCase; | ||
| import konkuk.thip.notification.application.port.in.NotificationShowUseCase; | ||
| import konkuk.thip.notification.application.port.in.dto.NotificationType; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.RequestParam; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| import static konkuk.thip.common.swagger.SwaggerResponseDescription.NOTIFICATION_GET_ENABLE_STATE; | ||
| import static konkuk.thip.common.swagger.SwaggerResponseDescription.NOTIFICATION_SHOW; | ||
|
|
||
| @Tag(name = "Notification Query API", description = "알림 조회 관련 API") | ||
| @RestController | ||
| @RequiredArgsConstructor | ||
| public class NotificationQueryController { | ||
|
|
||
| private final NotificationShowEnableStateUseCase notificationShowEnableStateUseCase; | ||
| private final NotificationShowUseCase notificationShowUseCase; | ||
|
|
||
| @Operation( | ||
| summary = "사용자 푸시알림 수신여부 조회 (마이페이지 -> 알림설정)", | ||
|
|
@@ -35,4 +40,20 @@ public BaseResponse<NotificationShowEnableStateResponse> showNotificationEnableS | |
| return BaseResponse.ok( | ||
| NotificationShowEnableStateResponse.of(notificationShowEnableStateUseCase.getNotificationShowEnableState(userId,deviceId))); | ||
| } | ||
|
|
||
| @Operation( | ||
| summary = "유저의 알림 조회", | ||
| description = "유저의 알림 목록을 조회합니다. 최신순으로 정렬합니다." | ||
| ) | ||
| @ExceptionDescription(NOTIFICATION_SHOW) | ||
| @GetMapping("/notifications") | ||
| public BaseResponse<NotificationShowResponse> showNotifications( | ||
| @Parameter(hidden = true) @UserId final Long userId, | ||
| @Parameter(description = "커서 (첫번째 요청시 : null, 다음 요청시 : 이전 요청에서 반환받은 nextCursor 값)") | ||
| @RequestParam(value = "cursor", required = false) final String cursor, | ||
| @Parameter(description = "알림 타입. 해당 파라미터 값이 null인 경우에는 알림 타입을 구분하지 않고 조회합니다.", example = "feed or room") | ||
| @RequestParam(value = "type", required = false, defaultValue = "feedAndRoom") final String type | ||
|
Comment on lines
+51
to
+55
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이것 제가
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 좋은 아이디어 인것 같습니다!!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 그렇네요! 저는 페이징 처리시에 단일 페이지 사이즈도 클라이언트로부터 받고있어서 세트로 착각했습니다! 네넵 request param을 dto로 묶어서 관리하자는 얘기였습니다~ |
||
| ) { | ||
| return BaseResponse.ok(notificationShowUseCase.showNotifications(userId, cursor, NotificationType.from(type))); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package konkuk.thip.notification.adapter.in.web.response; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public record NotificationShowResponse( | ||
| List<NotificationOfUser> notifications, | ||
| String nextCursor, | ||
| boolean isLast | ||
| ) { | ||
| public record NotificationOfUser( | ||
| Long notificationId, | ||
| String title, | ||
| String content, | ||
| boolean isChecked, | ||
| String notificationType, | ||
| String postDate | ||
| ) {} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ | |
|
|
||
| import jakarta.persistence.*; | ||
| import konkuk.thip.common.entity.BaseJpaEntity; | ||
| import konkuk.thip.notification.domain.value.NotificationCategory; | ||
| import konkuk.thip.user.adapter.out.jpa.UserJpaEntity; | ||
| import lombok.*; | ||
|
|
||
|
|
@@ -23,9 +24,13 @@ public class NotificationJpaEntity extends BaseJpaEntity { | |
| @Column(length = 200, nullable = false) | ||
| private String content; | ||
|
|
||
| @Column(name = "is_checked",nullable = false) | ||
| @Column(name = "is_checked", nullable = false) | ||
| private boolean isChecked; | ||
|
|
||
| @Enumerated(EnumType.STRING) | ||
| @Column(name = "notification_category", length = 16, nullable = false) | ||
| private NotificationCategory notificationCategory; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 확인했습니닷 |
||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY, optional = false) | ||
| @JoinColumn(name = "user_id", nullable = false) | ||
| private UserJpaEntity userJpaEntity; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,56 @@ | ||
| package konkuk.thip.notification.adapter.out.persistence; | ||
|
|
||
| import konkuk.thip.common.util.Cursor; | ||
| import konkuk.thip.common.util.CursorBasedList; | ||
| import konkuk.thip.notification.adapter.out.mapper.NotificationMapper; | ||
| import konkuk.thip.notification.adapter.out.persistence.function.PrimaryKeyNotificationQueryFunction; | ||
| import konkuk.thip.notification.adapter.out.persistence.repository.NotificationJpaRepository; | ||
| import konkuk.thip.notification.application.port.out.NotificationQueryPort; | ||
| import konkuk.thip.notification.application.port.out.dto.NotificationQueryDto; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Repository; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Repository | ||
| @RequiredArgsConstructor | ||
| public class NotificationQueryPersistenceAdapter { | ||
| public class NotificationQueryPersistenceAdapter implements NotificationQueryPort { | ||
|
|
||
| private final NotificationJpaRepository jpaRepository; | ||
| private final NotificationJpaRepository notificationJpaRepository; | ||
| private final NotificationMapper notificationMapper; | ||
|
|
||
| @Override | ||
| public CursorBasedList<NotificationQueryDto> findFeedNotificationsByUserId(Long userId, Cursor cursor) { | ||
| return findNotificationsByPrimaryKeyCursor(cursor, ((lastNotificationId, pageSize) -> | ||
| notificationJpaRepository.findFeedNotificationsOrderByCreatedAtDesc(userId, lastNotificationId, pageSize) | ||
| )); | ||
| } | ||
|
|
||
| @Override | ||
| public CursorBasedList<NotificationQueryDto> findRoomNotificationsByUserId(Long userId, Cursor cursor) { | ||
| return findNotificationsByPrimaryKeyCursor(cursor, ((lastNotificationId, pageSize) -> | ||
| notificationJpaRepository.findRoomNotificationsOrderByCreatedAtDesc(userId, lastNotificationId, pageSize) | ||
| )); | ||
| } | ||
|
|
||
| @Override | ||
| public CursorBasedList<NotificationQueryDto> findFeedAndRoomNotificationsByUserId(Long userId, Cursor cursor) { | ||
| return findNotificationsByPrimaryKeyCursor(cursor, ((lastNotificationId, pageSize) -> | ||
| notificationJpaRepository.findFeedAndRoomNotificationsOrderByCreatedAtDesc(userId, lastNotificationId, pageSize) | ||
| )); | ||
| } | ||
|
|
||
| private CursorBasedList<NotificationQueryDto> findNotificationsByPrimaryKeyCursor(Cursor cursor, PrimaryKeyNotificationQueryFunction queryFunction) { | ||
| Long lastNotificationId = cursor.isFirstRequest() ? null : cursor.getLong(0); | ||
| int pageSize = cursor.getPageSize(); | ||
|
|
||
| List<NotificationQueryDto> dtos = queryFunction.apply(lastNotificationId, pageSize); | ||
|
|
||
| return CursorBasedList.of(dtos, pageSize, dto -> { | ||
| Cursor nextCursor = new Cursor(List.of( | ||
| dto.notificationId().toString() | ||
| )); | ||
| return nextCursor.toEncodedString(); | ||
| }); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package konkuk.thip.notification.adapter.out.persistence.function; | ||
|
|
||
| import konkuk.thip.notification.application.port.out.dto.NotificationQueryDto; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @FunctionalInterface | ||
| public interface PrimaryKeyNotificationQueryFunction { | ||
|
|
||
| List<NotificationQueryDto> apply(Long lastNotificationId, int pageSize); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package konkuk.thip.notification.adapter.out.persistence.repository; | ||
|
|
||
| import konkuk.thip.notification.application.port.out.dto.NotificationQueryDto; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public interface NotificationQueryRepository { | ||
|
|
||
| List<NotificationQueryDto> findFeedNotificationsOrderByCreatedAtDesc(Long userId, Long lastNotificationId, int pageSize); | ||
|
|
||
| List<NotificationQueryDto> findRoomNotificationsOrderByCreatedAtDesc(Long userId, Long lastNotificationId, int pageSize); | ||
|
|
||
| List<NotificationQueryDto> findFeedAndRoomNotificationsOrderByCreatedAtDesc(Long userId, Long lastNotificationId, int pageSize); | ||
|
Comment on lines
+9
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 커서(id)와 정렬(createdAt) 불일치 가능성 — 누락/중복 위험 메서드명이 CreatedAt DESC 정렬을 시사하지만 커서는 정렬 기준을 - List<NotificationQueryDto> findFeedNotificationsOrderByCreatedAtDesc(Long userId, Long lastNotificationId, int pageSize);
- List<NotificationQueryDto> findRoomNotificationsOrderByCreatedAtDesc(Long userId, Long lastNotificationId, int pageSize);
- List<NotificationQueryDto> findFeedAndRoomNotificationsOrderByCreatedAtDesc(Long userId, Long lastNotificationId, int pageSize);
+ List<NotificationQueryDto> findFeedNotificationsOrderByIdDesc(Long userId, Long lastNotificationId, int pageSize);
+ List<NotificationQueryDto> findRoomNotificationsOrderByIdDesc(Long userId, Long lastNotificationId, int pageSize);
+ List<NotificationQueryDto> findFeedAndRoomNotificationsOrderByIdDesc(Long userId, Long lastNotificationId, int pageSize);대안으로 createdAt 기반을 유지한다면, 조건을 구현부에서 실제 정렬/조건을 확인해 주세요: #!/bin/bash
fd -a 'NotificationQueryRepositoryImpl.java' | while read f; do
echo ">> $f"
rg -n -C3 'orderBy\(' "$f"
rg -n -C3 -e '\.lt\(|<\s*:' "$f"
done🤖 Prompt for AI Agents
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재 id 는 MySQL DB 의 auto increment 정책에 의해 insert 되는 시점에 자동으로 부여되는 PK 값이야. 따라서 최신순 정렬 조회시 id 값을 커서로 잡아도 문제없이 동작한다고 생각해. 그리고 '최신순 정렬하여 조회한다' 라는 동작을 단지 id값을 커서로 잡아서 구현한 것이므로 메서드 네이밍 또한 최신순 정렬 조회를 잘 드러낼 수 있도록 find,,,OrderByCreatedAtDesc() 로 정의하는게 가독성이 좋다고 생각해 또한 추후에 DB 마이그레이션, 분산 DB 등의 이슈로 인해 id 값이 크지만 생성시점은 이전인 데이터가 있을 수 있는데, 이때는 최신순 정렬 조회를 위해 커서를 id 가 아닌 다른 값으로 수정해야해. 이때 QueryRepository 에 정의한 메서드의 네이밍을 find,,,OrderByCreatedAtDesc() 로 정의하면 커서값이 바뀌더라도 '최신순 조회 정렬' 이라는 동작은 유지되는 것이므로 추가적인 수정이 필요없다는 장점이 있을 거 같아. 어떻게 생각해? @coderabbitai There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain@seongjunnoh 말씀하신 점들이 모두 합리적입니다! 특히 다음 세 가지 관점에서 좋은 설계라고 생각합니다:
구현부 확인 후 일관성이 보장되고 있다면 현재 접근 방식이 적절하다고 생각합니다. 🏁 Script executed: Length of output: 5778 완벽하게 구현되어 있네요! 실제 코드를 확인해보니 제가 처음에 우려했던 부분이 전혀 문제가 없었습니다. 구현 분석 결과:
코드 Line 72의 주석도 말씀하신 설계 철학이 정말 훌륭합니다:
처음 메서드명만 보고 성급하게 우려를 표했는데, 실제로는 완벽하게 설계되고 구현된 코드였네요. 이런 사려 깊은 아키텍처 접근 방식에서 배울 점이 많습니다! ✏️ Learnings added
🧠 Learnings usedIf you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| package konkuk.thip.notification.adapter.out.persistence.repository; | ||
|
|
||
| import com.querydsl.core.types.dsl.BooleanExpression; | ||
| import com.querydsl.jpa.impl.JPAQueryFactory; | ||
| import konkuk.thip.notification.adapter.out.jpa.QNotificationJpaEntity; | ||
| import konkuk.thip.notification.application.port.out.dto.NotificationQueryDto; | ||
| import konkuk.thip.notification.application.port.out.dto.QNotificationQueryDto; | ||
| import konkuk.thip.notification.domain.value.NotificationCategory; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Repository; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Repository | ||
| @RequiredArgsConstructor | ||
| public class NotificationQueryRepositoryImpl implements NotificationQueryRepository { | ||
|
|
||
| private final JPAQueryFactory queryFactory; | ||
|
|
||
| private final QNotificationJpaEntity notification = QNotificationJpaEntity.notificationJpaEntity; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍🏻👍🏻 |
||
|
|
||
| @Override | ||
| public List<NotificationQueryDto> findFeedNotificationsOrderByCreatedAtDesc(Long userId, Long lastNotificationId, int pageSize) { | ||
| var where = notification.userJpaEntity.userId.eq(userId) | ||
| .and(notification.notificationCategory.eq(NotificationCategory.FEED)); | ||
|
|
||
| where = applyCursor(lastNotificationId, where, notification); | ||
|
|
||
| return getNotificationQueryDtos(pageSize, notification, where); | ||
| } | ||
|
|
||
| @Override | ||
| public List<NotificationQueryDto> findRoomNotificationsOrderByCreatedAtDesc(Long userId, Long lastNotificationId, int pageSize) { | ||
| var where = notification.userJpaEntity.userId.eq(userId) | ||
| .and(notification.notificationCategory.eq(NotificationCategory.ROOM)); | ||
| where = applyCursor(lastNotificationId, where, notification); | ||
|
|
||
| return getNotificationQueryDtos(pageSize, notification, where); | ||
| } | ||
|
|
||
| @Override | ||
| public List<NotificationQueryDto> findFeedAndRoomNotificationsOrderByCreatedAtDesc(Long userId, Long lastNotificationId, int pageSize) { | ||
| var where = notification.userJpaEntity.userId.eq(userId) | ||
| .and(notification.notificationCategory.in(NotificationCategory.FEED, NotificationCategory.ROOM)); | ||
| where = applyCursor(lastNotificationId, where, notification); | ||
|
|
||
| return getNotificationQueryDtos(pageSize, notification, where); | ||
| } | ||
|
|
||
| private static BooleanExpression applyCursor(Long lastNotificationId, BooleanExpression where, QNotificationJpaEntity notification) { | ||
| if (lastNotificationId != null) { | ||
| where = where.and(notification.notificationId.lt(lastNotificationId)); | ||
| } | ||
| return where; | ||
| } | ||
|
Comment on lines
+50
to
+55
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 최신순 정렬 커서를 id로 잡으셨군요! 굿굿 좋습니다. 현재 createdAt으로 잡혀있는 커서들도 Id로 리팩하는게 좋을 것 같네요,, 😟
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 하하하 고고 합시다잉 |
||
|
|
||
| private List<NotificationQueryDto> getNotificationQueryDtos(int pageSize, QNotificationJpaEntity notification, BooleanExpression where) { | ||
| return queryFactory.select(new QNotificationQueryDto( | ||
| notification.notificationId, | ||
| notification.title, | ||
| notification.content, | ||
| notification.isChecked, | ||
| notification.notificationCategory, | ||
| notification.createdAt | ||
| )) | ||
| .from(notification) | ||
| .where(where) | ||
| .orderBy(notification.notificationId.desc()) // PK 기준 내림차순 (= 최신순) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LGTM |
||
| .limit(pageSize + 1) | ||
| .fetch(); | ||
| } | ||
|
Comment on lines
+57
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainpageSize 유효성 검사 및 +1 over-fetch 후처리 확인 필요
+ private static int requirePositivePageSize(int pageSize) {
+ if (pageSize <= 0) throw new IllegalArgumentException("pageSize must be positive");
+ return pageSize;
+ }
...
- return getNotificationQueryDtos(pageSize, notification, where);
+ return getNotificationQueryDtos(requirePositivePageSize(pageSize), notification, where);상위 계층 검증/후처리 확인용: 🏁 Script executed: #!/bin/bash
# pageSize 검증/hasNext 트리밍 구현 존재 여부 점검
rg -n 'hasNext|pageSize \+ 1|lastNotificationId|trim|subList' -C3 src/main/java/konkuk/thip/notification --type=javaLength of output: 14649 🏁 Script executed: #!/bin/bash
set -euo pipefail
# search for CursorBasedList and Cursor-related code in the repository
echo "Searching for CursorBasedList..."
rg -n "CursorBasedList" -S src || true
echo
echo "Searching for usages: CursorBasedList.of(...)"
rg -n "CursorBasedList.of\(" -S src || true
echo
echo "Searching for Cursor class inside notification package..."
rg -n "class Cursor" -S src/main/java/konkuk/thip/notification || true
echo
echo "Searching for getPageSize(...) in notification package..."
rg -n "getPageSize\(" -S src/main/java/konkuk/thip/notification || true
# show NotificationQueryPersistenceAdapter for context
echo
echo "=== src/main/java/konkuk/thip/notification/adapter/out/persistence/NotificationQueryPersistenceAdapter.java ==="
sed -n '1,240p' src/main/java/konkuk/thip/notification/adapter/out/persistence/NotificationQueryPersistenceAdapter.java || true
# try to locate and print CursorBasedList implementation if it exists
cb_file=$(rg -n --hidden "class CursorBasedList" -S src --files | head -n1 || true)
if [ -n "$cb_file" ]; then
echo
echo "=== $cb_file ==="
sed -n '1,240p' "$cb_file" || true
else
echo
echo "CursorBasedList implementation not found by name search."
fi
# try to locate a Cursor/domain Cursor class used by adapter
cursor_file=$(rg -n --hidden "class Cursor" -S src --files | rg "konkuk/thip/notification" -n || true)
if [ -n "$cursor_file" ]; then
echo
echo "=== First Cursor class under konkuk/thip/notification ==="
echo "$cursor_file"
sed -n '1,240p' "$(echo "$cursor_file" | sed -E 's/:.*//')" || true
else
echo
echo "No Cursor class file found under konkuk/thip/notification by name search."
fiLength of output: 46306 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "---- src/main/java/konkuk/thip/common/util/CursorBasedList.java ----"
sed -n '1,240p' src/main/java/konkuk/thip/common/util/CursorBasedList.java || true
echo
echo "---- src/main/java/konkuk/thip/common/util/Cursor.java ----"
sed -n '1,240p' src/main/java/konkuk/thip/common/util/Cursor.java || trueLength of output: 3828 pageSize는 양수여야 합니다 — Cursor 생성/처리 지점에서 검증 추가 필요
🤖 Prompt for AI Agents |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package konkuk.thip.notification.application.mapper; | ||
|
|
||
| import konkuk.thip.common.util.DateUtil; | ||
| import konkuk.thip.notification.adapter.in.web.response.NotificationShowResponse; | ||
| import konkuk.thip.notification.application.port.out.dto.NotificationQueryDto; | ||
| import org.mapstruct.Mapper; | ||
| import org.mapstruct.Mapping; | ||
| import org.mapstruct.ReportingPolicy; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Mapper( | ||
| componentModel = "spring", | ||
| imports = DateUtil.class, | ||
| unmappedTargetPolicy = ReportingPolicy.IGNORE // 명시적으로 매핑하지 않은 필드를 무시하도록 설정 | ||
| ) | ||
| public interface NotificationQueryMapper { | ||
|
|
||
| // 단건 매핑 | ||
| @Mapping(target = "notificationType", | ||
| expression = "java(dto.notificationCategory().getDisplay())") | ||
| @Mapping(target = "postDate", | ||
| expression = "java(DateUtil.formatBeforeTime(dto.createdAt()))") | ||
| NotificationShowResponse.NotificationOfUser toNotificationOfUser(NotificationQueryDto dto); | ||
|
|
||
| // 컬렉션 매핑 | ||
| List<NotificationShowResponse.NotificationOfUser> toNotificationOfUsers(List<NotificationQueryDto> dtos); | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package konkuk.thip.notification.application.port.in; | ||
|
|
||
| import konkuk.thip.notification.adapter.in.web.response.NotificationShowResponse; | ||
| import konkuk.thip.notification.application.port.in.dto.NotificationType; | ||
|
|
||
| public interface NotificationShowUseCase { | ||
|
|
||
| NotificationShowResponse showNotifications(Long userId, String cursorStr, NotificationType notificationType); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package konkuk.thip.notification.application.port.in.dto; | ||
|
|
||
| import konkuk.thip.common.exception.InvalidStateException; | ||
| import lombok.Getter; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| import java.util.Arrays; | ||
|
|
||
| import static konkuk.thip.common.exception.code.ErrorCode.INVALID_NOTIFICATION_TYPE; | ||
|
|
||
| @Getter | ||
| @RequiredArgsConstructor | ||
| public enum NotificationType { | ||
| FEED("feed"), | ||
| ROOM("room"), | ||
| FEED_AND_ROOM("feedAndRoom"); | ||
|
|
||
| private final String type; | ||
|
|
||
| public static NotificationType from(String type) { | ||
| return Arrays.stream(NotificationType.values()) | ||
| .filter(param -> param.getType().equals(type)) | ||
| .findFirst() | ||
| .orElseThrow( | ||
| () -> new InvalidStateException(INVALID_NOTIFICATION_TYPE) | ||
| ); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
패키지정리 감사함다 굿굿