refactor/#251 User, Post, Comment, FileEntity간 관계 매핑을 ID 참조로 변경 - #259
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Walkthrough도메인(Post/Comment)에서 연관관계를 제거하고 ID 기반(authorId, fileId, postId)으로 전환. 이에 따라 생성/업데이트 메서드 시그니처 변경, 조회 시 User/File 로딩 추가, 응답 DTO/Facade들이 authorName 맵을 주입받아 작성자 이름을 채우도록 수정. 테스트/페이크 리포지토리/컨테이너 전반 갱신. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
aics-domain/src/main/java/kgu/developers/domain/comment/application/command/CommentCommandService.java (2)
13-19: CommentCommandService 클래스에 @transactional 누락
updateComment(…)와 deleteComment(…)가 JPA 변경 감지에 의존하므로 클래스(또는 메서드)에@Transactional을 적용해야 합니다. 조회 전용 메서드는 필요 시@Transactional(readOnly = true)로 분리하세요.import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor -public class CommentCommandService { +@Transactional +public class CommentCommandService {
27-33: CommentCommandService에 @transactional 적용 필요
updateComment, deleteComment 메서드가 트랜잭션 없이 실행되어 영속성 변경이 보장되지 않습니다.
클래스 선언부 또는 각 메서드에@Transactional애노테이션을 추가하세요.aics-api/src/main/java/kgu/developers/api/comment/presentation/response/CommentListResponse.java (1)
14-21: 스웨거 설명 오기(파일 → 댓글) 수정 필요
"게시글에 첨부된 파일"은 댓글 리스트 스키마에 부적절한 설명입니다. 사용자 문서 품질 이슈로 수정이 필요합니다.- @Schema(description = "게시글에 첨부된 파일", + @Schema(description = "게시글의 댓글 목록", example = "[{" + "\"commentId\": 1, " - + "\"author\": \"이신행\", " + + "\"author\": \"이신행\", " + "\"createdAt\": \"2024-11-11\", " + "\"content\": \"예시 코멘트입니다, 좋은 소식이네요!\"}]", requiredMode = REQUIRED)aics-domain/src/main/java/kgu/developers/domain/post/application/response/PostDetailResponse.java (1)
70-86: author null 시 NPE 발생 가능PostQueryService에서 author를 orElse(null)로 전달하므로 여기서 author.getName()이 NPE가 될 수 있습니다. 아래처럼 null-safe 처리하거나, 서비스에서 author 미존재 시 예외를 던지도록 일관화해 주세요.
- return PostDetailResponse.builder() + String authorName = (author != null) ? author.getName() : "알 수 없음"; + return PostDetailResponse.builder() @@ - .author(author.getName()) + .author(authorName)
🧹 Nitpick comments (29)
aics-domain/src/main/java/kgu/developers/domain/comment/domain/Comment.java (1)
28-33: ID 필드 전환은 적절. 그러나 FK/인덱스와 컬럼명 명시는 필요
- 연관관계 제거로 DB FK가 사라졌습니다. 무결성·삭제 전파 보장을 위해 DB 마이그레이션(Flyway/Liquibase)으로 FK를 추가해 주세요.
- 조회가 자주 발생하는 postId/authorId에 인덱스가 없으면 N+1 제거 이점이 줄어듭니다. 인덱스를 권장합니다.
- 컬럼명을 명시하면 물리적 네이밍 전략 변경 시에도 안전합니다.
적용 예(해당 라인 범위 내 변경):
- @Column(nullable = false) + @Column(name = "post_id", nullable = false) private Long postId; - @Column(nullable = false) + @Column(name = "author_id", nullable = false) private String authorId;추가 코드(선택, 범위 밖): 클래스 수준 인덱스 선언
// imports import jakarta.persistence.Index; import jakarta.persistence.Table; // annotations @Entity @Table(indexes = { @Index(name = "idx_comment_post_id", columnList = "post_id"), @Index(name = "idx_comment_author_id", columnList = "author_id") })DB FK 예시(참고):
alter table comment add constraint fk_comment_post foreign key (post_id) references post(id); alter table comment add constraint fk_comment_author foreign key (author_id) references "user"(id);aics-domain/src/main/java/kgu/developers/domain/user/application/query/UserQueryService.java (1)
55-57: 중복 ID·NULL 입력 방어 및 충돌 안전 수집기로 보강 권장
- 중복 ID가 들어와도 결과는 동일해야 합니다(merge 함수 지정).
- NULL/빈 리스트 입력에 대한 빠른 반환으로 방어적 코딩.
- public Map<String, String> getUserNameMapByIds(List<String> authorIds) { - return getAllUsersByIds(authorIds).stream().collect(Collectors.toMap(User::getId, User::getName)); - } + public Map<String, String> getUserNameMapByIds(List<String> authorIds) { + if (authorIds == null || authorIds.isEmpty()) { + return Map.of(); + } + // 중복 제거 후 조회 + var distinctIds = authorIds.stream().distinct().toList(); + return getAllUsersByIds(distinctIds).stream() + .collect(Collectors.toMap(User::getId, User::getName, (a, b) -> a)); + }추가(범위 밖):
import java.util.Map;는 이미 있으므로, 별도 import 불필요.aics-api/src/main/java/kgu/developers/api/post/presentation/response/PostSummaryResponse.java (3)
42-53: authorName 주입 전환은 타당. null/blank 방어 로직을 추가하세요.호출측에서 이름 매핑이 누락되면 계약상 REQUIRED 스키마와 불일치할 수 있습니다. 기본 표시값을 두어 NPE/빈 문자열을 방지하세요.
- .author(authorName) + .author((authorName != null && !authorName.isBlank()) ? authorName : "알 수 없음")추가로, DateTimeFormatter는 매 호출 생성 대신 정적 상수로 공유하는 편이 좋습니다. 아래처럼 상단에 선언 후 사용을 권장합니다.
// record 본문 상단에 추가 private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");그리고 메서드 내 로컬 변수
formatter사용부는DATE_FORMATTER로 교체하세요.
45-47: 스키마(“앞부분 30자”)와 구현(80자) 불일치현재 80자로 잘라내지만 스키마 설명은 30자로 표기되어 있습니다. 어느 쪽이 정답인지 결정해 일치시켜 주세요. 30자로 맞출 경우:
- String description = content.length() > 80 ? content.substring(0, 80) : content; + String description = content.length() > 30 ? content.substring(0, 30) : content;
55-55: 첨부파일 여부 TODO 처리ID 기반으로 전환되었으므로 파일 참조가 존재하는지로 계산 가능해 보입니다. 도메인에
fileId(또는 동등 필드)가 있다면 다음과 같이 반영하세요.- .hasAttachment(false) // TODO : 첨부파일 여부 확인 + .hasAttachment(post.getFileId() != null)필드명이 다르면 해당 규약에 맞춰 적용 바랍니다.
aics-domain/src/main/java/kgu/developers/domain/comment/application/command/CommentCommandService.java (1)
20-25: ID 기반 생성 로직은 일관적. 다만 content 등의 입력 검증은 어디서 하나요?
Comment.create(content, user.getId(), post.getId())사용은 변경 방향과 일치합니다. 다만 빈 내용/최대 길이 등의 검증이 도메인 팩토리에서 보장되는지 확인해 주세요. 서비스층에서의 선제 검증이 필요하면 추가하십시오.aics-api/src/main/java/kgu/developers/api/comment/presentation/response/CommentResponse.java (1)
27-33: authorName 주입 OK. null/blank 방어 및 포맷터 상수화 제안호출측 매핑 누락 시 안전하게 동작하도록 기본값을 둡니다.
- .author(authorName) + .author((authorName != null && !authorName.isBlank()) ? authorName : "알 수 없음")DateTimeFormatter도 정적 상수로 올리면 미세 최적화 및 가독성이 향상됩니다.
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");aics-domain/src/main/java/kgu/developers/domain/post/infrastructure/QueryPostRepository.java (1)
60-66: ID 기반 서브쿼리 삭제 전환은 적절. 다만 JPA bulk DELETE의 서브쿼리 지원 여부를 런타임에서 확인하세요. 대안으로 EXISTS 패턴 제안일부 JPA 구현/DB 조합에서 DELETE WHERE 절의 서브쿼리 제약이 있을 수 있습니다. 통합 테스트로 확인해 주세요. 성능 측면에서도 IN 서브쿼리 대신 EXISTS가 더 우호적인 실행계획을 타는 경우가 많습니다.
EXISTS 대안:
- .where(comment.postId.in( - JPAExpressions.select(post.id) - .from(post) - .where(post.deletedAt.isNotNull() - .and(post.deletedAt.before(thresholdDate))) - )) + .where( + JPAExpressions + .selectOne() + .from(post) + .where( + post.id.eq(comment.postId) + .and(post.deletedAt.isNotNull()) + .and(post.deletedAt.before(thresholdDate)) + ) + .exists() + )운영 DB에
comment.post_id인덱스가 있는지 확인해 주세요. 없으면 대량 삭제 시 테이블 스캔이 발생할 수 있습니다.aics-domain/src/testFixtures/java/mock/repository/FakeCommentRepository.java (1)
36-37: postId 비교 시 NPE 가능성 — Objects.equals로 안전 비교 권장
comment.getPostId()가 null일 경우 NPE가 날 수 있습니다. 안전 비교로 교체해 주세요.- .filter(comment -> comment.getPostId().equals(postId) + .filter(comment -> java.util.Objects.equals(comment.getPostId(), postId) && comment.getDeletedAt() == null)aics-domain/src/testFixtures/java/post/domain/PostDomainTest.java (1)
32-32: ID 기반 생성 호출 전환 OK + authorId 단언 추가 제안
author.getId()로의 전환은 올바릅니다. 생성된 Post에authorId가 정확히 세팅되었는지 단언을 추가하면 회귀 방지에 도움이 됩니다.assertEquals(NEWS, post.getCategory()); + assertEquals(user().getId(), post.getAuthorId());aics-api/src/main/java/kgu/developers/api/post/application/PostFacade.java (1)
39-43: 이름 맵 직접 조회 메서드로 중복 제거 및 성능·가독성 개선이미 Comment 쪽에서 사용하는
getUserNameMapByIds를 활용하면 불필요한 수집/매핑을 제거하고 서비스 간 일관성을 유지할 수 있습니다.- Map<String, String> authorNameMap = userQueryService.getAllUsersByIds(authorIds).stream() - .collect(Collectors.toMap( - User::getId, - User::getName - )); + Map<String, String> authorNameMap = userQueryService.getUserNameMapByIds(authorIds);aics-api/src/main/java/kgu/developers/api/comment/presentation/response/CommentListResponse.java (1)
23-27: 작성자 이름 누락 시 기본값 처리 + 인자명 명확화(nameMap → authorNameMap)이름 매핑이 없을 때의 표시값을 정해두면 응답 일관성이 좋아집니다. 또한 파라미터명을 명확히 하면 가독성이 향상됩니다.
- public static CommentListResponse from(List<Comment> comments, Map<String,String> nameMap) { + public static CommentListResponse from(List<Comment> comments, Map<String,String> authorNameMap) { return CommentListResponse.builder() .contents(comments.stream() - .map(comment -> CommentResponse.from(comment,nameMap.get(comment.getAuthorId()))) + .map(comment -> CommentResponse.from( + comment, + authorNameMap.getOrDefault(comment.getAuthorId(), "탈퇴한 사용자") + )) .toList()) .build(); }aics-api/src/main/java/kgu/developers/api/comment/application/CommentFacade.java (2)
38-38: authorIds 중복 제거로 불필요한 조회 줄이기중복 ID를 제거하면 사용자 이름 조회 호출을 줄일 수 있습니다. PostFacade와도 일관됩니다.
- List<String> authorIds = comments.stream().map(Comment::getAuthorId).collect(Collectors.toList()); + List<String> authorIds = comments.stream().map(Comment::getAuthorId).distinct().toList();
40-41: 지역 변수명 통일(가독성) 및 의미 명확화
nameMap→authorNameMap으로 변경하면 역할이 명확해집니다. (외부 시그니처 영향 없음)- Map<String, String> nameMap = userQueryService.getUserNameMapByIds(authorIds); - return CommentListResponse.from(comments,nameMap); + Map<String, String> authorNameMap = userQueryService.getUserNameMapByIds(authorIds); + return CommentListResponse.from(comments, authorNameMap);aics-api/src/main/java/kgu/developers/api/post/presentation/response/PostSummaryPageResponse.java (1)
32-36: authorNameMap 누락/미스매칭 대비 방어 코드와 fallback을 추가해 주세요null map 또는 매핑 누락 시 NPE/빈 authorName 가능성이 있습니다. 안전한 기본값과 getOrDefault로의 fallback을 권장합니다. 또한 파라미터 표기 공백(nit)도 함께 정리해 주세요.
- public static <T> PostSummaryPageResponse<T> of(List<Post> posts, PageableResponse<T> pageable, Map<String, String>authorNameMap) { + public static <T> PostSummaryPageResponse<T> of(List<Post> posts, PageableResponse<T> pageable, Map<String, String> authorNameMap) { + authorNameMap = (authorNameMap == null) ? Map.of() : authorNameMap; return PostSummaryPageResponse.<T>builder() .contents(posts.stream() - .map(post -> PostSummaryResponse.from(post, authorNameMap.get(post.getAuthorId()))) + .map(post -> PostSummaryResponse.from( + post, + authorNameMap.getOrDefault(post.getAuthorId(), post.getAuthorId()) + )) .toList()) .pageable(pageable) .build(); }선택: 기존 호출부 호환을 위해
of(posts, pageable)오버로드(내부에서Map.of()사용) 추가도 고려할 만합니다.aics-domain/src/testFixtures/java/comment/application/CommentQueryServiceTest.java (1)
26-31: 하드코딩된 ID 의존(1L, 2L) 제거로 테스트 안정화가짜 리포지토리의 ID 할당 정책에 암묵적으로 의존하고 있습니다. 저장 결과에서 실제 ID를 받아 사용하도록 리팩터링하면 테스트가 견고해집니다.
@@ - private static final Long SAVED_COMMENT_ID = 2L; - private static final Long NOT_EXIST_COMMENT_ID = 3L; - private static final Long TEST_POST_ID = 1L; + private static final Long NOT_EXIST_COMMENT_ID = 3L; + private Long savedCommentId; + private Long testPostId; @@ public void init() { - deletedComment(fakeCommentRepository, post.getId()); - saveTestComment(fakeCommentRepository, post.getId()); + deletedComment(fakeCommentRepository, post.getId()); + this.savedCommentId = saveTestComment(fakeCommentRepository, post.getId()); + this.testPostId = post.getId(); @@ public void getComments_Success() { - List<Comment> comments = commentQueryService.getComments(TEST_POST_ID); + List<Comment> comments = commentQueryService.getComments(testPostId); @@ public void getById_Success() { - Long savedCommentId = SAVED_COMMENT_ID; + Long savedCommentId = this.savedCommentId;그리고 헬퍼가 ID를 반환하도록 바꾸면 호출부가 단순해집니다:
- private static void saveTestComment(FakeCommentRepository fakeCommentRepository, Long postId) { - fakeCommentRepository.save( - Comment.create(TARGET_COMMENT_CONTENT, TEST_AUTHOR_ID, postId) - ); - } + private static Long saveTestComment(FakeCommentRepository fakeCommentRepository, Long postId) { + return fakeCommentRepository + .save(Comment.create(TARGET_COMMENT_CONTENT, TEST_AUTHOR_ID, postId)) + .getId(); + }Also applies to: 62-73, 79-89
aics-admin/src/testFixtures/java/post/application/PostAdminFacadeTest.java (2)
82-86: fileId=1L 하드코딩은 테스트 취약점—실재 파일 준비 또는 null 허용 확인 권장가짜 파일 리포지토리에 ID=1 파일이 존재한다는 가정이 숨겨져 있습니다. 저장 없이
1L를 쓰면 구현에 따라 실패할 수 있습니다. 실제 파일을 저장해 얻은 ID를 사용하거나(권장), 파일 미첨부 시나리오면 명시적으로null을 전달하세요.- Long fileId = 1L; + Long fileId = null; // 파일 미첨부 시나리오라면 이렇게 명시또는 테스트 setup에서 파일을 저장해 실제 ID를 주입해 주세요.
60-64: SecurityContext 정리 추가 제안테스트 간 컨텍스트 누수 방지를 위해
@AfterEach에서SecurityContextHolder.clearContext()호출을 권장합니다.// 파일 하단 등 적절한 위치 @AfterEach void tearDown() { SecurityContextHolder.clearContext(); }aics-domain/src/testFixtures/java/comment/domain/CommentDomainTest.java (1)
39-39: ID 기반 생성 시 null ID 가능성 점검 필요author.getId(), post.getId()가 영속화 전 객체라면 null일 수 있어 생성 시점에 NPE/검증 실패가 날 수 있습니다. 테스트 픽스처에서 ID를 명시적으로 세팅하거나(예: TestEntityUtils로 setId) 저장을 통해 ID를 채운 뒤 사용해 주세요. 최소한 Comment.create/Post.create가 null ID를 허용하는지 확인이 필요합니다.
Also applies to: 47-47
aics-domain/src/main/java/kgu/developers/domain/post/application/command/PostCommandService.java (1)
5-5: 미사용 의존성 정리 제안(FileQueryService)현재 클래스 내에서 FileQueryService를 사용하지 않습니다. 검증을 추가하지 않을 계획이라면 의존성 제거로 DI 단순화가 가능합니다.
-import kgu.developers.domain.file.application.query.FileQueryService; @@ - private final FileQueryService fileQueryService;Also applies to: 18-19
aics-api/src/testFixtures/java/comment/application/CommentFacadeTest.java (1)
82-87: SecurityContext 정리 루틴 추가 제안각 테스트 후 SecurityContext를 명시적으로 정리하면 테스트 간 교차 오염 가능성을 낮출 수 있습니다.
아래 메서드를 추가하세요:
@org.junit.jupiter.api.AfterEach void tearDown() { org.springframework.security.core.context.SecurityContextHolder.clearContext(); }aics-api/src/testFixtures/java/post/application/PostFacadeTest.java (1)
49-53: 동일 인스턴스 재사용 권장: UserQueryService 중복 생성
postFacade생성 시 이미 확보한userQueryService대신 새 인스턴스를 생성하고 있습니다. 동일 리포지토리를 공유하더라도 테스트 가독성과 일관성을 위해 기존 인스턴스를 재사용하세요.다음과 같이 변경:
postFacade = new PostFacade( new PostCommandService(userQueryService, fakePostRepository, fileQueryService), - new PostQueryService(fakePostRepository, fakeFileRepository, fakeUserRepository), - new UserQueryService(fakeUserRepository) + new PostQueryService(fakePostRepository, fakeFileRepository, fakeUserRepository), + userQueryService );aics-domain/src/testFixtures/java/comment/application/CommentCommandServiceTest.java (4)
58-59: Post.create에 하드코딩된 작성자 ID 제거저장한 사용자(TEST_USER_ID)와 다른 “202412345”를 하드코딩했습니다. 테스트 일관성과 가독성을 위해 상수 사용을 권장합니다. fileId=null 처리도 서비스/조회 로직에서 NPE 없이 안전한지 확인해 주세요.
적용 제안:
- "202412345", null, false + TEST_USER_ID, null, false
98-100: Comment.create에 매직값 대신 상수 사용 + 권한 시나리오 확인작성자 ID와 postId를 직접 값으로 넣기보다 상수(TEST_USER_ID, TEST_POST_ID) 사용을 권장합니다. 또한 CommentCommandService가 “작성자만 수정 가능” 규칙을 가진 경우, 현재 보안 컨텍스트 사용자(TEST_USER_ID)와 댓글 작성자("202312345")가 달라 테스트가 실제 정책을 반영하지 않을 수 있습니다. 정책 확인을 부탁드립니다.
적용 제안:
- Comment comment = Comment.create("SW 부트캠프 모집이 정말 기대됩니다.", "202312345", - 1L); + Comment comment = Comment.create("SW 부트캠프 모집이 정말 기대됩니다.", TEST_USER_ID, + TEST_POST_ID);
113-115: 삭제 테스트도 상수 사용으로 일관성 확보위와 동일하게 매직값을 상수로 치환해 유지보수성을 높이세요.
적용 제안:
- Comment comment = Comment.create("SW 부트캠프 모집이 정말 기대됩니다.", "202312345", - 1L); + Comment comment = Comment.create("SW 부트캠프 모집이 정말 기대됩니다.", TEST_USER_ID, + TEST_POST_ID);
81-92: SecurityContext 정리(@AfterEach) 추가 권장테스트 간 보안 컨텍스트 누수를 방지하려면 매 테스트 이후 clearContext가 안전합니다.
아래 보조 메서드를 추가해 주세요:
import org.junit.jupiter.api.AfterEach; @AfterEach void tearDown() { SecurityContextHolder.clearContext(); }aics-domain/src/main/java/kgu/developers/domain/post/domain/Post.java (3)
46-46: fileId 컬럼 매핑 명시(선택)명시적 컬럼명을 두면 스키마와 코드의 대응이 분명해집니다.
적용 제안:
- private Long fileId; + @Column(name = "file_id") + private Long fileId;
48-57: 팩토리 메서드 입력값 null 체크 추가 권장도메인 무결성을 엔티티 생성 시 보장해 두면 이후 계층에서의 방어 코드가 줄어듭니다.
적용 제안:
+import java.util.Objects; @@ - public static Post create(String title, String content, Category category, String authorId, Long fileId, boolean isPinned) { - return Post.builder() + public static Post create(String title, String content, Category category, String authorId, Long fileId, boolean isPinned) { + Objects.requireNonNull(title, "title must not be null"); + Objects.requireNonNull(content, "content must not be null"); + Objects.requireNonNull(category, "category must not be null"); + Objects.requireNonNull(authorId, "authorId must not be null"); + return Post.builder()
80-82: updateFileId null 사용 의도 명시null로 첨부 해제를 허용한다면 Javadoc 주석 또는 보조 메서드로 의도를 드러내는 것을 권장합니다.
보조 메서드 예시:
/** * 파일 첨부 해제 */ public void clearFileId() { this.fileId = null; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (27)
aics-admin/src/testFixtures/java/post/application/PostAdminFacadeTest.java(2 hunks)aics-api/src/main/java/kgu/developers/api/comment/application/CommentFacade.java(3 hunks)aics-api/src/main/java/kgu/developers/api/comment/presentation/response/CommentListResponse.java(2 hunks)aics-api/src/main/java/kgu/developers/api/comment/presentation/response/CommentResponse.java(1 hunks)aics-api/src/main/java/kgu/developers/api/post/application/PostFacade.java(2 hunks)aics-api/src/main/java/kgu/developers/api/post/presentation/response/PostSummaryPageResponse.java(2 hunks)aics-api/src/main/java/kgu/developers/api/post/presentation/response/PostSummaryResponse.java(2 hunks)aics-api/src/testFixtures/java/comment/application/CommentFacadeTest.java(3 hunks)aics-api/src/testFixtures/java/post/application/PostFacadeTest.java(2 hunks)aics-domain/src/main/java/kgu/developers/domain/comment/application/command/CommentCommandService.java(1 hunks)aics-domain/src/main/java/kgu/developers/domain/comment/domain/Comment.java(1 hunks)aics-domain/src/main/java/kgu/developers/domain/post/application/command/PostCommandService.java(2 hunks)aics-domain/src/main/java/kgu/developers/domain/post/application/query/PostQueryService.java(3 hunks)aics-domain/src/main/java/kgu/developers/domain/post/application/response/PostDetailResponse.java(2 hunks)aics-domain/src/main/java/kgu/developers/domain/post/domain/Post.java(2 hunks)aics-domain/src/main/java/kgu/developers/domain/post/infrastructure/QueryPostRepository.java(2 hunks)aics-domain/src/main/java/kgu/developers/domain/user/application/query/UserQueryService.java(2 hunks)aics-domain/src/main/java/kgu/developers/domain/user/domain/User.java(0 hunks)aics-domain/src/testFixtures/java/comment/application/CommentCommandServiceTest.java(5 hunks)aics-domain/src/testFixtures/java/comment/application/CommentQueryServiceTest.java(1 hunks)aics-domain/src/testFixtures/java/comment/domain/CommentDomainTest.java(1 hunks)aics-domain/src/testFixtures/java/mock/FakeTestContainer.java(2 hunks)aics-domain/src/testFixtures/java/mock/TestContainer.java(1 hunks)aics-domain/src/testFixtures/java/mock/repository/FakeCommentRepository.java(2 hunks)aics-domain/src/testFixtures/java/mock/repository/FakePostRepository.java(1 hunks)aics-domain/src/testFixtures/java/post/application/PostQueryServiceTest.java(2 hunks)aics-domain/src/testFixtures/java/post/domain/PostDomainTest.java(1 hunks)
💤 Files with no reviewable changes (1)
- aics-domain/src/main/java/kgu/developers/domain/user/domain/User.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-12-03T07:09:18.535Z
Learnt from: minjo-on
PR: kgu-developers/aics-server#125
File: aics-domain/src/testFixtures/java/mock/FakeCommentRepository.java:41-45
Timestamp: 2024-12-03T07:09:18.535Z
Learning: `aics-domain/src/testFixtures/java/mock/FakeCommentRepository.java`의 `findById` 메서드에서는 데이터가 확장될 가능성이 없고 성능 차이가 크지 않으므로 Map을 사용하지 않고 List를 사용하는 것이 바람직합니다.
Applied to files:
aics-domain/src/testFixtures/java/mock/repository/FakePostRepository.javaaics-domain/src/testFixtures/java/comment/application/CommentQueryServiceTest.javaaics-domain/src/testFixtures/java/mock/repository/FakeCommentRepository.javaaics-api/src/testFixtures/java/comment/application/CommentFacadeTest.java
📚 Learning: 2024-12-03T05:01:55.233Z
Learnt from: LeeShinHaeng
PR: kgu-developers/aics-server#124
File: aics-domain/src/testFixtures/java/mock/FakeLabRepository.java:13-57
Timestamp: 2024-12-03T05:01:55.233Z
Learning: `LabServiceTest.java`에서 Java의 `BeforeEach` 애너테이션을 사용하여 각 테스트 전에 `FakeLabRepository`를 초기화하므로, `FakeLabRepository.java`에 `clear()` 메서드를 추가할 필요가 없다.
Applied to files:
aics-domain/src/testFixtures/java/comment/application/CommentQueryServiceTest.javaaics-domain/src/testFixtures/java/comment/application/CommentCommandServiceTest.javaaics-domain/src/testFixtures/java/post/application/PostQueryServiceTest.javaaics-api/src/testFixtures/java/comment/application/CommentFacadeTest.java
🧬 Code graph analysis (3)
aics-domain/src/testFixtures/java/comment/application/CommentCommandServiceTest.java (1)
aics-domain/src/testFixtures/java/mock/repository/FakeFileRepository.java (1)
FakeFileRepository(9-33)
aics-domain/src/testFixtures/java/post/application/PostQueryServiceTest.java (2)
aics-domain/src/testFixtures/java/mock/repository/FakeFileRepository.java (1)
FakeFileRepository(9-33)aics-domain/src/testFixtures/java/mock/repository/FakeUserRepository.java (1)
FakeUserRepository(18-79)
aics-api/src/testFixtures/java/comment/application/CommentFacadeTest.java (1)
aics-domain/src/testFixtures/java/mock/repository/FakeFileRepository.java (1)
FakeFileRepository(9-33)
🪛 GitHub Actions: Validate Test Coverage and Upload to Codecov On Pull Request
aics-domain/src/testFixtures/java/post/application/PostQueryServiceTest.java
[error] 99-99: NullPointerException in PostQueryServiceTest.java at line 99 during test 'getPostById는 마지막 게시글 조회 시 다음 게시글은 null이어야 한다'.
[error] 77-77: NullPointerException in PostQueryServiceTest.java at line 77 during test 'getPostById는 해당 게시글과 이전, 다음 게시글을 조회할 수 있다'.
🔇 Additional comments (18)
aics-domain/src/main/java/kgu/developers/domain/user/application/query/UserQueryService.java (1)
18-19: 필요한 import 추가 LGTMaics-domain/src/testFixtures/java/mock/TestContainer.java (1)
116-118: PostQueryService 3-인자 생성자 연결 LGTMID 참조 전환에 따른 의존성 주입이 올바르게 반영되었습니다. 테스트 컨테이너 내 다른 사용처와도 일관됩니다.
aics-domain/src/testFixtures/java/mock/repository/FakeCommentRepository.java (1)
23-24: ID 참조 전환 저장 로직 적합builder에서
authorId,postId사용으로 PR 목적과 일관성 있게 반영되었습니다. 테스트 픽스처 관점에서도 적절합니다. (과거 러닝: List 유지 선호 사항과도 충돌 없음)aics-api/src/main/java/kgu/developers/api/post/presentation/response/PostSummaryPageResponse.java (1)
11-11: 필요한 import 추가 확인ID→이름 매핑 도입에 따른
Mapimport 추가는 적절합니다.aics-domain/src/testFixtures/java/comment/application/CommentQueryServiceTest.java (1)
58-59: 도메인 시그니처 변경 반영 적절
Post.create(..., String authorId, Long fileId, ...)로의 전환을 테스트가 정확히 따릅니다.aics-admin/src/testFixtures/java/post/application/PostAdminFacadeTest.java (2)
47-47: PostQueryService 생성자 변경 반영 OK리포지토리 3종을 주입하도록 수정된 시그니처에 맞게 테스트 초기화가 잘 맞춰졌습니다.
68-69: Post.create의 author 참조를 ID로 변경한 부분 적합
author.getId()전달로 ID 기반 도메인 변경을 올바르게 반영했습니다.aics-domain/src/testFixtures/java/mock/repository/FakePostRepository.java (1)
34-44: ID 참조 전환 저장 로직 적합(LGTM)authorId/fileId로의 매핑 전환이 일관되게 반영되었습니다. fileId를 null 허용으로 유지하는 것도 조회 단계의 유연성을 보장합니다.
aics-domain/src/main/java/kgu/developers/domain/post/application/query/PostQueryService.java (1)
26-27: 레포지토리 직접 주입 전환 적절(LGTM)조회 서비스 레이어에서 User/File을 로딩하도록 의존성 주입이 명확해졌습니다.
aics-domain/src/testFixtures/java/post/application/PostQueryServiceTest.java (2)
11-12: 의존성 임포트 추가 적절ID 참조 전환에 맞는 FakeFileRepository/FakeUserRepository 임포트 추가는 타당합니다.
31-33: 테스트 필드 추가 OK새 리포지토리 필드 주입으로 PostQueryService 시그니처 변경을 반영했습니다.
aics-api/src/testFixtures/java/comment/application/CommentFacadeTest.java (3)
43-48: PostQueryService 의존성 주입 정합성 확보파일/사용자 리포지토리까지 주입하도록 수정된 구성은 현재 도메인 변경과 일치합니다.
49-58: Facade/서비스 배선 개선 LGTMCommentCommandService가 외부에서 주입된 PostQueryService/UserQueryService를 사용하도록 정리되어 중복 생성을 줄였습니다.
69-79: ID 기반 생성 호출 전환 적절Post/Comment 생성 시 authorId, postId를 사용하도록 수정된 부분은 도메인 시그니처 변경과 일치합니다.
aics-api/src/testFixtures/java/post/application/PostFacadeTest.java (1)
71-81: ID 기반 Post 생성 호출 전환 LGTM
author.getId()사용으로 시그니처 변경을 정확히 반영했습니다.aics-domain/src/testFixtures/java/comment/application/CommentCommandServiceTest.java (3)
9-9: FakeFileRepository import 추가 적절테스트에서 PostQueryService가 파일 리포지토리를 요구하므로 import 보강은 타당합니다.
41-41: 파일 리포지토리 주입 추가 OK테스트 픽스처 내 의존성 구성이 실제 서비스 시그니처와 일치합니다.
63-65: 초기화 메서드 시그니처 확장 적절테스트 설정에서 추가된 리포지토리 의존성 반영이 잘 되어 있습니다.
Test Coverage Report
Files
|
Codecov Report❌ Patch coverage is
@@ Coverage Diff @@
## develop #259 +/- ##
=============================================
+ Coverage 91.42% 93.30% +1.87%
- Complexity 159 160 +1
=============================================
Files 49 49
Lines 455 463 +8
Branches 9 4 -5
=============================================
+ Hits 416 432 +16
+ Misses 29 26 -3
+ Partials 10 5 -5
... and 10 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
|
일단 테스트를 통과하도록 로직은 전부 변경했습니다. |
Summary
User,Post,Comment,FileEntity간의 관계 매핑을 ID 참조 기반으로 변경하였습니다.Tasks
User,Post,Comment,FileEntity간의 관계 매핑을 ID 참조 기반으로 변경