Skip to content
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

[#33] 피드를 여행일지로 묶기 #34

Merged
merged 70 commits into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
5263c13
Feat: 일, 주, 월별 인기 피드 업데이트
jzakka Feb 5, 2024
37fffa3
Fix: zset조회 로직 수정
jzakka Feb 5, 2024
38b4e53
Fix: deleteByMemberAndFeed가 id를 받도록 수정
jzakka Feb 5, 2024
0bd5a48
Refactor: feedId를 인자로 받도록 수정
jzakka Feb 5, 2024
e9810dd
Refactor: 랭킹정보를 RankingController에서 제공
jzakka Feb 6, 2024
ee59359
Style: 테스트이름 변경
jzakka Feb 6, 2024
5d632ce
Feat: 권한이 필요한 경우 서비스에서 PostAuthroize로 체크
jzakka Feb 4, 2024
a5d1fdc
Feat: 좋아요 기능
jzakka Feb 4, 2024
59e31df
Feat: 댓글, 대댓글 작성
jzakka Feb 4, 2024
9f412ce
Delete: FeedService에서 rankingRepository에 대한 의존성 제거
jzakka Feb 6, 2024
2bf9736
Feat: 배치작업 구성
jzakka Feb 8, 2024
e24aa60
Test: 통합테스트 한 테스트로 묶음
jzakka Feb 8, 2024
51a51d0
Test: RankingRepositoryTest 통합테스트로 묶음
jzakka Feb 8, 2024
f4d1144
Test: 테스트 추가
jzakka Feb 8, 2024
bb90b84
Feat: 여행일지 작성
jzakka Feb 6, 2024
fd65df0
Feat: 기본 여행일지 제목 테스트
jzakka Feb 6, 2024
45369c1
Fix: 연관관계 설정 수정
jzakka Feb 6, 2024
51e31e4
충돌 수정
jzakka Feb 8, 2024
ac4725f
Test: 테스트 리팩토링
jzakka Feb 8, 2024
c314823
Feat: 여행일지에 섬네일 지정
jzakka Feb 8, 2024
8178870
Feat: 사용자의 여행일지 조회
jzakka Feb 8, 2024
1ec063f
Feat: 여행일지 취소
jzakka Feb 8, 2024
2ee6a56
Feat: 컨트롤러에 diaryService 연결
jzakka Feb 8, 2024
ca72473
Fix: geoApi 연결 설정 수정
jzakka Feb 8, 2024
8f3ed12
Package: batch 설정을 config패키지 밖으로 뺌
jzakka Feb 9, 2024
c4bae8f
Refactor: CacheKey 목적에 따라 분리
jzakka Feb 9, 2024
124e3e0
Refactor: 배치 파일을 잡 목적에 따라 분리
jzakka Feb 9, 2024
082c0e2
Feat: 잡이 프로필설정에 따라 생성되도록 설정
jzakka Feb 9, 2024
2e77773
Fix: 인기 피드 정보를 한 쿼리로 가져오도록 수정
jzakka Feb 9, 2024
eef16d7
Fix: 잡 이름 수정
jzakka Feb 9, 2024
2c0e01d
Feat: 인기 피드는 삭제 못하게 설정
jzakka Feb 9, 2024
f3b3cdf
Feat: 여행일지 작성
jzakka Feb 6, 2024
9a9fd5e
Feat: 기본 여행일지 제목 테스트
jzakka Feb 6, 2024
13cac6e
Fix: 연관관계 설정 수정
jzakka Feb 6, 2024
4448917
충돌 수정
jzakka Feb 8, 2024
d73b418
Test: 테스트 리팩토링
jzakka Feb 8, 2024
86c3e1e
Feat: 여행일지에 섬네일 지정
jzakka Feb 8, 2024
4717de0
Feat: 사용자의 여행일지 조회
jzakka Feb 8, 2024
2901c77
Feat: 여행일지 취소
jzakka Feb 8, 2024
859d3cf
Feat: 컨트롤러에 diaryService 연결
jzakka Feb 8, 2024
bab0db3
Fix: geoApi 연결 설정 수정
jzakka Feb 8, 2024
328a4cb
Refactor: 여행일지 썸네일이 GraphicContent를 참조하도록 수정
jzakka Feb 9, 2024
2271738
Style: ResponseEntity<Object> -> void
jzakka Feb 9, 2024
eeddc8f
Refactor: 페이지 반환값을 커스텀 페이지로 반환
jzakka Feb 9, 2024
49c20b3
Refactor: @PostAuthorize에서 검증역할을 도메인으로 옮김
jzakka Feb 9, 2024
c959510
충돌수정
jzakka Feb 9, 2024
8d106bf
Feat: 인기피드 저장시, `id`, `작성자`, `여행지역`을 저장하도록 수정
jzakka Feb 10, 2024
3155b96
Style: 메서드 이름 수정
jzakka Feb 10, 2024
8960803
Feat: 여행일지 작성
jzakka Feb 6, 2024
93b68b1
Feat: 기본 여행일지 제목 테스트
jzakka Feb 6, 2024
bcd6aa5
Fix: 연관관계 설정 수정
jzakka Feb 6, 2024
2ccd84c
충돌 수정
jzakka Feb 8, 2024
de7294b
Test: 테스트 리팩토링
jzakka Feb 8, 2024
9c2abb3
Feat: 여행일지에 섬네일 지정
jzakka Feb 8, 2024
a331ecd
Feat: 사용자의 여행일지 조회
jzakka Feb 8, 2024
2047a9c
Feat: 여행일지 취소
jzakka Feb 8, 2024
97e97be
Feat: 컨트롤러에 diaryService 연결
jzakka Feb 8, 2024
0b89cfa
Fix: geoApi 연결 설정 수정
jzakka Feb 8, 2024
39a8792
Refactor: 여행일지 썸네일이 GraphicContent를 참조하도록 수정
jzakka Feb 9, 2024
cc95e28
Style: ResponseEntity<Object> -> void
jzakka Feb 9, 2024
e060707
Refactor: 페이지 반환값을 커스텀 페이지로 반환
jzakka Feb 9, 2024
7286be6
Refactor: @PostAuthorize에서 검증역할을 도메인으로 옮김
jzakka Feb 9, 2024
29119ec
Feat: 기본 여행일지 제목 테스트
jzakka Feb 6, 2024
28a94d6
충돌 수정
jzakka Feb 8, 2024
248e3b3
Test: 테스트 리팩토링
jzakka Feb 8, 2024
ab3e2db
Feat: 사용자의 여행일지 조회
jzakka Feb 8, 2024
938fb27
Feat: 컨트롤러에 diaryService 연결
jzakka Feb 8, 2024
6e52db5
충돌수정
jzakka Feb 10, 2024
341d0d4
충돌수정
jzakka Feb 10, 2024
c7a99aa
충돌수정
jzakka Feb 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/main/java/com/stoury/controller/CommentController.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public List<ChildCommentResponse> getChildComments(@PathVariable Long commentId,
}

@DeleteMapping("/comments/{commentId}")
public void deleteComment(@PathVariable Long commentId) {
commentService.deleteComment(commentId);
public void deleteComment(@AuthenticationPrincipal AuthenticatedMember authenticatedMember,
@PathVariable Long commentId) {
commentService.deleteCommentIfOwner(commentId, authenticatedMember.getId());
}
}
6 changes: 4 additions & 2 deletions src/main/java/com/stoury/controller/DiaryController.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ public DiaryPageResponse getMemberDiaries(@PathVariable Long memberId,
}

@DeleteMapping("/diaries/{diaryId}")
public void cancelDiary(@PathVariable Long diaryId) {
diaryService.cancelDiary(diaryId);
public void cancelDiary(
@AuthenticationPrincipal AuthenticatedMember authenticatedMember,
@PathVariable Long diaryId) {
diaryService.cancelDiaryIfOwner(diaryId, authenticatedMember.getId());
}
}
11 changes: 7 additions & 4 deletions src/main/java/com/stoury/controller/FeedController.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ public List<FeedResponse> getFeedsOfMember(@PathVariable Long memberId,
}

@PutMapping("/feeds/{feedId}")
public FeedResponse updateFeed(@PathVariable Long feedId, @RequestBody FeedUpdateRequest feedUpdateRequest) {
return feedService.updateFeed(feedId, feedUpdateRequest);
public FeedResponse updateFeed(@AuthenticationPrincipal AuthenticatedMember authenticatedMember,
@PathVariable Long feedId,
@RequestBody FeedUpdateRequest feedUpdateRequest) {
return feedService.updateFeedIfOwner(feedId, feedUpdateRequest, authenticatedMember.getId());
}

@DeleteMapping("/feeds/{feedId}")
public void deleteFeed(@PathVariable Long feedId) {
feedService.deleteFeed(feedId);
public void deleteFeed(@AuthenticationPrincipal AuthenticatedMember authenticatedMember,
@PathVariable Long feedId) {
feedService.deleteFeedIfOwner(feedId, authenticatedMember.getId());
}
}
20 changes: 16 additions & 4 deletions src/main/java/com/stoury/service/CommentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.stoury.dto.comment.CommentResponse;
import com.stoury.exception.CommentCreateException;
import com.stoury.exception.CommentSearchException;
import com.stoury.exception.authentication.NotAuthorizedException;
import com.stoury.exception.feed.FeedSearchException;
import com.stoury.exception.member.MemberSearchException;
import com.stoury.repository.CommentRepository;
Expand All @@ -16,7 +17,6 @@
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -85,13 +85,25 @@ public List<ChildCommentResponse> getChildComments(Long parentCommentId, LocalDa
orderThan, pageable));
}

@PostAuthorize("returnObject.writer.id == authentication.principal.id")
@Transactional
public CommentResponse deleteComment(Long commentId) {
protected CommentResponse deleteComment(Long commentId) {
Comment comment = commentRepository.findById(Objects.requireNonNull(commentId))
.orElseThrow(CommentSearchException::new);

comment.delete();
return CommentResponse.from(comment);
}

@Transactional
public CommentResponse deleteCommentIfOwner(Long commentId, Long memberId) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍
방향은 잘 맞은 것 같네요!
하지만 요 검증로직 ( 변경 시 멤버 확인 )은 entity로 들어가는게 맞을 것 같아요..!
도메인에서 처리한다 라고 하면 Entity 클래스에서 처리한다 라고 이해해주시면 될 것 같습니다 ~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵! 다음 PR올릴때 수정해두겠습니다

Comment comment = commentRepository.findById(Objects.requireNonNull(commentId))
.orElseThrow(CommentSearchException::new);
if(isNotOwner(memberId, comment)){
throw new NotAuthorizedException();
}
return deleteComment(commentId);
}

private boolean isNotOwner(Long memberId, Comment comment) {
return !comment.getMember().getId().equals(memberId);
}
}
23 changes: 18 additions & 5 deletions src/main/java/com/stoury/service/DiaryService.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
import com.stoury.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.domain.*;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
Expand Down Expand Up @@ -115,13 +117,24 @@ public DiaryPageResponse getMemberDiaries(Long memberId, int pageNo) {
return DiaryPageResponse.from(diaryPage);
}

@PostAuthorize("returnObject.memberId() == authentication.principal.id")
@Transactional
public SimpleDiaryResponse cancelDiary(Long diaryId) {
protected SimpleDiaryResponse cancelDiary(Long diaryId) {
Diary toCancelDiary = diaryRepository.findById(diaryId).orElseThrow(DiarySearchException::new);

diaryRepository.delete(toCancelDiary);

return SimpleDiaryResponse.from(toCancelDiary);
}

@Transactional
public SimpleDiaryResponse cancelDiaryIfOwner(Long diaryId, Long memberId) {
Diary toCancelDiary = diaryRepository.findById(diaryId).orElseThrow(DiarySearchException::new);
if (isNotOwner(memberId, toCancelDiary)) {
throw new NotAuthorizedException();
}
return cancelDiary(diaryId);
}

private boolean isNotOwner(Long memberId, Diary toCancelDiary) {
return !toCancelDiary.getMember().getId().equals(memberId);
}
}
40 changes: 31 additions & 9 deletions src/main/java/com/stoury/service/FeedService.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.stoury.dto.feed.LocationResponse;
import com.stoury.event.GraphicDeleteEvent;
import com.stoury.event.GraphicSaveEvent;
import com.stoury.exception.authentication.NotAuthorizedException;
import com.stoury.exception.feed.FeedCreateException;
import com.stoury.exception.feed.FeedDeleteException;
import com.stoury.exception.feed.FeedSearchException;
Expand All @@ -26,7 +27,6 @@
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -41,7 +41,7 @@
@RequiredArgsConstructor
public class FeedService {
@Value("${path-prefix}")
public String pathPrefix;
public String pathPrefix;
public static final int PAGE_SIZE = 10;
private final FeedRepository feedRepository;
private final MemberRepository memberRepository;
Expand Down Expand Up @@ -145,9 +145,7 @@ private FeedResponse toFeedResponse(Feed feed) {
return FeedResponse.from(feed, likes);
}

@PostAuthorize("returnObject.writer().id() == authentication.principal.id")
@Transactional
public FeedResponse updateFeed(Long feedId, FeedUpdateRequest feedUpdateRequest) {
protected FeedResponse updateFeed(Long feedId, FeedUpdateRequest feedUpdateRequest) {
Feed feed = feedRepository.findById(Objects.requireNonNull(feedId))
.orElseThrow(FeedSearchException::new);

Expand All @@ -162,6 +160,22 @@ public FeedResponse updateFeed(Long feedId, FeedUpdateRequest feedUpdateRequest)
return FeedResponse.from(feed, likeRepository.getCountByFeedId(feed.getId().toString()));
}

@Transactional
public FeedResponse updateFeedIfOwner(Long feedId, FeedUpdateRequest feedUpdateRequest, Long memberId) {
Feed feed = feedRepository.findById(Objects.requireNonNull(feedId))
.orElseThrow(FeedSearchException::new);

if (isNotOwner(feed, memberId)) {
throw new NotAuthorizedException();
}

return updateFeed(feedId, feedUpdateRequest);
}

private boolean isNotOwner(Feed feed, Long memberId) {
return !feed.getMember().getId().equals(memberId);
}

private void publishDeleteFileEvents(List<GraphicContent> beforeDeleteGraphicContents,
List<GraphicContent> afterDeleteGraphicContents) {
for (GraphicContent beforeDeleteGraphicContent : beforeDeleteGraphicContents) {
Expand All @@ -171,16 +185,24 @@ private void publishDeleteFileEvents(List<GraphicContent> beforeDeleteGraphicCon
}
}

@PostAuthorize("returnObject.writer().id() == authentication.name")
@Transactional
public FeedResponse deleteFeed(Long feedId) {
protected void deleteFeed(Long feedId) {
if (rankingService.isRankedFeed(feedId)) {
throw new FeedDeleteException("As the feed is in hot feeds, cannot delete this.");
}
Feed feed = feedRepository.findById(Objects.requireNonNull(feedId))
.orElseThrow(FeedSearchException::new);
feedRepository.delete(feed);
return FeedResponse.from(feed, 0);
}

@Transactional
public void deleteFeedIfOwner(Long feedId, Long memberId) {
Feed feed = feedRepository.findById(Objects.requireNonNull(feedId))
.orElseThrow(FeedSearchException::new);

if (isNotOwner(feed, memberId)) {
throw new NotAuthorizedException();
}
deleteFeed(feedId);
}

@Transactional(readOnly = true)
Expand Down