From 534966189d2441a09840748ab65b9ced40ef83c2 Mon Sep 17 00:00:00 2001 From: Minjae Chung Date: Wed, 18 Feb 2026 04:29:32 +0900 Subject: [PATCH] =?UTF-8?q?[fix]=20PostResponseDto=EC=97=90=20additionalCo?= =?UTF-8?q?mposers=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 큐레이션 임시저장 후 불러오기 시 additionalComposers 정보가 응답에 포함되도록 수정 Co-Authored-By: Claude Opus 4.6 --- .../server/post/dto/PostResponseDto.java | 14 +++++++ .../ComposerQueryControllerTest.java | 7 ++++ .../presentation/PostQueryControllerTest.java | 42 +++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/src/main/java/com/daramg/server/post/dto/PostResponseDto.java b/src/main/java/com/daramg/server/post/dto/PostResponseDto.java index 0501588..4ea93ab 100644 --- a/src/main/java/com/daramg/server/post/dto/PostResponseDto.java +++ b/src/main/java/com/daramg/server/post/dto/PostResponseDto.java @@ -25,6 +25,7 @@ public record PostResponseDto( String thumbnailImageUrl, PostType type, ComposerSummary primaryComposer, + List additionalComposers, Boolean isLiked, Boolean isScrapped ) { @@ -36,6 +37,7 @@ public static PostResponseDto from(Post post, Boolean isLiked, Boolean isScrappe List imageUrls = post.getImages(); PostType type = getPostType(post); ComposerSummary primaryComposer = extractPrimaryComposer(post); + List additionalComposers = extractAdditionalComposers(post); return new PostResponseDto( post.getId(), post.getTitle(), @@ -48,6 +50,7 @@ public static PostResponseDto from(Post post, Boolean isLiked, Boolean isScrappe imageUrls.isEmpty() ? null : imageUrls.getFirst(), type, primaryComposer, + additionalComposers, isLiked, isScrapped ); @@ -79,6 +82,17 @@ public static ComposerSummary from(Composer composer) { } } + private static List extractAdditionalComposers(Post post) { + if (post instanceof CurationPost curationPost + && curationPost.getAdditionalComposers() != null + && !curationPost.getAdditionalComposers().isEmpty()) { + return curationPost.getAdditionalComposers().stream() + .map(ComposerSummary::from) + .toList(); + } + return null; + } + private static PostType getPostType(Post post) { if (post instanceof StoryPost) { return PostType.STORY; diff --git a/src/test/java/com/daramg/server/composer/presentation/ComposerQueryControllerTest.java b/src/test/java/com/daramg/server/composer/presentation/ComposerQueryControllerTest.java index 7128ee0..263e341 100644 --- a/src/test/java/com/daramg/server/composer/presentation/ComposerQueryControllerTest.java +++ b/src/test/java/com/daramg/server/composer/presentation/ComposerQueryControllerTest.java @@ -109,6 +109,7 @@ public class ComposerQueryControllerTest extends ControllerTestSupport { "https://example.com/image1.jpg", PostType.STORY, null, + null, true, false ); @@ -125,6 +126,7 @@ public class ComposerQueryControllerTest extends ControllerTestSupport { null, PostType.CURATION, null, + null, false, true ); @@ -191,6 +193,11 @@ public class ComposerQueryControllerTest extends ControllerTestSupport { fieldWithPath("posts.content[].primaryComposer.koreanName").type(JsonFieldType.STRING).description("작곡가 한글 이름").optional(), fieldWithPath("posts.content[].primaryComposer.era").type(JsonFieldType.STRING).description("작곡가 시대 (Era)").optional(), fieldWithPath("posts.content[].primaryComposer.continent").type(JsonFieldType.STRING).description("작곡가 대륙 (Continent)").optional(), + fieldWithPath("posts.content[].additionalComposers").type(JsonFieldType.ARRAY).description("추가 작곡가 목록 (CURATION 타입일 때만 존재)").optional(), + fieldWithPath("posts.content[].additionalComposers[].id").type(JsonFieldType.NUMBER).description("추가 작곡가 ID").optional(), + fieldWithPath("posts.content[].additionalComposers[].koreanName").type(JsonFieldType.STRING).description("추가 작곡가 한글 이름").optional(), + fieldWithPath("posts.content[].additionalComposers[].era").type(JsonFieldType.STRING).description("추가 작곡가 시대 (Era)").optional(), + fieldWithPath("posts.content[].additionalComposers[].continent").type(JsonFieldType.STRING).description("추가 작곡가 대륙 (Continent)").optional(), fieldWithPath("posts.content[].isLiked").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 좋아요 여부 (비로그인 시 null)").optional(), fieldWithPath("posts.content[].isScrapped").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 스크랩 여부 (비로그인 시 null)").optional(), fieldWithPath("posts.nextCursor").type(JsonFieldType.STRING).description("다음 페이지 조회를 위한 커서 (Base64 인코딩된 문자열). 마지막 페이지인 경우 null").optional(), diff --git a/src/test/java/com/daramg/server/post/presentation/PostQueryControllerTest.java b/src/test/java/com/daramg/server/post/presentation/PostQueryControllerTest.java index e41055e..c478b2b 100644 --- a/src/test/java/com/daramg/server/post/presentation/PostQueryControllerTest.java +++ b/src/test/java/com/daramg/server/post/presentation/PostQueryControllerTest.java @@ -52,6 +52,7 @@ public class PostQueryControllerTest extends ControllerTestSupport { PostType.FREE, null, null, + null, null ); PostResponseDto freePost2 = new PostResponseDto( @@ -67,6 +68,7 @@ public class PostQueryControllerTest extends ControllerTestSupport { PostType.FREE, null, null, + null, null ); @@ -115,6 +117,11 @@ public class PostQueryControllerTest extends ControllerTestSupport { fieldWithPath("content[].primaryComposer.koreanName").type(JsonFieldType.STRING).description("작곡가 한글 이름").optional(), fieldWithPath("content[].primaryComposer.era").type(JsonFieldType.STRING).description("작곡가 시대 (Era)").optional(), fieldWithPath("content[].primaryComposer.continent").type(JsonFieldType.STRING).description("작곡가 대륙 (Continent)").optional(), + fieldWithPath("content[].additionalComposers").type(JsonFieldType.ARRAY).description("추가 작곡가 목록 (CURATION 타입일 때만 존재)").optional(), + fieldWithPath("content[].additionalComposers[].id").type(JsonFieldType.NUMBER).description("추가 작곡가 ID").optional(), + fieldWithPath("content[].additionalComposers[].koreanName").type(JsonFieldType.STRING).description("추가 작곡가 한글 이름").optional(), + fieldWithPath("content[].additionalComposers[].era").type(JsonFieldType.STRING).description("추가 작곡가 시대 (Era)").optional(), + fieldWithPath("content[].additionalComposers[].continent").type(JsonFieldType.STRING).description("추가 작곡가 대륙 (Continent)").optional(), fieldWithPath("content[].isLiked").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 좋아요 여부 (비로그인 시 null)").optional(), fieldWithPath("content[].isScrapped").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 스크랩 여부 (비로그인 시 null)").optional(), fieldWithPath("nextCursor").type(JsonFieldType.STRING).description("다음 페이지 조회를 위한 커서 (Base64 인코딩된 문자열). 마지막 페이지인 경우 null").optional(), @@ -140,6 +147,7 @@ public class PostQueryControllerTest extends ControllerTestSupport { "https://example.com/curation1.jpg", PostType.CURATION, null, // primaryComposer + null, // additionalComposers null, null ); @@ -155,6 +163,7 @@ public class PostQueryControllerTest extends ControllerTestSupport { null, PostType.CURATION, null, // primaryComposer + null, // additionalComposers null, null ); @@ -208,6 +217,11 @@ public class PostQueryControllerTest extends ControllerTestSupport { fieldWithPath("content[].primaryComposer.koreanName").type(JsonFieldType.STRING).description("작곡가 한글 이름").optional(), fieldWithPath("content[].primaryComposer.era").type(JsonFieldType.STRING).description("작곡가 시대 (Era)").optional(), fieldWithPath("content[].primaryComposer.continent").type(JsonFieldType.STRING).description("작곡가 대륙 (Continent)").optional(), + fieldWithPath("content[].additionalComposers").type(JsonFieldType.ARRAY).description("추가 작곡가 목록 (CURATION 타입일 때만 존재)").optional(), + fieldWithPath("content[].additionalComposers[].id").type(JsonFieldType.NUMBER).description("추가 작곡가 ID").optional(), + fieldWithPath("content[].additionalComposers[].koreanName").type(JsonFieldType.STRING).description("추가 작곡가 한글 이름").optional(), + fieldWithPath("content[].additionalComposers[].era").type(JsonFieldType.STRING).description("추가 작곡가 시대 (Era)").optional(), + fieldWithPath("content[].additionalComposers[].continent").type(JsonFieldType.STRING).description("추가 작곡가 대륙 (Continent)").optional(), fieldWithPath("content[].isLiked").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 좋아요 여부 (비로그인 시 null)").optional(), fieldWithPath("content[].isScrapped").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 스크랩 여부 (비로그인 시 null)").optional(), fieldWithPath("nextCursor").type(JsonFieldType.STRING).description("다음 페이지 조회를 위한 커서 (Base64 인코딩된 문자열). 마지막 페이지인 경우 null").optional(), @@ -234,6 +248,7 @@ public class PostQueryControllerTest extends ControllerTestSupport { PostType.STORY, null, null, + null, null ); PostResponseDto storyPost2 = new PostResponseDto( @@ -249,6 +264,7 @@ public class PostQueryControllerTest extends ControllerTestSupport { PostType.STORY, null, null, + null, null ); @@ -295,6 +311,11 @@ public class PostQueryControllerTest extends ControllerTestSupport { fieldWithPath("content[].primaryComposer.koreanName").type(JsonFieldType.STRING).description("작곡가 한글 이름").optional(), fieldWithPath("content[].primaryComposer.era").type(JsonFieldType.STRING).description("작곡가 시대 (Era)").optional(), fieldWithPath("content[].primaryComposer.continent").type(JsonFieldType.STRING).description("작곡가 대륙 (Continent)").optional(), + fieldWithPath("content[].additionalComposers").type(JsonFieldType.ARRAY).description("추가 작곡가 목록 (CURATION 타입일 때만 존재)").optional(), + fieldWithPath("content[].additionalComposers[].id").type(JsonFieldType.NUMBER).description("추가 작곡가 ID").optional(), + fieldWithPath("content[].additionalComposers[].koreanName").type(JsonFieldType.STRING).description("추가 작곡가 한글 이름").optional(), + fieldWithPath("content[].additionalComposers[].era").type(JsonFieldType.STRING).description("추가 작곡가 시대 (Era)").optional(), + fieldWithPath("content[].additionalComposers[].continent").type(JsonFieldType.STRING).description("추가 작곡가 대륙 (Continent)").optional(), fieldWithPath("content[].isLiked").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 좋아요 여부 (비로그인 시 null)").optional(), fieldWithPath("content[].isScrapped").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 스크랩 여부 (비로그인 시 null)").optional(), fieldWithPath("nextCursor").type(JsonFieldType.STRING).description("다음 페이지 조회를 위한 커서 (Base64 인코딩된 문자열). 마지막 페이지인 경우 null").optional(), @@ -322,6 +343,7 @@ public class PostQueryControllerTest extends ControllerTestSupport { PostType.FREE, null, null, + null, null ); PostResponseDto publishedPost2 = new PostResponseDto( @@ -337,6 +359,7 @@ public class PostQueryControllerTest extends ControllerTestSupport { PostType.STORY, null, null, + null, null ); @@ -388,6 +411,11 @@ public class PostQueryControllerTest extends ControllerTestSupport { fieldWithPath("content[].primaryComposer.koreanName").type(JsonFieldType.STRING).description("작곡가 한글 이름").optional(), fieldWithPath("content[].primaryComposer.era").type(JsonFieldType.STRING).description("작곡가 시대 (Era)").optional(), fieldWithPath("content[].primaryComposer.continent").type(JsonFieldType.STRING).description("작곡가 대륙 (Continent)").optional(), + fieldWithPath("content[].additionalComposers").type(JsonFieldType.ARRAY).description("추가 작곡가 목록 (CURATION 타입일 때만 존재)").optional(), + fieldWithPath("content[].additionalComposers[].id").type(JsonFieldType.NUMBER).description("추가 작곡가 ID").optional(), + fieldWithPath("content[].additionalComposers[].koreanName").type(JsonFieldType.STRING).description("추가 작곡가 한글 이름").optional(), + fieldWithPath("content[].additionalComposers[].era").type(JsonFieldType.STRING).description("추가 작곡가 시대 (Era)").optional(), + fieldWithPath("content[].additionalComposers[].continent").type(JsonFieldType.STRING).description("추가 작곡가 대륙 (Continent)").optional(), fieldWithPath("content[].isLiked").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 좋아요 여부 (비로그인 시 null)").optional(), fieldWithPath("content[].isScrapped").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 스크랩 여부 (비로그인 시 null)").optional(), fieldWithPath("nextCursor").type(JsonFieldType.STRING).description("다음 페이지 조회를 위한 커서 (Base64 인코딩된 문자열). 마지막 페이지인 경우 null").optional(), @@ -415,6 +443,7 @@ public class PostQueryControllerTest extends ControllerTestSupport { PostType.CURATION, null, null, + null, null ); PostResponseDto draftPost2 = new PostResponseDto( @@ -430,6 +459,7 @@ public class PostQueryControllerTest extends ControllerTestSupport { PostType.FREE, null, null, + null, null ); @@ -481,6 +511,11 @@ public class PostQueryControllerTest extends ControllerTestSupport { fieldWithPath("content[].primaryComposer.koreanName").type(JsonFieldType.STRING).description("작곡가 한글 이름").optional(), fieldWithPath("content[].primaryComposer.era").type(JsonFieldType.STRING).description("작곡가 시대 (Era)").optional(), fieldWithPath("content[].primaryComposer.continent").type(JsonFieldType.STRING).description("작곡가 대륙 (Continent)").optional(), + fieldWithPath("content[].additionalComposers").type(JsonFieldType.ARRAY).description("추가 작곡가 목록 (CURATION 타입일 때만 존재)").optional(), + fieldWithPath("content[].additionalComposers[].id").type(JsonFieldType.NUMBER).description("추가 작곡가 ID").optional(), + fieldWithPath("content[].additionalComposers[].koreanName").type(JsonFieldType.STRING).description("추가 작곡가 한글 이름").optional(), + fieldWithPath("content[].additionalComposers[].era").type(JsonFieldType.STRING).description("추가 작곡가 시대 (Era)").optional(), + fieldWithPath("content[].additionalComposers[].continent").type(JsonFieldType.STRING).description("추가 작곡가 대륙 (Continent)").optional(), fieldWithPath("content[].isLiked").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 좋아요 여부 (비로그인 시 null)").optional(), fieldWithPath("content[].isScrapped").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 스크랩 여부 (비로그인 시 null)").optional(), fieldWithPath("nextCursor").type(JsonFieldType.STRING).description("다음 페이지 조회를 위한 커서 (Base64 인코딩된 문자열). 마지막 페이지인 경우 null").optional(), @@ -508,6 +543,7 @@ public class PostQueryControllerTest extends ControllerTestSupport { PostType.STORY, null, null, + null, null ); PostResponseDto scrappedPost2 = new PostResponseDto( @@ -523,6 +559,7 @@ public class PostQueryControllerTest extends ControllerTestSupport { PostType.CURATION, null, null, + null, null ); @@ -572,6 +609,11 @@ public class PostQueryControllerTest extends ControllerTestSupport { fieldWithPath("content[].primaryComposer.koreanName").type(JsonFieldType.STRING).description("작곡가 한글 이름").optional(), fieldWithPath("content[].primaryComposer.era").type(JsonFieldType.STRING).description("작곡가 시대 (Era)").optional(), fieldWithPath("content[].primaryComposer.continent").type(JsonFieldType.STRING).description("작곡가 대륙 (Continent)").optional(), + fieldWithPath("content[].additionalComposers").type(JsonFieldType.ARRAY).description("추가 작곡가 목록 (CURATION 타입일 때만 존재)").optional(), + fieldWithPath("content[].additionalComposers[].id").type(JsonFieldType.NUMBER).description("추가 작곡가 ID").optional(), + fieldWithPath("content[].additionalComposers[].koreanName").type(JsonFieldType.STRING).description("추가 작곡가 한글 이름").optional(), + fieldWithPath("content[].additionalComposers[].era").type(JsonFieldType.STRING).description("추가 작곡가 시대 (Era)").optional(), + fieldWithPath("content[].additionalComposers[].continent").type(JsonFieldType.STRING).description("추가 작곡가 대륙 (Continent)").optional(), fieldWithPath("content[].isLiked").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 좋아요 여부 (비로그인 시 null)").optional(), fieldWithPath("content[].isScrapped").type(JsonFieldType.BOOLEAN).description("로그인한 유저의 스크랩 여부 (비로그인 시 null)").optional(), fieldWithPath("nextCursor").type(JsonFieldType.STRING).description("다음 페이지 조회를 위한 커서 (Base64 인코딩된 문자열). 마지막 페이지인 경우 null").optional(),