Skip to content

Commit

Permalink
Merge branch 'dev-be' into be/feat/#93-좋아요-조회
Browse files Browse the repository at this point in the history
  • Loading branch information
devbattery committed Dec 6, 2023
2 parents 205a035 + 56a7a88 commit 3df0a04
Show file tree
Hide file tree
Showing 85 changed files with 1,615 additions and 577 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ build
/be/out/
/be/src/main/resources/application-aws.yml
/be/src/main/resources/application-jwt.yml
/be/src/test/resources/application-aws.yml
/be/src/test/resources/application-jwt.yml
/be/src/main/resources/static
102 changes: 53 additions & 49 deletions be/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -238,54 +238,6 @@ operation::fetchMemberFeedsEmpty_success[snippets='http-response']

operation::fetchAllTasteMoods_success[snippets='http-request,http-response']

[[mood]]
== 무드

=== 무드 조회

==== 성공

operation::fetchSliceMood_success[snippets='http-request,http-response']

==== 성공 - 페이징

operation::fetchSliceMood_whenPageAndSizeExists_success[snippets='http-request,http-response']

=== 무드 랜덤 조회

==== 성공

operation::fetchRandomMood_success[snippets='http-request,http-response']

==== 성공 - DB에 무드가 없을 때

operation::fetchRandomMood_whenMoodNotExists_success[snippets='http-response']

==== 요청의 쿼리 파라미터에 count가 없을 때

operation::fetchRandomMood_failedByCountNull[snippets='http-request,http-response']

=== 무드 추가

==== 성공

operation::registerMood_success[snippets='http-request,http-response']

==== 이미 존재하는 무드일 때

operation::registerMood_failedByDuplicateName[snippets='http-response']

==== 요청으로 받은 무드가 null일 때

operation::registerMood_failedByNullName[snippets='http-response']

=== 개별 무드 조회

==== 성공

operation::findMoodyById_success[snippets='http-request,http-response']


[[notification]]
== 알람

Expand Down Expand Up @@ -337,7 +289,7 @@ operation::notification_delete_notification_list_success[snippets='http-request,

==== 성공

operation::notificaiton_setting_request_success[snippets='http-request,http-response']
operation::notification_setting_request_success[snippets='http-request,http-response']

=== 알람 설정 변경

Expand All @@ -350,3 +302,55 @@ operation::notification_setting_update_success[snippets='http-request,http-respo
=== 알람 실시간 전송

operation::sse_request_success[snippets='http-request,http-response']

[[image]]
== 이미지

=== 이미지 업로드 공통

요청 body에 이미지 파일이 깨져서 나와서 curl입니다

==== 이미지 크기가 2.8MB보다 클 때

operation::uploadFeedImageOverSizeLimit_Fail[snippets='http-response']

==== 지원되지 않는 형식의 이미지일 때

현재 jpeg(jpg), png 지원됩니다

operation::uploadFeedImageWithUnsupportedFormat_Fail[snippets='http-response']

=== 회원 이미지 업로드

==== 성공

operation::uploadMemberProfileImage_success[snippets='curl-request,http-response']

=== 피드 이미지 업로드

==== 성공

operation::uploadFeedImage_success[snippets='curl-request,http-response']

==== 존재하지 않는 피드 아이디일 때

operation::uploadFeedImage_failedByFeedNotFound[snippets='http-response']

==== 현재 로그인한 회원이 피드 작성자가 아닐 때

operation::uploadFeedImage_failedByUnauthorized[snippets='http-response']

=== 이미지 삭제

==== 성공

operation::deleteFeedImage_success[snippets='http-request,http-response']

==== 존재하지 않는 이미지 id일 때

operation::deleteFeedImage_failedByNotExistId[snippets='http-response']

==== 현재 로그인한 회원이 업로드한 이미지가 아닐 때

operation::deleteFeedImage_failedByUnAuthorized[snippets='http-response']

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.foodymoody.be.comment.application.dto.response.MemberReplySummary;
import com.foodymoody.be.comment.application.dto.response.MemberReplySummaryResponse;
import com.foodymoody.be.comment.domain.entity.CommentId;
import com.foodymoody.be.comment.domain.entity.Reply;
import com.foodymoody.be.comment.domain.entity.ReplyId;
import com.foodymoody.be.comment.domain.repository.ReplyRepository;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -35,4 +36,9 @@ public Slice<MemberReplySummaryResponse> fetchAllReplyByMemberId(CommentId comme
public void validate(ReplyId replyId) {
replyRepository.existsById(replyId);
}

public Reply fetchById(ReplyId replyId) {
return replyRepository.findById(replyId)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 댓글입니다."));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void addReply(Reply reply) {
}

private Event toCommentRepliedAddedEvent(Reply reply) {
return CommentRepliedAddedEvent.of(id, reply.getId(), memberId, reply.getMemberId(), reply.getContent(),
return CommentRepliedAddedEvent.of(id, reply.getId(), memberId, reply.getMemberId(), reply.getContent(), feedId,
reply.getCreatedAt());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static CommentAddedEvent of(
return new CommentAddedEvent(
feedId,
content,
NotificationType.COMMENT_ADDED,
NotificationType.COMMENT_ADDED_EVENT,
commentId,
memberId,
createdAt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,24 @@ public class CommentRepliedAddedEvent implements Event {
private ReplyId replyId;
private String toMemberId;
private String fromMemberId;
private String feedId;
private String content;
private LocalDateTime createdAt;

private CommentRepliedAddedEvent(CommentId id, ReplyId replyId, String toMemberId, String fromMemberId,
String content,
String feedId, String content,
LocalDateTime createdAt) {
this.replyId = replyId;
this.commentId = id;
this.toMemberId = toMemberId;
this.fromMemberId = fromMemberId;
this.feedId = feedId;
this.content = content;
this.createdAt = createdAt;
}

public static CommentRepliedAddedEvent of(CommentId id, ReplyId replyId, String toMemberId, String fromMemberId,
String content,
LocalDateTime createdAt) {
return new CommentRepliedAddedEvent(id, replyId, toMemberId, fromMemberId, content, createdAt);
String content, String feedId, LocalDateTime createdAt) {
return new CommentRepliedAddedEvent(id, replyId, toMemberId, fromMemberId, feedId, content, createdAt);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.foodymoody.be.comment.application.dto.response.MemberReplySummary;
import com.foodymoody.be.comment.domain.entity.CommentId;
import com.foodymoody.be.comment.domain.entity.Reply;
import com.foodymoody.be.comment.domain.entity.ReplyId;
import java.util.Optional;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;

Expand All @@ -13,4 +15,6 @@ public interface ReplyRepository {
Slice<MemberReplySummary> findByCommentIdAndMemberId(CommentId commentId, String memberId, Pageable pageable);

boolean existsById(ReplyId replyId);

Optional<Reply> findById(ReplyId replyId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import com.foodymoody.be.comment.application.dto.response.MemberReplySummary;
import com.foodymoody.be.comment.domain.entity.CommentId;
import com.foodymoody.be.comment.domain.entity.Reply;
import com.foodymoody.be.comment.domain.entity.ReplyId;
import com.foodymoody.be.comment.domain.repository.ReplyRepository;
import com.foodymoody.be.comment.infra.persistence.jpa.ReplyJpaRepository;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
Expand All @@ -31,4 +33,9 @@ public Slice<MemberReplySummary> findByCommentIdAndMemberId(CommentId commentId,
public boolean existsById(ReplyId replyId) {
return replyJpaRepository.existsById(replyId);
}

@Override
public Optional<Reply> findById(ReplyId replyId) {
return replyJpaRepository.findById(replyId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.foodymoody.be.comment_heart.domain.CommentHeartId;
import com.foodymoody.be.comment_heart.domain.CommentHeartIdFactory;
import com.foodymoody.be.comment_heart.domain.CommentHeartRepository;
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -16,10 +17,11 @@ public class CommentHeartWriteService {
private final CommentHeartRepository commentHeartRepository;

@Transactional
public void registerCommentHeart(CommentId commentId, String memberId) {
public CommentHeart registerCommentHeart(CommentId commentId, String memberId) {
CommentHeartId commentHeartId = CommentHeartIdFactory.newId();
CommentHeart commentHeart = new CommentHeart(commentHeartId, commentId, memberId);
commentHeartRepository.save(commentHeart);
LocalDateTime now = LocalDateTime.now();
CommentHeart commentHeart = new CommentHeart(commentHeartId, commentId, memberId, now, now);
return commentHeartRepository.save(commentHeart);
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.foodymoody.be.comment_heart.domain;

import com.foodymoody.be.comment.domain.entity.CommentId;
import java.time.LocalDateTime;
import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
Expand All @@ -17,10 +18,23 @@ public class CommentHeart {
@AttributeOverride(name = "value", column = @Column(name = "comment_id"))
private CommentId commentId;
private String memberId;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;

public CommentHeart(CommentHeartId id, CommentId commentId, String memberId) {
public CommentHeart(CommentHeartId id, CommentId commentId, String memberId, LocalDateTime createdAt,
LocalDateTime updatedAt) {
this.id = id;
this.commentId = commentId;
this.memberId = memberId;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}

public LocalDateTime getCreatedAt() {
return createdAt;
}

public String getMemberId() {
return memberId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.foodymoody.be.comment_heart.infra.usecase;

import com.foodymoody.be.comment.domain.entity.CommentId;
import com.foodymoody.be.common.event.Event;
import com.foodymoody.be.common.event.NotificationType;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Getter
public class CommentHeartAddedEvent implements Event {

private final String feedId;
private final String content;
private final NotificationType notificationType;
private final CommentId commentId;
private final String memberId;
private final LocalDateTime createdAt;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.foodymoody.be.comment_heart.infra.usecase;

import com.foodymoody.be.comment.application.CommentReadService;
import com.foodymoody.be.comment.domain.entity.Comment;
import com.foodymoody.be.comment.domain.entity.CommentId;
import com.foodymoody.be.comment_heart.application.CommentHeartWriteService;
import com.foodymoody.be.comment_heart.domain.CommentHeart;
import com.foodymoody.be.comment_heart_count.application.CommentHeartCountWriteService;
import com.foodymoody.be.common.event.Events;
import com.foodymoody.be.common.event.NotificationType;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -19,22 +23,35 @@ public class CommentHeartWriteUseCase {
@Transactional
public void registerCommentHeart(String commentIdValue, String memberId) {
CommentId commentId = new CommentId(commentIdValue);
commentReadService.validate(commentId);
Comment comment = commentReadService.fetchById(commentId);
if (commentHeartWriteService.existsByCommentIdAndMemberId(commentId, memberId)) {
return;
}
commentHeartWriteService.registerCommentHeart(commentId, memberId);
CommentHeart commentHeart = commentHeartWriteService.registerCommentHeart(commentId, memberId);
commentHeartCountWriteService.increment(commentId);
Events.publish(toCommentHeartAddedEvent(comment, commentHeart, memberId));
}

@Transactional
public void deleteCommentHeart(String commentIdValue, String memberId) {
CommentId commentId = new CommentId(commentIdValue);
commentReadService.validate(commentId);
commentReadService.fetchById(commentId);
if (!commentHeartWriteService.existsByCommentIdAndMemberId(commentId, memberId)) {
return;
}
commentHeartWriteService.deleteCommentHeart(commentId, memberId);
commentHeartCountWriteService.decrement(commentId);
}

private static CommentHeartAddedEvent toCommentHeartAddedEvent(Comment comment, CommentHeart commentHeart,
String memberId) {
return new CommentHeartAddedEvent(
comment.getFeedId(),
comment.getContent(),
NotificationType.COMMENT_HEART_ADDED_EVENT,
comment.getId(),
memberId,
commentHeart.getCreatedAt()
);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.foodymoody.be.common.event;

public enum NotificationType {
COMMENT_ADDED,
HEART_ADDED,
REPLY_ADDED,
COMMENT_ADDED_EVENT,
COMMENT_HEART_ADDED_EVENT,
REPLY_ADDED_EVENT, COMMENT_HEART_DELETED_EVENT, REPLY_HEART_ADDED_EVENT,
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ public enum ErrorMessage {
DUPLICATE_MOOD("이미 존재하는 무드입니다", "o001"),
MOOD_NOT_FOUND("존재하지 않는 무드입니다", "o002"),
// image
IMAGE_NOT_FOUND("해당 id의 이미지가 존재하지 않습니다", "i001");
IMAGE_NOT_FOUND("해당 id의 이미지가 존재하지 않습니다", "i001"),
IMAGE_UPLOAD_FAILED("이미지 업로드에 실패했습니다", "i002"),
FILE_SIGNATURE_DOES_NOT_MATCH_CONTENT_TYPE("파일 시그니처와 ContentType 헤더가 일치하지 않습니다", "i003"),
INVALID_IMAGE_FILE("유효하지 않은 이미지 파일입니다", "i004"),
UNSUPPORTED_IMAGE_FORMAT_EXCEPTION("지원되지 않는 이미지 형식입니다", "i005"),
INVALID_IMAGE_URL("유효하지 않은 이미지 url입니다", "i006"),
MAX_UPLOAD_SIZE_EXEEDED("2.8MB 이하의 이미지만 업로드 가능합니다", "i007");

private final String message;
private final String code;
Expand Down
Loading

0 comments on commit 3df0a04

Please sign in to comment.