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

Develop to main #54

Merged
merged 55 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
5f54321
fix: 상세조회 & 커리큘럼 조회 로직수정
Jeongh00 Nov 22, 2023
75d839d
Merge pull request #44 from KOA-TF/feature/notice-error-handling
Jeongh00 Nov 22, 2023
4aa547f
fix: curriculum date column & entity
Jeongh00 Nov 22, 2023
b5ee0b3
Merge pull request #45 from KOA-TF/feature/notice-error-handling
Jeongh00 Nov 22, 2023
2746b29
refactor : 익명 여부 칼럼 추가, dto에 필드 추가
isprogrammingfun Nov 22, 2023
0837b55
feat : 비밀번호 찾기 이후에 사용할 비밀번호 변경 API 추가
isprogrammingfun Nov 22, 2023
d1286d4
Merge pull request #46 from KOA-TF/feat/comment
isprogrammingfun Nov 22, 2023
6694bba
fix: entity relations
Jeongh00 Nov 22, 2023
6b41d14
fix: usecase logics
Jeongh00 Nov 22, 2023
e2e5640
fix: controller & query service logics
Jeongh00 Nov 22, 2023
adb6e05
fix: related notice repositoiries
Jeongh00 Nov 22, 2023
a64bb21
Merge pull request #47 from KOA-TF/feature/notice-error-handling
Jeongh00 Nov 22, 2023
889ba84
fix: readonly transactional 제거
Jeongh00 Nov 22, 2023
729a686
refactor : Comment 응답값에 작성자 id, 작성자 프로필 이미지 url 추가, 댓글 작성 시간 포맷팅
isprogrammingfun Nov 23, 2023
61297cd
refactor : n + 1 문제 수정
isprogrammingfun Nov 23, 2023
add7885
refactor : 회원가입 가능 여부 API와 회원가입 API 추가
isprogrammingfun Nov 23, 2023
9a54ddf
refactor : 회원가입 가능 여부 API 토큰 검증 무시하도록 처리
isprogrammingfun Nov 23, 2023
e859b4a
Merge pull request #48 from KOA-TF/feat/comment
isprogrammingfun Nov 23, 2023
9084590
feat: curriculum response dto
Jeongh00 Nov 23, 2023
280f14a
fix: curriculum mapper
Jeongh00 Nov 23, 2023
61f6659
fix: query repository
Jeongh00 Nov 23, 2023
916f61c
fix: controller & service layer
Jeongh00 Nov 23, 2023
ed74c06
Merge pull request #49 from KOA-TF/feature/curriculum-handling
Jeongh00 Nov 23, 2023
9ef909b
fix: test data delete
Jeongh00 Nov 23, 2023
75e051b
refactor : 댓글 정렬 수정
isprogrammingfun Nov 23, 2023
8911191
Merge pull request #50 from KOA-TF/feat/comment
isprogrammingfun Nov 23, 2023
31a090c
fix: 공지 상세 분리
Jeongh00 Nov 24, 2023
94f83ea
fix: notice deail repository 분리
Jeongh00 Nov 24, 2023
67171f1
fix: noticeId 넣기 & logics changed
Jeongh00 Nov 24, 2023
99ee818
fix: 날짜 형식 조정
Jeongh00 Nov 24, 2023
0e913cd
fix: report logics save
Jeongh00 Nov 24, 2023
b2fcb43
Merge pull request #51 from KOA-TF/feature/deploy-issue-handle
Jeongh00 Nov 24, 2023
b1ad6bb
fix: mapping 변경
Jeongh00 Nov 24, 2023
a6b7b1a
feat: vote request dto
Jeongh00 Nov 20, 2023
00f51ac
feat: controller & usecase service layer
Jeongh00 Nov 20, 2023
d068b00
feat: entity relations
Jeongh00 Nov 20, 2023
ec9d6d6
feat: mapper & service layer
Jeongh00 Nov 20, 2023
27ce0b4
feat: related vote repositories
Jeongh00 Nov 20, 2023
bcf4ede
feat: related vote mapper
Jeongh00 Nov 27, 2023
a291aea
fix: vote entity
Jeongh00 Nov 27, 2023
e77a8b4
feat: vote controller & service layer
Jeongh00 Nov 27, 2023
eef53c5
feat: error code
Jeongh00 Nov 30, 2023
173b50f
feat: exception files & dto
Jeongh00 Nov 30, 2023
f4ca1eb
feat: repository & query
Jeongh00 Nov 30, 2023
9d66154
feat: vote usecase
Jeongh00 Nov 30, 2023
0691489
feat: controller & query service
Jeongh00 Nov 30, 2023
4d65d7d
refactor: unused code
Jeongh00 Nov 30, 2023
114006c
fix: 토큰있는 멤버들에게 알림 보내지도록 설정
Jeongh00 Dec 1, 2023
f14c8b0
fix: 항목별로 멤버 담기도록 설정
Jeongh00 Dec 1, 2023
55464e8
fix: list 로 투표항목 가져오기
Jeongh00 Dec 1, 2023
f756a21
Merge pull request #53 from KOA-TF/feature/fcm-update
Jeongh00 Dec 1, 2023
6b8ef79
fix: null 까지 체크
Jeongh00 Dec 1, 2023
aaf5846
fix: 연관관계 정리 & setter 모두 제거
Jeongh00 Dec 4, 2023
9a0f968
fix: 연관관계 change & 로직 변경
Jeongh00 Dec 4, 2023
086991c
Merge pull request #52 from KOA-TF/feature/vote
Jeongh00 Dec 4, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.koa.coremodule.member.application.service.MemberGetUseCase;
import com.koa.coremodule.member.application.service.MemberCheckUseCase;
import com.koa.coremodule.member.application.service.MemberPasswordChangeUseCase;
import com.koa.coremodule.member.application.service.MemberRegisterUseCase;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand All @@ -40,6 +41,7 @@ public class MemberController {
private final MemberDeleteUseCase memberDeleteUseCase;
private final EmailVerificationUseCase emailVerificationUseCase;
private final MemberPasswordChangeUseCase memberPasswordChangeUseCase;
private final MemberRegisterUseCase memberRegisterUseCase;

@GetMapping("/info")
public ApplicationResponse<MemberInfoResponse> getMemberInfo(){
Expand All @@ -53,11 +55,19 @@ public ApplicationResponse<Void> postMemberDetail(@RequestPart(value = "dto") Me
return ApplicationResponse.ok(null);
}

@PostMapping("/register")
@PostMapping("/check/register")
public ApplicationResponse<CheckRegisterResponse> checkMemberRegistered(@RequestParam String email, @RequestParam String password) {
CheckRegisterResponse response = memberCheckUseCase.checkMemberRegistered(email, password);
return ApplicationResponse.ok(response);
}

@PostMapping("/register")
public ApplicationResponse<Void> postMemberDetail(@RequestParam String email, @RequestParam String password){
memberRegisterUseCase.registerMember(email, password);
return ApplicationResponse.ok(null);
}


@GetMapping("/info/detail")
public ApplicationResponse<MemberDetailInfoResponse> getMemberDetailInfo() {
MemberDetailInfoResponse response = memberGetUseCase.getMemberDetailInfo();
Expand Down Expand Up @@ -99,4 +109,10 @@ public ApplicationResponse<Void> putPassword(@RequestBody MemberPasswordChangeRe
memberPasswordChangeUseCase.changePassword(memberPasswordChangeRequest);
return ApplicationResponse.ok(null);
}

@PutMapping("/password/unauthenticated")
public ApplicationResponse<Void> putPasswordUnauthenticated(@RequestParam String email, @RequestBody MemberPasswordChangeRequest memberPasswordChangeRequest) {
memberPasswordChangeUseCase.changePasswordUnauthenticated(email, memberPasswordChangeRequest);
return ApplicationResponse.ok(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ public ApplicationResponse<Long> saveNotice(
@RequestPart(value = "dto") NoticeRequest request,
@RequestPart(value = "file") MultipartFile multipartFile) {

Member memberRequest = memberUtils.getAccessMember();
request.setMemberId(memberRequest.getId());
Long noticeId = noticeSaveUseCase.saveNotice(request, multipartFile);
return ApplicationResponse.ok(noticeId, "공지 작성에 성공했습니다.");
}
Expand Down Expand Up @@ -103,12 +101,12 @@ public ApplicationResponse<Void> deleteNotice(
* 공지 상세 조회 (내용)
*/
@GetMapping(value = "/{noticeId}/detail")
public ApplicationResponse<NoticeListResponse> noticeDetail(
public ApplicationResponse<NoticeDetailListResponse> noticeDetail(
@PathVariable Long noticeId) {

Member memberRequest = memberUtils.getAccessMember();

NoticeListResponse response = noticeSaveUseCase.selectNoticeDetail(memberRequest.getId(), noticeId);
NoticeDetailListResponse response = noticeSaveUseCase.selectNoticeDetail(memberRequest.getId(), noticeId);
return ApplicationResponse.ok(response, "공지 상세 조회에 성공했습니다.");
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.koa.apimodule.command.api;

import com.koa.commonmodule.common.ApplicationResponse;
import com.koa.coremodule.vote.application.dto.VoteRequest;
import com.koa.coremodule.vote.application.dto.VoteStatus;
import com.koa.coremodule.vote.application.service.VoteFindUseCase;
import com.koa.coremodule.vote.application.service.VoteSaveUseCase;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/v1/vote")
public class VoteController {

private final VoteSaveUseCase voteSaveUseCase;
private final VoteFindUseCase voteFindUseCase;

/**
* 투표 생성
*/
@PostMapping
public ApplicationResponse<Long> makeVote(@RequestBody VoteRequest voteRequest) {

Long voteId = voteSaveUseCase.saveVote(voteRequest);
return ApplicationResponse.ok(voteId, "투표 생성을 완료했습니다.");
}

/**
* 투표 현황 조회 - 명단까지 리스트로 전달 필요
*/
@GetMapping
public ApplicationResponse<VoteStatus> getVoteStatus(Long noticeId) {

VoteStatus voteStatus = voteFindUseCase.findVoteStatus(noticeId);
return ApplicationResponse.ok(voteStatus, "투표 현황 조회 완료했습니다.");
}

/**
* 투표 참여
*/
@PostMapping(value = "/attend")
public ApplicationResponse<Long> attendVote(Long voteItemId) {

Long voteItemRecordId = voteSaveUseCase.attendVote(voteItemId);
return ApplicationResponse.ok(voteItemRecordId, "투표 참여를 완료했습니다.");
}

/**
* 투표 마감 처리
*/

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ public enum Error {
//REPORT
DUPLICATE_REPORT("이미 등록된 신고내용입니다.", 400),

//NOTICE
// VOTE
VOTE_NOT_FOUND("투표가 존재하지 않습니다.", 400),
VOTE_ITEM_NOT_FOUND("투표 항목이 존재하지 않습니다.", 400),
VOTE_ITEM_RECORD_NOT_FOUND("투표 항목 참여자가 존재하지 않습니다.", 400),

// MEMBER
MEMBER_NOT_FOUND("사용자를 찾을 수 없습니다.", 2000),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ private static Map<String, Set<HttpMethod>> createIgnoredPathMap() {

map.put("/v1/auth/reissue", Set.of(HttpMethod.GET));
map.put("/v1/member/register", Set.of(HttpMethod.POST));
map.put("/v1/member/check/register", Set.of(HttpMethod.POST));
map.put("/h2-console/**", Set.of(HttpMethod.GET, HttpMethod.POST));
map.put("/v1/auth/login/**", Set.of(HttpMethod.GET, HttpMethod.POST));
map.put("/v1/member/email", Set.of(HttpMethod.POST));
map.put("/v1/member/verify", Set.of(HttpMethod.POST));
map.put("/v1/member/verify/code", Set.of(HttpMethod.POST));
map.put("/v1/member/password/unauthenticated", Set.of(HttpMethod.PUT));
map.put("/api-docs/**", Set.of(HttpMethod.GET, HttpMethod.POST));
map.put("/error", Set.of(HttpMethod.GET, HttpMethod.POST));
map.put("/favicon.ico", Set.of(HttpMethod.GET, HttpMethod.POST));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
@NoArgsConstructor
public class CommentCreateRequest {
private String content;
private Boolean isAnonymous;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ public class CommentInfoResponse {
private final String writer;
private final String createdAt;
private final Boolean isMine;
private final Boolean isAnonymous;
private final String profileImageUrl;
private final Long writerId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ public class CommentListResponse {
private final String createdAt;
private final Integer commentCount;
private final Boolean isMine;
private final Boolean isAnonymous;
private final String profileImageUrl;
private final Long writerId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.koa.coremodule.comment.application.dto.response.CommentInfoResponse;
import com.koa.coremodule.comment.domain.entity.Comment;
import com.koa.coremodule.member.domain.entity.Member;
import com.koa.coremodule.member.domain.entity.MemberDetail;
import com.koa.coremodule.notice.domain.entity.Notice;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
Expand All @@ -11,32 +12,37 @@
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class CommentMapper {

public static Comment mapToCommentWithUserAndAlbum(String content, Notice notice, Member member) {
public static Comment mapToCommentWithUserAndAlbum(String content, Notice notice, Member member, Boolean isAnonymous) {
Comment comment = Comment.builder()
.content(content)
.notice(notice)
.writer(member)
.isAnonymous(isAnonymous)
.build();
return comment;
}

public static Comment mapToCommentWithUserAndNoticeAndParent(String content, Notice notice, Member member, Comment parent) {
public static Comment mapToCommentWithUserAndNoticeAndParent(String content, Notice notice, Member member, Comment parent, Boolean isAnonymous) {
Comment comment = Comment.builder()
.content(content)
.notice(notice)
.writer(member)
.parent(parent)
.isAnonymous(isAnonymous)
.build();
return comment;
}

public static CommentInfoResponse mapToCommentInfoResponse(Comment comment, Member member) {
public static CommentInfoResponse mapToCommentInfoResponse(Comment comment, Member member, MemberDetail memberDetail) {
return CommentInfoResponse.builder()
.commentId(comment.getId())
.content(comment.getContent())
.writer(member.getName())
.createdAt(comment.getCreatedAt().toString())
.createdAt(comment.getCreatedAtByFormat())
.isMine(comment.getWriter().equals(member))
.isAnonymous(comment.getIsAnonymous())
.profileImageUrl(memberDetail.getProfileImage())
.writerId(member.getId())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import com.koa.coremodule.comment.domain.service.CommentQueryService;
import com.koa.coremodule.comment.domain.service.CommentSaveService;
import com.koa.coremodule.member.domain.entity.Member;
import com.koa.coremodule.member.domain.entity.MemberDetail;
import com.koa.coremodule.member.domain.service.MemberDetailQueryService;
import com.koa.coremodule.member.domain.utils.MemberUtils;
import com.koa.coremodule.notice.domain.service.NoticeQueryService;
import com.koa.coremodule.notice.domain.entity.Notice;
Expand All @@ -21,25 +23,28 @@ public class CommentCreateUseCase {
private final NoticeQueryService noticeQueryService;
private final CommentSaveService commentSaveService;
private final CommentQueryService commentQueryService;
private final MemberDetailQueryService memberDetailQueryService;

@Transactional
public CommentInfoResponse createComment(Long noticeId, CommentCreateRequest commentCreateRequest){
final Member member = memberUtils.getAccessMember();
final Notice notice = noticeQueryService.findByNoticeId(noticeId);
final Comment comment = CommentMapper.mapToCommentWithUserAndAlbum(commentCreateRequest.getContent(), notice, member);
final Comment comment = CommentMapper.mapToCommentWithUserAndAlbum(commentCreateRequest.getContent(), notice, member, commentCreateRequest.getIsAnonymous());
final MemberDetail memberDetail = memberDetailQueryService.findMemberDetailByMemberId(member.getId());

commentSaveService.saveComment(comment);
return CommentMapper.mapToCommentInfoResponse(comment, member);
return CommentMapper.mapToCommentInfoResponse(comment, member, memberDetail);
}

@Transactional
public CommentInfoResponse createReComment(Long noticeId, Long commentId, CommentCreateRequest commentCreateRequest){
final Member member = memberUtils.getAccessMember();
final Notice notice = noticeQueryService.findByNoticeId(noticeId);
final Comment parent = commentQueryService.getCommentById(commentId);
final Comment comment = CommentMapper.mapToCommentWithUserAndNoticeAndParent(commentCreateRequest.getContent(), notice, member, parent);
final Comment comment = CommentMapper.mapToCommentWithUserAndNoticeAndParent(commentCreateRequest.getContent(), notice, member, parent, commentCreateRequest.getIsAnonymous());
final MemberDetail memberDetail = memberDetailQueryService.findMemberDetailByMemberId(member.getId());

commentSaveService.saveComment(comment);
return CommentMapper.mapToCommentInfoResponse(comment, member);
return CommentMapper.mapToCommentInfoResponse(comment, member, memberDetail);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
import com.koa.coremodule.comment.domain.entity.Comment;
import com.koa.coremodule.comment.domain.service.CommentQueryService;
import com.koa.coremodule.member.domain.entity.Member;
import com.koa.coremodule.member.domain.entity.MemberDetail;
import com.koa.coremodule.member.domain.service.MemberDetailQueryService;
import com.koa.coremodule.member.domain.utils.MemberUtils;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -20,28 +26,60 @@
public class CommentGetUseCase {
private final CommentQueryService commentQueryService;
private final MemberUtils memberUtils;
private final MemberDetailQueryService memberDetailQueryService;

public List<CommentListResponse> getCommentList(Long noticeId){
final Member member = memberUtils.getAccessMember();
final Map<Long, List<Comment>> childCommentMap = commentQueryService.getChildCommentByNoticeId(noticeId);
final ArrayList<CommentListResponse> commentListResponses = new ArrayList<>();
List<Comment> commentList = commentQueryService.getCommentByNoticeId(noticeId);
for (Comment comment : commentList) {
final Map<Comment, MemberDetail> commentMemberDetailMap = createCommentMemberDetailMapWithNoticeId(noticeId);
for (Comment comment : commentMemberDetailMap.keySet()) {
final List<Comment> childCommentList = childCommentMap.get(comment.getId());
commentListResponses.add(new CommentListResponse(comment.getId(), comment.getContent(), comment.getWriter().getName(), comment.getCreatedAt().toString()
,childCommentList != null ? childCommentList.size() : 0, comment.getWriter().equals(member)));
commentListResponses.add(new CommentListResponse(comment.getId(), comment.getContent(), comment.getWriter().getName(),
comment.getCreatedAtByFormat() ,childCommentList != null ? childCommentList.size() : 0,
comment.getWriter().equals(member), comment.getIsAnonymous(), commentMemberDetailMap.get(comment).getProfileImage(),
comment.getWriter().getId()));
}
return commentListResponses;
}

public List<CommentInfoResponse> getReCommentList(Long commentId){
final Member member = memberUtils.getAccessMember();
final List<Comment> childCommentList = commentQueryService.getChildCommentByCommentId(commentId);
final Map<Comment, MemberDetail> childCommentMemberDetailMap = createCommentMemberDetailMapWithCommentId(commentId);
final ArrayList<CommentInfoResponse> childCommentInfoResponses = new ArrayList<>();
for (Comment comment : childCommentList) {
for (Comment comment : childCommentMemberDetailMap.keySet()) {
childCommentInfoResponses.add(new CommentInfoResponse(comment.getId(), comment.getContent()
, comment.getWriter().getName(), comment.getCreatedAt().toString(), comment.getWriter().equals(member)));
, comment.getWriter().getName(), comment.getCreatedAtByFormat(),
comment.getWriter().equals(member), comment.getIsAnonymous(),
childCommentMemberDetailMap.get(comment).getProfileImage(), comment.getWriter().getId()));
}
return childCommentInfoResponses;
}

private <T> Map<Comment, MemberDetail> createCommentMemberDetailMap(Long id, Function<Long, List<Comment>> commentGetter) {
final List<Comment> commentList = commentGetter.apply(id);
final List<Long> memberIdList = commentList.stream()
.map(comment -> comment.getWriter().getId())
.collect(Collectors.toList());
final List<MemberDetail> memberDetailList = memberDetailQueryService.findMemberDetailListByMemberIdList(memberIdList);
final Map<Long, MemberDetail> memberDetailMap = memberDetailList.stream()
.collect(Collectors.toMap(memberDetail -> memberDetail.getMember().getId(), memberDetail -> memberDetail));
final Map<Comment, MemberDetail> commentMemberDetailMap = commentList.stream()
.sorted(Comparator.comparing(Comment::getCreatedAt))
.collect(Collectors.toMap(
comment -> comment,
comment -> memberDetailMap.get(comment.getWriter().getId()),
(existing, replacement) -> existing,
LinkedHashMap::new
));
return commentMemberDetailMap;
}

public Map<Comment, MemberDetail> createCommentMemberDetailMapWithNoticeId(Long noticeId) {
return createCommentMemberDetailMap(noticeId, commentQueryService::getCommentByNoticeId);
}

public Map<Comment, MemberDetail> createCommentMemberDetailMapWithCommentId(Long commentId) {
return createCommentMemberDetailMap(commentId, commentQueryService::getChildCommentByCommentId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.koa.coremodule.notice.domain.entity.Notice;
import com.koa.coremodule.member.domain.entity.Member;
import jakarta.persistence.*;
import java.time.format.DateTimeFormatter;
import lombok.*;

@Builder
Expand Down Expand Up @@ -31,7 +32,13 @@ public class Comment extends BaseEntity {
@JoinColumn(name = "parent_id")
private Comment parent;

private Boolean isAnonymous;

public Long getParentId() {
return this.parent != null ? this.parent.getId() : null;
}

public String getCreatedAtByFormat() {
return this.createdAt.format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
public interface CommentRepository extends JpaRepository<Comment, Long> {


@Query("select c from Comment c where c.notice.id = :noticeId and c.parent is null order by c.createdAt asc")
@Query("select c from Comment c join fetch c.writer where c.notice.id = :noticeId and c.parent is null order by c.createdAt asc")
List<Comment> findByNoticeId(@Param("noticeId") Long noticeId);

@Query("select c from Comment c where c.notice.id = :noticeId and c.parent is not null order by c.createdAt asc")
@Query("select c from Comment c join fetch c.writer where c.notice.id = :noticeId and c.parent is not null order by c.createdAt asc")
List<Comment> findChildByNoticeId(@Param("noticeId") Long noticeId);

@Query("select c from Comment c where c.parent.id = :commentId order by c.createdAt asc")
Expand Down
Loading