Skip to content

Commit

Permalink
fix: 컨플릭트 해결
Browse files Browse the repository at this point in the history
  • Loading branch information
hong-sile committed Jul 27, 2023
2 parents 6ff6c80 + cc5ede1 commit e0ab33e
Show file tree
Hide file tree
Showing 45 changed files with 2,358 additions and 89 deletions.
15 changes: 1 addition & 14 deletions .github/workflows/backend-dev-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ jobs:
steps:
- name: 백엔드 메인으로 checkout
uses: actions/checkout@v3
with:
ref: backend-main

- name: JDK 11로 설정
uses: actions/setup-java@v3
Expand All @@ -48,19 +46,8 @@ jobs:
restore-keys: |
${{ runner.os }}-gradle-
- name: keystore 생성
id: generate-keystore
run: |
echo "$KEY_STORE" > keystore.b64
base64 -d -i keystore.b64 > keystore.p12
- name: keystore 이동
id: cp-keystore
run: |
cp keystore.p12 src/main/resources/ssl
- name: gradle 빌드
run: ./gradlew clean build
run: ./gradlew build && ./gradlew build

- name: jar artifact에 업로드
uses: actions/upload-artifact@v3
Expand Down
69 changes: 69 additions & 0 deletions backend/emm-sale/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,72 @@ include::{snippets}/participate-event/http-request.adoc[]

.HTTP response
include::{snippets}/participate-event/http-response.adoc[]

=== `GET`: 행사 목록 조회

.HTTP request
include::{snippets}/find-events/http-request.adoc[]

.HTTP request 설명
include::{snippets}/find-events/request-parameters.adoc[]

.HTTP response
include::{snippets}/find-events/http-response.adoc[]

.HTTP response 설명
include::{snippets}/find-events/response-fields.adoc[]

== Comment

=== `GET` : 댓글 모두 조회

.HTTP request 설명
include::{snippets}/get-comment/request-parameters.adoc[]

.HTTP request
include::{snippets}/get-comment/http-request.adoc[]

.HTTP response
include::{snippets}/get-comment/http-response.adoc[]

.HTTP response 설명
include::{snippets}/get-comment/response-fields.adoc[]

=== `POST` : 댓글 및 대댓글 생성

.HTTP request
include::{snippets}/add-comment/http-request.adoc[]

.HTTP response
include::{snippets}/add-comment/http-response.adoc[]

.HTTP response 설명
include::{snippets}/add-comment/response-fields.adoc[]

=== `DELETE` : 댓글 삭제

.HTTP request
include::{snippets}/delete-comment/http-request.adoc[]

.HTTP request 설명
include::{snippets}/delete-comment/path-parameters.adoc[]

.HTTP response
include::{snippets}/delete-comment/http-response.adoc[]

=== `PATCH` : 댓글 수정

.HTTP request
include::{snippets}/modify-comment/http-request.adoc[]

.HTTP request 설명
include::{snippets}/modify-comment/request-fields.adoc[]

.PathVariable 설명
include::{snippets}/modify-comment/path-parameters.adoc[]

.HTTP response
include::{snippets}/modify-comment/http-response.adoc[]

.HTTP response 설명
include::{snippets}/modify-comment/response-fields.adoc[]
11 changes: 9 additions & 2 deletions backend/emm-sale/src/main/java/com/emmsale/base/BaseEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@
@MappedSuperclass
public abstract class BaseEntity {

@Column(updatable = false, nullable = false)
@Column(updatable = false)
@CreatedDate
private LocalDateTime createdAt;
@Column(nullable = false)
@LastModifiedDate
private LocalDateTime updatedAt;

public LocalDateTime getCreatedAt() {
return createdAt;
}

public LocalDateTime getUpdatedAt() {
return updatedAt;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.emmsale.comment.api;

import com.emmsale.comment.application.CommentCommandService;
import com.emmsale.comment.application.CommentQueryService;
import com.emmsale.comment.application.dto.CommentAddRequest;
import com.emmsale.comment.application.dto.CommentHierarchyResponse;
import com.emmsale.comment.application.dto.CommentModifyRequest;
import com.emmsale.comment.application.dto.CommentResponse;
import com.emmsale.member.domain.Member;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class CommentApi {

private final CommentCommandService commentCommandService;
private final CommentQueryService commentQueryService;

@PostMapping("/comments")
public CommentResponse create(
@RequestBody final CommentAddRequest commentAddRequest,
final Member member
) {
return commentCommandService.create(commentAddRequest, member);
}

@GetMapping("/comments")
public List<CommentHierarchyResponse> findAll(@RequestParam final Long eventId) {
return commentQueryService.findAllCommentsByEventId(eventId);
}

@DeleteMapping("/comments/{comment-id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(@PathVariable("comment-id") final Long commentId, final Member member) {
commentCommandService.delete(commentId, member);
}

@PatchMapping("/comments/{comment-id}")
public CommentResponse modify(
@PathVariable("comment-id") final Long commentId,
final Member member,
@RequestBody final CommentModifyRequest commentModifyRequest
) {
return commentCommandService.modify(commentId, member, commentModifyRequest);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.emmsale.comment.application;

import static com.emmsale.comment.exception.CommentExceptionType.FORBIDDEN_DELETE_COMMENT;
import static com.emmsale.comment.exception.CommentExceptionType.FORBIDDEN_MODIFY_COMMENT;
import static com.emmsale.comment.exception.CommentExceptionType.FORBIDDEN_MODIFY_DELETED_COMMENT;
import static com.emmsale.comment.exception.CommentExceptionType.NOT_FOUND_COMMENT;

import com.emmsale.comment.application.dto.CommentAddRequest;
import com.emmsale.comment.application.dto.CommentModifyRequest;
import com.emmsale.comment.application.dto.CommentResponse;
import com.emmsale.comment.domain.Comment;
import com.emmsale.comment.domain.CommentRepository;
import com.emmsale.comment.exception.CommentException;
import com.emmsale.comment.exception.CommentExceptionType;
import com.emmsale.event.domain.Event;
import com.emmsale.event.domain.repository.EventRepository;
import com.emmsale.event.exception.EventException;
import com.emmsale.event.exception.EventExceptionType;
import com.emmsale.member.domain.Member;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional
public class CommentCommandService {

private final CommentRepository commentRepository;
private final EventRepository eventRepository;

public CommentResponse create(
final CommentAddRequest commentAddRequest,
final Member member
) {
final Event savedEvent = eventRepository.findById(commentAddRequest.getEventId())
.orElseThrow(() -> new EventException(EventExceptionType.NOT_FOUND_EVENT));
final String content = commentAddRequest.getContent();

final Comment comment = commentAddRequest.optionalParentId()
.map(commentId -> Comment.createChild(
savedEvent,
findSavedComment(commentId),
member,
content)
)
.orElseGet(() -> Comment.createRoot(savedEvent, member, content));

return CommentResponse.from(commentRepository.save(comment));
}

private Comment findSavedComment(final Long commentId) {
return commentRepository.findById(commentId)
.orElseThrow(() -> new CommentException(NOT_FOUND_COMMENT));
}

public void delete(final Long commentId, final Member loginMember) {

final Comment comment = findSavedComment(commentId);

validateSameWriter(loginMember, comment, FORBIDDEN_DELETE_COMMENT);

comment.delete();
}

private void validateSameWriter(
final Member loginMember,
final Comment comment,
final CommentExceptionType commentExceptionType
) {
if (loginMember.isNotMe(comment.getMember())) {
throw new CommentException(commentExceptionType);
}
}

public CommentResponse modify(
final Long commentId,
final Member loginMember,
final CommentModifyRequest commentModifyRequest
) {

final Comment comment = findSavedComment(commentId);

validateAlreadyDeleted(comment);
validateSameWriter(loginMember, comment, FORBIDDEN_MODIFY_COMMENT);

comment.modify(commentModifyRequest.getContent());

return CommentResponse.from(comment);
}

private void validateAlreadyDeleted(final Comment comment) {
if (comment.isDeleted()) {
throw new CommentException(FORBIDDEN_MODIFY_DELETED_COMMENT);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.emmsale.comment.application;

import com.emmsale.comment.application.dto.CommentHierarchyResponse;
import com.emmsale.comment.domain.Comment;
import com.emmsale.comment.domain.CommentRepository;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class CommentQueryService {

private final CommentRepository commentRepository;

public List<CommentHierarchyResponse> findAllCommentsByEventId(final Long eventId) {

final List<Comment> comments = commentRepository.findByEventId(eventId);

return CommentHierarchyResponse.from(comments);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.emmsale.comment.application.dto;

import java.util.Optional;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Getter
public class CommentAddRequest {

private final String content;
private final Long eventId;
private final Long parentId;

public Optional<Long> optionalParentId() {
return Optional.ofNullable(parentId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.emmsale.comment.application.dto;

import com.emmsale.base.BaseEntity;
import com.emmsale.comment.domain.Comment;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Getter
public class CommentHierarchyResponse {

private final CommentResponse parentComment;
private final List<CommentResponse> childComments;

public static List<CommentHierarchyResponse> from(final List<Comment> comments) {

final Map<Comment, List<Comment>> groupedByParent =
groupingByParentAndSortedByCreatedAt(comments);

final List<CommentHierarchyResponse> result = new ArrayList<>();

for (final Entry<Comment, List<Comment>> entry : groupedByParent.entrySet()) {
final Comment parentComment = entry.getKey();
final List<CommentResponse> childCommentResponses =
mapToCommentResponse(entry, parentComment);

result.add(
new CommentHierarchyResponse(CommentResponse.from(parentComment), childCommentResponses)
);
}

return result;
}

private static LinkedHashMap<Comment, List<Comment>> groupingByParentAndSortedByCreatedAt(
final List<Comment> comments
) {
return comments.stream()
.sorted(Comparator.comparing(BaseEntity::getCreatedAt))
.collect(Collectors.groupingBy(
it -> it.getParent().orElse(it),
LinkedHashMap::new, Collectors.toList())
);
}

private static List<CommentResponse> mapToCommentResponse(
final Entry<Comment, List<Comment>> entry,
final Comment parentComment
) {
return entry.getValue().stream()
.filter(it -> isNotSameKeyAndValue(parentComment, it))
.map(CommentResponse::from)
.sorted(Comparator.comparing(CommentResponse::getCreatedAt))
.collect(Collectors.toList());
}

private static boolean isNotSameKeyAndValue(final Comment parentComment, final Comment target) {
return !target.equals(parentComment);
}
}
Loading

0 comments on commit e0ab33e

Please sign in to comment.