From a46396df44b3d5d97070a0544148ff9810939bef Mon Sep 17 00:00:00 2001 From: rladmstn Date: Wed, 6 Nov 2024 01:13:10 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat=20:=20=EA=B3=B5=EC=A7=80=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20API=EC=97=90=EC=84=9C=20=EC=9D=BD=EC=9D=8C=20?= =?UTF-8?q?=ED=91=9C=EC=8B=9C=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/notice/domain/NoticeRead.java | 32 +++++++++++++++++++ .../repository/NoticeReadRepository.java | 11 +++++++ .../feature/notice/service/NoticeService.java | 13 ++++++++ 3 files changed, 56 insertions(+) create mode 100644 src/main/java/com/gamzabat/algohub/feature/notice/domain/NoticeRead.java create mode 100644 src/main/java/com/gamzabat/algohub/feature/notice/repository/NoticeReadRepository.java diff --git a/src/main/java/com/gamzabat/algohub/feature/notice/domain/NoticeRead.java b/src/main/java/com/gamzabat/algohub/feature/notice/domain/NoticeRead.java new file mode 100644 index 00000000..3e9da497 --- /dev/null +++ b/src/main/java/com/gamzabat/algohub/feature/notice/domain/NoticeRead.java @@ -0,0 +1,32 @@ +package com.gamzabat.algohub.feature.notice.domain; + +import com.gamzabat.algohub.feature.user.domain.User; + +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor +public class NoticeRead { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @ManyToOne(fetch = FetchType.LAZY) + private Notice notice; + @ManyToOne(fetch = FetchType.LAZY) + private User user; + + @Builder + public NoticeRead(Notice notice, User user) { + this.notice = notice; + this.user = user; + } +} diff --git a/src/main/java/com/gamzabat/algohub/feature/notice/repository/NoticeReadRepository.java b/src/main/java/com/gamzabat/algohub/feature/notice/repository/NoticeReadRepository.java new file mode 100644 index 00000000..7161a670 --- /dev/null +++ b/src/main/java/com/gamzabat/algohub/feature/notice/repository/NoticeReadRepository.java @@ -0,0 +1,11 @@ +package com.gamzabat.algohub.feature.notice.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.gamzabat.algohub.feature.notice.domain.Notice; +import com.gamzabat.algohub.feature.notice.domain.NoticeRead; +import com.gamzabat.algohub.feature.user.domain.User; + +public interface NoticeReadRepository extends JpaRepository { + boolean existsByNoticeAndUser(Notice notice, User user); +} diff --git a/src/main/java/com/gamzabat/algohub/feature/notice/service/NoticeService.java b/src/main/java/com/gamzabat/algohub/feature/notice/service/NoticeService.java index cf136ba9..50bdf958 100644 --- a/src/main/java/com/gamzabat/algohub/feature/notice/service/NoticeService.java +++ b/src/main/java/com/gamzabat/algohub/feature/notice/service/NoticeService.java @@ -18,11 +18,13 @@ import com.gamzabat.algohub.feature.group.studygroup.repository.GroupMemberRepository; import com.gamzabat.algohub.feature.group.studygroup.repository.StudyGroupRepository; import com.gamzabat.algohub.feature.notice.domain.Notice; +import com.gamzabat.algohub.feature.notice.domain.NoticeRead; import com.gamzabat.algohub.feature.notice.dto.CreateNoticeRequest; import com.gamzabat.algohub.feature.notice.dto.GetNoticeResponse; import com.gamzabat.algohub.feature.notice.dto.UpdateNoticeRequest; import com.gamzabat.algohub.feature.notice.exception.NoticeValidationException; import com.gamzabat.algohub.feature.notice.repository.NoticeCommentRepository; +import com.gamzabat.algohub.feature.notice.repository.NoticeReadRepository; import com.gamzabat.algohub.feature.notice.repository.NoticeRepository; import com.gamzabat.algohub.feature.user.domain.User; @@ -38,6 +40,7 @@ public class NoticeService { private final NoticeCommentRepository noticeCommentRepository; private final StudyGroupRepository studyGroupRepository; private final GroupMemberRepository groupMemberRepository; + private final NoticeReadRepository noticeReadRepository; @Transactional public void createNotice(@AuthedUser User user, CreateNoticeRequest request) { @@ -67,6 +70,8 @@ public GetNoticeResponse getNotice(@AuthedUser User user, Long noticeId) { if (!groupMemberRepository.existsByUserAndStudyGroup(user, notice.getStudyGroup())) throw new StudyGroupValidationException(HttpStatus.FORBIDDEN.value(), "참여하지 않은 스터디 그룹 입니다."); + readNotice(user, notice); + log.info("success to get notice"); return GetNoticeResponse.builder() .author(notice.getAuthor().getNickname()) @@ -121,4 +126,12 @@ private void validateStudyGroupExists(Notice notice) { .orElseThrow(() -> new StudyGroupValidationException(HttpStatus.BAD_REQUEST.value(), "존재하지 않는 스터디 그룹입니다")); } + private void readNotice(User user, Notice notice) { + if (!noticeReadRepository.existsByNoticeAndUser(notice, user)) { + noticeReadRepository.save( + NoticeRead.builder().notice(notice).user(user).build() + ); + } + log.info("success to read notice. userId: {}, noticeId: {}", user.getId(), notice.getId()); + } } From 7ca8580556797deef6ad2201878956e11b348c2b Mon Sep 17 00:00:00 2001 From: rladmstn Date: Wed, 6 Nov 2024 01:36:37 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat=20:=20=EA=B3=B5=EC=A7=80=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20=EC=9D=BD=EC=9D=8C?= =?UTF-8?q?=20=EC=97=AC=EB=B6=80=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 --- .../algohub/feature/notice/dto/GetNoticeResponse.java | 7 ++++--- .../algohub/feature/notice/service/NoticeService.java | 5 ++++- .../com/gamzabat/algohub/service/NoticeServiceTest.java | 6 ++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/gamzabat/algohub/feature/notice/dto/GetNoticeResponse.java b/src/main/java/com/gamzabat/algohub/feature/notice/dto/GetNoticeResponse.java index 85b0606e..0990a907 100644 --- a/src/main/java/com/gamzabat/algohub/feature/notice/dto/GetNoticeResponse.java +++ b/src/main/java/com/gamzabat/algohub/feature/notice/dto/GetNoticeResponse.java @@ -10,16 +10,17 @@ public record GetNoticeResponse(String author, Long noticeId, String noticeContent, String noticeTitle, - String createAt) { + String createAt, + boolean isRead) { - public static GetNoticeResponse toDTO(Notice notice) { + public static GetNoticeResponse toDTO(Notice notice, boolean isRead) { return GetNoticeResponse.builder() .author(notice.getAuthor().getNickname()) .noticeId(notice.getId()) .noticeTitle(notice.getTitle()) .noticeContent(notice.getContent()) .createAt(DateFormatUtil.formatDate(notice.getCreatedAt().toLocalDate())) + .isRead(isRead) .build(); - } } diff --git a/src/main/java/com/gamzabat/algohub/feature/notice/service/NoticeService.java b/src/main/java/com/gamzabat/algohub/feature/notice/service/NoticeService.java index 50bdf958..477cb3b9 100644 --- a/src/main/java/com/gamzabat/algohub/feature/notice/service/NoticeService.java +++ b/src/main/java/com/gamzabat/algohub/feature/notice/service/NoticeService.java @@ -79,6 +79,7 @@ public GetNoticeResponse getNotice(@AuthedUser User user, Long noticeId) { .noticeTitle(notice.getTitle()) .noticeContent(notice.getContent()) .createAt(DateFormatUtil.formatDate(notice.getCreatedAt().toLocalDate())) + .isRead(noticeReadRepository.existsByNoticeAndUser(notice, user)) .build(); } @@ -90,7 +91,9 @@ public List getNoticeList(@AuthedUser User user, Long studyGr throw new GroupMemberValidationException(HttpStatus.FORBIDDEN.value(), "참여하지 않은 스터디 그룹입니다"); List list = noticeRepository.findAllByStudyGroup(studyGroup); - List result = list.stream().map(GetNoticeResponse::toDTO).toList(); + List result = list.stream().map( + notice -> GetNoticeResponse.toDTO(notice, noticeReadRepository.existsByNoticeAndUser(notice, user)) + ).toList(); log.info("success to get notice list"); return result; } diff --git a/src/test/java/com/gamzabat/algohub/service/NoticeServiceTest.java b/src/test/java/com/gamzabat/algohub/service/NoticeServiceTest.java index fdb2162d..a62927be 100644 --- a/src/test/java/com/gamzabat/algohub/service/NoticeServiceTest.java +++ b/src/test/java/com/gamzabat/algohub/service/NoticeServiceTest.java @@ -31,11 +31,13 @@ import com.gamzabat.algohub.feature.group.studygroup.repository.GroupMemberRepository; import com.gamzabat.algohub.feature.group.studygroup.repository.StudyGroupRepository; import com.gamzabat.algohub.feature.notice.domain.Notice; +import com.gamzabat.algohub.feature.notice.domain.NoticeRead; import com.gamzabat.algohub.feature.notice.dto.CreateNoticeRequest; import com.gamzabat.algohub.feature.notice.dto.GetNoticeResponse; import com.gamzabat.algohub.feature.notice.dto.UpdateNoticeRequest; import com.gamzabat.algohub.feature.notice.exception.NoticeValidationException; import com.gamzabat.algohub.feature.notice.repository.NoticeCommentRepository; +import com.gamzabat.algohub.feature.notice.repository.NoticeReadRepository; import com.gamzabat.algohub.feature.notice.repository.NoticeRepository; import com.gamzabat.algohub.feature.notice.service.NoticeService; import com.gamzabat.algohub.feature.user.domain.User; @@ -52,6 +54,8 @@ public class NoticeServiceTest { GroupMemberRepository groupMemberRepository; @Mock private NoticeCommentRepository noticeCommentRepository; + @Mock + private NoticeReadRepository noticeReadRepository; @Captor private ArgumentCaptor noticeCaptor; @@ -180,6 +184,7 @@ void getNoticeSuccess_1() { assertThat(response.noticeTitle()).isEqualTo("title"); assertThat(response.createAt()).isEqualTo(DateFormatUtil.formatDate(LocalDateTime.now().toLocalDate())); assertThat(response.noticeId()).isEqualTo(1000L); + verify(noticeReadRepository, times(1)).save(any(NoticeRead.class)); } @Test @@ -241,6 +246,7 @@ void getNoticeListSuccess_1() { for (int i = 0; i < 20; i++) { assertThat(result.get(i).noticeContent()).isEqualTo("content" + i); assertThat(result.get(i).noticeTitle()).isEqualTo("title" + i); + assertThat(result.get(i).isRead()).isFalse(); } } From b9b215d294f49358f9ce900acfabb8369a1f543c Mon Sep 17 00:00:00 2001 From: rladmstn Date: Wed, 6 Nov 2024 01:40:53 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat=20:=20@JoinColumn=20=EB=88=84=EB=9D=BD?= =?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 --- .../com/gamzabat/algohub/feature/notice/domain/NoticeRead.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/gamzabat/algohub/feature/notice/domain/NoticeRead.java b/src/main/java/com/gamzabat/algohub/feature/notice/domain/NoticeRead.java index 3e9da497..70ee20f5 100644 --- a/src/main/java/com/gamzabat/algohub/feature/notice/domain/NoticeRead.java +++ b/src/main/java/com/gamzabat/algohub/feature/notice/domain/NoticeRead.java @@ -7,6 +7,7 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import lombok.Builder; import lombok.Getter; @@ -20,8 +21,10 @@ public class NoticeRead { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "notice_id") private Notice notice; @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") private User user; @Builder From d126d95d2e17a1ffd66c4f0266dd55c3cce22b64 Mon Sep 17 00:00:00 2001 From: rladmstn Date: Fri, 8 Nov 2024 14:52:00 +0900 Subject: [PATCH 4/4] =?UTF-8?q?refactor=20:=20=EA=B3=B5=EC=A7=80=20?= =?UTF-8?q?=EC=9D=BD=EC=9D=8C=20=ED=91=9C=EC=8B=9C=20=EB=A9=94=EC=86=8C?= =?UTF-8?q?=EB=93=9C=20=EB=A6=AC=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B0=8F=20?= =?UTF-8?q?=EC=BD=94=EB=A9=98=ED=8A=B8=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../algohub/feature/notice/service/NoticeService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/gamzabat/algohub/feature/notice/service/NoticeService.java b/src/main/java/com/gamzabat/algohub/feature/notice/service/NoticeService.java index 477cb3b9..4c869f63 100644 --- a/src/main/java/com/gamzabat/algohub/feature/notice/service/NoticeService.java +++ b/src/main/java/com/gamzabat/algohub/feature/notice/service/NoticeService.java @@ -70,7 +70,7 @@ public GetNoticeResponse getNotice(@AuthedUser User user, Long noticeId) { if (!groupMemberRepository.existsByUserAndStudyGroup(user, notice.getStudyGroup())) throw new StudyGroupValidationException(HttpStatus.FORBIDDEN.value(), "참여하지 않은 스터디 그룹 입니다."); - readNotice(user, notice); + markNoticeAsRead(user, notice); log.info("success to get notice"); return GetNoticeResponse.builder() @@ -79,7 +79,7 @@ public GetNoticeResponse getNotice(@AuthedUser User user, Long noticeId) { .noticeTitle(notice.getTitle()) .noticeContent(notice.getContent()) .createAt(DateFormatUtil.formatDate(notice.getCreatedAt().toLocalDate())) - .isRead(noticeReadRepository.existsByNoticeAndUser(notice, user)) + .isRead(true) .build(); } @@ -129,7 +129,7 @@ private void validateStudyGroupExists(Notice notice) { .orElseThrow(() -> new StudyGroupValidationException(HttpStatus.BAD_REQUEST.value(), "존재하지 않는 스터디 그룹입니다")); } - private void readNotice(User user, Notice notice) { + private void markNoticeAsRead(User user, Notice notice) { if (!noticeReadRepository.existsByNoticeAndUser(notice, user)) { noticeReadRepository.save( NoticeRead.builder().notice(notice).user(user).build()