From 75ccd6a36c25bba55ac5e8a661e5e1ba8d1a7816 Mon Sep 17 00:00:00 2001 From: hgkim Date: Fri, 15 May 2026 15:57:38 +0900 Subject: [PATCH 01/33] =?UTF-8?q?feat:=20spec=20=EA=B8=B0=EB=B0=98=20?= =?UTF-8?q?=ED=81=90=EB=A0=88=EC=9D=B4=EC=85=98=20API=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/CurationSpecResourceSyncRunner.kt | 32 ++ .../AdminCurationSpecController.kt | 23 + .../AdminSpecBasedCurationController.kt | 44 ++ .../src/main/resources/application.yml | 4 + ...dminSpecBasedCurationControllerDocsTest.kt | 214 ++++++++ bottlenote-mono/build.gradle | 1 + .../repository/JpaAlcoholQueryRepository.java | 4 + .../bottlenote/curation/domain/Curation.java | 103 ++++ .../curation/domain/CurationExtension.java | 44 ++ .../domain/CurationExtensionRepository.java | 14 + .../curation/domain/CurationRepository.java | 21 + .../curation/domain/CurationSpec.java | 92 ++++ .../domain/CurationSpecRepository.java | 22 + .../dto/request/CurationCreateRequest.java | 27 + .../dto/request/CurationSearchRequest.java | 12 + .../request/CurationSpecCreateRequest.java | 12 + .../dto/request/CurationUpdateRequest.java | 21 + .../AdminSpecBasedCurationDetailResponse.java | 20 + .../AdminSpecBasedCurationListResponse.java | 12 + .../dto/response/CurationSpecResponse.java | 14 + .../response/CurationSpecSyncResponse.java | 8 + .../curation/exception/CurationException.java | 12 + .../exception/CurationExceptionCode.java | 29 + .../CurationAlcoholGraphqlResolver.java | 52 ++ .../JpaCurationExtensionRepository.java | 16 + .../repository/JpaCurationRepository.java | 26 + .../repository/JpaCurationSpecRepository.java | 22 + .../AdminSpecBasedCurationService.java | 204 +++++++ .../CurationAlcoholGraphqlService.java | 99 ++++ .../service/CurationPayloadValidator.java | 64 +++ .../CurationSpecResourceSyncService.java | 64 +++ .../curation/service/CurationV2Service.java | 101 ++++ .../support/CurationSpecResourceReader.java | 80 +++ .../picks/domain/PicksRepository.java | 3 + .../rating/domain/RatingRepository.java | 4 + .../repository/JpaRatingRepository.java | 10 + .../review/domain/ReviewRepository.java | 5 + .../main/resources/graphql/schema.graphqls | 19 + .../openapi/curation/recommended_whisky.json | 295 ++++++++++ .../openapi/curation/whisky_pairing.json | 409 ++++++++++++++ .../curation/whisky_tasting_event.json | 509 ++++++++++++++++++ .../CurationOpenApiSpecResourceTest.java | 58 ++ .../InMemoryCurationExtensionRepository.java | 28 + .../fixture/InMemoryCurationRepository.java | 63 +++ .../InMemoryCurationSpecRepository.java | 54 ++ .../CurationAlcoholGraphqlResolverTest.java | 208 +++++++ .../AdminSpecBasedCurationServiceTest.java | 171 ++++++ .../CurationSpecResourceSyncServiceTest.java | 56 ++ .../service/CurationV2ServiceTest.java | 142 +++++ .../graphql/CurationGraphqlSchemaTest.java | 45 ++ .../fixture/InMemoryReviewRepository.java | 12 + .../src/main/resources/application.yml | 4 + .../picks/fake/FakePicksRepository.java | 9 + .../fixture/InMemoryRatingRepository.java | 18 + .../fixture/InMemoryReviewRepository.java | 12 + .../app/rule/api/ControllerLayerRules.java | 14 + git.environment-variables | 2 +- gradle/libs.versions.toml | 1 + plan/spec-based-curation-v2-graphql-sdl.md | 293 ++++++++++ 59 files changed, 3956 insertions(+), 1 deletion(-) create mode 100644 bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/config/CurationSpecResourceSyncRunner.kt create mode 100644 bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminCurationSpecController.kt create mode 100644 bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminSpecBasedCurationController.kt create mode 100644 bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/domain/Curation.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationExtension.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationExtensionRepository.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationRepository.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationSpec.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationSpecRepository.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationCreateRequest.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationSearchRequest.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationSpecCreateRequest.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationUpdateRequest.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/AdminSpecBasedCurationDetailResponse.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/AdminSpecBasedCurationListResponse.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/CurationSpecResponse.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/CurationSpecSyncResponse.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationException.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationExceptionCode.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolver.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationExtensionRepository.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationRepository.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationSpecRepository.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/AdminSpecBasedCurationService.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationAlcoholGraphqlService.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationSpecResourceSyncService.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationV2Service.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/support/CurationSpecResourceReader.java create mode 100644 bottlenote-mono/src/main/resources/graphql/schema.graphqls create mode 100644 bottlenote-mono/src/main/resources/openapi/curation/recommended_whisky.json create mode 100644 bottlenote-mono/src/main/resources/openapi/curation/whisky_pairing.json create mode 100644 bottlenote-mono/src/main/resources/openapi/curation/whisky_tasting_event.json create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/CurationOpenApiSpecResourceTest.java create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationExtensionRepository.java create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationRepository.java create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationSpecRepository.java create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolverTest.java create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/service/AdminSpecBasedCurationServiceTest.java create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationSpecResourceSyncServiceTest.java create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationV2ServiceTest.java create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/graphql/CurationGraphqlSchemaTest.java create mode 100644 plan/spec-based-curation-v2-graphql-sdl.md diff --git a/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/config/CurationSpecResourceSyncRunner.kt b/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/config/CurationSpecResourceSyncRunner.kt new file mode 100644 index 000000000..3d2f5d4f1 --- /dev/null +++ b/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/config/CurationSpecResourceSyncRunner.kt @@ -0,0 +1,32 @@ +package app.bottlenote.curation.config + +import app.bottlenote.curation.service.CurationSpecResourceSyncService +import org.slf4j.LoggerFactory +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.context.event.ApplicationReadyEvent +import org.springframework.context.event.EventListener +import org.springframework.stereotype.Component + +@Component +@ConditionalOnProperty( + prefix = "curation.spec-sync", + name = ["enabled"], + havingValue = "true", + matchIfMissing = true +) +class CurationSpecResourceSyncRunner( + private val curationSpecResourceSyncService: CurationSpecResourceSyncService +) { + private val log = LoggerFactory.getLogger(javaClass) + + @EventListener(ApplicationReadyEvent::class) + fun sync() { + val result = curationSpecResourceSyncService.sync() + log.info( + "큐레이션 스펙 리소스 동기화 완료: created={}, updated={}, total={}", + result.createdCount(), + result.updatedCount(), + result.totalCount() + ) + } +} diff --git a/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminCurationSpecController.kt b/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminCurationSpecController.kt new file mode 100644 index 000000000..2ae760b0f --- /dev/null +++ b/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminCurationSpecController.kt @@ -0,0 +1,23 @@ +package app.bottlenote.curation.presentation + +import app.bottlenote.curation.service.AdminSpecBasedCurationService +import app.bottlenote.global.data.response.GlobalResponse +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/curation-specs") +class AdminCurationSpecController( + private val adminSpecBasedCurationService: AdminSpecBasedCurationService +) { + @GetMapping + fun list(): ResponseEntity<*> = GlobalResponse.ok(adminSpecBasedCurationService.listSpecs()) + + @GetMapping("/{specId}") + fun detail( + @PathVariable specId: Long + ): ResponseEntity<*> = GlobalResponse.ok(adminSpecBasedCurationService.getSpecDetail(specId)) +} diff --git a/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminSpecBasedCurationController.kt b/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminSpecBasedCurationController.kt new file mode 100644 index 000000000..c84cbb364 --- /dev/null +++ b/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminSpecBasedCurationController.kt @@ -0,0 +1,44 @@ +package app.bottlenote.curation.presentation + +import app.bottlenote.curation.dto.request.CurationCreateRequest +import app.bottlenote.curation.dto.request.CurationSearchRequest +import app.bottlenote.curation.dto.request.CurationUpdateRequest +import app.bottlenote.curation.service.AdminSpecBasedCurationService +import app.bottlenote.global.data.response.GlobalResponse +import jakarta.validation.Valid +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.ModelAttribute +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.PutMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/spec-based-curations") +class AdminSpecBasedCurationController( + private val adminSpecBasedCurationService: AdminSpecBasedCurationService +) { + @GetMapping + fun list( + @ModelAttribute request: CurationSearchRequest + ): ResponseEntity = ResponseEntity.ok(adminSpecBasedCurationService.search(request)) + + @GetMapping("/{curationId}") + fun detail( + @PathVariable curationId: Long + ): ResponseEntity<*> = GlobalResponse.ok(adminSpecBasedCurationService.getDetail(curationId)) + + @PostMapping + fun create( + @RequestBody @Valid request: CurationCreateRequest + ): ResponseEntity<*> = GlobalResponse.ok(adminSpecBasedCurationService.create(request)) + + @PutMapping("/{curationId}") + fun update( + @PathVariable curationId: Long, + @RequestBody @Valid request: CurationUpdateRequest + ): ResponseEntity<*> = GlobalResponse.ok(adminSpecBasedCurationService.update(curationId, request)) +} diff --git a/bottlenote-admin-api/src/main/resources/application.yml b/bottlenote-admin-api/src/main/resources/application.yml index 49e516919..37aec8d13 100644 --- a/bottlenote-admin-api/src/main/resources/application.yml +++ b/bottlenote-admin-api/src/main/resources/application.yml @@ -62,6 +62,10 @@ schedules: sync: enable: false +curation: + spec-sync: + enabled: ${CURATION_SPEC_SYNC_ENABLED:true} + root: admin: email: ${ROOT_ADMIN_EMAIL:email@email.com} diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt new file mode 100644 index 000000000..61f37f023 --- /dev/null +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt @@ -0,0 +1,214 @@ +package app.docs.curation + +import app.bottlenote.curation.dto.request.CurationCreateRequest +import app.bottlenote.curation.dto.request.CurationSearchRequest +import app.bottlenote.curation.dto.request.CurationUpdateRequest +import app.bottlenote.curation.dto.response.AdminSpecBasedCurationDetailResponse +import app.bottlenote.curation.dto.response.AdminSpecBasedCurationListResponse +import app.bottlenote.curation.dto.response.CurationSpecResponse +import app.bottlenote.curation.presentation.AdminCurationSpecController +import app.bottlenote.curation.presentation.AdminSpecBasedCurationController +import app.bottlenote.curation.service.AdminSpecBasedCurationService +import app.bottlenote.global.data.response.GlobalResponse +import app.bottlenote.global.dto.response.AdminResultResponse +import com.fasterxml.jackson.databind.ObjectMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyLong +import org.mockito.BDDMockito.given +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.data.domain.PageImpl +import org.springframework.http.MediaType +import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document +import org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest +import org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse +import org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint +import org.springframework.test.context.bean.override.mockito.MockitoBean +import org.springframework.test.web.servlet.assertj.MockMvcTester +import java.time.LocalDate +import java.time.LocalDateTime + +@WebMvcTest( + controllers = [ + AdminSpecBasedCurationController::class, + AdminCurationSpecController::class + ], + excludeAutoConfiguration = [SecurityAutoConfiguration::class] +) +@AutoConfigureRestDocs +@DisplayName("Admin Spec Based Curation 컨트롤러 RestDocs 테스트") +class AdminSpecBasedCurationControllerDocsTest { + + @Autowired + private lateinit var mvc: MockMvcTester + + @Autowired + private lateinit var mapper: ObjectMapper + + @MockitoBean + private lateinit var adminSpecBasedCurationService: AdminSpecBasedCurationService + + @Test + @DisplayName("큐레이션 스펙 목록을 조회할 수 있다") + fun listSpecs() { + given(adminSpecBasedCurationService.listSpecs()).willReturn(listOf(specResponse())) + + assertThat(mvc.get().uri("/curation-specs")) + .hasStatusOk() + .apply( + document( + "admin/curation-specs/list", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()) + ) + ) + } + + @Test + @DisplayName("큐레이션 스펙 상세를 조회할 수 있다") + fun getSpecDetail() { + given(adminSpecBasedCurationService.getSpecDetail(anyLong())).willReturn(specResponse()) + + assertThat(mvc.get().uri("/curation-specs/{specId}", 1L)) + .hasStatusOk() + .apply( + document( + "admin/curation-specs/detail", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()) + ) + ) + } + + @Test + @DisplayName("spec 기반 큐레이션 목록을 조회할 수 있다") + fun listCurations() { + given(adminSpecBasedCurationService.search(any(CurationSearchRequest::class.java))) + .willReturn(GlobalResponse.fromPage(PageImpl(listOf(listResponse())))) + + assertThat(mvc.get().uri("/spec-based-curations?keyword=&isActive=true&page=0&size=20")) + .hasStatusOk() + .apply( + document( + "admin/spec-based-curations/list", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()) + ) + ) + } + + @Test + @DisplayName("spec 기반 큐레이션 상세를 조회할 수 있다") + fun getDetail() { + given(adminSpecBasedCurationService.getDetail(anyLong())).willReturn(detailResponse()) + + assertThat(mvc.get().uri("/spec-based-curations/{curationId}", 1L)) + .hasStatusOk() + .apply( + document( + "admin/spec-based-curations/detail", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()) + ) + ) + } + + @Test + @DisplayName("spec 기반 큐레이션을 등록할 수 있다") + fun create() { + given(adminSpecBasedCurationService.create(any(CurationCreateRequest::class.java))) + .willReturn(AdminResultResponse.of(AdminResultResponse.ResultCode.CURATION_CREATED, 1L)) + + assertThat( + mvc.post().uri("/spec-based-curations") + .contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(createRequest())) + ) + .hasStatusOk() + .apply( + document( + "admin/spec-based-curations/create", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()) + ) + ) + } + + @Test + @DisplayName("spec 기반 큐레이션을 수정할 수 있다") + fun update() { + given(adminSpecBasedCurationService.update(anyLong(), any(CurationUpdateRequest::class.java))) + .willReturn(AdminResultResponse.of(AdminResultResponse.ResultCode.CURATION_UPDATED, 1L)) + + assertThat( + mvc.put().uri("/spec-based-curations/{curationId}", 1L) + .contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(updateRequest())) + ) + .hasStatusOk() + .apply( + document( + "admin/spec-based-curations/update", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()) + ) + ) + } + + private fun specResponse(): CurationSpecResponse = CurationSpecResponse( + 1L, + "RECOMMENDED_WHISKY", + "추천 위스키", + "추천 위스키 카드 목록", + "alcohol", + 1, + true, + mapOf("type" to "object", "required" to listOf("source", "alcohol")), + mapOf("type" to "object") + ) + + private fun listResponse(): AdminSpecBasedCurationListResponse = AdminSpecBasedCurationListResponse( + 1L, + 1L, + "RECOMMENDED_WHISKY", + "비 오는 날 위스키", + 1, + true, + LocalDateTime.of(2026, 5, 15, 0, 0) + ) + + private fun detailResponse(): AdminSpecBasedCurationDetailResponse = AdminSpecBasedCurationDetailResponse( + 1L, + "비 오는 날 위스키", + "스모키 위스키 추천", + "https://cdn.example.com/cover.jpg", + listOf("https://cdn.example.com/cover.jpg"), + LocalDate.of(2026, 6, 1), + LocalDate.of(2026, 6, 30), + 1, + true, + LocalDateTime.of(2026, 5, 15, 0, 0), + LocalDateTime.of(2026, 5, 15, 0, 0), + specResponse(), + mapOf("source" to "BOTTLE_NOTE", "alcohol" to mapOf("korName" to "테스트 위스키")) + ) + + private fun createRequest(): Map = mapOf( + "specId" to 1L, + "name" to "비 오는 날 위스키", + "description" to "스모키 위스키 추천", + "imageUrls" to listOf("https://cdn.example.com/cover.jpg"), + "exposureStartDate" to "2026-06-01", + "exposureEndDate" to "2026-06-30", + "displayOrder" to 1, + "isActive" to true, + "payload" to mapOf("source" to "BOTTLE_NOTE", "alcohol" to mapOf("korName" to "테스트 위스키")) + ) + + private fun updateRequest(): Map = createRequest() + mapOf("name" to "수정된 큐레이션") +} diff --git a/bottlenote-mono/build.gradle b/bottlenote-mono/build.gradle index 1c84e6120..4564a4363 100644 --- a/bottlenote-mono/build.gradle +++ b/bottlenote-mono/build.gradle @@ -4,6 +4,7 @@ dependencies { // ===== Core ===== implementation libs.spring.boot.starter.web + implementation libs.spring.boot.starter.graphql implementation libs.spring.boot.starter.validation // ===== Database ===== diff --git a/bottlenote-mono/src/main/java/app/bottlenote/alcohols/repository/JpaAlcoholQueryRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/alcohols/repository/JpaAlcoholQueryRepository.java index 60185e559..b249a052d 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/alcohols/repository/JpaAlcoholQueryRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/alcohols/repository/JpaAlcoholQueryRepository.java @@ -12,6 +12,10 @@ public interface JpaAlcoholQueryRepository extends AlcoholQueryRepository, JpaRepository, CustomAlcoholQueryRepository { + @Override + @Query("select distinct a from alcohol a left join fetch a.region where a.id in :ids") + List findAllByIdIn(@Param("ids") List ids); + @Override @Query( """ diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/Curation.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/Curation.java new file mode 100644 index 000000000..4ff794e11 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/Curation.java @@ -0,0 +1,103 @@ +package app.bottlenote.curation.domain; + +import app.bottlenote.common.domain.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import java.time.LocalDate; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Comment; + +@Comment("spec 기반 큐레이션") +@Entity(name = "curation") +@Table(name = "curation") +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class Curation extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Comment("큐레이션 스펙 ID") + @Column(name = "spec_id", nullable = false) + private Long specId; + + @Comment("큐레이션명") + @Column(name = "name", nullable = false, length = 120) + private String name; + + @Comment("큐레이션 설명") + @Column(name = "description", columnDefinition = "TEXT") + private String description; + + @Comment("대표 이미지 URL") + @Column(name = "cover_image_url", nullable = false, length = 2048) + private String coverImageUrl; + + @Comment("추가 이미지 URL 2") + @Column(name = "image_url_2", length = 2048) + private String imageUrl2; + + @Comment("추가 이미지 URL 3") + @Column(name = "image_url_3", length = 2048) + private String imageUrl3; + + @Comment("노출 시작일") + @Column(name = "exposure_start_date") + private LocalDate exposureStartDate; + + @Comment("노출 종료일") + @Column(name = "exposure_end_date") + private LocalDate exposureEndDate; + + @Builder.Default + @Comment("노출 순서") + @Column(name = "display_order", nullable = false) + private Integer displayOrder = 0; + + @Builder.Default + @Comment("활성화 여부") + @Column(name = "is_active", nullable = false) + private Boolean isActive = true; + + public void update( + Long specId, + String name, + String description, + String coverImageUrl, + String imageUrl2, + String imageUrl3, + LocalDate exposureStartDate, + LocalDate exposureEndDate, + Integer displayOrder, + Boolean isActive) { + this.specId = specId; + this.name = name; + this.description = description; + this.coverImageUrl = coverImageUrl; + this.imageUrl2 = imageUrl2; + this.imageUrl3 = imageUrl3; + this.exposureStartDate = exposureStartDate; + this.exposureEndDate = exposureEndDate; + this.displayOrder = displayOrder != null ? displayOrder : this.displayOrder; + this.isActive = isActive != null ? isActive : this.isActive; + } + + public void updateStatus(Boolean isActive) { + this.isActive = isActive; + } + + public void updateDisplayOrder(Integer displayOrder) { + this.displayOrder = displayOrder; + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationExtension.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationExtension.java new file mode 100644 index 000000000..9d04615cf --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationExtension.java @@ -0,0 +1,44 @@ +package app.bottlenote.curation.domain; + +import app.bottlenote.common.domain.BaseEntity; +import io.hypersistence.utils.hibernate.type.json.JsonType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Comment; +import org.hibernate.annotations.Type; + +@Comment("spec 기반 큐레이션 payload") +@Entity(name = "curation_extension") +@Table(name = "curation_extension") +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class CurationExtension extends BaseEntity { + + @Id + @Comment("큐레이션 ID") + @Column(name = "curation_id") + private Long curationId; + + @Comment("큐레이션 스펙 ID") + @Column(name = "spec_id", nullable = false) + private Long specId; + + @Comment("request spec 검증을 통과한 payload") + @Column(name = "payload", nullable = false, columnDefinition = "json") + @Type(JsonType.class) + private Object payload; + + public void update(Long specId, Object payload) { + this.specId = specId; + this.payload = payload; + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationExtensionRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationExtensionRepository.java new file mode 100644 index 000000000..bf79b8edd --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationExtensionRepository.java @@ -0,0 +1,14 @@ +package app.bottlenote.curation.domain; + +import app.bottlenote.common.annotation.DomainRepository; +import java.util.Optional; + +@DomainRepository +public interface CurationExtensionRepository { + + Optional findByCurationId(Long curationId); + + CurationExtension save(CurationExtension curationExtension); + + void deleteByCurationId(Long curationId); +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationRepository.java new file mode 100644 index 000000000..059bd2493 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationRepository.java @@ -0,0 +1,21 @@ +package app.bottlenote.curation.domain; + +import app.bottlenote.common.annotation.DomainRepository; +import java.util.List; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +@DomainRepository +public interface CurationRepository { + + Optional findById(Long id); + + List findAllByIsActiveTrueOrderByDisplayOrderAscIdAsc(); + + Page searchForAdmin(String keyword, Boolean isActive, Pageable pageable); + + Curation save(Curation curation); + + void delete(Curation curation); +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationSpec.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationSpec.java new file mode 100644 index 000000000..fe3f455a6 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationSpec.java @@ -0,0 +1,92 @@ +package app.bottlenote.curation.domain; + +import app.bottlenote.common.domain.BaseEntity; +import io.hypersistence.utils.hibernate.type.json.JsonType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import java.util.LinkedHashMap; +import java.util.Map; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Comment; +import org.hibernate.annotations.Type; + +@Comment("spec 기반 큐레이션 스펙") +@Entity(name = "curation_spec") +@Table(name = "curation_spec") +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class CurationSpec extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Comment("스펙 코드") + @Column(name = "code", nullable = false, length = 80) + private String code; + + @Comment("스펙 표시명") + @Column(name = "name", nullable = false, length = 120) + private String name; + + @Comment("스펙 설명") + @Column(name = "description", columnDefinition = "TEXT") + private String description; + + @Builder.Default + @Comment("OpenAPI request schema") + @Column(name = "request_spec", nullable = false, columnDefinition = "json") + @Type(JsonType.class) + private Map requestSpec = new LinkedHashMap<>(); + + @Builder.Default + @Comment("OpenAPI response schema") + @Column(name = "response_spec", nullable = false, columnDefinition = "json") + @Type(JsonType.class) + private Map responseSpec = new LinkedHashMap<>(); + + @Comment("GraphQL hydration 식별자") + @Column(name = "hydrator_key", nullable = false, length = 80) + private String hydratorKey; + + @Builder.Default + @Comment("스펙 버전") + @Column(name = "version", nullable = false) + private Integer version = 1; + + @Builder.Default + @Comment("활성화 여부") + @Column(name = "is_active", nullable = false) + private Boolean isActive = true; + + public void update( + String name, + String description, + Map requestSpec, + Map responseSpec, + String hydratorKey, + Integer version, + Boolean isActive) { + this.name = name; + this.description = description; + this.requestSpec = copyOf(requestSpec); + this.responseSpec = copyOf(responseSpec); + this.hydratorKey = hydratorKey; + this.version = version != null ? version : this.version; + this.isActive = isActive != null ? isActive : this.isActive; + } + + private static Map copyOf(Map value) { + return value != null ? new LinkedHashMap<>(value) : new LinkedHashMap<>(); + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationSpecRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationSpecRepository.java new file mode 100644 index 000000000..18a91eeb5 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationSpecRepository.java @@ -0,0 +1,22 @@ +package app.bottlenote.curation.domain; + +import app.bottlenote.common.annotation.DomainRepository; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +@DomainRepository +public interface CurationSpecRepository { + + Optional findById(Long id); + + Optional findByCode(String code); + + List findAllByIsActiveTrueOrderByIdAsc(); + + List findAllByIdIn(Collection ids); + + boolean existsByCode(String code); + + CurationSpec save(CurationSpec curationSpec); +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationCreateRequest.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationCreateRequest.java new file mode 100644 index 000000000..453163fa2 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationCreateRequest.java @@ -0,0 +1,27 @@ +package app.bottlenote.curation.dto.request; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.time.LocalDate; +import java.util.List; + +public record CurationCreateRequest( + @NotNull(message = "큐레이션 스펙 ID는 필수입니다.") Long specId, + @NotBlank(message = "큐레이션 이름은 필수입니다.") String name, + String description, + @NotEmpty(message = "큐레이션 이미지는 최소 1개 이상이어야 합니다.") + @Size(max = 3, message = "큐레이션 이미지는 최대 3개까지 등록할 수 있습니다.") + List imageUrls, + LocalDate exposureStartDate, + LocalDate exposureEndDate, + Integer displayOrder, + Boolean isActive, + @NotNull(message = "payload는 필수입니다.") Object payload) { + + public CurationCreateRequest { + displayOrder = displayOrder != null ? displayOrder : 0; + isActive = isActive != null ? isActive : true; + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationSearchRequest.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationSearchRequest.java new file mode 100644 index 000000000..7f82f2322 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationSearchRequest.java @@ -0,0 +1,12 @@ +package app.bottlenote.curation.dto.request; + +import lombok.Builder; + +public record CurationSearchRequest(String keyword, Boolean isActive, Integer page, Integer size) { + + @Builder + public CurationSearchRequest { + page = page != null ? page : 0; + size = size != null ? size : 20; + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationSpecCreateRequest.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationSpecCreateRequest.java new file mode 100644 index 000000000..04fce36db --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationSpecCreateRequest.java @@ -0,0 +1,12 @@ +package app.bottlenote.curation.dto.request; + +import java.util.Map; + +public record CurationSpecCreateRequest( + String code, + String name, + String description, + Map requestSpec, + Map responseSpec, + String hydratorKey, + Integer version) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationUpdateRequest.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationUpdateRequest.java new file mode 100644 index 000000000..a4ac309c7 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationUpdateRequest.java @@ -0,0 +1,21 @@ +package app.bottlenote.curation.dto.request; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.time.LocalDate; +import java.util.List; + +public record CurationUpdateRequest( + @NotNull(message = "큐레이션 스펙 ID는 필수입니다.") Long specId, + @NotBlank(message = "큐레이션 이름은 필수입니다.") String name, + String description, + @NotEmpty(message = "큐레이션 이미지는 최소 1개 이상이어야 합니다.") + @Size(max = 3, message = "큐레이션 이미지는 최대 3개까지 등록할 수 있습니다.") + List imageUrls, + LocalDate exposureStartDate, + LocalDate exposureEndDate, + @NotNull(message = "노출 순서는 필수입니다.") Integer displayOrder, + @NotNull(message = "활성화 상태는 필수입니다.") Boolean isActive, + @NotNull(message = "payload는 필수입니다.") Object payload) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/AdminSpecBasedCurationDetailResponse.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/AdminSpecBasedCurationDetailResponse.java new file mode 100644 index 000000000..ba849897e --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/AdminSpecBasedCurationDetailResponse.java @@ -0,0 +1,20 @@ +package app.bottlenote.curation.dto.response; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +public record AdminSpecBasedCurationDetailResponse( + Long id, + String name, + String description, + String coverImageUrl, + List imageUrls, + LocalDate exposureStartDate, + LocalDate exposureEndDate, + Integer displayOrder, + Boolean isActive, + LocalDateTime createdAt, + LocalDateTime modifiedAt, + CurationSpecResponse spec, + Object payload) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/AdminSpecBasedCurationListResponse.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/AdminSpecBasedCurationListResponse.java new file mode 100644 index 000000000..ebd1ecf16 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/AdminSpecBasedCurationListResponse.java @@ -0,0 +1,12 @@ +package app.bottlenote.curation.dto.response; + +import java.time.LocalDateTime; + +public record AdminSpecBasedCurationListResponse( + Long id, + Long specId, + String specCode, + String name, + Integer displayOrder, + Boolean isActive, + LocalDateTime createdAt) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/CurationSpecResponse.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/CurationSpecResponse.java new file mode 100644 index 000000000..33e756aa2 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/CurationSpecResponse.java @@ -0,0 +1,14 @@ +package app.bottlenote.curation.dto.response; + +import java.util.Map; + +public record CurationSpecResponse( + Long id, + String code, + String name, + String description, + String hydratorKey, + Integer version, + Boolean isActive, + Map requestSpec, + Map responseSpec) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/CurationSpecSyncResponse.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/CurationSpecSyncResponse.java new file mode 100644 index 000000000..a41e3de5a --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/CurationSpecSyncResponse.java @@ -0,0 +1,8 @@ +package app.bottlenote.curation.dto.response; + +public record CurationSpecSyncResponse(int createdCount, int updatedCount) { + + public int totalCount() { + return createdCount + updatedCount; + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationException.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationException.java new file mode 100644 index 000000000..ef22b7140 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationException.java @@ -0,0 +1,12 @@ +package app.bottlenote.curation.exception; + +import app.bottlenote.global.exception.custom.AbstractCustomException; +import lombok.Getter; + +@Getter +public class CurationException extends AbstractCustomException { + + public CurationException(CurationExceptionCode code) { + super(code); + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationExceptionCode.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationExceptionCode.java new file mode 100644 index 000000000..e31f34e3b --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationExceptionCode.java @@ -0,0 +1,29 @@ +package app.bottlenote.curation.exception; + +import app.bottlenote.global.exception.custom.code.ExceptionCode; +import org.springframework.http.HttpStatus; + +public enum CurationExceptionCode implements ExceptionCode { + CURATION_SPEC_NOT_FOUND(HttpStatus.NOT_FOUND, "큐레이션 스펙을 찾을 수 없습니다."), + CURATION_SPEC_DUPLICATE_CODE(HttpStatus.CONFLICT, "동일한 큐레이션 스펙 코드가 이미 존재합니다."), + CURATION_NOT_FOUND(HttpStatus.NOT_FOUND, "큐레이션을 찾을 수 없습니다."), + CURATION_PAYLOAD_INVALID(HttpStatus.BAD_REQUEST, "큐레이션 payload가 스펙과 일치하지 않습니다."); + + private final HttpStatus httpStatus; + private final String message; + + CurationExceptionCode(HttpStatus httpStatus, String message) { + this.httpStatus = httpStatus; + this.message = message; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public HttpStatus getHttpStatus() { + return httpStatus; + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolver.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolver.java new file mode 100644 index 000000000..4b8d36c49 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolver.java @@ -0,0 +1,52 @@ +package app.bottlenote.curation.graphql; + +import app.bottlenote.alcohols.domain.Alcohol; +import app.bottlenote.curation.service.CurationAlcoholGraphqlService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.graphql.data.method.annotation.Argument; +import org.springframework.graphql.data.method.annotation.QueryMapping; +import org.springframework.graphql.data.method.annotation.SchemaMapping; +import org.springframework.stereotype.Controller; + +@Controller +@RequiredArgsConstructor +public class CurationAlcoholGraphqlResolver { + + private final CurationAlcoholGraphqlService curationAlcoholGraphqlService; + + @QueryMapping + public List alcohols(@Argument List ids) { + return curationAlcoholGraphqlService.findAlcohols(ids); + } + + @SchemaMapping(typeName = "Alcohol", field = "alcoholId") + public Long alcoholId(Alcohol alcohol) { + return alcohol.getId(); + } + + @SchemaMapping(typeName = "Alcohol", field = "regionName") + public String regionName(Alcohol alcohol) { + return curationAlcoholGraphqlService.regionName(alcohol); + } + + @SchemaMapping(typeName = "Alcohol", field = "rating") + public Double rating(Alcohol alcohol) { + return curationAlcoholGraphqlService.rating(alcohol); + } + + @SchemaMapping(typeName = "Alcohol", field = "totalRatingsCount") + public Long totalRatingsCount(Alcohol alcohol) { + return curationAlcoholGraphqlService.totalRatingsCount(alcohol); + } + + @SchemaMapping(typeName = "Alcohol", field = "reviewCount") + public Long reviewCount(Alcohol alcohol) { + return curationAlcoholGraphqlService.reviewCount(alcohol); + } + + @SchemaMapping(typeName = "Alcohol", field = "totalPickCount") + public Long totalPickCount(Alcohol alcohol) { + return curationAlcoholGraphqlService.totalPickCount(alcohol); + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationExtensionRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationExtensionRepository.java new file mode 100644 index 000000000..d1013796a --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationExtensionRepository.java @@ -0,0 +1,16 @@ +package app.bottlenote.curation.repository; + +import app.bottlenote.common.annotation.JpaRepositoryImpl; +import app.bottlenote.curation.domain.CurationExtension; +import app.bottlenote.curation.domain.CurationExtensionRepository; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +@JpaRepositoryImpl +public interface JpaCurationExtensionRepository + extends CurationExtensionRepository, JpaRepository { + + Optional findByCurationId(Long curationId); + + void deleteByCurationId(Long curationId); +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationRepository.java new file mode 100644 index 000000000..70db59308 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationRepository.java @@ -0,0 +1,26 @@ +package app.bottlenote.curation.repository; + +import app.bottlenote.common.annotation.JpaRepositoryImpl; +import app.bottlenote.curation.domain.Curation; +import app.bottlenote.curation.domain.CurationRepository; +import java.util.List; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +@JpaRepositoryImpl +public interface JpaCurationRepository extends CurationRepository, JpaRepository { + + List findAllByIsActiveTrueOrderByDisplayOrderAscIdAsc(); + + @Query( + """ + SELECT c + FROM curation c + WHERE (:keyword IS NULL OR :keyword = '' OR c.name LIKE CONCAT('%', :keyword, '%')) + AND (:isActive IS NULL OR c.isActive = :isActive) + ORDER BY c.displayOrder ASC, c.id ASC + """) + Page searchForAdmin(String keyword, Boolean isActive, Pageable pageable); +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationSpecRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationSpecRepository.java new file mode 100644 index 000000000..96acc0db5 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationSpecRepository.java @@ -0,0 +1,22 @@ +package app.bottlenote.curation.repository; + +import app.bottlenote.common.annotation.JpaRepositoryImpl; +import app.bottlenote.curation.domain.CurationSpec; +import app.bottlenote.curation.domain.CurationSpecRepository; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +@JpaRepositoryImpl +public interface JpaCurationSpecRepository + extends CurationSpecRepository, JpaRepository { + + Optional findByCode(String code); + + List findAllByIsActiveTrueOrderByIdAsc(); + + List findAllByIdIn(Collection ids); + + boolean existsByCode(String code); +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/AdminSpecBasedCurationService.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/AdminSpecBasedCurationService.java new file mode 100644 index 000000000..0b25e116e --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/AdminSpecBasedCurationService.java @@ -0,0 +1,204 @@ +package app.bottlenote.curation.service; + +import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_NOT_FOUND; +import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_PAYLOAD_INVALID; +import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_SPEC_NOT_FOUND; +import static app.bottlenote.global.dto.response.AdminResultResponse.ResultCode.CURATION_CREATED; +import static app.bottlenote.global.dto.response.AdminResultResponse.ResultCode.CURATION_UPDATED; + +import app.bottlenote.curation.domain.Curation; +import app.bottlenote.curation.domain.CurationExtension; +import app.bottlenote.curation.domain.CurationExtensionRepository; +import app.bottlenote.curation.domain.CurationRepository; +import app.bottlenote.curation.domain.CurationSpec; +import app.bottlenote.curation.domain.CurationSpecRepository; +import app.bottlenote.curation.dto.request.CurationCreateRequest; +import app.bottlenote.curation.dto.request.CurationSearchRequest; +import app.bottlenote.curation.dto.request.CurationUpdateRequest; +import app.bottlenote.curation.dto.response.AdminSpecBasedCurationDetailResponse; +import app.bottlenote.curation.dto.response.AdminSpecBasedCurationListResponse; +import app.bottlenote.curation.dto.response.CurationSpecResponse; +import app.bottlenote.curation.exception.CurationException; +import app.bottlenote.curation.service.CurationPayloadValidator.MapBackedSchema; +import app.bottlenote.global.data.response.GlobalResponse; +import app.bottlenote.global.dto.response.AdminResultResponse; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class AdminSpecBasedCurationService { + + private final CurationSpecRepository curationSpecRepository; + private final CurationRepository curationRepository; + private final CurationExtensionRepository curationExtensionRepository; + private final CurationPayloadValidator curationPayloadValidator; + + @Transactional(readOnly = true) + public List listSpecs() { + return curationSpecRepository.findAllByIsActiveTrueOrderByIdAsc().stream() + .map(this::toSpecResponse) + .toList(); + } + + @Transactional(readOnly = true) + public CurationSpecResponse getSpecDetail(Long specId) { + return toSpecResponse(getSpec(specId)); + } + + @Transactional(readOnly = true) + public GlobalResponse search(CurationSearchRequest request) { + PageRequest pageable = PageRequest.of(request.page(), request.size()); + Page page = + curationRepository.searchForAdmin(request.keyword(), request.isActive(), pageable); + Map specMap = + curationSpecRepository + .findAllByIdIn( + page.getContent().stream().map(Curation::getSpecId).collect(Collectors.toSet())) + .stream() + .collect(Collectors.toMap(CurationSpec::getId, Function.identity())); + return GlobalResponse.fromPage( + page.map(curation -> toListResponse(curation, specMap.get(curation.getSpecId())))); + } + + @Transactional(readOnly = true) + public AdminSpecBasedCurationDetailResponse getDetail(Long curationId) { + Curation curation = getCuration(curationId); + CurationSpec spec = getSpec(curation.getSpecId()); + CurationExtension extension = getExtension(curationId); + return toDetailResponse(curation, spec, extension); + } + + @Transactional + public AdminResultResponse create(CurationCreateRequest request) { + CurationSpec spec = getSpec(request.specId()); + validatePayload(spec, request.payload()); + Curation saved = curationRepository.save(toCuration(request, spec)); + curationExtensionRepository.save( + CurationExtension.builder() + .curationId(saved.getId()) + .specId(spec.getId()) + .payload(request.payload()) + .build()); + return AdminResultResponse.of(CURATION_CREATED, saved.getId()); + } + + @Transactional + public AdminResultResponse update(Long curationId, CurationUpdateRequest request) { + Curation curation = getCuration(curationId); + CurationSpec spec = getSpec(request.specId()); + validatePayload(spec, request.payload()); + curation.update( + spec.getId(), + request.name(), + request.description(), + request.imageUrls().get(0), + request.imageUrls().size() > 1 ? request.imageUrls().get(1) : null, + request.imageUrls().size() > 2 ? request.imageUrls().get(2) : null, + request.exposureStartDate(), + request.exposureEndDate(), + request.displayOrder(), + request.isActive()); + getExtension(curationId).update(spec.getId(), request.payload()); + return AdminResultResponse.of(CURATION_UPDATED, curationId); + } + + private Curation toCuration(CurationCreateRequest request, CurationSpec spec) { + return Curation.builder() + .specId(spec.getId()) + .name(request.name()) + .description(request.description()) + .coverImageUrl(request.imageUrls().get(0)) + .imageUrl2(request.imageUrls().size() > 1 ? request.imageUrls().get(1) : null) + .imageUrl3(request.imageUrls().size() > 2 ? request.imageUrls().get(2) : null) + .exposureStartDate(request.exposureStartDate()) + .exposureEndDate(request.exposureEndDate()) + .displayOrder(request.displayOrder()) + .isActive(request.isActive()) + .build(); + } + + private Curation getCuration(Long curationId) { + return curationRepository + .findById(curationId) + .orElseThrow(() -> new CurationException(CURATION_NOT_FOUND)); + } + + private CurationSpec getSpec(Long specId) { + return curationSpecRepository + .findById(specId) + .orElseThrow(() -> new CurationException(CURATION_SPEC_NOT_FOUND)); + } + + private CurationExtension getExtension(Long curationId) { + return curationExtensionRepository + .findByCurationId(curationId) + .orElseThrow(() -> new CurationException(CURATION_NOT_FOUND)); + } + + private void validatePayload(CurationSpec spec, Object payload) { + List errors = + curationPayloadValidator.validate(new MapBackedSchema(spec.getRequestSpec()), payload); + if (!errors.isEmpty()) { + throw new CurationException(CURATION_PAYLOAD_INVALID); + } + } + + private AdminSpecBasedCurationListResponse toListResponse(Curation curation, CurationSpec spec) { + return new AdminSpecBasedCurationListResponse( + curation.getId(), + curation.getSpecId(), + spec != null ? spec.getCode() : null, + curation.getName(), + curation.getDisplayOrder(), + curation.getIsActive(), + curation.getCreateAt()); + } + + private AdminSpecBasedCurationDetailResponse toDetailResponse( + Curation curation, CurationSpec spec, CurationExtension extension) { + return new AdminSpecBasedCurationDetailResponse( + curation.getId(), + curation.getName(), + curation.getDescription(), + curation.getCoverImageUrl(), + imageUrls(curation), + curation.getExposureStartDate(), + curation.getExposureEndDate(), + curation.getDisplayOrder(), + curation.getIsActive(), + curation.getCreateAt(), + curation.getLastModifyAt(), + toSpecResponse(spec), + extension.getPayload()); + } + + private List imageUrls(Curation curation) { + return java.util.stream.Stream.of( + curation.getCoverImageUrl(), curation.getImageUrl2(), curation.getImageUrl3()) + .filter(Objects::nonNull) + .filter(imageUrl -> !imageUrl.isBlank()) + .toList(); + } + + private CurationSpecResponse toSpecResponse(CurationSpec spec) { + return new CurationSpecResponse( + spec.getId(), + spec.getCode(), + spec.getName(), + spec.getDescription(), + spec.getHydratorKey(), + spec.getVersion(), + spec.getIsActive(), + spec.getRequestSpec(), + spec.getResponseSpec()); + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationAlcoholGraphqlService.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationAlcoholGraphqlService.java new file mode 100644 index 000000000..8c664e352 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationAlcoholGraphqlService.java @@ -0,0 +1,99 @@ +package app.bottlenote.curation.service; + +import app.bottlenote.alcohols.domain.Alcohol; +import app.bottlenote.alcohols.domain.AlcoholQueryRepository; +import app.bottlenote.picks.constant.PicksStatus; +import app.bottlenote.picks.domain.PicksRepository; +import app.bottlenote.rating.domain.RatingRepository; +import app.bottlenote.review.constant.ReviewActiveStatus; +import app.bottlenote.review.constant.ReviewDisplayStatus; +import app.bottlenote.review.domain.ReviewRepository; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class CurationAlcoholGraphqlService { + + private final AlcoholQueryRepository alcoholQueryRepository; + private final RatingRepository ratingRepository; + private final ReviewRepository reviewRepository; + private final PicksRepository picksRepository; + + @Transactional(readOnly = true) + public List findAlcohols(List ids) { + if (ids == null || ids.isEmpty()) { + return List.of(); + } + + List alcoholIds = ids.stream().filter(Objects::nonNull).distinct().toList(); + if (alcoholIds.isEmpty()) { + return List.of(); + } + + Map alcoholsById = + alcoholQueryRepository.findAllByIdIn(alcoholIds).stream() + .collect(Collectors.toMap(Alcohol::getId, Function.identity(), (left, right) -> left)); + + return alcoholIds.stream().map(alcoholsById::get).filter(Objects::nonNull).toList(); + } + + @Transactional(readOnly = true) + public String regionName(Alcohol alcohol) { + if (alcohol == null || alcohol.getRegion() == null) { + return null; + } + return alcohol.getRegion().getKorName(); + } + + @Transactional(readOnly = true) + public Double rating(Alcohol alcohol) { + Long alcoholId = alcoholIdOf(alcohol); + if (alcoholId == null) { + return 0.0; + } + return ratingRepository.findAverageRatingByAlcoholId(alcoholId); + } + + @Transactional(readOnly = true) + public Long totalRatingsCount(Alcohol alcohol) { + Long alcoholId = alcoholIdOf(alcohol); + if (alcoholId == null) { + return 0L; + } + return ratingRepository.countByAlcoholId(alcoholId); + } + + @Transactional(readOnly = true) + public Long reviewCount(Alcohol alcohol) { + Long alcoholId = alcoholIdOf(alcohol); + if (alcoholId == null) { + return 0L; + } + return reviewRepository.countByAlcoholIdAndActiveStatusAndStatus( + alcoholId, ReviewActiveStatus.ACTIVE, ReviewDisplayStatus.PUBLIC); + } + + @Transactional(readOnly = true) + public Long totalPickCount(Alcohol alcohol) { + Long alcoholId = alcoholIdOf(alcohol); + if (alcoholId == null) { + return 0L; + } + return picksRepository.countByAlcoholIdAndStatus(alcoholId, PicksStatus.PICK); + } + + private Long alcoholIdOf(Alcohol alcohol) { + if (alcohol == null) { + return null; + } + return alcohol.getId(); + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java new file mode 100644 index 000000000..284e30ffc --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java @@ -0,0 +1,64 @@ +package app.bottlenote.curation.service; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class CurationPayloadValidator { + + private static final int MAX_PAYLOAD_BYTES = 128 * 1024; + + private final ObjectMapper objectMapper; + + public CurationPayloadValidator(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + public List validate(MapBackedSchema requestSpec, Object payload) { + JsonNode schema = objectMapper.valueToTree(requestSpec.value()); + JsonNode payloadNode = objectMapper.valueToTree(payload); + + if (payloadNode == null || payloadNode.isNull()) { + return List.of("payload가 null입니다."); + } + int payloadBytes = payloadNode.toString().getBytes(StandardCharsets.UTF_8).length; + if (payloadBytes > MAX_PAYLOAD_BYTES) { + return List.of("payload size must be <= " + MAX_PAYLOAD_BYTES + ", actual=" + payloadBytes); + } + if (payloadNode.isArray()) { + if (payloadNode.isEmpty()) { + return List.of("payload 배열은 비어 있을 수 없습니다."); + } + List errors = new ArrayList<>(); + for (int i = 0; i < payloadNode.size(); i++) { + errors.addAll(validateObject(schema, payloadNode.get(i), "[" + i + "]")); + } + return errors; + } + return validateObject(schema, payloadNode, "$"); + } + + private List validateObject(JsonNode schema, JsonNode payload, String path) { + if (!payload.isObject()) { + return List.of(path + " payload는 object여야 합니다."); + } + JsonNode required = schema.path("required"); + if (!required.isArray()) { + return List.of(); + } + List errors = new ArrayList<>(); + for (JsonNode field : required) { + String fieldName = field.asText(); + if (!payload.hasNonNull(fieldName)) { + errors.add(path + "." + fieldName + " 필드는 필수입니다."); + } + } + return errors; + } + + public record MapBackedSchema(Object value) {} +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationSpecResourceSyncService.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationSpecResourceSyncService.java new file mode 100644 index 000000000..3220aa060 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationSpecResourceSyncService.java @@ -0,0 +1,64 @@ +package app.bottlenote.curation.service; + +import app.bottlenote.curation.domain.CurationSpec; +import app.bottlenote.curation.domain.CurationSpecRepository; +import app.bottlenote.curation.dto.response.CurationSpecSyncResponse; +import app.bottlenote.curation.support.CurationSpecResourceReader; +import app.bottlenote.curation.support.CurationSpecResourceReader.CurationSpecResourceDocument; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class CurationSpecResourceSyncService { + + private final CurationSpecRepository curationSpecRepository; + private final CurationSpecResourceReader curationSpecResourceReader; + + @Transactional + public CurationSpecSyncResponse sync() { + int createdCount = 0; + int updatedCount = 0; + + for (CurationSpecResourceDocument specDocument : curationSpecResourceReader.readAll()) { + Optional existingSpec = curationSpecRepository.findByCode(specDocument.code()); + if (existingSpec.isPresent()) { + curationSpecRepository.save(update(existingSpec.get(), specDocument)); + updatedCount++; + } else { + curationSpecRepository.save(create(specDocument)); + createdCount++; + } + } + + return new CurationSpecSyncResponse(createdCount, updatedCount); + } + + private CurationSpec update( + CurationSpec curationSpec, CurationSpecResourceDocument specDocument) { + curationSpec.update( + specDocument.name(), + specDocument.description(), + specDocument.requestSpec(), + specDocument.responseSpec(), + specDocument.hydratorKey(), + specDocument.version(), + true); + return curationSpec; + } + + private CurationSpec create(CurationSpecResourceDocument specDocument) { + return CurationSpec.builder() + .code(specDocument.code()) + .name(specDocument.name()) + .description(specDocument.description()) + .requestSpec(specDocument.requestSpec()) + .responseSpec(specDocument.responseSpec()) + .hydratorKey(specDocument.hydratorKey()) + .version(specDocument.version()) + .isActive(true) + .build(); + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationV2Service.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationV2Service.java new file mode 100644 index 000000000..1a2ebf129 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationV2Service.java @@ -0,0 +1,101 @@ +package app.bottlenote.curation.service; + +import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_NOT_FOUND; +import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_SPEC_DUPLICATE_CODE; +import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_SPEC_NOT_FOUND; + +import app.bottlenote.curation.domain.Curation; +import app.bottlenote.curation.domain.CurationExtension; +import app.bottlenote.curation.domain.CurationExtensionRepository; +import app.bottlenote.curation.domain.CurationRepository; +import app.bottlenote.curation.domain.CurationSpec; +import app.bottlenote.curation.domain.CurationSpecRepository; +import app.bottlenote.curation.dto.request.CurationCreateRequest; +import app.bottlenote.curation.dto.request.CurationSpecCreateRequest; +import app.bottlenote.curation.exception.CurationException; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class CurationV2Service { + + private final CurationSpecRepository curationSpecRepository; + private final CurationRepository curationRepository; + private final CurationExtensionRepository curationExtensionRepository; + + @Transactional + public CurationSpec createSpec(CurationSpecCreateRequest command) { + if (curationSpecRepository.existsByCode(command.code())) { + throw new CurationException(CURATION_SPEC_DUPLICATE_CODE); + } + + CurationSpec curationSpec = + CurationSpec.builder() + .code(command.code()) + .name(command.name()) + .description(command.description()) + .requestSpec(command.requestSpec()) + .responseSpec(command.responseSpec()) + .hydratorKey(command.hydratorKey()) + .version(command.version() != null ? command.version() : 1) + .isActive(true) + .build(); + return curationSpecRepository.save(curationSpec); + } + + @Transactional + public Curation createCuration(CurationCreateRequest command) { + CurationSpec curationSpec = getSpec(command.specId()); + Curation curation = + Curation.builder() + .specId(curationSpec.getId()) + .name(command.name()) + .description(command.description()) + .coverImageUrl(command.imageUrls().get(0)) + .imageUrl2(command.imageUrls().size() > 1 ? command.imageUrls().get(1) : null) + .imageUrl3(command.imageUrls().size() > 2 ? command.imageUrls().get(2) : null) + .exposureStartDate(command.exposureStartDate()) + .exposureEndDate(command.exposureEndDate()) + .displayOrder(command.displayOrder() != null ? command.displayOrder() : 0) + .isActive(command.isActive()) + .build(); + + Curation saved = curationRepository.save(curation); + curationExtensionRepository.save( + CurationExtension.builder() + .curationId(saved.getId()) + .specId(curationSpec.getId()) + .payload(command.payload()) + .build()); + return saved; + } + + @Transactional(readOnly = true) + public CurationSpec getSpec(Long specId) { + return curationSpecRepository + .findById(specId) + .orElseThrow(() -> new CurationException(CURATION_SPEC_NOT_FOUND)); + } + + @Transactional(readOnly = true) + public Curation getCuration(Long curationId) { + return curationRepository + .findById(curationId) + .orElseThrow(() -> new CurationException(CURATION_NOT_FOUND)); + } + + @Transactional(readOnly = true) + public CurationExtension getExtension(Long curationId) { + return curationExtensionRepository + .findByCurationId(curationId) + .orElseThrow(() -> new CurationException(CURATION_NOT_FOUND)); + } + + @Transactional(readOnly = true) + public List findActiveCurations() { + return curationRepository.findAllByIsActiveTrueOrderByDisplayOrderAscIdAsc(); + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/support/CurationSpecResourceReader.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/support/CurationSpecResourceReader.java new file mode 100644 index 000000000..32e3aeef7 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/support/CurationSpecResourceReader.java @@ -0,0 +1,80 @@ +package app.bottlenote.curation.support; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class CurationSpecResourceReader { + + private static final String SPEC_RESOURCE_PATTERN = "classpath*:openapi/curation/*.json"; + private static final TypeReference> MAP_TYPE = new TypeReference<>() {}; + + private final ResourcePatternResolver resourcePatternResolver; + private final ObjectMapper objectMapper; + + public List readAll() { + return Arrays.stream(loadResources()).map(this::readSpec).toList(); + } + + private Resource[] loadResources() { + try { + Resource[] resources = resourcePatternResolver.getResources(SPEC_RESOURCE_PATTERN); + Arrays.sort(resources, Comparator.comparing(Resource::getFilename)); + return resources; + } catch (IOException e) { + throw new IllegalStateException("큐레이션 스펙 리소스를 읽을 수 없습니다.", e); + } + } + + private CurationSpecResourceDocument readSpec(Resource resource) { + try { + JsonNode root = objectMapper.readTree(resource.getInputStream()); + JsonNode schemas = root.path("components").path("schemas"); + JsonNode requestSpec = findSchema(schemas, "Request"); + JsonNode responseSpec = findSchema(schemas, "Response"); + return new CurationSpecResourceDocument( + root.path("x-curation").path("code").asText(), + root.path("info").path("title").asText(), + root.path("info").path("description").asText(null), + objectMapper.convertValue(requestSpec, MAP_TYPE), + objectMapper.convertValue(responseSpec, MAP_TYPE), + root.path("x-curation").path("hydratorKey").asText(), + parseMajorVersion(root.path("info").path("version").asText("1"))); + } catch (IOException e) { + throw new IllegalStateException("큐레이션 스펙 리소스 파싱에 실패했습니다: " + resource.getFilename(), e); + } + } + + private JsonNode findSchema(JsonNode schemas, String suffix) { + return schemas.properties().stream() + .filter(entry -> entry.getKey().endsWith(suffix)) + .findFirst() + .map(Map.Entry::getValue) + .orElseThrow(() -> new IllegalStateException(suffix + " schema를 찾을 수 없습니다.")); + } + + private int parseMajorVersion(String version) { + String major = version.split("\\.")[0]; + return Integer.parseInt(major); + } + + public record CurationSpecResourceDocument( + String code, + String name, + String description, + Map requestSpec, + Map responseSpec, + String hydratorKey, + Integer version) {} +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/picks/domain/PicksRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/picks/domain/PicksRepository.java index 96ab623ce..62c8d2251 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/picks/domain/PicksRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/picks/domain/PicksRepository.java @@ -1,10 +1,13 @@ package app.bottlenote.picks.domain; +import app.bottlenote.picks.constant.PicksStatus; import java.util.Optional; public interface PicksRepository { Optional findByAlcoholIdAndUserId(Long alcoholId, Long userId); + Long countByAlcoholIdAndStatus(Long alcoholId, PicksStatus status); + Picks save(Picks picks); } diff --git a/bottlenote-mono/src/main/java/app/bottlenote/rating/domain/RatingRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/rating/domain/RatingRepository.java index d3639db6d..80c1b6710 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/rating/domain/RatingRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/rating/domain/RatingRepository.java @@ -23,5 +23,9 @@ public interface RatingRepository { Optional fetchUserRating(Long alcoholId, Long userId); + Double findAverageRatingByAlcoholId(Long alcoholId); + + Long countByAlcoholId(Long alcoholId); + boolean existsByAlcoholId(Long alcoholId); } diff --git a/bottlenote-mono/src/main/java/app/bottlenote/rating/repository/JpaRatingRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/rating/repository/JpaRatingRepository.java index fe8cf809f..ec47dd094 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/rating/repository/JpaRatingRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/rating/repository/JpaRatingRepository.java @@ -32,6 +32,16 @@ Optional findByAlcoholIdAndUserId( Optional fetchUserRating( @Param("alcoholId") Long alcoholId, @Param("userId") Long userId); + @Override + @Query( + "select coalesce(avg(r.ratingPoint.rating), 0.0) from rating r where r.id.alcoholId = :alcoholId and r.ratingPoint.rating > 0.0") + Double findAverageRatingByAlcoholId(@Param("alcoholId") Long alcoholId); + + @Override + @Query( + "select count(r) from rating r where r.id.alcoholId = :alcoholId and r.ratingPoint.rating > 0.0") + Long countByAlcoholId(@Param("alcoholId") Long alcoholId); + @Override @Query( "select case when count(r) > 0 then true else false end from rating r where r.id.alcoholId = :alcoholId") diff --git a/bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java index 436725c1c..58619d31d 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java @@ -2,6 +2,8 @@ import app.bottlenote.global.service.cursor.CursorResponse; import app.bottlenote.global.service.cursor.PageResponse; +import app.bottlenote.review.constant.ReviewActiveStatus; +import app.bottlenote.review.constant.ReviewDisplayStatus; import app.bottlenote.review.dto.request.ReviewPageableRequest; import app.bottlenote.review.dto.response.ReviewExploreItem; import app.bottlenote.review.dto.response.ReviewListResponse; @@ -30,6 +32,9 @@ PageResponse getReviewsByMe( List findByUserId(Long userId); + Long countByAlcoholIdAndActiveStatusAndStatus( + Long alcoholId, ReviewActiveStatus activeStatus, ReviewDisplayStatus status); + boolean existsById(Long reviewId); boolean existsByAlcoholId(Long alcoholId); diff --git a/bottlenote-mono/src/main/resources/graphql/schema.graphqls b/bottlenote-mono/src/main/resources/graphql/schema.graphqls new file mode 100644 index 000000000..473efaa8c --- /dev/null +++ b/bottlenote-mono/src/main/resources/graphql/schema.graphqls @@ -0,0 +1,19 @@ +type Query { + alcohols(ids: [ID!]!): [Alcohol!]! +} + +type Alcohol { + alcoholId: ID! + korName: String! + engName: String + imageUrl: String + regionName: String + korCategory: String + cask: String + abv: String + volume: String + rating: Float + totalRatingsCount: Int + reviewCount: Int + totalPickCount: Int +} diff --git a/bottlenote-mono/src/main/resources/openapi/curation/recommended_whisky.json b/bottlenote-mono/src/main/resources/openapi/curation/recommended_whisky.json new file mode 100644 index 000000000..d419c5647 --- /dev/null +++ b/bottlenote-mono/src/main/resources/openapi/curation/recommended_whisky.json @@ -0,0 +1,295 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "추천 큐레이션", + "description": "추천 위스키를 카드 목록으로 발행하는 큐레이션. 각 항목은 위스키 1건과 큐레이터 코멘트로 구성된다.", + "version": "2.0.0" + }, + "x-curation": { + "code": "RECOMMENDED_WHISKY", + "hydratorKey": "alcohol", + "container": "array" + }, + "paths": {}, + "components": { + "schemas": { + "RecommendedWhiskyItemRequest": { + "type": "object", + "description": "큐레이션 위스키 카드", + "x-field-style": "alcohol-card", + "x-display-name": "위스키", + "properties": { + "source": { + "type": "string", + "enum": [ + "BOTTLE_NOTE", + "MANUAL" + ], + "description": "위스키 데이터 출처", + "example": "BOTTLE_NOTE" + }, + "alcohol": { + "type": "object", + "description": "발행 시점의 위스키 노출용 미러 데이터", + "properties": { + "alcoholId": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "DB 알코올 ID. 직접 입력이면 null", + "example": 1 + }, + "korName": { + "type": "string", + "description": "위스키 한글명", + "example": "글렌드로낙 오리지널 12년", + "maxLength": 100 + }, + "engName": { + "type": "string", + "description": "위스키 영문명", + "example": "GLENDRONACH ORIGINAL 12Y", + "maxLength": 150 + }, + "imageUrl": { + "type": "string", + "description": "위스키 이미지 URL", + "example": "https://img.example.com/alcohols/1.png", + "maxLength": 2048, + "x-field-style": "image-url", + "x-display-name": "이미지" + }, + "regionName": { + "type": "string", + "description": "지역 또는 국가명", + "example": "스코틀랜드/하이랜드", + "maxLength": 80 + }, + "korCategory": { + "type": "string", + "description": "한글 카테고리명", + "example": "싱글 몰트", + "maxLength": 80 + }, + "cask": { + "type": "string", + "description": "캐스크 정보", + "example": "셰리 캐스크", + "maxLength": 120 + }, + "abv": { + "type": "string", + "description": "알코올 도수", + "example": "43", + "maxLength": 20 + }, + "volume": { + "type": "string", + "description": "용량", + "example": "700ml", + "maxLength": 20 + }, + "selectedTags": { + "type": "array", + "description": "최종 선택된 테이스팅 태그명 목록 배열 순서가 앱 노출 순서다.", + "example": [ + "셰리", + "건포도", + "오크" + ], + "maxItems": 12, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 30 + }, + "x-field-style": "tag-list", + "x-display-name": "테이스팅 태그", + "x-ui-orderable": true + } + }, + "required": [ + "korName", + "selectedTags" + ], + "x-field-style": "alcohol-card", + "x-display-name": "위스키" + }, + "comment": { + "type": "string", + "description": "큐레이터 코멘트", + "example": "셰리 캐스크 입문용으로 추천", + "maxLength": 500, + "x-field-style": "long-text", + "x-display-name": "큐레이터 코멘트", + "nullable": true + } + }, + "required": [ + "source", + "alcohol" + ], + "x-form-style": "alcohol-list", + "x-container": "array" + }, + "RecommendedWhiskyItemResponse": { + "type": "object", + "description": "큐레이션 위스키 카드 조회 응답", + "x-field-style": "alcohol-card", + "x-display-name": "위스키", + "properties": { + "source": { + "type": "string", + "description": "위스키 데이터 출처" + }, + "alcohol": { + "type": "object", + "description": "발행 시점의 위스키 노출용 미러 데이터", + "properties": { + "alcoholId": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "DB 알코올 ID. 직접 입력이면 null", + "example": 1 + }, + "korName": { + "type": "string", + "description": "위스키 한글명", + "example": "글렌드로낙 오리지널 12년", + "maxLength": 100 + }, + "engName": { + "type": "string", + "description": "위스키 영문명", + "example": "GLENDRONACH ORIGINAL 12Y", + "maxLength": 150 + }, + "imageUrl": { + "type": "string", + "description": "위스키 이미지 URL", + "example": "https://img.example.com/alcohols/1.png", + "maxLength": 2048, + "x-field-style": "image-url", + "x-display-name": "이미지" + }, + "regionName": { + "type": "string", + "description": "지역 또는 국가명", + "example": "스코틀랜드/하이랜드", + "maxLength": 80 + }, + "korCategory": { + "type": "string", + "description": "한글 카테고리명", + "example": "싱글 몰트", + "maxLength": 80 + }, + "cask": { + "type": "string", + "description": "캐스크 정보", + "example": "셰리 캐스크", + "maxLength": 120 + }, + "abv": { + "type": "string", + "description": "알코올 도수", + "example": "43", + "maxLength": 20 + }, + "volume": { + "type": "string", + "description": "용량", + "example": "700ml", + "maxLength": 20 + }, + "selectedTags": { + "type": "array", + "description": "최종 선택된 테이스팅 태그명 목록 배열 순서가 앱 노출 순서다.", + "example": [ + "셰리", + "건포도", + "오크" + ], + "maxItems": 12, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 30 + }, + "x-field-style": "tag-list", + "x-display-name": "테이스팅 태그", + "x-ui-orderable": true + } + }, + "required": [ + "korName", + "selectedTags" + ], + "x-field-style": "alcohol-card", + "x-display-name": "위스키" + }, + "comment": { + "type": "string", + "description": "큐레이터 코멘트", + "example": "셰리 캐스크 입문용으로 추천", + "maxLength": 500, + "x-field-style": "long-text", + "x-display-name": "큐레이터 코멘트", + "nullable": true + }, + "stats": { + "type": "object", + "nullable": true, + "description": "DB alcoholId가 있을 때만 조회 시 보강되는 통계", + "x-graphql": { + "query": "alcohols", + "argFrom": "$.alcohol.alcoholId", + "argName": "ids", + "argType": "[ID!]!", + "writeTo": "stats", + "resultKey": "alcoholId" + }, + "properties": { + "rating": { + "type": "number", + "format": "double", + "nullable": true, + "x-graphql": true, + "x-field-style": "rating-display", + "x-display-name": "평균 별점" + }, + "totalRatingsCount": { + "type": "integer", + "format": "int64", + "nullable": true, + "x-graphql": true, + "x-display-name": "평점 수" + }, + "reviewCount": { + "type": "integer", + "format": "int64", + "nullable": true, + "x-graphql": true, + "x-display-name": "리뷰 수" + }, + "totalPickCount": { + "type": "integer", + "format": "int64", + "nullable": true, + "x-graphql": true, + "x-display-name": "찜 수" + } + } + } + }, + "required": [ + "source", + "alcohol" + ], + "x-form-style": "alcohol-list", + "x-container": "array" + } + } + } +} diff --git a/bottlenote-mono/src/main/resources/openapi/curation/whisky_pairing.json b/bottlenote-mono/src/main/resources/openapi/curation/whisky_pairing.json new file mode 100644 index 000000000..a60b0f7ea --- /dev/null +++ b/bottlenote-mono/src/main/resources/openapi/curation/whisky_pairing.json @@ -0,0 +1,409 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "위스키 페어링", + "description": "위스키 1건과 그 위스키에 어울리는 페어링 음식 N개를 묶어 소개하는 큐레이션.", + "version": "2.0.0" + }, + "x-curation": { + "code": "WHISKY_PAIRING", + "hydratorKey": "alcohol", + "container": "array" + }, + "paths": {}, + "components": { + "schemas": { + "WhiskyPairingItemRequest": { + "type": "object", + "description": "큐레이션 위스키 카드", + "x-field-style": "alcohol-card", + "x-display-name": "위스키", + "properties": { + "source": { + "type": "string", + "enum": [ + "BOTTLE_NOTE", + "MANUAL" + ], + "description": "위스키 데이터 출처", + "example": "BOTTLE_NOTE" + }, + "alcohol": { + "type": "object", + "description": "발행 시점의 위스키 노출용 미러 데이터", + "properties": { + "alcoholId": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "DB 알코올 ID. 직접 입력이면 null", + "example": 1 + }, + "korName": { + "type": "string", + "description": "위스키 한글명", + "example": "글렌드로낙 오리지널 12년", + "maxLength": 100 + }, + "engName": { + "type": "string", + "description": "위스키 영문명", + "example": "GLENDRONACH ORIGINAL 12Y", + "maxLength": 150 + }, + "imageUrl": { + "type": "string", + "description": "위스키 이미지 URL", + "example": "https://img.example.com/alcohols/1.png", + "maxLength": 2048, + "x-field-style": "image-url", + "x-display-name": "이미지" + }, + "regionName": { + "type": "string", + "description": "지역 또는 국가명", + "example": "스코틀랜드/하이랜드", + "maxLength": 80 + }, + "korCategory": { + "type": "string", + "description": "한글 카테고리명", + "example": "싱글 몰트", + "maxLength": 80 + }, + "cask": { + "type": "string", + "description": "캐스크 정보", + "example": "셰리 캐스크", + "maxLength": 120 + }, + "abv": { + "type": "string", + "description": "알코올 도수", + "example": "43", + "maxLength": 20 + }, + "volume": { + "type": "string", + "description": "용량", + "example": "700ml", + "maxLength": 20 + }, + "selectedTags": { + "type": "array", + "description": "최종 선택된 테이스팅 태그명 목록 배열 순서가 앱 노출 순서다.", + "example": [ + "셰리", + "건포도", + "오크" + ], + "maxItems": 12, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 30 + }, + "x-field-style": "tag-list", + "x-display-name": "테이스팅 태그", + "x-ui-orderable": true + } + }, + "required": [ + "korName", + "selectedTags" + ], + "x-field-style": "alcohol-card", + "x-display-name": "위스키" + }, + "comment": { + "type": "string", + "description": "위스키 기대평", + "example": "셰리 캐스크 입문용으로 추천", + "maxLength": 500, + "x-field-style": "long-text", + "x-display-name": "위스키 기대평", + "nullable": true + }, + "pairings": { + "type": "array", + "description": "해당 위스키와 함께 보여줄 페어링 음식 목록", + "example": [ + { + "itemName": "부드러운 티라미수 초콜릿", + "itemImageUrl": "https://images.unsplash.com/photo-1551024601-bec78aea704b?w=480", + "pairingNote": "진한 초콜릿 향이 위스키의 단맛과 이어진다." + } + ], + "x-field-style": "pairing-food-list", + "x-display-name": "위스키와 페어링할 음식", + "minItems": 1, + "maxItems": 5, + "items": { + "type": "object", + "description": "페어링 음식 한 항목", + "example": { + "itemName": "부드러운 티라미수 초콜릿", + "itemImageUrl": "https://images.unsplash.com/photo-1551024601-bec78aea704b?w=480", + "pairingNote": "진한 초콜릿 향이 위스키의 단맛과 이어진다." + }, + "x-field-style": "none", + "x-display-name": "페어링 음식", + "properties": { + "itemName": { + "type": "string", + "description": "페어링 음식명", + "example": "부드러운 티라미수 초콜릿", + "maxLength": 100, + "x-field-style": "plain-text", + "x-display-name": "음식명" + }, + "itemImageUrl": { + "type": "string", + "description": "페어링 음식 이미지 URL", + "example": "https://images.unsplash.com/photo-1551024601-bec78aea704b?w=480", + "maxLength": 2048, + "x-field-style": "image-url", + "x-display-name": "음식 이미지" + }, + "pairingNote": { + "type": "string", + "description": "페어링 설명", + "example": "진한 초콜릿 향이 위스키의 단맛과 이어진다.", + "maxLength": 500, + "x-field-style": "long-text", + "x-display-name": "페어링 설명" + } + }, + "required": [ + "itemName", + "pairingNote" + ] + } + } + }, + "required": [ + "source", + "alcohol", + "pairings" + ], + "x-form-style": "pairing-list", + "x-container": "array" + }, + "WhiskyPairingItemResponse": { + "type": "object", + "description": "큐레이션 위스키 카드 조회 응답", + "x-field-style": "alcohol-card", + "x-display-name": "위스키", + "properties": { + "source": { + "type": "string", + "description": "위스키 데이터 출처" + }, + "alcohol": { + "type": "object", + "description": "발행 시점의 위스키 노출용 미러 데이터", + "properties": { + "alcoholId": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "DB 알코올 ID. 직접 입력이면 null", + "example": 1 + }, + "korName": { + "type": "string", + "description": "위스키 한글명", + "example": "글렌드로낙 오리지널 12년", + "maxLength": 100 + }, + "engName": { + "type": "string", + "description": "위스키 영문명", + "example": "GLENDRONACH ORIGINAL 12Y", + "maxLength": 150 + }, + "imageUrl": { + "type": "string", + "description": "위스키 이미지 URL", + "example": "https://img.example.com/alcohols/1.png", + "maxLength": 2048, + "x-field-style": "image-url", + "x-display-name": "이미지" + }, + "regionName": { + "type": "string", + "description": "지역 또는 국가명", + "example": "스코틀랜드/하이랜드", + "maxLength": 80 + }, + "korCategory": { + "type": "string", + "description": "한글 카테고리명", + "example": "싱글 몰트", + "maxLength": 80 + }, + "cask": { + "type": "string", + "description": "캐스크 정보", + "example": "셰리 캐스크", + "maxLength": 120 + }, + "abv": { + "type": "string", + "description": "알코올 도수", + "example": "43", + "maxLength": 20 + }, + "volume": { + "type": "string", + "description": "용량", + "example": "700ml", + "maxLength": 20 + }, + "selectedTags": { + "type": "array", + "description": "최종 선택된 테이스팅 태그명 목록 배열 순서가 앱 노출 순서다.", + "example": [ + "셰리", + "건포도", + "오크" + ], + "maxItems": 12, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 30 + }, + "x-field-style": "tag-list", + "x-display-name": "테이스팅 태그", + "x-ui-orderable": true + } + }, + "required": [ + "korName", + "selectedTags" + ], + "x-field-style": "alcohol-card", + "x-display-name": "위스키" + }, + "comment": { + "type": "string", + "description": "큐레이터 코멘트", + "example": "셰리 캐스크 입문용으로 추천", + "maxLength": 500, + "x-field-style": "long-text", + "x-display-name": "큐레이터 코멘트", + "nullable": true + }, + "stats": { + "type": "object", + "nullable": true, + "description": "DB alcoholId가 있을 때만 조회 시 보강되는 통계", + "x-graphql": { + "query": "alcohols", + "argFrom": "$.alcohol.alcoholId", + "argName": "ids", + "argType": "[ID!]!", + "writeTo": "stats", + "resultKey": "alcoholId" + }, + "properties": { + "rating": { + "type": "number", + "format": "double", + "nullable": true, + "x-graphql": true, + "x-field-style": "rating-display", + "x-display-name": "평균 별점" + }, + "totalRatingsCount": { + "type": "integer", + "format": "int64", + "nullable": true, + "x-graphql": true, + "x-display-name": "평점 수" + }, + "reviewCount": { + "type": "integer", + "format": "int64", + "nullable": true, + "x-graphql": true, + "x-display-name": "리뷰 수" + }, + "totalPickCount": { + "type": "integer", + "format": "int64", + "nullable": true, + "x-graphql": true, + "x-display-name": "찜 수" + } + } + }, + "pairings": { + "type": "array", + "description": "해당 위스키와 함께 보여줄 페어링 음식 목록", + "example": [ + { + "itemName": "부드러운 티라미수 초콜릿", + "itemImageUrl": "https://images.unsplash.com/photo-1551024601-bec78aea704b?w=480", + "pairingNote": "진한 초콜릿 향이 위스키의 단맛과 이어진다." + } + ], + "x-field-style": "pairing-food-list", + "x-display-name": "페어링 음식", + "minItems": 1, + "maxItems": 5, + "items": { + "type": "object", + "description": "페어링 음식 한 항목", + "example": { + "itemName": "부드러운 티라미수 초콜릿", + "itemImageUrl": "https://images.unsplash.com/photo-1551024601-bec78aea704b?w=480", + "pairingNote": "진한 초콜릿 향이 위스키의 단맛과 이어진다." + }, + "x-field-style": "none", + "x-display-name": "페어링 음식", + "properties": { + "itemName": { + "type": "string", + "description": "페어링 음식명", + "example": "부드러운 티라미수 초콜릿", + "maxLength": 100, + "x-field-style": "plain-text", + "x-display-name": "음식명" + }, + "itemImageUrl": { + "type": "string", + "description": "페어링 음식 이미지 URL", + "example": "https://images.unsplash.com/photo-1551024601-bec78aea704b?w=480", + "maxLength": 2048, + "x-field-style": "image-url", + "x-display-name": "음식 이미지" + }, + "pairingNote": { + "type": "string", + "description": "페어링 설명", + "example": "진한 초콜릿 향이 위스키의 단맛과 이어진다.", + "maxLength": 500, + "x-field-style": "long-text", + "x-display-name": "페어링 설명" + } + }, + "required": [ + "itemName", + "pairingNote" + ] + } + } + }, + "required": [ + "source", + "alcohol", + "pairings" + ], + "x-form-style": "pairing-list", + "x-container": "array" + } + } + } +} diff --git a/bottlenote-mono/src/main/resources/openapi/curation/whisky_tasting_event.json b/bottlenote-mono/src/main/resources/openapi/curation/whisky_tasting_event.json new file mode 100644 index 000000000..61c482625 --- /dev/null +++ b/bottlenote-mono/src/main/resources/openapi/curation/whisky_tasting_event.json @@ -0,0 +1,509 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "위스키 시음회", + "description": "시음회 날짜, 장소, 참가 정보와 시음 위스키 라인업을 함께 발행하는 이벤트형 큐레이션.", + "version": "2.0.0" + }, + "x-curation": { + "code": "WHISKY_TASTING_EVENT", + "hydratorKey": "alcohol", + "container": "object" + }, + "paths": {}, + "components": { + "schemas": { + "WhiskyTastingEventRequest": { + "type": "object", + "description": "위스키 시음회 큐레이션 등록 요청", + "x-form-style": "tasting-form", + "properties": { + "eventDate": { + "type": "string", + "format": "date", + "description": "시음회 날짜", + "example": "2025-06-15", + "x-field-style": "none", + "x-display-name": "시음회 날짜" + }, + "eventTime": { + "type": "string", + "description": "시음회 시간", + "example": "19:30", + "maxLength": 20, + "x-field-style": "none", + "x-display-name": "시음회 시간" + }, + "barAddress": { + "type": "string", + "description": "장소 및 바 주소", + "example": "서울 강남구 테헤란로 123", + "maxLength": 200, + "x-field-style": "plain-text", + "x-display-name": "장소 및 바(bar) 주소" + }, + "detailAddress": { + "type": "string", + "description": "상세 주소", + "example": "2층 도시남 바", + "maxLength": 200, + "x-field-style": "plain-text", + "x-display-name": "상세 주소" + }, + "isRecruiting": { + "type": "boolean", + "description": "시음회 참여자를 모집할지 여부", + "example": true, + "x-field-style": "none", + "x-display-name": "참여자 모집 여부" + }, + "entryFee": { + "type": "integer", + "minimum": 0, + "description": "참가비", + "example": 75000, + "x-field-style": "plain-number", + "x-display-name": "참가비(1인당)" + }, + "capacity": { + "type": "integer", + "minimum": 1, + "maximum": 999, + "description": "총 모집 인원수", + "example": 20, + "x-field-style": "plain-number", + "x-display-name": "총 모집 인원수" + }, + "applicationLink": { + "type": "string", + "description": "신청 링크", + "example": "https://forms.example.com/tasting", + "maxLength": 2048, + "x-field-style": "plain-text", + "x-display-name": "신청링크" + }, + "guideText": { + "type": "string", + "description": "시음회 안내사항", + "example": "시작 10분 전 입장해 주세요.", + "maxLength": 1000, + "x-field-style": "long-text", + "x-display-name": "안내사항" + }, + "alcohols": { + "type": "array", + "description": "시음 위스키 라인업", + "example": [ + { + "source": "BOTTLE_NOTE", + "alcohol": { + "alcoholId": 1, + "korName": "글렌드로낙 오리지널 12년", + "selectedTags": [ + "셰리" + ] + }, + "comment": "첫 잔으로 가볍게 시작하는 위스키" + } + ], + "x-field-style": "alcohol-card-list", + "x-display-name": "시음 위스키", + "minItems": 1, + "maxItems": 10, + "items": { + "type": "object", + "description": "큐레이션 위스키 카드", + "x-field-style": "none", + "x-display-name": "시음 위스키", + "properties": { + "source": { + "type": "string", + "enum": [ + "BOTTLE_NOTE", + "MANUAL" + ], + "description": "위스키 데이터 출처", + "example": "BOTTLE_NOTE" + }, + "alcohol": { + "type": "object", + "description": "발행 시점의 위스키 노출용 미러 데이터", + "properties": { + "alcoholId": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "DB 알코올 ID. 직접 입력이면 null", + "example": 1 + }, + "korName": { + "type": "string", + "description": "위스키 한글명", + "example": "글렌드로낙 오리지널 12년", + "maxLength": 100 + }, + "engName": { + "type": "string", + "description": "위스키 영문명", + "example": "GLENDRONACH ORIGINAL 12Y", + "maxLength": 150 + }, + "imageUrl": { + "type": "string", + "description": "위스키 이미지 URL", + "example": "https://img.example.com/alcohols/1.png", + "maxLength": 2048, + "x-field-style": "image-url", + "x-display-name": "이미지" + }, + "regionName": { + "type": "string", + "description": "지역 또는 국가명", + "example": "스코틀랜드/하이랜드", + "maxLength": 80 + }, + "korCategory": { + "type": "string", + "description": "한글 카테고리명", + "example": "싱글 몰트", + "maxLength": 80 + }, + "cask": { + "type": "string", + "description": "캐스크 정보", + "example": "셰리 캐스크", + "maxLength": 120 + }, + "abv": { + "type": "string", + "description": "알코올 도수", + "example": "43", + "maxLength": 20 + }, + "volume": { + "type": "string", + "description": "용량", + "example": "700ml", + "maxLength": 20 + }, + "selectedTags": { + "type": "array", + "description": "최종 선택된 테이스팅 태그명 목록 배열 순서가 앱 노출 순서다.", + "example": [ + "셰리", + "건포도", + "오크" + ], + "maxItems": 12, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 30 + }, + "x-field-style": "tag-list", + "x-display-name": "테이스팅 태그", + "x-ui-orderable": true + } + }, + "required": [ + "korName", + "selectedTags" + ], + "x-field-style": "alcohol-card", + "x-display-name": "위스키" + }, + "comment": { + "type": "string", + "description": "위스키 기대평", + "example": "셰리 캐스크 입문용으로 추천", + "maxLength": 500, + "x-field-style": "long-text", + "x-display-name": "위스키 기대평", + "nullable": true + } + }, + "required": [ + "source", + "alcohol" + ] + } + } + }, + "required": [ + "eventDate", + "eventTime", + "barAddress", + "detailAddress", + "entryFee", + "capacity", + "applicationLink", + "guideText", + "alcohols" + ] + }, + "WhiskyTastingEventResponse": { + "type": "object", + "description": "위스키 시음회 큐레이션 조회 응답", + "x-form-style": "tasting-form", + "properties": { + "eventDate": { + "type": "string", + "format": "date", + "description": "시음회 날짜", + "example": "2025-06-15", + "x-field-style": "none", + "x-display-name": "시음회 날짜" + }, + "eventTime": { + "type": "string", + "description": "시음회 시간", + "example": "19:30", + "maxLength": 20, + "x-field-style": "none", + "x-display-name": "시음회 시간" + }, + "barAddress": { + "type": "string", + "description": "장소 및 바 주소", + "example": "서울 강남구 테헤란로 123", + "maxLength": 200, + "x-field-style": "plain-text", + "x-display-name": "장소 및 바(bar) 주소" + }, + "detailAddress": { + "type": "string", + "description": "상세 주소", + "example": "2층 도시남 바", + "maxLength": 200, + "x-field-style": "plain-text", + "x-display-name": "상세 주소" + }, + "isRecruiting": { + "type": "boolean", + "description": "시음회 참여자 모집 여부", + "example": true, + "x-field-style": "none", + "x-display-name": "참여자 모집 여부" + }, + "entryFee": { + "type": "integer", + "description": "참가비", + "example": 75000, + "x-field-style": "plain-number", + "x-display-name": "참가비(1인당)" + }, + "capacity": { + "type": "integer", + "description": "총 모집 인원수", + "example": 20, + "x-field-style": "plain-number", + "x-display-name": "총 모집 인원수" + }, + "applicationLink": { + "type": "string", + "description": "신청 링크", + "example": "https://forms.example.com/tasting", + "maxLength": 2048, + "x-field-style": "plain-text", + "x-display-name": "신청링크" + }, + "guideText": { + "type": "string", + "description": "시음회 안내사항", + "example": "시작 10분 전 입장해 주세요.", + "maxLength": 1000, + "x-field-style": "long-text", + "x-display-name": "안내사항" + }, + "alcohols": { + "type": "array", + "description": "시음 위스키 라인업 조회 응답", + "example": [ + { + "source": "BOTTLE_NOTE", + "alcohol": { + "alcoholId": 1, + "korName": "글렌드로낙 오리지널 12년", + "selectedTags": [ + "셰리" + ] + }, + "comment": "첫 잔으로 가볍게 시작하는 위스키" + } + ], + "x-field-style": "alcohol-card-list", + "x-display-name": "시음 위스키", + "items": { + "type": "object", + "description": "큐레이션 위스키 카드 조회 응답", + "x-field-style": "alcohol-card", + "x-display-name": "시음 위스키", + "properties": { + "source": { + "type": "string", + "description": "위스키 데이터 출처" + }, + "alcohol": { + "type": "object", + "description": "발행 시점의 위스키 노출용 미러 데이터", + "properties": { + "alcoholId": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "DB 알코올 ID. 직접 입력이면 null", + "example": 1 + }, + "korName": { + "type": "string", + "description": "위스키 한글명", + "example": "글렌드로낙 오리지널 12년", + "maxLength": 100 + }, + "engName": { + "type": "string", + "description": "위스키 영문명", + "example": "GLENDRONACH ORIGINAL 12Y", + "maxLength": 150 + }, + "imageUrl": { + "type": "string", + "description": "위스키 이미지 URL", + "example": "https://img.example.com/alcohols/1.png", + "maxLength": 2048, + "x-field-style": "image-url", + "x-display-name": "이미지" + }, + "regionName": { + "type": "string", + "description": "지역 또는 국가명", + "example": "스코틀랜드/하이랜드", + "maxLength": 80 + }, + "korCategory": { + "type": "string", + "description": "한글 카테고리명", + "example": "싱글 몰트", + "maxLength": 80 + }, + "cask": { + "type": "string", + "description": "캐스크 정보", + "example": "셰리 캐스크", + "maxLength": 120 + }, + "abv": { + "type": "string", + "description": "알코올 도수", + "example": "43", + "maxLength": 20 + }, + "volume": { + "type": "string", + "description": "용량", + "example": "700ml", + "maxLength": 20 + }, + "selectedTags": { + "type": "array", + "description": "최종 선택된 테이스팅 태그명 목록 배열 순서가 앱 노출 순서다.", + "example": [ + "셰리", + "건포도", + "오크" + ], + "maxItems": 12, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 30 + }, + "x-field-style": "tag-list", + "x-display-name": "테이스팅 태그", + "x-ui-orderable": true + } + }, + "required": [ + "korName", + "selectedTags" + ], + "x-field-style": "alcohol-card", + "x-display-name": "위스키" + }, + "comment": { + "type": "string", + "description": "큐레이터 코멘트", + "example": "셰리 캐스크 입문용으로 추천", + "maxLength": 500, + "x-field-style": "long-text", + "x-display-name": "큐레이터 코멘트", + "nullable": true + }, + "stats": { + "type": "object", + "nullable": true, + "description": "DB alcoholId가 있을 때만 조회 시 보강되는 통계", + "x-graphql": { + "query": "alcohols", + "argFrom": "$.alcohol.alcoholId", + "argName": "ids", + "argType": "[ID!]!", + "writeTo": "stats", + "resultKey": "alcoholId", + "payloadPath": "$.alcohols" + }, + "properties": { + "rating": { + "type": "number", + "format": "double", + "nullable": true, + "x-graphql": true, + "x-field-style": "rating-display", + "x-display-name": "평균 별점" + }, + "totalRatingsCount": { + "type": "integer", + "format": "int64", + "nullable": true, + "x-graphql": true, + "x-display-name": "평점 수" + }, + "reviewCount": { + "type": "integer", + "format": "int64", + "nullable": true, + "x-graphql": true, + "x-display-name": "리뷰 수" + }, + "totalPickCount": { + "type": "integer", + "format": "int64", + "nullable": true, + "x-graphql": true, + "x-display-name": "찜 수" + } + } + } + }, + "required": [ + "source", + "alcohol" + ] + } + } + }, + "required": [ + "eventDate", + "eventTime", + "barAddress", + "detailAddress", + "entryFee", + "capacity", + "applicationLink", + "guideText", + "alcohols" + ] + } + } + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/CurationOpenApiSpecResourceTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/CurationOpenApiSpecResourceTest.java new file mode 100644 index 000000000..c7c4699d7 --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/CurationOpenApiSpecResourceTest.java @@ -0,0 +1,58 @@ +package app.bottlenote.curation; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.core.io.ClassPathResource; + +@Tag("unit") +class CurationOpenApiSpecResourceTest { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + @Test + @DisplayName("큐레이션 OpenAPI 스펙 3종은 리소스에 포함되고 GraphQL 보강 메타를 가진다") + void curationOpenApiSpecs_whenLoaded_containCurationMetadata() throws IOException { + List specs = + List.of( + new SpecResource( + "openapi/curation/recommended_whisky.json", "RECOMMENDED_WHISKY", "array"), + new SpecResource("openapi/curation/whisky_pairing.json", "WHISKY_PAIRING", "array"), + new SpecResource( + "openapi/curation/whisky_tasting_event.json", "WHISKY_TASTING_EVENT", "object")); + + for (SpecResource spec : specs) { + ClassPathResource resource = new ClassPathResource(spec.path()); + + assertThat(resource.exists()).isTrue(); + + JsonNode root = OBJECT_MAPPER.readTree(resource.getInputStream()); + + assertThat(root.path("openapi").asText()).isEqualTo("3.0.3"); + assertThat(root.path("paths").isObject()).isTrue(); + assertThat(root.path("x-curation").path("code").asText()).isEqualTo(spec.code()); + assertThat(root.path("x-curation").path("hydratorKey").asText()).isEqualTo("alcohol"); + assertThat(root.path("x-curation").path("container").asText()).isEqualTo(spec.container()); + assertThat(root.path("components").path("schemas").isObject()).isTrue(); + assertThat(root.toString()) + .contains( + "\"source\"", + "\"BOTTLE_NOTE\"", + "\"MANUAL\"", + "\"alcoholId\"", + "\"stats\"", + "\"x-graphql\"", + "\"totalRatingsCount\"", + "\"reviewCount\"", + "\"totalPickCount\""); + } + } + + private record SpecResource(String path, String code, String container) {} +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationExtensionRepository.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationExtensionRepository.java new file mode 100644 index 000000000..6a8c91c47 --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationExtensionRepository.java @@ -0,0 +1,28 @@ +package app.bottlenote.curation.fixture; + +import app.bottlenote.curation.domain.CurationExtension; +import app.bottlenote.curation.domain.CurationExtensionRepository; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class InMemoryCurationExtensionRepository implements CurationExtensionRepository { + + private final Map database = new HashMap<>(); + + @Override + public Optional findByCurationId(Long curationId) { + return Optional.ofNullable(database.get(curationId)); + } + + @Override + public CurationExtension save(CurationExtension curationExtension) { + database.put(curationExtension.getCurationId(), curationExtension); + return curationExtension; + } + + @Override + public void deleteByCurationId(Long curationId) { + database.remove(curationId); + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationRepository.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationRepository.java new file mode 100644 index 000000000..dc6102b7a --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationRepository.java @@ -0,0 +1,63 @@ +package app.bottlenote.curation.fixture; + +import app.bottlenote.curation.domain.Curation; +import app.bottlenote.curation.domain.CurationRepository; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.test.util.ReflectionTestUtils; + +public class InMemoryCurationRepository implements CurationRepository { + + private final Map database = new HashMap<>(); + + @Override + public Optional findById(Long id) { + return Optional.ofNullable(database.get(id)); + } + + @Override + public List findAllByIsActiveTrueOrderByDisplayOrderAscIdAsc() { + return database.values().stream() + .filter(curation -> Boolean.TRUE.equals(curation.getIsActive())) + .sorted(Comparator.comparing(Curation::getDisplayOrder).thenComparing(Curation::getId)) + .toList(); + } + + @Override + public Page searchForAdmin(String keyword, Boolean isActive, Pageable pageable) { + List all = + database.values().stream() + .filter( + curation -> + keyword == null || keyword.isBlank() || curation.getName().contains(keyword)) + .filter(curation -> isActive == null || curation.getIsActive().equals(isActive)) + .sorted(Comparator.comparing(Curation::getDisplayOrder).thenComparing(Curation::getId)) + .toList(); + int start = (int) pageable.getOffset(); + int end = Math.min(start + pageable.getPageSize(), all.size()); + List content = start < all.size() ? all.subList(start, end) : List.of(); + return new PageImpl<>(content, pageable, all.size()); + } + + @Override + public Curation save(Curation curation) { + Long id = curation.getId(); + if (id == null) { + id = database.size() + 1L; + ReflectionTestUtils.setField(curation, "id", id); + } + database.put(id, curation); + return curation; + } + + @Override + public void delete(Curation curation) { + database.remove(curation.getId()); + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationSpecRepository.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationSpecRepository.java new file mode 100644 index 000000000..2586d4d36 --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationSpecRepository.java @@ -0,0 +1,54 @@ +package app.bottlenote.curation.fixture; + +import app.bottlenote.curation.domain.CurationSpec; +import app.bottlenote.curation.domain.CurationSpecRepository; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.springframework.test.util.ReflectionTestUtils; + +public class InMemoryCurationSpecRepository implements CurationSpecRepository { + + private final Map database = new HashMap<>(); + + @Override + public Optional findById(Long id) { + return Optional.ofNullable(database.get(id)); + } + + @Override + public Optional findByCode(String code) { + return database.values().stream().filter(spec -> spec.getCode().equals(code)).findFirst(); + } + + @Override + public List findAllByIsActiveTrueOrderByIdAsc() { + return database.values().stream() + .filter(spec -> Boolean.TRUE.equals(spec.getIsActive())) + .sorted(java.util.Comparator.comparing(CurationSpec::getId)) + .toList(); + } + + @Override + public List findAllByIdIn(Collection ids) { + return database.values().stream().filter(spec -> ids.contains(spec.getId())).toList(); + } + + @Override + public boolean existsByCode(String code) { + return findByCode(code).isPresent(); + } + + @Override + public CurationSpec save(CurationSpec curationSpec) { + Long id = curationSpec.getId(); + if (id == null) { + id = database.size() + 1L; + ReflectionTestUtils.setField(curationSpec, "id", id); + } + database.put(id, curationSpec); + return curationSpec; + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolverTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolverTest.java new file mode 100644 index 000000000..4394359e9 --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolverTest.java @@ -0,0 +1,208 @@ +package app.bottlenote.curation.graphql; + +import static org.assertj.core.api.Assertions.assertThat; + +import app.bottlenote.alcohols.constant.AlcoholCategoryGroup; +import app.bottlenote.alcohols.constant.AlcoholType; +import app.bottlenote.alcohols.domain.Alcohol; +import app.bottlenote.alcohols.domain.Region; +import app.bottlenote.alcohols.fixture.InMemoryAlcoholQueryRepository; +import app.bottlenote.curation.service.CurationAlcoholGraphqlService; +import app.bottlenote.global.service.cursor.PageResponse; +import app.bottlenote.picks.constant.PicksStatus; +import app.bottlenote.picks.domain.Picks; +import app.bottlenote.picks.domain.PicksRepository; +import app.bottlenote.rating.domain.Rating; +import app.bottlenote.rating.domain.Rating.RatingId; +import app.bottlenote.rating.domain.RatingPoint; +import app.bottlenote.rating.domain.RatingRepository; +import app.bottlenote.rating.dto.dsl.RatingListFetchCriteria; +import app.bottlenote.rating.dto.response.RatingListFetchResponse; +import app.bottlenote.rating.dto.response.UserRatingResponse; +import app.bottlenote.review.constant.ReviewActiveStatus; +import app.bottlenote.review.constant.ReviewDisplayStatus; +import app.bottlenote.review.domain.Review; +import app.bottlenote.review.fixture.InMemoryReviewRepository; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +@Tag("unit") +class CurationAlcoholGraphqlResolverTest { + + @Test + @DisplayName("MANUAL 항목처럼 alcoholId가 null이면 GraphQL 조회에서 제외하고 실제 도메인 통계를 반환한다") + void alcohols_whenManualItemAlcoholIdIsNull_excludesNullAndMissingIdsAndResolvesStats() { + InMemoryAlcoholQueryRepository alcoholRepository = new InMemoryAlcoholQueryRepository(); + FakeRatingRepository ratingRepository = new FakeRatingRepository(); + InMemoryReviewRepository reviewRepository = new InMemoryReviewRepository(); + FakePicksRepository picksRepository = new FakePicksRepository(); + CurationAlcoholGraphqlResolver resolver = + new CurationAlcoholGraphqlResolver( + new CurationAlcoholGraphqlService( + alcoholRepository, ratingRepository, reviewRepository, picksRepository)); + + Alcohol alcohol = alcohol(1L); + alcoholRepository.save(alcohol); + ratingRepository.save(rating(10L, 1L, 4.5)); + ratingRepository.save(rating(11L, 1L, 3.5)); + ratingRepository.save(rating(12L, 1L, 0.0)); + reviewRepository.save(review(1L, ReviewActiveStatus.ACTIVE, ReviewDisplayStatus.PUBLIC)); + reviewRepository.save(review(1L, ReviewActiveStatus.ACTIVE, ReviewDisplayStatus.PRIVATE)); + reviewRepository.save(review(1L, ReviewActiveStatus.DELETED, ReviewDisplayStatus.PUBLIC)); + picksRepository.save(picks(1L, 20L, PicksStatus.PICK)); + picksRepository.save(picks(1L, 21L, PicksStatus.UNPICK)); + + List alcohols = resolver.alcohols(Arrays.asList(null, 1L, 999L)); + List manualOnly = resolver.alcohols(Collections.singletonList(null)); + + assertThat(alcohols).extracting(Alcohol::getId).containsExactly(1L); + assertThat(manualOnly).isEmpty(); + assertThat(resolver.alcoholId(alcohol)).isEqualTo(1L); + assertThat(resolver.regionName(alcohol)).isEqualTo("스코틀랜드"); + assertThat(resolver.rating(alcohol)).isEqualTo(4.0); + assertThat(resolver.totalRatingsCount(alcohol)).isEqualTo(2L); + assertThat(resolver.reviewCount(alcohol)).isEqualTo(1L); + assertThat(resolver.totalPickCount(alcohol)).isEqualTo(1L); + } + + private static Alcohol alcohol(Long alcoholId) { + Region region = Region.builder().id(1L).korName("스코틀랜드").engName("Scotland").build(); + return Alcohol.builder() + .id(alcoholId) + .korName("테스트 위스키") + .engName("Test Whisky") + .abv("40%") + .type(AlcoholType.WHISKY) + .korCategory("위스키") + .engCategory("Whisky") + .categoryGroup(AlcoholCategoryGroup.SINGLE_MALT) + .region(region) + .cask("Oak") + .imageUrl("https://example.com/test-whisky.jpg") + .volume("700ml") + .build(); + } + + private static Rating rating(Long userId, Long alcoholId, Double rating) { + return Rating.builder() + .id(RatingId.is(userId, alcoholId)) + .ratingPoint(RatingPoint.of(rating)) + .build(); + } + + private static Review review( + Long alcoholId, ReviewActiveStatus activeStatus, ReviewDisplayStatus displayStatus) { + return Review.builder() + .userId(1L) + .alcoholId(alcoholId) + .content("리뷰") + .activeStatus(activeStatus) + .status(displayStatus) + .build(); + } + + private static Picks picks(Long alcoholId, Long userId, PicksStatus status) { + return Picks.builder().alcoholId(alcoholId).userId(userId).status(status).build(); + } + + private static final class FakeRatingRepository implements RatingRepository { + + private final Map ratings = new HashMap<>(); + + @Override + public Rating save(Rating rating) { + ratings.put(rating.getId(), rating); + return rating; + } + + @Override + public Optional findById(RatingId ratingId) { + return Optional.ofNullable(ratings.get(ratingId)); + } + + @Override + public List findAll() { + return List.copyOf(ratings.values()); + } + + @Override + public List findAllByIdIn(List ids) { + return ids.stream().map(ratings::get).filter(Objects::nonNull).toList(); + } + + @Override + public Optional findByAlcoholIdAndUserId(Long alcoholId, Long userId) { + return findById(RatingId.is(userId, alcoholId)); + } + + @Override + public PageResponse fetchRatingList(RatingListFetchCriteria criteria) { + throw new UnsupportedOperationException("not used in GraphQL resolver test"); + } + + @Override + public Optional fetchUserRating(Long alcoholId, Long userId) { + throw new UnsupportedOperationException("not used in GraphQL resolver test"); + } + + @Override + public Double findAverageRatingByAlcoholId(Long alcoholId) { + return ratings.values().stream() + .filter(rating -> Objects.equals(rating.getId().getAlcoholId(), alcoholId)) + .mapToDouble(rating -> rating.getRatingPoint().getRating()) + .filter(rating -> rating > 0.0) + .average() + .orElse(0.0); + } + + @Override + public Long countByAlcoholId(Long alcoholId) { + return ratings.values().stream() + .filter(rating -> Objects.equals(rating.getId().getAlcoholId(), alcoholId)) + .map(rating -> rating.getRatingPoint().getRating()) + .filter(rating -> rating > 0.0) + .count(); + } + + @Override + public boolean existsByAlcoholId(Long alcoholId) { + return ratings.values().stream() + .anyMatch(rating -> Objects.equals(rating.getId().getAlcoholId(), alcoholId)); + } + } + + private static final class FakePicksRepository implements PicksRepository { + + private final List picks = new java.util.ArrayList<>(); + + @Override + public Optional findByAlcoholIdAndUserId(Long alcoholId, Long userId) { + return picks.stream() + .filter(pick -> Objects.equals(pick.getAlcoholId(), alcoholId)) + .filter(pick -> Objects.equals(pick.getUserId(), userId)) + .findFirst(); + } + + @Override + public Long countByAlcoholIdAndStatus(Long alcoholId, PicksStatus status) { + return picks.stream() + .filter(pick -> Objects.equals(pick.getAlcoholId(), alcoholId)) + .filter(pick -> pick.getStatus() == status) + .count(); + } + + @Override + public Picks save(Picks pick) { + picks.add(pick); + return pick; + } + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/AdminSpecBasedCurationServiceTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/AdminSpecBasedCurationServiceTest.java new file mode 100644 index 000000000..63fb08971 --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/AdminSpecBasedCurationServiceTest.java @@ -0,0 +1,171 @@ +package app.bottlenote.curation.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import app.bottlenote.curation.domain.CurationSpec; +import app.bottlenote.curation.dto.request.CurationCreateRequest; +import app.bottlenote.curation.dto.request.CurationSearchRequest; +import app.bottlenote.curation.dto.request.CurationSpecCreateRequest; +import app.bottlenote.curation.dto.request.CurationUpdateRequest; +import app.bottlenote.curation.dto.response.AdminSpecBasedCurationDetailResponse; +import app.bottlenote.curation.exception.CurationException; +import app.bottlenote.curation.exception.CurationExceptionCode; +import app.bottlenote.curation.fixture.InMemoryCurationExtensionRepository; +import app.bottlenote.curation.fixture.InMemoryCurationRepository; +import app.bottlenote.curation.fixture.InMemoryCurationSpecRepository; +import app.bottlenote.global.data.response.GlobalResponse; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.LocalDate; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +@Tag("unit") +@DisplayName("AdminSpecBasedCurationService 단위 테스트") +class AdminSpecBasedCurationServiceTest { + + InMemoryCurationSpecRepository curationSpecRepository; + InMemoryCurationRepository curationRepository; + InMemoryCurationExtensionRepository curationExtensionRepository; + CurationV2Service curationV2Service; + AdminSpecBasedCurationService adminSpecBasedCurationService; + + @BeforeEach + void setUp() { + curationSpecRepository = new InMemoryCurationSpecRepository(); + curationRepository = new InMemoryCurationRepository(); + curationExtensionRepository = new InMemoryCurationExtensionRepository(); + ObjectMapper objectMapper = new ObjectMapper(); + curationV2Service = + new CurationV2Service( + curationSpecRepository, curationRepository, curationExtensionRepository); + adminSpecBasedCurationService = + new AdminSpecBasedCurationService( + curationSpecRepository, + curationRepository, + curationExtensionRepository, + new CurationPayloadValidator(objectMapper)); + } + + @Test + @DisplayName("큐레이션을 생성하면 imageUrls 첫 번째 이미지를 coverImageUrl에 저장하고 payload를 함께 저장한다") + void create_이미지와_payload_저장() { + CurationSpec spec = createSpec(); + + var result = adminSpecBasedCurationService.create(createRequest(spec.getId())); + + AdminSpecBasedCurationDetailResponse detail = + adminSpecBasedCurationService.getDetail(result.targetId()); + assertThat(result.code()).isEqualTo("CURATION_CREATED"); + assertThat(detail.coverImageUrl()).isEqualTo("https://cdn.example.com/cover.jpg"); + assertThat(detail.imageUrls()) + .containsExactly("https://cdn.example.com/cover.jpg", "https://cdn.example.com/second.jpg"); + assertThat(detail.spec().code()).isEqualTo("RECOMMENDED_WHISKY"); + assertThat(new ObjectMapper().valueToTree(detail.payload()).path("source").asText()) + .isEqualTo("BOTTLE_NOTE"); + } + + @Test + @DisplayName("큐레이션 스펙 상세를 조회할 수 있다") + void getSpecDetail_스펙_상세_조회() { + CurationSpec spec = createSpec(); + + var result = adminSpecBasedCurationService.getSpecDetail(spec.getId()); + + assertThat(result.id()).isEqualTo(spec.getId()); + assertThat(result.code()).isEqualTo("RECOMMENDED_WHISKY"); + assertThat(result.requestSpec()).containsKey("required"); + } + + @Test + @DisplayName("payload가 requestSpec required 필드를 만족하지 않으면 예외가 발생한다") + void create_payload_검증_실패() { + CurationSpec spec = createSpec(); + + assertThatThrownBy( + () -> + adminSpecBasedCurationService.create( + new CurationCreateRequest( + spec.getId(), + "잘못된 큐레이션", + null, + List.of("https://cdn.example.com/cover.jpg"), + null, + null, + 0, + true, + Map.of("source", "BOTTLE_NOTE")))) + .isInstanceOf(CurationException.class) + .hasFieldOrPropertyWithValue( + "exceptionCode", CurationExceptionCode.CURATION_PAYLOAD_INVALID); + } + + @Test + @DisplayName("큐레이션을 수정하면 본문과 extension payload를 함께 갱신한다") + void update_본문과_payload_수정() { + CurationSpec spec = createSpec(); + Long curationId = adminSpecBasedCurationService.create(createRequest(spec.getId())).targetId(); + + var result = + adminSpecBasedCurationService.update( + curationId, + new CurationUpdateRequest( + spec.getId(), + "수정된 큐레이션", + "수정된 설명", + List.of("https://cdn.example.com/updated.jpg"), + LocalDate.of(2026, 7, 1), + LocalDate.of(2026, 7, 31), + 5, + false, + Map.of("source", "MANUAL", "alcohol", Map.of("korName", "수동 입력")))); + + AdminSpecBasedCurationDetailResponse detail = + adminSpecBasedCurationService.getDetail(curationId); + assertThat(result.code()).isEqualTo("CURATION_UPDATED"); + assertThat(detail.name()).isEqualTo("수정된 큐레이션"); + assertThat(detail.isActive()).isFalse(); + assertThat(detail.imageUrls()).containsExactly("https://cdn.example.com/updated.jpg"); + } + + @Test + @DisplayName("큐레이션 목록을 조회할 수 있다") + void search_목록_조회() { + CurationSpec spec = createSpec(); + adminSpecBasedCurationService.create(createRequest(spec.getId())); + + GlobalResponse result = + adminSpecBasedCurationService.search(new CurationSearchRequest("", null, 0, 20)); + + assertThat(result.getData()).asList().hasSize(1); + } + + private CurationSpec createSpec() { + return curationV2Service.createSpec( + new CurationSpecCreateRequest( + "RECOMMENDED_WHISKY", + "추천 위스키", + null, + Map.of("type", "object", "required", List.of("source", "alcohol")), + Map.of("type", "object"), + "alcohol", + 1)); + } + + private CurationCreateRequest createRequest(Long specId) { + return new CurationCreateRequest( + specId, + "비 오는 날 위스키", + "스모키 위스키 추천", + List.of("https://cdn.example.com/cover.jpg", "https://cdn.example.com/second.jpg"), + LocalDate.of(2026, 6, 1), + LocalDate.of(2026, 6, 30), + 1, + true, + Map.of("source", "BOTTLE_NOTE", "alcohol", Map.of("korName", "테스트 위스키"))); + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationSpecResourceSyncServiceTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationSpecResourceSyncServiceTest.java new file mode 100644 index 000000000..1cd495b9b --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationSpecResourceSyncServiceTest.java @@ -0,0 +1,56 @@ +package app.bottlenote.curation.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import app.bottlenote.curation.domain.CurationSpec; +import app.bottlenote.curation.dto.response.CurationSpecSyncResponse; +import app.bottlenote.curation.fixture.InMemoryCurationSpecRepository; +import app.bottlenote.curation.support.CurationSpecResourceReader; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +@Tag("unit") +@DisplayName("CurationSpecResourceSyncService 단위 테스트") +class CurationSpecResourceSyncServiceTest { + + @Test + @DisplayName("리소스 OpenAPI 스펙을 curation_spec으로 생성하고 재실행 시 갱신한다") + void sync_리소스_스펙_생성_및_갱신() { + InMemoryCurationSpecRepository curationSpecRepository = new InMemoryCurationSpecRepository(); + CurationSpecResourceReader resourceReader = + new CurationSpecResourceReader( + new PathMatchingResourcePatternResolver(), new ObjectMapper()); + CurationSpecResourceSyncService service = + new CurationSpecResourceSyncService(curationSpecRepository, resourceReader); + + CurationSpecSyncResponse firstResult = service.sync(); + + assertThat(firstResult.createdCount()).isEqualTo(3); + assertThat(firstResult.updatedCount()).isZero(); + assertThat(curationSpecRepository.findAllByIsActiveTrueOrderByIdAsc()).hasSize(3); + assertThat( + curationSpecRepository.findAllByIsActiveTrueOrderByIdAsc().stream() + .map(CurationSpec::getCode) + .toList()) + .containsExactlyInAnyOrder("RECOMMENDED_WHISKY", "WHISKY_PAIRING", "WHISKY_TASTING_EVENT"); + + CurationSpec recommended = + curationSpecRepository.findByCode("RECOMMENDED_WHISKY").orElseThrow(); + assertThat(recommended.getVersion()).isEqualTo(2); + assertThat(recommended.getRequestSpec()).containsKey("required"); + assertThat(recommended.getResponseSpec().toString()).contains("x-graphql", "stats"); + + CurationSpecSyncResponse secondResult = service.sync(); + + assertThat(secondResult.createdCount()).isZero(); + assertThat(secondResult.updatedCount()).isEqualTo(3); + assertThat(curationSpecRepository.findAllByIsActiveTrueOrderByIdAsc()) + .extracting(CurationSpec::getCode) + .containsExactlyElementsOf( + List.of("RECOMMENDED_WHISKY", "WHISKY_PAIRING", "WHISKY_TASTING_EVENT")); + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationV2ServiceTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationV2ServiceTest.java new file mode 100644 index 000000000..871565436 --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationV2ServiceTest.java @@ -0,0 +1,142 @@ +package app.bottlenote.curation.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import app.bottlenote.curation.domain.Curation; +import app.bottlenote.curation.domain.CurationExtension; +import app.bottlenote.curation.domain.CurationSpec; +import app.bottlenote.curation.dto.request.CurationCreateRequest; +import app.bottlenote.curation.dto.request.CurationSpecCreateRequest; +import app.bottlenote.curation.exception.CurationException; +import app.bottlenote.curation.exception.CurationExceptionCode; +import app.bottlenote.curation.fixture.InMemoryCurationExtensionRepository; +import app.bottlenote.curation.fixture.InMemoryCurationRepository; +import app.bottlenote.curation.fixture.InMemoryCurationSpecRepository; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.LocalDate; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +@Tag("unit") +@DisplayName("CurationV2Service 단위 테스트") +class CurationV2ServiceTest { + + InMemoryCurationSpecRepository curationSpecRepository; + InMemoryCurationRepository curationRepository; + InMemoryCurationExtensionRepository curationExtensionRepository; + CurationV2Service curationV2Service; + + @BeforeEach + void setUp() { + curationSpecRepository = new InMemoryCurationSpecRepository(); + curationRepository = new InMemoryCurationRepository(); + curationExtensionRepository = new InMemoryCurationExtensionRepository(); + curationV2Service = + new CurationV2Service( + curationSpecRepository, curationRepository, curationExtensionRepository); + } + + @Test + @DisplayName("새 큐레이션 스펙을 저장할 수 있다") + void createSpec_신규_스펙_저장() { + CurationSpec result = + curationV2Service.createSpec( + new CurationSpecCreateRequest( + "RECOMMENDED_WHISKY", + "추천 위스키", + "개인화 추천", + Map.of("type", "object", "required", List.of("source", "alcohol")), + Map.of("type", "object"), + "BOTTLE_NOTE", + null)); + + assertThat(result.getId()).isNotNull(); + assertThat(result.getVersion()).isEqualTo(1); + assertThat(result.getIsActive()).isTrue(); + } + + @Test + @DisplayName("중복 코드로 큐레이션 스펙을 저장하면 예외가 발생한다") + void createSpec_중복_코드_예외() { + curationV2Service.createSpec( + new CurationSpecCreateRequest( + "RECOMMENDED_WHISKY", + "추천 위스키", + null, + Map.of("type", "object", "required", List.of("source", "alcohol")), + Map.of("type", "object"), + "BOTTLE_NOTE", + 1)); + + assertThatThrownBy( + () -> + curationV2Service.createSpec( + new CurationSpecCreateRequest( + "RECOMMENDED_WHISKY", "중복 추천", null, Map.of(), Map.of(), "BOTTLE_NOTE", 1))) + .isInstanceOf(CurationException.class) + .hasFieldOrPropertyWithValue( + "exceptionCode", CurationExceptionCode.CURATION_SPEC_DUPLICATE_CODE); + } + + @Test + @DisplayName("큐레이션 저장 시 본문과 payload 확장을 함께 저장한다") + void createCuration_본문과_payload_저장() { + CurationSpec spec = + curationV2Service.createSpec( + new CurationSpecCreateRequest( + "RECOMMENDED_WHISKY", + "추천 위스키", + null, + Map.of("type", "object", "required", List.of("source", "alcohol")), + Map.of("type", "object"), + "BOTTLE_NOTE", + 1)); + + Curation curation = + curationV2Service.createCuration( + new CurationCreateRequest( + spec.getId(), + "비 오는 날 위스키", + "스모키 위스키 추천", + List.of("https://cdn.example.com/cover.jpg"), + LocalDate.of(2026, 5, 15), + LocalDate.of(2026, 6, 15), + 10, + true, + Map.of("source", "BOTTLE_NOTE", "alcohol", Map.of("korName", "테스트")))); + + CurationExtension extension = curationV2Service.getExtension(curation.getId()); + + assertThat(curation.getSpecId()).isEqualTo(spec.getId()); + assertThat(curation.getDisplayOrder()).isEqualTo(10); + assertThat(extension.getSpecId()).isEqualTo(spec.getId()); + assertThat(new ObjectMapper().valueToTree(extension.getPayload()).path("source").asText()) + .isEqualTo("BOTTLE_NOTE"); + } + + @Test + @DisplayName("존재하지 않는 스펙으로 큐레이션을 저장하면 예외가 발생한다") + void createCuration_스펙_없음_예외() { + assertThatThrownBy( + () -> + curationV2Service.createCuration( + new CurationCreateRequest( + 999L, + "없는 스펙", + null, + List.of("https://cdn.example.com/cover.jpg"), + null, + null, + 0, + true, + Map.of()))) + .isInstanceOf(CurationException.class) + .hasFieldOrPropertyWithValue( + "exceptionCode", CurationExceptionCode.CURATION_SPEC_NOT_FOUND); + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/graphql/CurationGraphqlSchemaTest.java b/bottlenote-mono/src/test/java/app/bottlenote/graphql/CurationGraphqlSchemaTest.java new file mode 100644 index 000000000..a45188ff5 --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/graphql/CurationGraphqlSchemaTest.java @@ -0,0 +1,45 @@ +package app.bottlenote.graphql; + +import static org.assertj.core.api.Assertions.assertThat; + +import graphql.schema.idl.SchemaParser; +import graphql.schema.idl.TypeDefinitionRegistry; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.core.io.ClassPathResource; + +@Tag("unit") +class CurationGraphqlSchemaTest { + + @Test + @DisplayName("큐레이션 GraphQL SDL은 Alcohol 통계 조회 필드만 노출한다") + void schema_whenParsed_exposesAlcoholStatsOnly() throws IOException { + ClassPathResource resource = new ClassPathResource("graphql/schema.graphqls"); + String schema = resource.getContentAsString(StandardCharsets.UTF_8); + + TypeDefinitionRegistry registry = new SchemaParser().parse(schema); + + assertThat(registry.getType("Query")).isPresent(); + assertThat(registry.getType("Alcohol")).isPresent(); + assertThat(schema).contains("alcohols(ids: [ID!]!): [Alcohol!]!"); + assertThat(schema) + .contains( + "alcoholId", + "korName", + "engName", + "imageUrl", + "regionName", + "korCategory", + "cask", + "abv", + "volume", + "rating", + "totalRatingsCount", + "reviewCount", + "totalPickCount"); + assertThat(schema).doesNotContain("picks(", "ratings(", "reviews("); + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java b/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java index 99642e7a0..8313db102 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java @@ -2,6 +2,8 @@ import app.bottlenote.global.service.cursor.CursorResponse; import app.bottlenote.global.service.cursor.PageResponse; +import app.bottlenote.review.constant.ReviewActiveStatus; +import app.bottlenote.review.constant.ReviewDisplayStatus; import app.bottlenote.review.domain.Review; import app.bottlenote.review.domain.ReviewRepository; import app.bottlenote.review.dto.request.ReviewPageableRequest; @@ -74,6 +76,16 @@ public List findByUserId(Long userId) { return List.of(); } + @Override + public Long countByAlcoholIdAndActiveStatusAndStatus( + Long alcoholId, ReviewActiveStatus activeStatus, ReviewDisplayStatus status) { + return database.values().stream() + .filter(review -> Objects.equals(review.getAlcoholId(), alcoholId)) + .filter(review -> review.getActiveStatus() == activeStatus) + .filter(review -> review.getStatus() == status) + .count(); + } + @Override public boolean existsById(Long reviewId) { return database.containsKey(reviewId); diff --git a/bottlenote-product-api/src/main/resources/application.yml b/bottlenote-product-api/src/main/resources/application.yml index e6334ac16..170570de7 100644 --- a/bottlenote-product-api/src/main/resources/application.yml +++ b/bottlenote-product-api/src/main/resources/application.yml @@ -86,6 +86,10 @@ spring: config: activate: on-profile: default,local + graphql: + graphiql: + enabled: true + path: /graphiql logging: level: diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/picks/fake/FakePicksRepository.java b/bottlenote-product-api/src/test/java/app/bottlenote/picks/fake/FakePicksRepository.java index abad274a6..8f1525d49 100644 --- a/bottlenote-product-api/src/test/java/app/bottlenote/picks/fake/FakePicksRepository.java +++ b/bottlenote-product-api/src/test/java/app/bottlenote/picks/fake/FakePicksRepository.java @@ -5,6 +5,7 @@ import app.bottlenote.picks.domain.PicksRepository; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.Optional; import org.springframework.test.util.ReflectionTestUtils; @@ -25,6 +26,14 @@ public Optional findByAlcoholIdAndUserId(Long alcoholId, Long userId) { .findFirst(); } + @Override + public Long countByAlcoholIdAndStatus(Long alcoholId, PicksStatus status) { + return picksDatabase.values().stream() + .filter(picks -> Objects.equals(picks.getAlcoholId(), alcoholId)) + .filter(picks -> picks.getStatus() == status) + .count(); + } + @Override public Picks save(Picks picks) { long id = picksDatabase.size() + 1L; diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/rating/fixture/InMemoryRatingRepository.java b/bottlenote-product-api/src/test/java/app/bottlenote/rating/fixture/InMemoryRatingRepository.java index d5c56166f..72724d172 100644 --- a/bottlenote-product-api/src/test/java/app/bottlenote/rating/fixture/InMemoryRatingRepository.java +++ b/bottlenote-product-api/src/test/java/app/bottlenote/rating/fixture/InMemoryRatingRepository.java @@ -57,6 +57,24 @@ public Optional fetchUserRating(Long alcoholId, Long userId) return Optional.empty(); } + @Override + public Double findAverageRatingByAlcoholId(Long alcoholId) { + return ratings.values().stream() + .filter(rating -> rating.getId().getAlcoholId().equals(alcoholId)) + .mapToDouble(rating -> rating.getRatingPoint().getRating()) + .filter(rating -> rating > 0.0) + .average() + .orElse(0.0); + } + + @Override + public Long countByAlcoholId(Long alcoholId) { + return ratings.values().stream() + .filter(rating -> rating.getId().getAlcoholId().equals(alcoholId)) + .filter(rating -> rating.getRatingPoint().getRating() > 0.0) + .count(); + } + @Override public boolean existsByAlcoholId(Long alcoholId) { return ratings.values().stream() diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java b/bottlenote-product-api/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java index 980e2538f..eaf99d4db 100644 --- a/bottlenote-product-api/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java +++ b/bottlenote-product-api/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java @@ -2,6 +2,8 @@ import app.bottlenote.global.service.cursor.CursorResponse; import app.bottlenote.global.service.cursor.PageResponse; +import app.bottlenote.review.constant.ReviewActiveStatus; +import app.bottlenote.review.constant.ReviewDisplayStatus; import app.bottlenote.review.domain.Review; import app.bottlenote.review.domain.ReviewRepository; import app.bottlenote.review.dto.request.ReviewPageableRequest; @@ -76,6 +78,16 @@ public List findByUserId(Long userId) { return List.of(); } + @Override + public Long countByAlcoholIdAndActiveStatusAndStatus( + Long alcoholId, ReviewActiveStatus activeStatus, ReviewDisplayStatus status) { + return database.values().stream() + .filter(review -> Objects.equals(review.getAlcoholId(), alcoholId)) + .filter(review -> review.getActiveStatus() == activeStatus) + .filter(review -> review.getStatus() == status) + .count(); + } + @Override public boolean existsById(Long reviewId) { return database.containsKey(reviewId); diff --git a/bottlenote-product-api/src/test/java/app/rule/api/ControllerLayerRules.java b/bottlenote-product-api/src/test/java/app/rule/api/ControllerLayerRules.java index 3d3a65f00..361ea279a 100644 --- a/bottlenote-product-api/src/test/java/app/rule/api/ControllerLayerRules.java +++ b/bottlenote-product-api/src/test/java/app/rule/api/ControllerLayerRules.java @@ -39,6 +39,8 @@ @SuppressWarnings({"NonAsciiCharacters", "JUnitTestClassNamingConvention"}) public class ControllerLayerRules extends AbstractRules { + private static final String GRAPHQL_PACKAGE = "..graphql.."; + /** 컨트롤러 클래스 명명 규칙을 검증합니다. 컨트롤러 애노테이션이 있는 모든 클래스는 이름이 'Controller'로 끝나야 합니다. */ @Test public void 컨트롤러_클래스_명명_규칙_검증() { @@ -48,6 +50,8 @@ public class ControllerLayerRules extends AbstractRules { .areAnnotatedWith(RestController.class) .or() .areAnnotatedWith(Controller.class) + .and() + .resideOutsideOfPackage(GRAPHQL_PACKAGE) .should() .haveSimpleNameEndingWith("Controller") .because("컨트롤러 클래스는 명확한 식별을 위해 'Controller'로 끝나야 합니다"); @@ -64,6 +68,8 @@ public class ControllerLayerRules extends AbstractRules { .areAnnotatedWith(RestController.class) .or() .areAnnotatedWith(Controller.class) + .and() + .resideOutsideOfPackage(GRAPHQL_PACKAGE) .should() .resideInAnyPackage("..controller..", "..api..") .because("컨트롤러 클래스는 구조적 일관성을 위해 '.controller' 또는 '.api' 패키지에 위치해야 합니다"); @@ -98,6 +104,8 @@ public class ControllerLayerRules extends AbstractRules { .areAnnotatedWith(RestController.class) .or() .areAnnotatedWith(Controller.class) + .and() + .resideOutsideOfPackage(GRAPHQL_PACKAGE) .should() .beAnnotatedWith(RequestMapping.class) .because("컨트롤러 클래스는 기본 경로 정의를 위해 클래스 수준의 @RequestMapping을 가져야 합니다"); @@ -123,6 +131,9 @@ public class ControllerLayerRules extends AbstractRules { .arePublic() .and() .areNotStatic() + .and() + .areDeclaredInClassesThat() + .resideOutsideOfPackage(GRAPHQL_PACKAGE) .should() .beAnnotatedWith(GetMapping.class) .orShould() @@ -251,6 +262,9 @@ public boolean test(JavaClass javaClass) { .areAnnotatedWith(Controller.class) .and() .arePublic() + .and() + .areDeclaredInClassesThat() + .resideOutsideOfPackage(GRAPHQL_PACKAGE) .should(followControllerMethodNamingConvention()) .because("컨트롤러 메서드는 명확한 동사로 시작하는 명명 규칙을 따라야 합니다(예: getUser, createOrder)"); diff --git a/git.environment-variables b/git.environment-variables index 5f4f19f1d..03212f4ff 160000 --- a/git.environment-variables +++ b/git.environment-variables @@ -1 +1 @@ -Subproject commit 5f4f19f1dd52a3d12cd83b03330aa8b6904fb548 +Subproject commit 03212f4ff7f450220448ab1850bf2cd67c319110 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index de6c71075..a626b0687 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -69,6 +69,7 @@ kotlin = "1.9.23" # Spring Boot Core spring-boot-starter = { module = "org.springframework.boot:spring-boot-starter", version.ref = "spring-boot" } spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web", version.ref = "spring-boot" } +spring-boot-starter-graphql = { module = "org.springframework.boot:spring-boot-starter-graphql", version.ref = "spring-boot" } spring-boot-starter-data-jpa = { module = "org.springframework.boot:spring-boot-starter-data-jpa", version.ref = "spring-boot" } spring-boot-starter-data-redis = { module = "org.springframework.boot:spring-boot-starter-data-redis", version.ref = "spring-boot" } spring-boot-starter-validation = { module = "org.springframework.boot:spring-boot-starter-validation", version.ref = "spring-boot" } diff --git a/plan/spec-based-curation-v2-graphql-sdl.md b/plan/spec-based-curation-v2-graphql-sdl.md new file mode 100644 index 000000000..e34956a96 --- /dev/null +++ b/plan/spec-based-curation-v2-graphql-sdl.md @@ -0,0 +1,293 @@ +# Plan: Spec-Based Curation V2 - GraphQL SDL Foundation + +## Overview + +`curation_demo`에서 검증한 spec 기반 큐레이션을 `bottle-note-api-server`에 이식한다. + +전체 기능은 신규 도메인, DB schema, Admin/Product endpoint, payload validation, GraphQL hydration까지 포함하므로 한 번에 끝내지 않는다. 이번 기능은 검증 범위를 3개 phase로 나눈 뒤, Phase 1에서 GraphQL 도메인 SDL과 서버 내 실행 기반만 먼저 만든다. + +기존 `curation_keyword`와 `curation_keyword_alcohol_ids`는 유연한 이관을 위해 그대로 둔다. 기존 Admin/Product endpoint도 변경하지 않는다. 신규 외부 API는 이후 phase에서 v2 endpoint로 추가한다. + +### Phase Roadmap + +1. **GraphQL SDL Foundation** + - Spring GraphQL 의존성, SDL, resolver, 내부 실행 검증 기반을 추가한다. + - Alcohol 도메인 조회와 stats hydration에 필요한 최소 field만 다룬다. + - 외부 curation v2 endpoint와 신규 curation DB table은 만들지 않는다. +2. **Curation V2 Persistence + Admin Command** + - `git.environment-variables/storage/mysql/changelog/`에 `curation_spec`, `curation`, `curation_extension` schema changeset을 추가하고, mono domain/repository/service를 추가한다. + - Admin v2 등록/수정/상세/목록 API에서 spec 기반 payload 저장과 검증을 처리한다. +3. **Product V2 Query + Hydration** + - Product v2 목록/상세 API를 추가한다. + - 저장 payload를 response spec과 GraphQL hydration 결과로 앱 응답 형태로 조립한다. + - `BOTTLE_NOTE` 항목만 stats를 보강하고 `MANUAL` 항목은 stats를 생략한다. + +## Assumptions + +- 신규 기능은 기존 `app.bottlenote.alcohols.domain.CurationKeyword`를 개조하지 않고 별도 `app.bottlenote.curation` 도메인으로 진행한다. +- 기존 테이블 `curation_keyword`, `curation_keyword_alcohol_ids`는 이번 전체 이식 기간 동안 drop 또는 data migration하지 않는다. +- DB schema 변경이 필요한 phase에서는 반드시 서브모듈 `git.environment-variables/storage/mysql/changelog/` 아래 changelog를 사용한다. +- 기존 endpoint는 유지하고, 신규 endpoint는 후속 phase에서 v2로 추가한다. +- Phase 1은 GraphQL 기반만 다루며, curation v2 DB table과 Admin/Product curation endpoint는 만들지 않는다. +- GraphQL은 외부 공개 API로 먼저 설계하지 않고, 서버 내부 hydration 실행 기반으로 도입한다. `/graphql` HTTP 노출 여부는 구현 단계에서 Spring GraphQL 기본 동작과 보안 설정 영향을 확인한 뒤 필요한 경우 제한한다. +- OpenAPI curation spec seed는 Liquibase insert changeset이 아니라 `bottlenote-mono/src/main/resources/openapi/curation/*.json` 리소스를 admin-api 기동 시 `curation_spec`으로 동기화하는 방식으로 관리한다. +- 도메인 SDL은 `Alcohol`을 시작점으로 하며, Phase 1의 선택 field는 stats hydration에 필요한 평균 별점, 평점 수, 리뷰 수, 찜 수와 기본 alcohol 식별/표시 field로 제한한다. +- 사용자별 picks/reviews/ratings 원본 목록은 curation v2 응답에 노출하지 않는다. +- `reviewCount`는 데모처럼 rating count를 재사용하지 않고 실제 review 도메인 집계 기준으로 정의한다. + +## Success Criteria + +- `bottlenote-mono` 또는 GraphQL 설정을 소유할 적절한 모듈에 Spring GraphQL 의존성과 SDL 리소스가 추가된다. +- SDL에 `Query.alcohols(ids: [ID!]!)` 또는 동등한 batch 조회 진입점이 정의된다. +- SDL의 `Alcohol` 타입에 curation stats hydration에 필요한 필드가 정의된다: + - `alcoholId` + - `korName` + - `engName` + - `imageUrl` + - `regionName` + - `korCategory` + - `cask` + - `abv` + - `volume` + - `rating` + - `totalRatingsCount` + - `reviewCount` + - `totalPickCount` +- GraphQL resolver는 기존 alcohol/rating/review/picks 도메인의 repository 또는 service를 사용해 위 필드를 해석한다. +- `reviewCount`는 실제 review count를 반환한다. +- 없는 alcohol id는 전체 요청을 실패시키지 않고 누락 또는 null 정책을 명확히 따른다. +- `source = MANUAL` 같은 `alcoholId = null` 입력은 후속 payload hydration 단계에서 GraphQL 조회 대상이 되지 않는 정책으로 문서화된다. +- Phase 1 완료 시 기존 `curation_keyword` API 동작 표면은 변경되지 않는다. +- Phase 1 완료 시 다음 검증이 통과해야 한다: + - `./gradlew :bottlenote-mono:compileJava` + - GraphQL resolver 또는 builder 대상 단위 테스트 + - `./gradlew check_rule_test` + +## Impact Scope + +- **Modules** + - `bottlenote-mono`: GraphQL SDL, resolver, stats 조회 조립, 테스트가 들어갈 가능성이 높다. + - `bottlenote-product-api`: Phase 1에서는 외부 curation endpoint를 추가하지 않는다. Spring GraphQL runtime wiring이 executable app 쪽 설정을 요구하는지는 `/plan`에서 확인한다. + - `bottlenote-admin-api`: Phase 1 영향 없음. + - `git.environment-variables`: Phase 1 schema 변경 없음. +- **Persistence** + - Phase 1에서는 신규 테이블을 만들지 않는다. + - 기존 `curation_keyword`, `curation_keyword_alcohol_ids`는 읽기 확인 대상일 뿐 수정 대상이 아니다. + - Phase 2 이후 DB schema 변경은 `/Users/hgkim/workspace/etc/bottlenote/bottle-note-api-server/git.environment-variables/storage/mysql/changelog/`의 Liquibase changelog에 append한다. + - 이미 적용된 기존 changeset은 수정하지 않는다. +- **API Contract** + - Phase 1에서는 신규 public REST endpoint를 만들지 않는다. + - `/graphql` HTTP endpoint가 자동 노출되는 경우 보안/운영 노출 정책을 별도 결정해야 한다. +- **Cross-Domain Coupling** + - GraphQL resolver가 alcohol, rating, review, picks 집계를 한 지점에서 묶는다. + - curation 도메인에서 직접 각 도메인을 호출하는 대신, 후속 phase에서 GraphQL hydration boundary를 재사용한다. +- **Validation** + - Phase 1은 payload JSON Schema validation을 구현하지 않는다. + - payload validation은 Phase 2 범위다. +- **Tests** + - SDL schema loading 또는 GraphQL query execution 테스트가 필요하다. + - resolver 단위 테스트는 Fake/InMemory 우선 원칙을 따른다. + - 기존 curation keyword endpoint regression은 최소 smoke 수준으로 범위를 정한다. +- **Docs** + - 이번 plan 문서는 전체 phase boundary와 Phase 1 정의의 source of truth다. + - `/plan` 단계에서 Phase 1 task breakdown과 검증 명령을 추가한다. + +## Phase 1 Out of Scope + +- `curation_spec`, `curation`, `curation_extension` table 추가 +- Admin curation v2 등록/수정/목록/상세 endpoint +- Product curation v2 목록/상세 endpoint +- 기존 `curation_keyword` 제거, drop, data migration +- 기존 curation keyword endpoint path 변경 +- FE/Admin 화면 구현 + +## Tasks + +### Task 1: Spring GraphQL module wiring + +- Acceptance: + - Spring GraphQL 의존성이 version catalog 또는 기존 Gradle 패턴에 맞게 추가된다. + - SDL 리소스 경로는 `bottlenote-mono/src/main/resources/graphql/schema.graphqls`로 확정한다. + - Phase 1에서 `git.environment-variables/storage/mysql/changelog/`는 수정하지 않는다. +- Verification: + - `./gradlew :bottlenote-mono:compileJava` + - `./gradlew :bottlenote-product-api:compileJava` + - `git diff -- git.environment-variables/storage/mysql/changelog/` 결과가 비어 있어야 한다. +- Files: + - `gradle/libs.versions.toml` + - `bottlenote-mono/build.gradle` + - `bottlenote-mono/src/main/resources/graphql/schema.graphqls` path decision +- Size: S +- Status: [x] done + +### Task 2: Alcohol GraphQL SDL contract + +- Acceptance: + - `Alcohol` 타입과 `Query.alcohols(ids: [ID!]!)` 또는 동등한 batch 조회 진입점이 SDL에 정의된다. + - SDL field는 Phase 1 성공 기준의 stats hydration 필드로 제한된다. + - 사용자별 picks/reviews/ratings 목록 field는 SDL에 포함하지 않는다. +- Verification: + - SDL 파일에서 `type Alcohol`, `type Query`, `alcohols` 진입점이 확인된다. + - GraphQL schema loading 테스트 또는 application context 테스트가 SDL을 로딩한다. +- Files: + - `bottlenote-mono/src/main/resources/graphql/schema.graphqls` + - GraphQL schema loading test +- Size: S +- Status: [x] done + +### Task 3: Alcohol stats resolver foundation + +- Acceptance: + - resolver는 기존 alcohol/rating/review/picks 도메인의 repository 또는 service를 사용한다. + - `reviewCount`는 rating count가 아니라 실제 review count 기준으로 계산한다. + - 존재하지 않는 alcohol id는 전체 GraphQL 실행을 실패시키지 않는 정책으로 처리된다. +- Verification: + - resolver unit test 또는 in-process GraphQL execution test가 `rating`, `totalRatingsCount`, `reviewCount`, `totalPickCount`를 검증한다. + - `MANUAL` 항목처럼 `alcoholId = null`인 케이스는 GraphQL 조회 대상에서 제외해야 한다는 정책이 테스트명 또는 문서에 남는다. +- Files: + - GraphQL resolver package under the selected module + - Existing domain repository/service additions only if needed + - Resolver or execution test +- Size: M +- Status: [x] done + +### Checkpoint: after Tasks 1-3 + +- [x] `./gradlew :bottlenote-mono:compileJava` +- [x] `./gradlew :bottlenote-product-api:compileJava` +- [x] GraphQL schema/resolver focused tests pass +- [x] `git diff -- git.environment-variables/storage/mysql/changelog/` is empty + +### Task 4: Product bootRun smoke with .env + +- Acceptance: + - `.env`를 로드한 상태로 product API를 `bootRun` 기동할 수 있다. + - 기동 검증은 secret 값을 로그나 문서에 노출하지 않는다. + - Phase 1이 기존 REST curation keyword endpoint path를 변경하지 않았음을 확인한다. +- Verification: + - `set -a; source .env; set +a; ./gradlew :bottlenote-product-api:bootRun` + - 서버 기동 후 GraphQL wiring 또는 application startup log 확인 + - 필요 시 별도 터미널에서 기존 reference endpoint smoke 확인 +- Files: + - No required source file unless startup wiring needs a config adjustment +- Size: S +- Status: [x] done + +### Task 5: Phase 1 final verification + +- Acceptance: + - Phase 1 성공 기준이 모두 충족된다. + - 다음 phase에서 사용할 GraphQL hydration boundary가 문서상 명확하다. + - 신규 DB schema, Admin spec 기반 endpoint, Product curation v2 endpoint가 아직 추가되지 않았음이 확인된다. +- Verification: + - `./gradlew :bottlenote-mono:compileJava` + - `./gradlew :bottlenote-product-api:compileJava` + - `./gradlew check_rule_test` + - `rg -n "curation_spec|curation_extension" git.environment-variables/storage/mysql/changelog/schema.mysql.sql` 결과가 기존 파일 기준으로 신규 추가되지 않았는지 diff로 확인 +- Files: + - `plan/spec-based-curation-v2-graphql-sdl.md` + - Optional focused docs update only if implementation decisions diverge from this plan +- Size: S +- Status: [x] done + +### Phase 2 Task 1: Curation V2 schema changelog apply + +- Acceptance: + - `git.environment-variables/storage/mysql/changelog/schema.mysql.sql`에 `curation_spec`, `curation`, `curation_extension` changeset을 append한다. + - 기존 `curation_keyword`, `curation_keyword_alcohol_ids`는 변경하지 않는다. + - SOPS 기반 Liquibase 설정을 사용하되 secret 값을 출력하거나 문서화하지 않는다. + - 개발 DB와 운영 DB 모두 pending changeset이 이번 3개뿐인지 확인한 뒤 적용한다. +- Verification: + - `liquibase validate` + - `liquibase status --verbose` + - `liquibase update` + - `information_schema.tables`에서 `curation_spec`, `curation`, `curation_extension` 생성 확인 + - `liquibase status --verbose` 결과가 up to date +- Files: + - `git.environment-variables/storage/mysql/changelog/schema.mysql.sql` +- Size: S +- Status: [x] done + +### Phase 2 Task 2: Mono curation v2 persistence model + +- Acceptance: + - `bottlenote-mono`에 `curation_spec`, `curation`, `curation_extension`에 대응되는 Entity를 추가한다. + - Repository는 domain interface + JPA implementation 패턴을 따른다. + - JSON 컬럼은 기존 Hypersistence `JsonType` 기반 매핑을 사용한다. + - Admin command가 재사용할 persistence service를 추가하되, REST endpoint는 아직 만들지 않는다. +- Verification: + - `./gradlew :bottlenote-mono:compileJava` + - `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationV2ServiceTest'` + - `./gradlew check_rule_test` +- Files: + - `bottlenote-mono/src/main/java/app/bottlenote/curation/domain/*` + - `bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/*` + - `bottlenote-mono/src/main/java/app/bottlenote/curation/repository/*` + - `bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationV2Service.java` + - `bottlenote-mono/src/test/java/app/bottlenote/curation/**` +- Size: M +- Status: [x] done + +### Phase 2 Task 3: Admin spec-based curation command/query API + +- Acceptance: + - Admin spec 기반 등록/수정/상세/목록 API를 추가한다. + - Admin context-path가 이미 `/admin/api/v1`이므로 컨트롤러 path에 `/v2` prefix를 중복으로 붙이지 않는다. + - 스펙 API는 `/curation-specs`, spec 기반 큐레이션 API는 기존 `/curations`와 충돌하지 않도록 `/spec-based-curations`를 사용한다. + - 스펙 목록과 스펙 상세 API를 제공한다. + - request payload는 저장 전 OpenAPI spec resource 기준 검증 경계로 연결한다. + - admin-api 기동 시 `openapi/curation/*.json` 리소스를 읽어 `curation_spec`을 생성 또는 갱신한다. + - 리소스 동기화는 `curation.spec-sync.enabled` 설정으로 비활성화할 수 있다. + - 기존 Admin curation keyword API와 path는 변경하지 않는다. + - Product v2 hydration API는 아직 만들지 않는다. +- Verification: + - Admin API compile + - Admin controller/docs focused test + - Resource sync focused test + - `./gradlew check_rule_test` +- Files: + - `bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/**` + - 필요한 mono DTO/service 확장 +- Size: L +- Status: [x] done + +## Progress Log + +- 2026-05-15 Task 1 완료: Spring GraphQL starter alias를 version catalog에 추가하고, `bottlenote-mono`에 GraphQL runtime dependency를 연결했다. SDL 경로는 `bottlenote-mono/src/main/resources/graphql/schema.graphqls`로 확정했다. 검증: `./gradlew :bottlenote-mono:compileJava` 성공, `./gradlew :bottlenote-product-api:compileJava` 성공, `git diff -- git.environment-variables/storage/mysql/changelog/` 변경 없음. +- 2026-05-15 Task 2 완료: `bottlenote-mono/src/main/resources/graphql/schema.graphqls`에 `Query.alcohols(ids: [ID!]!)`와 stats hydration용 `Alcohol` SDL을 추가했다. 사용자별 `picks`, `ratings`, `reviews` 목록 field는 포함하지 않았다. 검증: `rg -n "type Alcohol|type Query|alcohols|picks\\(|ratings\\(|reviews\\(" ...` 확인, `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.graphql.CurationGraphqlSchemaTest'` 성공, changelog diff 변경 없음. +- 2026-05-15 Task 3 완료: `bottlenote-mono`에 `CurationAlcoholGraphqlResolver`와 `CurationAlcoholGraphqlService`를 추가해 `Alcohol` field resolver를 연결했다. `rating`/`totalRatingsCount`는 rating repository 집계, `reviewCount`는 `ACTIVE` + `PUBLIC` review count, `totalPickCount`는 `PICK` 상태 count로 계산한다. `alcoholId = null`인 `MANUAL` 항목과 존재하지 않는 alcohol id는 GraphQL 조회 결과에서 제외하는 정책을 resolver 테스트명과 검증에 남겼다. 검증: `./gradlew :bottlenote-mono:compileJava` 성공, `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.graphql.CurationGraphqlSchemaTest' --tests 'app.bottlenote.curation.graphql.CurationAlcoholGraphqlResolverTest'` 성공, `./gradlew :bottlenote-product-api:compileJava` 성공, `git diff -- git.environment-variables/storage/mysql/changelog/` 변경 없음. +- 2026-05-15 추가 반영: `curation_demo/spec`의 OpenAPI 3.0 JSON 스펙 3종을 `bottlenote-mono/src/main/resources/openapi/curation/`에 그대로 추가했다. 대상은 `RECOMMENDED_WHISKY`, `WHISKY_PAIRING`, `WHISKY_TASTING_EVENT`이며 `x-curation`, `x-form-style`, `x-field-style`, `x-graphql` 메타를 포함한다. 검증: 원본 파일과 `cmp -s` 3건 일치, `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.CurationOpenApiSpecResourceTest'` 성공. +- 2026-05-15 Task 4 완료: `.env`에 `SPRING_PROFILES_ACTIVE=local`을 추가하고 Redis를 로컬 `bottle-note-redis` 컨테이너(`localhost:26379`, no auth)로 연결하도록 수정했다. `set -a; source .env; set +a; ./gradlew :bottlenote-product-api:bootRun`으로 product API가 8080에서 기동했고, 로그에서 GraphQL schema 1개 로드, unmapped field 없음, `POST /graphql` 매핑, Redis connection success를 확인했다. smoke 결과: `GET /actuator/health` HTTP 200 및 Redis UP, `POST /graphql { __typename }` HTTP 200, 기존 `GET /api/v1/curations?cursor=0&pageSize=1` HTTP 200, changelog diff 변경 없음. +- 2026-05-15 GraphiQL 운영 확인: `spring.graphql.graphiql.enabled=true`, `spring.graphql.graphiql.path=/graphiql`를 local/default profile에 추가해 브라우저 기반 GraphQL query console을 열 수 있게 했다. `GET /graphql`은 HTTP 405가 맞고, query 실행은 `POST /graphql` 또는 `/graphiql` UI를 사용한다. +- 2026-05-15 GraphQL browser smoke: Chrome에서 `/graphiql?path=/graphql`로 직접 쿼리를 실행했다. `[1, 999999]`는 존재하는 `1`만 반환했고, `[1, 1, 2]`는 중복 제거 후 `1, 2`만 반환했다. `[]`는 빈 배열을 반환했다. `[3, 1, 999999, 1, 2]`는 요청 순서 기준으로 `3, 1, 2`를 반환했고 없는 id와 중복 id를 제외했다. +- 2026-05-15 GraphQL boundary smoke: Chrome에서 `picks` field 요청 시 `Field 'picks' in type 'Alcohol' is undefined` validation error가 발생했다. `[1, null]` 입력은 `[ID!]!` 제약에 의해 `ids[1] ... must not be null` validation error가 발생했다. `engName`, `imageUrl`, `regionName`, `korCategory`, `cask`, `abv`, `volume`, `rating`, `totalRatingsCount`, `reviewCount`, `totalPickCount` 전체 field hydration도 정상 확인했다. +- 2026-05-15 Task 5 완료: final verification 중 `check_rule_test`가 먼저 product-api 테스트 fake repository compile error로 실패했다. 원인은 `PicksRepository`, `RatingRepository`, `ReviewRepository`에 Phase 1 stats count 메서드를 추가하면서 product-api 테스트 fake 3곳이 새 인터페이스 시그니처를 구현하지 않은 것이었다. `FakePicksRepository`, `InMemoryRatingRepository`, `InMemoryReviewRepository`에 count/average 메서드를 추가했다. +- 2026-05-15 Task 5 완료: 두 번째 `check_rule_test` 실패는 GraphQL resolver의 `@Controller`가 REST controller ArchUnit 규칙에 포함된 것이 원인이었다. GraphQL handler는 HTTP mapping 기반 REST controller가 아니므로 `ControllerLayerRules`에서 `..graphql..` 패키지를 REST controller naming/mapping/method naming rule 대상에서 제외했다. 또한 `CurationAlcoholGraphqlService` public 메서드에는 프로젝트 rule에 맞춰 `@Transactional(readOnly = true)`를 메서드 레벨로 명시했다. +- 2026-05-15 Task 5 검증 결과: `./gradlew :bottlenote-mono:compileJava` 성공, `./gradlew :bottlenote-product-api:compileJava` 성공, focused tests 3종 성공, `./gradlew check_rule_test` 성공, `git diff -- git.environment-variables/storage/mysql/changelog/` 변경 없음. Phase 1은 종료 가능한 상태로 확인했다. +- 2026-05-15 Phase 2 Task 1 완료: `git.environment-variables/storage/mysql/changelog/schema.mysql.sql`에 `curation_spec`, `curation`, `curation_extension` changeset 3개를 추가했다. SOPS 기반 Liquibase 설정은 임시 파일로만 사용했고 secret 값은 출력하지 않았다. 개발 DB와 운영 DB 모두 `validate` 성공, pending 3건 확인 후 `update` 3건 실행, 세 테이블 생성 확인, 최종 `status --verbose` up to date를 확인했다. +- 2026-05-15 Phase 2 Task 3 추가 완료: Liquibase insert seed 대신 admin-api startup resource sync를 추가했다. `CurationSpecResourceReader`가 `bottlenote-mono/src/main/resources/openapi/curation/*.json` 3종을 읽고, `CurationSpecResourceSyncService`가 `code` 기준으로 `curation_spec`을 생성 또는 갱신한다. admin-api runner는 `curation.spec-sync.enabled=${CURATION_SPEC_SYNC_ENABLED:true}`로 제어된다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-admin-api:compileKotlin :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationSpecResourceSyncServiceTest'` 성공, `./gradlew check_rule_test` 성공. +- 2026-05-15 Phase 2 Task 2 완료: `bottlenote-mono`에 curation v2 Entity, domain repository interface, JPA repository, `CurationV2Service`, focused fake repository와 unit test를 추가했다. `request_spec`, `response_spec`, `payload` JSON 컬럼은 기존 의존성인 Hypersistence `JsonType`으로 매핑했다. `check_rule_test`에서 서비스 메서드 파라미터 5개 제한과 DTO 패키지/네이밍 규칙이 먼저 실패해 service 입력을 `dto.request`의 `*Request` record로 묶었다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationV2ServiceTest' check_rule_test` 성공, focused 테스트 4개 통과. +- 2026-05-15 Phase 2 Task 3 완료: 기존 Admin `/curations` endpoint는 유지하고, 신규 spec 기반 Admin surface를 `/spec-based-curations`와 `/curation-specs`로 추가했다. admin-api의 context-path가 이미 `/admin/api/v1`이므로 컨트롤러 path에 `/v2` prefix를 붙이지 않는다. 스펙 API는 목록/상세를 제공한다. 등록/수정은 `specId`로 `curation_spec`을 조회하고, `imageUrls` 1~3장을 정규화해 첫 번째 이미지를 `cover_image_url`에 저장하며, payload는 `curation_extension.payload`에 저장한다. 새 의존성 없이 requestSpec의 required field와 payload 크기를 검증하는 `CurationPayloadValidator`를 추가했다. 검증: `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.AdminSpecBasedCurationServiceTest' :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` 성공, service 테스트 5개와 RestDocs 테스트 6개 통과. `./gradlew check_rule_test` 성공. + +## Current Decision Summary + +- Phase 1의 GraphQL boundary는 외부 공개 curation endpoint가 아니라 서버 내부 hydration 기반으로 둔다. +- 현재 SDL은 `Query.alcohols(ids: [ID!]!)`와 `Alcohol` 표시/stats field만 노출한다. +- 사용자별 원본 목록 field(`picks`, `reviews`, `ratings`)는 SDL에 노출하지 않는다. +- 없는 alcohol id는 전체 요청 실패가 아니라 결과에서 제외한다. +- 중복 alcohol id는 resolver service에서 제거하며, 반환 순서는 최초 요청 순서를 따른다. +- `MANUAL` 항목처럼 `alcoholId = null`인 payload는 후속 Product hydration 단계에서 GraphQL 조회 대상으로 넘기지 않는다. +- 기존 `curation_keyword`, `curation_keyword_alcohol_ids`, 기존 curation endpoint는 유지한다. +- 신규 schema 변경은 Phase 2 Task 1에서 `git.environment-variables/storage/mysql/changelog/` 아래 changelog로 추가했고, 개발 DB와 운영 DB에 Liquibase CLI로 적용했다. +- Phase 2 Task 3에서 Admin spec 기반 endpoint를 추가했다. 최종 URL은 admin-api context-path를 포함해 `/admin/api/v1/curation-specs`, `/admin/api/v1/spec-based-curations`다. Product v2 endpoint는 아직 만들지 않았다. + +## Next Work + +### Next: Phase 3 - Product V2 Query + Hydration + +다음 작업은 Product에서 신규 curation v2를 조회하고 GraphQL hydration 결과를 조립하는 것이다. + +- Product v2 목록/상세 API를 추가한다. +- 저장 payload를 response spec과 GraphQL hydration 결과로 앱 응답 형태로 조립한다. +- `source = BOTTLE_NOTE` 항목만 stats를 보강하고 `source = MANUAL` 항목은 stats를 생략한다. +- 기존 curation keyword endpoint는 계속 유지한다. From 793ce4a917d286c06ab1402950dbe3efb1e4e997 Mon Sep 17 00:00:00 2001 From: hgkim Date: Fri, 15 May 2026 15:58:44 +0900 Subject: [PATCH 02/33] chore: Add runtime boundary rules and GSL skill execution constraints Introduced HARD STOP guidelines for all GSL skills to enforce runtime boundaries and prevent cross-skill execution in the same turn. Each skill now defines clear end points, user-triggered transitions, and behavior for ambiguous user commands like "continue." These updates ensure modular execution and adherence to skill-specific scopes. --- .agents/skills/debug/SKILL.md | 15 ++- .agents/skills/define/SKILL.md | 15 ++- .agents/skills/implement/SKILL.md | 25 +++- .../languages/bottlenote-patterns.md | 114 ++++++++++++++++++ .agents/skills/next-flow/SKILL.md | 31 +++-- .agents/skills/plan/SKILL.md | 15 ++- .agents/skills/scan-conventions/SKILL.md | 13 ++ .agents/skills/self-review/SKILL.md | 15 ++- .agents/skills/test/SKILL.md | 24 +++- .agents/skills/verify/SKILL.md | 15 ++- .claude/skills/debug/SKILL.md | 15 ++- .claude/skills/define/SKILL.md | 15 ++- .claude/skills/implement/SKILL.md | 25 +++- .../languages/bottlenote-patterns.md | 114 ++++++++++++++++++ .claude/skills/next-flow/SKILL.md | 31 +++-- .claude/skills/plan/SKILL.md | 15 ++- .claude/skills/scan-conventions/SKILL.md | 13 ++ .claude/skills/self-review/SKILL.md | 15 ++- .claude/skills/test/SKILL.md | 24 +++- .claude/skills/verify/SKILL.md | 15 ++- AGENTS.md | 12 ++ 21 files changed, 530 insertions(+), 46 deletions(-) create mode 100644 .agents/skills/implement/references/languages/bottlenote-patterns.md create mode 100644 .claude/skills/implement/references/languages/bottlenote-patterns.md diff --git a/.agents/skills/debug/SKILL.md b/.agents/skills/debug/SKILL.md index 5d0b8f4f9..01782267f 100644 --- a/.agents/skills/debug/SKILL.md +++ b/.agents/skills/debug/SKILL.md @@ -157,10 +157,23 @@ After fixing a bug: - [ ] Test doubles updated if interfaces changed - [ ] Original failure scenario verified end-to-end +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.agents/skills/define/SKILL.md b/.agents/skills/define/SKILL.md index 2fced36d5..c60108c7a 100644 --- a/.agents/skills/define/SKILL.md +++ b/.agents/skills/define/SKILL.md @@ -165,10 +165,23 @@ Before proceeding to `/plan`: - [ ] Impact scope identifies affected modules / surfaces / tests - [ ] User has explicitly approved the Overview +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.agents/skills/implement/SKILL.md b/.agents/skills/implement/SKILL.md index f5a31107e..8095a17ff 100644 --- a/.agents/skills/implement/SKILL.md +++ b/.agents/skills/implement/SKILL.md @@ -125,11 +125,12 @@ feat: rating statistics service **Cycle per Task:** 1. Implement Slice → compile / type-check → pass? continue : fix 2. Repeat until all Slices in the Task are done -3. Run `/self-review` on the Task's changes -4. Run `/verify standard` (unit + arch rules) +3. Run a self-review pass on the Task's changes (the 5-axis check). For a full independent review, stop and recommend `/self-review` as a separate invocation — do not run its full skill body inside `/implement`. +4. Run the compile/type-check and unit-test commands needed for this Task. For full `/verify standard` or `/verify full`, stop and recommend `/verify` as a separate invocation. 5. Commit with descriptive message 6. Update plan document (check off Task, add to Progress Log) -7. Move to next Task +7. **HARD STOP after this Task.** Do NOT start the next Task in the same response turn. Report: completed Task number/title, verification evidence, changed files, next recommended Task. Then wait for the user's next message. + - Exception: proceed to the next Task in the same turn ONLY IF the user explicitly named multiple Tasks for continuous execution in their request (e.g. "do Tasks 1 through 3"). An ambiguous "continue" / "진행하자" is NOT such permission. ### Phase 4: Final Verification @@ -211,6 +212,9 @@ During Slice execution, load ONLY the references for the current Slice's module. - Skipping Phase 0 (Explore) and jumping straight to coding - Multiple unrelated changes in a single Task - Task completed without running `/self-review` +- Starting Task N+1 after completing Task N without explicit user permission for continuous execution +- Treating an ambiguous "continue" as permission to finish all remaining Tasks +- Running `/test`, `/verify`, or `/self-review` as full skill bodies inside `/implement` instead of stopping at that skill boundary ## Verification @@ -225,10 +229,23 @@ After completing all Tasks for a feature: - [ ] Build / package succeeds - [ ] Plan document updated (all Tasks checked, Progress Log filled) +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.agents/skills/implement/references/languages/bottlenote-patterns.md b/.agents/skills/implement/references/languages/bottlenote-patterns.md new file mode 100644 index 000000000..33d07b7a2 --- /dev/null +++ b/.agents/skills/implement/references/languages/bottlenote-patterns.md @@ -0,0 +1,114 @@ +# bottlenote-patterns + +> bottle-note 한정 implement 함정 / 실수 방지 부록. +> 일반 컨벤션은 `plan/conventions.md`, 일반 Java/Spring 패턴은 `java-spring.md` 참조. +> 본 파일은 GSL sync 와 무관한 프로젝트 특화 reference. + +## When to load + +`/implement` Phase 0 에서 `plan/conventions.md` 와 함께 자동 참조. Repository / RestDocs / 이벤트 발행 관련 작업 시 우선 확인. + +--- + +## P4. InMemory 구현체 갱신 누락 (Repository interface 변경 시) + +### 함정 + +Repository interface 에 메서드 추가·시그니처 변경 시, JPA 구현체만 갱신하고 **InMemory 테스트 구현체 갱신을 잊는 경우** — PR #578 rebase 등에서 반복 발생. + +### 점검 경로 (필수) + +```text +bottlenote-mono/src/test/java/app/bottlenote/{domain}/fixture/InMemory{Domain}Repository.java +bottlenote-product-api/src/test/java/app/bottlenote/{domain}/fixture/InMemory{Domain}Repository.java +``` + +Admin / 외부 모듈에서도 동일 패턴이 추가될 수 있음: +```text +bottlenote-admin-api/src/test/kotlin/.../fixture/InMemory{Domain}Repository.kt +``` + +### 절차 (`/implement` 또는 `/self-review` 단계) + +1. Repository interface diff 의 변경 메서드 시그니처 확인 +2. 위 두 경로에서 `InMemory{Domain}Repository` 검색 +3. 동일 시그니처 구현 추가 (도메인 객체 상태 변경의 단순 모방으로 충분) +4. 해당 fake 를 사용하는 단위 테스트가 컴파일·통과하는지 확인 + +--- + +## P3 흡수. RestDocs / asciidoctor 워크플로우 + +원래 `/docs` 신규 스킬 후보였던 흐름. GSL 9 스킬로 분배: + +### 책임 분리 + +| 단계 | GSL 스킬 | bottle-note 구체 | +|------|---------|------------------| +| RestDocs 테스트 작성 | `/test` | `Rest{Domain}ControllerDocsTest` (product), `Admin{Domain}ControllerDocsTest` (admin) | +| `.adoc` 인덱스·조각 작성 | `/implement` Slice | `bottlenote-{product\|admin}-api/src/docs/asciidoc/**.adoc` | +| asciidoctor 빌드 검증 | `/verify` L3 | `./gradlew asciidoctor` | +| admin default test 검증 | `/verify` L3 | `./gradlew :bottlenote-admin-api:test` | + +### admin default test 케이스 (PR #578 사례) + +- product 의 `Rest*DocsTest` 는 `@Tag("integration")` 로 분리돼 root `test` 에서 제외됨 +- 그러나 **admin 의 `Admin*DocsTest` 는 default `:bottlenote-admin-api:test` 에서 함께 도는 경우 있음** +- 따라서 admin RestDocs 수정 시 `./gradlew :bottlenote-admin-api:test` 도 반드시 확인 (누락 시 PR drift 발생) + +### `/verify full` 권장 명령 시퀀스 + +```bash +./gradlew check_rule_test # baseline rule check +./gradlew unit_test integration_test # 표준 단위·통합 +./gradlew admin_integration_test # admin 통합 +./gradlew :bottlenote-admin-api:test # admin default test (DocsTest 누락 방지) +./gradlew asciidoctor # RestDocs HTML 빌드 검증 +``` + +--- + +## P5. (GSL 참조) `Projections.constructor` 와 local record + +→ 이미 GSL `java-spring.md` Tier 3 trap 에 명시됨. 본 plan 의 SC3 는 GSL 표준으로 충족. +요약: `Projections.constructor()` 인자에 쓰는 record 는 **메서드 본문 안 local record 금지**, 반드시 클래스/인터페이스 레벨 정의. + +--- + +## 추가 함정 + +### publishEvent drift + +- `ApplicationEventPublisher.publishEvent(...)` 호출이 도메인 로직 수정·리팩토링 중 **소리 없이 누락** 되는 경우 +- 검출: `/self-review` Correctness 축에서 "이 변경이 기존 publishEvent 호출을 제거·우회하지 않았는가?" +- 보조: `git diff` 시 `publishEvent` 키워드 grep 으로 누락 여부 확인 + +### Facade ↔ Service 경계 drift + +- Cross-domain 접근은 `{Domain}Facade` 경유 원칙 +- 일부 service 가 facade 도 구현하는 기존 drift 존재 (`conventions.md` Comparison 표 참조) +- 새 작업: facade 분리 권장. 기존 drift 는 plan 에 명시되지 않은 한 정리 대상 아님 + +### `@ThirdPartyService` 사용 시점 + +→ GSL `java-spring.md` External Integration Layer 섹션 참조. bottle-note 에서는 `app.external` 또는 도메인 외부 패키지에 위치. +- 테스트 격리: 외부 client 의 fake (예: `FakeProfanityClient`, `FakeWebhookRestTemplate`) 사용 +- 트랜잭션 불필요, `@Service` 포함하지만 도메인 service 와 의도 명확히 분리 + +### Batch 모듈 특이사항 (`/define` / `/plan` 시 주의) + +`conventions.md` 의 "Batch-Specific Current Conventions" 참조. 핵심만: +- `bottlenote-batch` 는 `testFixtures` 대신 `mono` test output 직접 사용 (drift) +- `git.environment-variables` 가 main+test 양쪽 resources 에 포함됨 +- main resource 에 하드코딩된 JWT secret / nonce salt default 존재 +- batch source test 가 0 (테스트 공백 인지 필요) + +위 항목들은 **알려진 drift** — 새 plan 이 명시적으로 정리하지 않는 한 보존. + +--- + +## Maintenance + +- 항목이 GSL 표준 `java-spring.md` 에 흡수되면 본 파일에서 제거 → 중복 방지 +- 새 함정 발견 시 추가 (PR 사례 인용 권장) +- conventions.md 가 자체 갱신될 때 본 파일과 충돌하는 부분은 conventions.md 우선 diff --git a/.agents/skills/next-flow/SKILL.md b/.agents/skills/next-flow/SKILL.md index 0b3dd578d..824a60073 100644 --- a/.agents/skills/next-flow/SKILL.md +++ b/.agents/skills/next-flow/SKILL.md @@ -28,7 +28,7 @@ Hard policy (from codex consultation): *auto-progression is restricted to read-o - Before `/define` (no plan document yet — start with `/define` directly) - When a `/debug` recovery is in progress (let `/debug` finish first) - When the user has already named the next step explicitly -- For `/plan` transition — `/plan` is a Claude Code UI command and cannot be auto-invoked from a skill; this skill will only print a notice telling the user to type `/plan` themselves +- For any next GSL command transition — print the command name and stop. In slash-command UI runtimes, tell the user to type that command directly; in codex, tell the user to send a new message containing that skill name. ## Process @@ -45,7 +45,7 @@ Read Overview, Tasks, Progress Log. Classify the work into exactly one of: | Signal | Current step | Next step | |--------|--------------|-----------| -| Plan doc has Overview only, no Tasks | post-`/define` | `/plan` (UI command — print notice) | +| Plan doc has Overview only, no Tasks | post-`/define` | `/plan` (print command and stop) | | Tasks exist, Progress Log empty | post-`/plan` | `/implement` | | Some Tasks done, more remain | mid-`/implement` | continue `/implement` with next Task | | All Tasks done, no integration tests written | post-`/implement` | `/test` (integration tests) | @@ -97,10 +97,10 @@ Preconditions: PASS [Run it? You can type / yourself, or reply "yes" to have me run it only if it is read-only.] ``` -For `/plan` and other UI commands, replace the last line with: +For any next GSL command, do not run it in this turn. Replace the last line with runtime-neutral guidance: ``` -/plan is a Claude Code UI command — please type it in the input box yourself; I cannot trigger it from a skill. +To continue, send a new message containing this command. In slash-command UI runtimes, type the command directly; in codex, send the skill name in a new message. ``` ## Common Rationalizations @@ -111,16 +111,16 @@ For `/plan` and other UI commands, replace the last line with: | "User said 'continue', so I can just push through commit" | Commit is a write boundary and an externally-visible action. Propose, never auto-run. | | "It's only a small edit to plan doc Progress Log" | Plan document is the single source of truth. Only `/implement` updates it after a Task commit. | | "/verify full passed — let me start the next feature" | Closing the current feature (stamp + plan/complete/ move) is a manual decision. Propose, don't act. | -| "I'll auto-call /plan since /implement needs it" | `/plan` is a UI command. You cannot. Print the notice and stop. | +| "I'll auto-call the next GSL command since it is obvious" | Next GSL commands are runtime boundaries. Print the command name and stop. | ## Red Flags - Auto-progression has caused any file to be created, edited, or deleted (immediate STOP — this skill should never do that) - Multiple next-step candidates proposed (the table in Step 2 should yield exactly one) - Preconditions skipped because "the user implied it was fine" -- Proposing `/plan` for auto-invocation (impossible — print notice instead) -- **Bypassing the UI-command notice by invoking `/plan` (or any other Claude Code UI command) through Bash, shell scripts, `subprocess`, MCP tools, or other wrappers — anti-pattern, STOP.** The notice is the only correct output for UI-command transitions. -- The next command requires user approval (e.g., post-`/define` → `/plan`) and you tried to invoke it anyway +- Proposing any next GSL command for same-turn execution instead of printing the command name and stopping +- **Bypassing the runtime-boundary notice by invoking the next GSL command through Bash, shell scripts, `subprocess`, MCP tools, or other wrappers — anti-pattern, STOP.** The notice is the only correct output for GSL command transitions. +- The next command requires user approval (e.g., post-`/define` → `/plan`) and you tried to execute it anyway ## Verification @@ -130,5 +130,18 @@ After running: - [ ] All preconditions were checked in a read-only way - [ ] If any auto-action was run, it was read-only only (verify / status / log / diff) - [ ] No file was created, edited, or deleted by this skill -- [ ] If the next step is `/plan`, the UI-command notice was printed instead of attempting auto-invoke +- [ ] If the next step is a GSL command, the runtime-boundary notice was printed instead of attempting same-turn execution - [ ] The proposal includes the reason and the user's explicit invocation prompt + +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. diff --git a/.agents/skills/plan/SKILL.md b/.agents/skills/plan/SKILL.md index 44f01d8b5..821f19007 100644 --- a/.agents/skills/plan/SKILL.md +++ b/.agents/skills/plan/SKILL.md @@ -180,10 +180,23 @@ Before starting `/implement`, confirm: - [ ] Checkpoints exist between major groups of Tasks - [ ] User has explicitly approved the task list +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.agents/skills/scan-conventions/SKILL.md b/.agents/skills/scan-conventions/SKILL.md index 84d09de1e..4529c7980 100644 --- a/.agents/skills/scan-conventions/SKILL.md +++ b/.agents/skills/scan-conventions/SKILL.md @@ -214,3 +214,16 @@ After running: - [ ] All CONFLICTs have a recorded user resolution - [ ] No source files were modified - [ ] Report printed to user with counts (MATCH / REFINEMENT / CONFLICT) + +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. diff --git a/.agents/skills/self-review/SKILL.md b/.agents/skills/self-review/SKILL.md index b6c0059bd..b2e0730e2 100644 --- a/.agents/skills/self-review/SKILL.md +++ b/.agents/skills/self-review/SKILL.md @@ -154,10 +154,23 @@ After completing the review: - [ ] Code compiles / type-checks (see `/verify` quick) - [ ] Unit tests pass (see `/verify` standard) +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.agents/skills/test/SKILL.md b/.agents/skills/test/SKILL.md index bd79a3ca8..cd842adfd 100644 --- a/.agents/skills/test/SKILL.md +++ b/.agents/skills/test/SKILL.md @@ -33,10 +33,11 @@ Write tests that prove code works. This skill guides you through creating unit t ## Relationship with `/implement` -- **Unit tests**: ideally written together with implementation during a Task in `/implement` -- **Integration tests**: written after all Tasks are implemented, via separate `/test` invocation -- **Docs tests** (API contract docs): only when user explicitly requests -- Slice-level compile checks in `/implement` may RUN existing tests; this skill WRITES new tests +- **Unit tests**: may be written together with implementation during a Task in `/implement` — writing test code alongside a Task is allowed. +- **NOT allowed**: running the full `/test` workflow (Phase 0 explore, Phase 1 scenario-approval gate, Phase 2-4) inside `/implement`. The full `/test` skill is a separate runtime boundary and needs its own explicit invocation. +- **Integration tests**: written after all Tasks are implemented, via a separate `/test` invocation. +- **Docs tests** (API contract docs): only when the user explicitly requests. +- Slice-level compile checks in `/implement` may RUN existing tests; the full `/test` skill WRITES new tests through its scenario-approval process. ## Test Types and Timing @@ -193,10 +194,23 @@ After completing test implementation: - [ ] All tests pass: `/verify` at appropriate level - [ ] Test doubles updated if domain interfaces changed +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.agents/skills/verify/SKILL.md b/.agents/skills/verify/SKILL.md index 12f4eb8f4..755ad26df 100644 --- a/.agents/skills/verify/SKILL.md +++ b/.agents/skills/verify/SKILL.md @@ -135,10 +135,23 @@ After running: - [ ] On failure: last 30 lines of output shown, remaining steps marked SKIPPED - [ ] Total time reported +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.claude/skills/debug/SKILL.md b/.claude/skills/debug/SKILL.md index 5d0b8f4f9..01782267f 100644 --- a/.claude/skills/debug/SKILL.md +++ b/.claude/skills/debug/SKILL.md @@ -157,10 +157,23 @@ After fixing a bug: - [ ] Test doubles updated if interfaces changed - [ ] Original failure scenario verified end-to-end +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.claude/skills/define/SKILL.md b/.claude/skills/define/SKILL.md index 2fced36d5..c60108c7a 100644 --- a/.claude/skills/define/SKILL.md +++ b/.claude/skills/define/SKILL.md @@ -165,10 +165,23 @@ Before proceeding to `/plan`: - [ ] Impact scope identifies affected modules / surfaces / tests - [ ] User has explicitly approved the Overview +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.claude/skills/implement/SKILL.md b/.claude/skills/implement/SKILL.md index f5a31107e..8095a17ff 100644 --- a/.claude/skills/implement/SKILL.md +++ b/.claude/skills/implement/SKILL.md @@ -125,11 +125,12 @@ feat: rating statistics service **Cycle per Task:** 1. Implement Slice → compile / type-check → pass? continue : fix 2. Repeat until all Slices in the Task are done -3. Run `/self-review` on the Task's changes -4. Run `/verify standard` (unit + arch rules) +3. Run a self-review pass on the Task's changes (the 5-axis check). For a full independent review, stop and recommend `/self-review` as a separate invocation — do not run its full skill body inside `/implement`. +4. Run the compile/type-check and unit-test commands needed for this Task. For full `/verify standard` or `/verify full`, stop and recommend `/verify` as a separate invocation. 5. Commit with descriptive message 6. Update plan document (check off Task, add to Progress Log) -7. Move to next Task +7. **HARD STOP after this Task.** Do NOT start the next Task in the same response turn. Report: completed Task number/title, verification evidence, changed files, next recommended Task. Then wait for the user's next message. + - Exception: proceed to the next Task in the same turn ONLY IF the user explicitly named multiple Tasks for continuous execution in their request (e.g. "do Tasks 1 through 3"). An ambiguous "continue" / "진행하자" is NOT such permission. ### Phase 4: Final Verification @@ -211,6 +212,9 @@ During Slice execution, load ONLY the references for the current Slice's module. - Skipping Phase 0 (Explore) and jumping straight to coding - Multiple unrelated changes in a single Task - Task completed without running `/self-review` +- Starting Task N+1 after completing Task N without explicit user permission for continuous execution +- Treating an ambiguous "continue" as permission to finish all remaining Tasks +- Running `/test`, `/verify`, or `/self-review` as full skill bodies inside `/implement` instead of stopping at that skill boundary ## Verification @@ -225,10 +229,23 @@ After completing all Tasks for a feature: - [ ] Build / package succeeds - [ ] Plan document updated (all Tasks checked, Progress Log filled) +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.claude/skills/implement/references/languages/bottlenote-patterns.md b/.claude/skills/implement/references/languages/bottlenote-patterns.md new file mode 100644 index 000000000..33d07b7a2 --- /dev/null +++ b/.claude/skills/implement/references/languages/bottlenote-patterns.md @@ -0,0 +1,114 @@ +# bottlenote-patterns + +> bottle-note 한정 implement 함정 / 실수 방지 부록. +> 일반 컨벤션은 `plan/conventions.md`, 일반 Java/Spring 패턴은 `java-spring.md` 참조. +> 본 파일은 GSL sync 와 무관한 프로젝트 특화 reference. + +## When to load + +`/implement` Phase 0 에서 `plan/conventions.md` 와 함께 자동 참조. Repository / RestDocs / 이벤트 발행 관련 작업 시 우선 확인. + +--- + +## P4. InMemory 구현체 갱신 누락 (Repository interface 변경 시) + +### 함정 + +Repository interface 에 메서드 추가·시그니처 변경 시, JPA 구현체만 갱신하고 **InMemory 테스트 구현체 갱신을 잊는 경우** — PR #578 rebase 등에서 반복 발생. + +### 점검 경로 (필수) + +```text +bottlenote-mono/src/test/java/app/bottlenote/{domain}/fixture/InMemory{Domain}Repository.java +bottlenote-product-api/src/test/java/app/bottlenote/{domain}/fixture/InMemory{Domain}Repository.java +``` + +Admin / 외부 모듈에서도 동일 패턴이 추가될 수 있음: +```text +bottlenote-admin-api/src/test/kotlin/.../fixture/InMemory{Domain}Repository.kt +``` + +### 절차 (`/implement` 또는 `/self-review` 단계) + +1. Repository interface diff 의 변경 메서드 시그니처 확인 +2. 위 두 경로에서 `InMemory{Domain}Repository` 검색 +3. 동일 시그니처 구현 추가 (도메인 객체 상태 변경의 단순 모방으로 충분) +4. 해당 fake 를 사용하는 단위 테스트가 컴파일·통과하는지 확인 + +--- + +## P3 흡수. RestDocs / asciidoctor 워크플로우 + +원래 `/docs` 신규 스킬 후보였던 흐름. GSL 9 스킬로 분배: + +### 책임 분리 + +| 단계 | GSL 스킬 | bottle-note 구체 | +|------|---------|------------------| +| RestDocs 테스트 작성 | `/test` | `Rest{Domain}ControllerDocsTest` (product), `Admin{Domain}ControllerDocsTest` (admin) | +| `.adoc` 인덱스·조각 작성 | `/implement` Slice | `bottlenote-{product\|admin}-api/src/docs/asciidoc/**.adoc` | +| asciidoctor 빌드 검증 | `/verify` L3 | `./gradlew asciidoctor` | +| admin default test 검증 | `/verify` L3 | `./gradlew :bottlenote-admin-api:test` | + +### admin default test 케이스 (PR #578 사례) + +- product 의 `Rest*DocsTest` 는 `@Tag("integration")` 로 분리돼 root `test` 에서 제외됨 +- 그러나 **admin 의 `Admin*DocsTest` 는 default `:bottlenote-admin-api:test` 에서 함께 도는 경우 있음** +- 따라서 admin RestDocs 수정 시 `./gradlew :bottlenote-admin-api:test` 도 반드시 확인 (누락 시 PR drift 발생) + +### `/verify full` 권장 명령 시퀀스 + +```bash +./gradlew check_rule_test # baseline rule check +./gradlew unit_test integration_test # 표준 단위·통합 +./gradlew admin_integration_test # admin 통합 +./gradlew :bottlenote-admin-api:test # admin default test (DocsTest 누락 방지) +./gradlew asciidoctor # RestDocs HTML 빌드 검증 +``` + +--- + +## P5. (GSL 참조) `Projections.constructor` 와 local record + +→ 이미 GSL `java-spring.md` Tier 3 trap 에 명시됨. 본 plan 의 SC3 는 GSL 표준으로 충족. +요약: `Projections.constructor()` 인자에 쓰는 record 는 **메서드 본문 안 local record 금지**, 반드시 클래스/인터페이스 레벨 정의. + +--- + +## 추가 함정 + +### publishEvent drift + +- `ApplicationEventPublisher.publishEvent(...)` 호출이 도메인 로직 수정·리팩토링 중 **소리 없이 누락** 되는 경우 +- 검출: `/self-review` Correctness 축에서 "이 변경이 기존 publishEvent 호출을 제거·우회하지 않았는가?" +- 보조: `git diff` 시 `publishEvent` 키워드 grep 으로 누락 여부 확인 + +### Facade ↔ Service 경계 drift + +- Cross-domain 접근은 `{Domain}Facade` 경유 원칙 +- 일부 service 가 facade 도 구현하는 기존 drift 존재 (`conventions.md` Comparison 표 참조) +- 새 작업: facade 분리 권장. 기존 drift 는 plan 에 명시되지 않은 한 정리 대상 아님 + +### `@ThirdPartyService` 사용 시점 + +→ GSL `java-spring.md` External Integration Layer 섹션 참조. bottle-note 에서는 `app.external` 또는 도메인 외부 패키지에 위치. +- 테스트 격리: 외부 client 의 fake (예: `FakeProfanityClient`, `FakeWebhookRestTemplate`) 사용 +- 트랜잭션 불필요, `@Service` 포함하지만 도메인 service 와 의도 명확히 분리 + +### Batch 모듈 특이사항 (`/define` / `/plan` 시 주의) + +`conventions.md` 의 "Batch-Specific Current Conventions" 참조. 핵심만: +- `bottlenote-batch` 는 `testFixtures` 대신 `mono` test output 직접 사용 (drift) +- `git.environment-variables` 가 main+test 양쪽 resources 에 포함됨 +- main resource 에 하드코딩된 JWT secret / nonce salt default 존재 +- batch source test 가 0 (테스트 공백 인지 필요) + +위 항목들은 **알려진 drift** — 새 plan 이 명시적으로 정리하지 않는 한 보존. + +--- + +## Maintenance + +- 항목이 GSL 표준 `java-spring.md` 에 흡수되면 본 파일에서 제거 → 중복 방지 +- 새 함정 발견 시 추가 (PR 사례 인용 권장) +- conventions.md 가 자체 갱신될 때 본 파일과 충돌하는 부분은 conventions.md 우선 diff --git a/.claude/skills/next-flow/SKILL.md b/.claude/skills/next-flow/SKILL.md index 0b3dd578d..824a60073 100644 --- a/.claude/skills/next-flow/SKILL.md +++ b/.claude/skills/next-flow/SKILL.md @@ -28,7 +28,7 @@ Hard policy (from codex consultation): *auto-progression is restricted to read-o - Before `/define` (no plan document yet — start with `/define` directly) - When a `/debug` recovery is in progress (let `/debug` finish first) - When the user has already named the next step explicitly -- For `/plan` transition — `/plan` is a Claude Code UI command and cannot be auto-invoked from a skill; this skill will only print a notice telling the user to type `/plan` themselves +- For any next GSL command transition — print the command name and stop. In slash-command UI runtimes, tell the user to type that command directly; in codex, tell the user to send a new message containing that skill name. ## Process @@ -45,7 +45,7 @@ Read Overview, Tasks, Progress Log. Classify the work into exactly one of: | Signal | Current step | Next step | |--------|--------------|-----------| -| Plan doc has Overview only, no Tasks | post-`/define` | `/plan` (UI command — print notice) | +| Plan doc has Overview only, no Tasks | post-`/define` | `/plan` (print command and stop) | | Tasks exist, Progress Log empty | post-`/plan` | `/implement` | | Some Tasks done, more remain | mid-`/implement` | continue `/implement` with next Task | | All Tasks done, no integration tests written | post-`/implement` | `/test` (integration tests) | @@ -97,10 +97,10 @@ Preconditions: PASS [Run it? You can type / yourself, or reply "yes" to have me run it only if it is read-only.] ``` -For `/plan` and other UI commands, replace the last line with: +For any next GSL command, do not run it in this turn. Replace the last line with runtime-neutral guidance: ``` -/plan is a Claude Code UI command — please type it in the input box yourself; I cannot trigger it from a skill. +To continue, send a new message containing this command. In slash-command UI runtimes, type the command directly; in codex, send the skill name in a new message. ``` ## Common Rationalizations @@ -111,16 +111,16 @@ For `/plan` and other UI commands, replace the last line with: | "User said 'continue', so I can just push through commit" | Commit is a write boundary and an externally-visible action. Propose, never auto-run. | | "It's only a small edit to plan doc Progress Log" | Plan document is the single source of truth. Only `/implement` updates it after a Task commit. | | "/verify full passed — let me start the next feature" | Closing the current feature (stamp + plan/complete/ move) is a manual decision. Propose, don't act. | -| "I'll auto-call /plan since /implement needs it" | `/plan` is a UI command. You cannot. Print the notice and stop. | +| "I'll auto-call the next GSL command since it is obvious" | Next GSL commands are runtime boundaries. Print the command name and stop. | ## Red Flags - Auto-progression has caused any file to be created, edited, or deleted (immediate STOP — this skill should never do that) - Multiple next-step candidates proposed (the table in Step 2 should yield exactly one) - Preconditions skipped because "the user implied it was fine" -- Proposing `/plan` for auto-invocation (impossible — print notice instead) -- **Bypassing the UI-command notice by invoking `/plan` (or any other Claude Code UI command) through Bash, shell scripts, `subprocess`, MCP tools, or other wrappers — anti-pattern, STOP.** The notice is the only correct output for UI-command transitions. -- The next command requires user approval (e.g., post-`/define` → `/plan`) and you tried to invoke it anyway +- Proposing any next GSL command for same-turn execution instead of printing the command name and stopping +- **Bypassing the runtime-boundary notice by invoking the next GSL command through Bash, shell scripts, `subprocess`, MCP tools, or other wrappers — anti-pattern, STOP.** The notice is the only correct output for GSL command transitions. +- The next command requires user approval (e.g., post-`/define` → `/plan`) and you tried to execute it anyway ## Verification @@ -130,5 +130,18 @@ After running: - [ ] All preconditions were checked in a read-only way - [ ] If any auto-action was run, it was read-only only (verify / status / log / diff) - [ ] No file was created, edited, or deleted by this skill -- [ ] If the next step is `/plan`, the UI-command notice was printed instead of attempting auto-invoke +- [ ] If the next step is a GSL command, the runtime-boundary notice was printed instead of attempting same-turn execution - [ ] The proposal includes the reason and the user's explicit invocation prompt + +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. diff --git a/.claude/skills/plan/SKILL.md b/.claude/skills/plan/SKILL.md index 44f01d8b5..821f19007 100644 --- a/.claude/skills/plan/SKILL.md +++ b/.claude/skills/plan/SKILL.md @@ -180,10 +180,23 @@ Before starting `/implement`, confirm: - [ ] Checkpoints exist between major groups of Tasks - [ ] User has explicitly approved the task list +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.claude/skills/scan-conventions/SKILL.md b/.claude/skills/scan-conventions/SKILL.md index 84d09de1e..4529c7980 100644 --- a/.claude/skills/scan-conventions/SKILL.md +++ b/.claude/skills/scan-conventions/SKILL.md @@ -214,3 +214,16 @@ After running: - [ ] All CONFLICTs have a recorded user resolution - [ ] No source files were modified - [ ] Report printed to user with counts (MATCH / REFINEMENT / CONFLICT) + +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. diff --git a/.claude/skills/self-review/SKILL.md b/.claude/skills/self-review/SKILL.md index b6c0059bd..b2e0730e2 100644 --- a/.claude/skills/self-review/SKILL.md +++ b/.claude/skills/self-review/SKILL.md @@ -154,10 +154,23 @@ After completing the review: - [ ] Code compiles / type-checks (see `/verify` quick) - [ ] Unit tests pass (see `/verify` standard) +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.claude/skills/test/SKILL.md b/.claude/skills/test/SKILL.md index bd79a3ca8..cd842adfd 100644 --- a/.claude/skills/test/SKILL.md +++ b/.claude/skills/test/SKILL.md @@ -33,10 +33,11 @@ Write tests that prove code works. This skill guides you through creating unit t ## Relationship with `/implement` -- **Unit tests**: ideally written together with implementation during a Task in `/implement` -- **Integration tests**: written after all Tasks are implemented, via separate `/test` invocation -- **Docs tests** (API contract docs): only when user explicitly requests -- Slice-level compile checks in `/implement` may RUN existing tests; this skill WRITES new tests +- **Unit tests**: may be written together with implementation during a Task in `/implement` — writing test code alongside a Task is allowed. +- **NOT allowed**: running the full `/test` workflow (Phase 0 explore, Phase 1 scenario-approval gate, Phase 2-4) inside `/implement`. The full `/test` skill is a separate runtime boundary and needs its own explicit invocation. +- **Integration tests**: written after all Tasks are implemented, via a separate `/test` invocation. +- **Docs tests** (API contract docs): only when the user explicitly requests. +- Slice-level compile checks in `/implement` may RUN existing tests; the full `/test` skill WRITES new tests through its scenario-approval process. ## Test Types and Timing @@ -193,10 +194,23 @@ After completing test implementation: - [ ] All tests pass: `/verify` at appropriate level - [ ] Test doubles updated if domain interfaces changed +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/.claude/skills/verify/SKILL.md b/.claude/skills/verify/SKILL.md index 12f4eb8f4..755ad26df 100644 --- a/.claude/skills/verify/SKILL.md +++ b/.claude/skills/verify/SKILL.md @@ -135,10 +135,23 @@ After running: - [ ] On failure: last 30 lines of output shown, remaining steps marked SKIPPED - [ ] Total time reported +## Runtime Boundary — HARD STOP + +This skill ENDS after the Verification checklist and final report are completed. + +For codex and any runtime without an enforced skill-return boundary: +- MUST stop the assistant turn here. +- MUST NOT invoke, load, or execute any next GSL skill in the same response turn. +- MUST NOT continue into `/next-flow`, `/define`, `/plan`, `/implement`, `/test`, `/verify`, `/debug`, or `/self-review`. +- MAY print exactly one suggested next command as plain text. +- MUST wait for the user's next message before running any next skill. + +If the user says only "continue", treat that as permission to report the next recommended command, not permission to execute it. + --- ## Lifecycle Integration **Before this skill:** if `plan/conventions.md` does not exist, run `/scan-conventions` first — analysis relies on knowing the project's actual conventions (naming, layering, test patterns, build system). -**After this skill:** invoke `/next-flow` to diagnose lifecycle state and propose the next command. `/next-flow` auto-progresses read-only verification only and never writes files. Note: `/plan` is a Claude Code UI command and cannot be auto-invoked — the user must type it themselves; `/next-flow` will print a notice in that case. +**After this skill:** the next GSL skill is started by the user, not by this skill — see the Runtime Boundary section above. `/next-flow` may be suggested for lifecycle diagnosis but is not auto-invoked. Runtime note: some environments expose slash commands as UI commands; codex loads GSL skills from `.agents/skills/`. In both cases, the next GSL skill requires a new explicit user message. diff --git a/AGENTS.md b/AGENTS.md index 95195562f..39b11c5fd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -317,3 +317,15 @@ Use these skills to follow the structured development lifecycle: - 의존성 주입: 생성자 주입 우선 - 불변성 지향: `final` 필드, `record` 활용 - 단일 책임 원칙: 클래스와 메서드 역할 명확화 + +## GSL on codex — Runtime Boundary Rules + +When using GSL skills from `.agents/skills/`, treat each `SKILL.md` as a single-turn procedure. + +- Load only the one GSL skill that matches the user's current explicit request. +- Do not pre-load all 9 GSL skills unless the user explicitly asks for a read-only diagnosis of the skillset. +- A GSL skill boundary is a hard stop. When a skill reaches its Verification / Runtime Boundary section, end the assistant turn. +- `After this skill`, `Next: /...`, or `should invoke` means "suggest the next command", not "execute it now". +- Do not transition between GSL skills (`/define`->`/plan`, `/plan`->`/implement`, `/implement` Task N->N+1, `/implement`->`/test`, `/test`->`/verify`, etc.) in the same assistant turn unless the user explicitly named that next skill — or named multiple Tasks for continuous execution — in their message. +- `/implement` may write test code alongside a Task, but must NOT run the full `/test` / `/verify` / `/self-review` workflow inside itself. Those are separate skill boundaries. +- If the user says "continue" ambiguously, ask whether to run the next suggested GSL skill or only report the next command. From 655a229b892e3681bccbe7af4a07f91d7a0f1e98 Mon Sep 17 00:00:00 2001 From: hgkim Date: Fri, 15 May 2026 16:19:53 +0900 Subject: [PATCH 03/33] =?UTF-8?q?docs:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20=ED=9D=90=EB=A6=84=EB=8F=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plan/assets/spec-based-curation-v2-flow.png | Bin 0 -> 1271833 bytes plan/spec-based-curation-v2-graphql-sdl.md | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 plan/assets/spec-based-curation-v2-flow.png diff --git a/plan/assets/spec-based-curation-v2-flow.png b/plan/assets/spec-based-curation-v2-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..3281d7edb8ccf2cffedc50e5ac0fb5481503556a GIT binary patch literal 1271833 zcmeEv1$2{H*KVC+6(~?VI5aeQ;|Wk8?k-J&#$B4EF}%3D%e2Mat+-QMTU-V!QrxB7 zleWw-^UZJf{&)TNt_5ql(sSPPp0oFJ_I~z0lFnF>fLXUzlUh+xQFYlYnj|VJVN6t1 z?ApW_P?L4v-8U*KN2}9Nl#x$su0so|TYyi!4(--NrADO;jfz?oMVy}#TUh~Gb*pa0 ztZL=>YpYz3vrD997rc&uB@&3JOs&DF&%_$AnoN>ji^|j)(RxUSA!@KjJs7K1dUbc5 zs=Cv7|7B2w#_KhBd={6}3tp&szWRl(kr#TNtb^V)jVJlsaXq4Y7@9P1*(O8)=PtZIs2KF&U6vzX=|6*dsj$v=+U#8>oN< zEP9_gt2F_IZw)gWEGDzBy5P4M0u)y;t2G3JVBm4&r!~xIvD>p+J6%pgYZ&Ou>CI|w z_W9ghkjOwFfCyj^E{_R`h9D?1TI=q$y16wzGfbb=nva8s2m+P_!=MNV42eX=q3{R- zfdE4jK^cXGMV^yLC>R=tK@f>p7?y}bV2C6b8UrEFL^KtPM7#)gqhX$`5R@brc%ZM85RN3IC%EW*0&M97$E}(LBI$KswM2NDT}EXaV5G zgJyui2!M4_Bw)Rm2yFra1l{~iYXC!~)8VSjk%|Un3?d*508&Y#5o1LGN~x5N0A?A0 zLW-1uj{$^%^uXsxpbQ8U9}yk{s(~`VguxFG78nDVAgdYyz(cqQ4@J7g0VP4C0%a^7CN8 z1L8uUI}rWAR0DR7&~7ABfl)x@!U2azfgpncn4rK^M4po{zyg4FIKYQEfEfyk@D>IT z3Xrksr0DG`&DXTfX84W#PdfvLTDsKmAbgxm>5VAg?gVS$5!01e93vkT~n0J^CxgLn|ZlMo5{k@h$o z4@(5$0|IIQu>pBkszHnpHwc47&>jZ}92c1JIYKXmWKz7x~odv@Xxj8DLdHr_oiWe+WPNkF>7F{@->y8ljRu={4e%vChtq;K9ep z%LS(D#(7JORlnIQb3&cRpz#^>`heNs-0uSfi_e5`nJAnLg1S`xr*?Q{`&)Hp!u=k{e*CWHG+b+o!9{ z_?(7-SLf0jyvXYI-pckq&>rdYXe>^Ho@_U{JQknXVbSpodW)v8T4pc|$YVho3r79- zrH+bfP_G(5_P-6FE|NeSEjj=}rq`$O zK$=}TuUnz9d-FoIe0(;W1qECbGM7rF5CZ{|$;hUdY#xe<&Y*~O0kW7*H<=8$NIRd5 zO2KQ`*%XSHl#}DeTKyihOymamGsrSA!LAUojUKZ}#J7?|0xKECm&pTs8a>FTsWp5y zQw4q$e7Y?_6{{HB0G38JyBK7$SdPK6F>)|tXqqsHC5uTMnlh+2Xw6i!jn1IiNOZbU zXUD?*7M4$-3!3y{gEH66mFJMnWS-j?cGH|xKGBp-<{NNy7E=;7k;y7rm>u9-RRMvF zj^fkELB5QP&dwoAm}FvzPh+F`Gh|h4`2DWRqA*p-|yOp-HFfCzG)NYB9ycS8FkjY&k>cvZ+aO22QNQaM(;2TW<-U z;|Mebk|PYu;cNzkR1l@w01m0Az&Cxb~WE(@;h@$IV7c2X?2RQ zW;jwSkh2_Kj)!C9dlUjE3g`$CxFM2CM5Um~A*vQDm2zZ4fkdDUDr{tm(2cb_+%$3^ zU|`wgI!L2Xfw%ot3Nm2K20I0ARr zWZ{!tG9jGg3hAv{rP}UMa|C9MooE(X^l&1a!SbR+Bs2*I}KQ%%PYB3JO^zBij`+;3GJ4zkm9o%i zR8B;eTosz+W7GK|IiMh^TtHzn*g-a(M3bY)Cb>fq26E=AnTim=j^eVC1%S75%r*;? z6o4oI6TmG(Dp^G&N1j_uT<|-c?6Om3VuPA1C1H6Eyhfp?s#PLkP>ST`%2_g=fWa3r zq z_@GPUrE5iDQ;xx;RY52;-pAt`@Hmu$YangB%*9TTSCN|L~eR6 zhwH@gIb^ycM?=+6_zu01tjyJ*xeT_IO(FQSIxdN4MA=l3K8H%>vMfTs#iOU0Wj2(< zm7^#5AcIxzbh~uf3?dWD@{{p$EHlU9Q+aH7q?Lus#i;dc2cMo}XOZ#nke>-Ub3tT{ z#tfP0Y_pP$&89i&1R6HPlECShuug8!s{&A1r!@$*uCSWt)>^y*ZEhfd53{kn92*g` zVC)f=CzF|0lS&sbsl)*q2o(wmBqNJiND7%9Ak)akh<&o8d^(dx&NflRIFW?H!f*^C z57tbODfudv4r3?eNbOu}#Fl@KmB8;zax$O7kJ!APBNp=kAuy@b>X;JXbNCdf@)^w} z{`cdkl`O23LrkQQjYK*H@Bsx&{wKeunM`a7ndb|;?b&n}+APKgX+amDmXOpzcgpZC z9vtH42Jj|4-p>n2@K~}+#qfp6b}17RrWu$dmmG3I7N1>3m+5>iv_~OBDlsa#0qLhI zvqNGpfs5j?AU~8FaN?aFn#s$fk*qdJ$j2t~H9nLTFU$?0On!L~$#Pl(1S19=rc*UM zl1M@dGlL9OKx%Tk96pmqMs^EP*^rg%uu(ZwH{D5wYn?p0-W&*MR2&gUD-kJl1h}1c`U4I1-G8&JxNjX1ZIaQJL{36w!rcs&ia6 zf3}B0&%vtLOus?T6<|1yY^PhtcCn;Nk|@V%XV4uu3X%kAD3Xu_MI-1r5xH$Uu&V;ql0bTpP#B!CN4d)yZSv?5a>e#|scxL_w|zh2r}R zAqi9E;1gUXmsd&<`&25e+icS_-3G4>o-L#i?I0xRg<27c6$+D$JQo}CyZB6#IyYqW z<{DKTUoHw~gUh)lkCKH8VKqUQ0{EYTk}Y+}bM01{7N-W$lODFokmOtjSsNx~<5g^{ zTM%&b?QWvgAn;H^E&{`D#d+a&B3Xda8bN+%c5pa25|N4o+f-6_Q0n0^bR@A}EVUTO z$WSe8B%O5qNIP+nw9}yat1DHeot#KJGl&sEd?f9ZXyjTWAUK`G#7BvBz7WNa4@g`X zorU;srJXEYKrf>RB4LOk^$N)Wwg!YsI)kgRaD6lu%R`gsm@bi?s0fENd=Co4a8W1` z*xe|hi-vb(3uQ!>KuO@?WnLDBW(ct5oRH5N;)8CbXswyS2x&!9ozlvYczk#=nexx+ zuZu$eDJ5lt@LQRZqOx=7Rz8&;U;Dk?0R=EY3ZLt?8r^)Pj$kCvIjme$0E2Pou=V~Nu90H!=di>`ogZS`wRkcT zt+Ix7G;M(CCx!I^CZ8BoU?~i=&SH>)=wxFFLp%#yE9X#+bh-fJqUQ)PJTXp4M5|;T z2^!)NREk_HPLI`7ctl7FxJgPtQfL8(pCl!i8CFg}luZ^l*tm#x%Qf zF-EJ?A2t!GPKKL|#yGibi571rV|;3>jq3{G@k$9^m7UE&%Y|@-&*cz1=|TpH=NCwk zqFk?2O3|@`0(StyvjOwCl{gO5!Jgw;x6$ZZKJL`)M} zZdaIqT-Ru2Vq_(=N52fidX z0>5D}!&E9cAT$A+r;tr-u~@2=1|YQ}Ob{|{Sh|Kqgbc{=-_s^9gG{4{_)=AX6A6uC zF^xt+{YyF~w@1=3j$exro5T>^RJr7n(N%nksxsZ9ngXIo`pKpX{5mJauX8XUO*Sc) zFZM>3f02Hf^Z-X850edy02Em+LLlo23TR-dWff>D>%u?RaWs6o>tEAR2|YjyRQ3l_ zSo5DLER7EG%PLtwDs22S6-HI2!aPN#?7m95r6{Q!=)jXw+U0( zWEyy`a#5@N4ID8U$zB_Vg~;tUT8Sa(V+#$EK=`poa&=GMd}0rdbRQpG{*Sgor_pQ6ka$qyeGXPHBiD=IA_Qw!3W$(q{jnC@yP-;TW+EX#a^bANN{;@98y4LXVM8noJWTef=nOFvlcN@jC?c>ZBD$Pl zt*X`IQ6xryCrEH|R2InRc8)pJOJHRa}CX zEyNnhG_f-*B4Et|uLK#+)&lOd5VRH|k%FT_K{Hr9JB$Jz7q0*dR04%)AAN=EbqVrW20H4){e>nH`16Q4!(vP%b;{(}G1ZEogSi zuo6zL%0kHwi%@iQFq@fcwG*%!CSIgbyHPZfU842|rE;F0%rGzv9Aub+W;@|Vg;2;) zWh+S8Laj`Mbp;i0J4V8zb8##lmz*un6(Nx-Abn*hLK*@iaEwoa<-t{6dRU z$}{rGAvr;V5rfreuAfWH)&xYR0Fq5t%M5lpi(@meRq%kA;rFq`u3Q|%LAjkyrAEaK z>y>C)wqGC&dMPxaO-gqvP*{S3E1?<;CWncuASU zk!rb7KoRk5A-YEncZRhNl9MQOGHG0uLn4IOE(O@c3Fg>xkyJ5FiZ#OJSP_B3<#NM( zl$Mk&H#*2TydEy5qjPLXjFt&jcU}N92`=TTObmnHub_LZEHBLq@+CkcU=5ANfqYZr zgP1ZNU+a>ykYKrwwK|1Josnpf$ps9oGo0-JtA}9N%;!k_TpCGiMTNk|=Ar5x(VqYI zj;LAVH6!#IpXQH^Q2fkA<~^^_AH?`J+mOX&_rZe!k&V!$Rzpx{&y8&UdWRJn!1k%f zm)^=~H#ki`bK@LmjHHCczPY;Qde8pF2VxKP zO6qAS?y`6FmXZnQN3_qLiQHB;Po;Bf^sI<1RsUj}RIAXTQU$cm{`0PQ7CpF*VZe}d8d4_FNF-%~17~BVMz2L@Vz5S% z0YZUF1IAa`S3j`vZSZJ(E>Ay;)96}KsaY^x=r%aXY*^(6HB4&o_$@jEj4T5Cj$nhj zP?zhm2itlLc4M1L46-V>uK&EVf&Al2Ml}+%75O~(%n7YlqVO}?F&rb$lcTS1^PC)l zI6v>q!Nq}IHm}>DQ&jD?8^CE00_;0`Op(oSAJ~`I;OHOBYhAWc{N%PxYZezdyAZ@!zj+RgW1zN&b%r{&@ycjpMlc(wajSuHMt6s$cYf)bGC@4OI94#IW#K>EopOYN`5S z?{BSXcVdL!o0Y4kjJ`7HyQAT`PF4MP`j7hm!_lg{C0s~6e5+{gvY4DA_%Qsb_h)9d zI1uN#Gi}a8nhH<2m2B4Qy7<5@gTYdH?t*YTO+R^4R1|MlwP$p!_KbhHG4#g_0%zil zkGRH#5vtl{h0(;e>83sAWQ|JTA6Qx>U*ow&;LS(IPU8O(nx5k%M3~4wViyj5MiL zCmA$>QC%Ll3-}UX4ODHYX5>ji{TR6vYSE}JIIhQ{!I?e|1>w}7NB~7}M+6kHYKZxl z=BUO{qpDt0s@+iNrn)-AcsweqIn=aDrnGzrpe$4DA!^UoFcz$nRrJ#PSr(o`FOIpsr2d&y%9M-ZBw}7{}9;e$2Cw$*S{kqZ- zTuWQE?(7qPttp!f*9S&-n|Qb4Ks+X}zQe7qur6DYb))ArJRc+hhJM`81UgtMGtr*|vN6-7%Y#-v>Bi+zhP3DF23Dfb5amB3S&U19}k7@I9E!ONzTrRaYUtsnguhoKd zDuMkbCN?@MdU0N~2_T|_>HsL4*N=|=9v1^eRZe#EHgRA|ho+ITQkXYpPhLM}0N}!J?GckfR+~;{#B?&* znGzHNI3LvZk5{8drB}ZiIePocyOmbZ92S=XB>_=ufwAMFhnMw@j)po#1aB7yZlwL_ zCpPYn-`f7!G$tBq9%-5s*Dx;a&B7G^rMf2Fqt@=o{&kv<4KtsqXC}@?%AQh?J0sD zTul4f7=cs8=EX!uDw4J``@QB7ZcDsSQ|y1cAc3*0-Cy~$a)(bDtuyRR2KirXh< zc6{>Dn0|{w&H5N0%s02_*m&&PttjG*j@J?frU zQ30#D2FJLZpE!X{A9|>0T1)w{ICX=Ct_x4EgyzrcvYS?K3O2q0cF)bF-T!M7T^8 zB#DcLceyrZ@RT-FroGcD=RG*M!aHiwkt;cmU!?ce519HqnSk`q2`coDT$J-EgQi9A z9@)_9ax~VDyz;&Etn!^NHl6F;B!0vob01tU?#3e)R>M%jL-VBk!U=S9ZCb-^{iW1dO37SFxVaYY89K(PAjslm$m9USz# zTQX`ah}#nnWf!0jFhue1$5Uk23#K&`?rn>kQ-O@P+-SOkfA3ZeWRo)cy948XzgXc3 zT&%wWekptQx;nKJMqi1Fi{3kZTfMQW1Syo4AcXSb2vt;^)&Z_NeyTY?bN&di$NqLf zU$l7Lt-o0gBt*3bUQ81WPYJ@fTgueC zrFo5RTxiIo2Ik*pH69cCZ82$yO3?R?pf+>%>s(5yKWp2NC9Q9i*Es5GdC9|=P$E9I zb$j^r^iOR%Tpk)zPn0{(oo{~pX!nSY0~cgG>9le`vZC0Z+L$5VfYd!1wCHVv4YVaa zZ}r6Yrj3)?vRU7ErMi|}elqD`i_(EtcAv5A%WoOQpHA;O7ZJK}HhR%-opv# ze`wP#(cy}1OL(y}`(#eD3bhaJWPGsXH(d~SdFS+~Yv*_MO-f7>CLXQ5{!=I3x#GBI zPv30H5e@KnFi-s?8nYvSyK=hVZt2BNk2pt1%T#R-nl?FV)WlscI+MPGvGh*u@z?Gy z|IK=)f5QtY^$veHaI3L5B){X{^5V&#pl5v4_?(+8=l1V$)CP>lVJt2{KcF{Uk4Yl-mWUh`8s|5kSEIp>E1Dx%ar|} zMob$iOgSmroYm#y%}$2Y&U|9)8W>Ia$*S6S`F>LM9W#{;dyQfXRKRvaMiplU3McUg56O zCOzlTUSF%Y0_UOC?GJbDd`-Ud8&eQ>XJT+ZVfbNR*CR~L3kTV=}eY@YqtsEr{Zr_(q zba4hXn$&lHQJu?4fl#Yq;WOnQnl+z4Y1^i86ve{HHgZN%g>Aw3=S>!OJlpTh<8%5J zCC?9z<)%NKcJ|%+gB{}eJEj&8+Rc6VZRm}+yN?kD?A;QbX;QvKK035{e9i+}Y#7?M zbW?8kUTp?(FZYF=_m)1UBWPl<2tpV4NR{wEU4(?Snu9hWguEaWKr(;ySIKe8lqW9+jPjzEdpW zITbfnWVU|NPujO`=GCJyHKV?c88?ouUsor+VdN?rghSyV0xEJf9Y+9nV)1Gyc4%~T zOrpB}(fare&gJ=eDMk<^--9(v-|9fAxz6Z_9yehkCt>@(ivIUv>^*X}|2Ai3#_)h`0}HsW_U|n?>Oi$3uhgy+E0dB@EudzRQf!?D z)yof131fS`xfZ7h1mGVF9SDR}EFO)I1XThAF6>knq1^wQ!c{NEV(TRTBplD60VqZn z{tQ#qvS@N-Su_qTi-tu#IdNp|jBhW$b@=UAaJeS##P_65nv5?6V@~&5Q8;^H(pcp9 zsmELH-Y{!QR$?=G-ho+@@YV)v$6Cs!T<=Un4_{I1bl?H5?D-0PuZkUaCM|pv11sow z2zPUN3gL0<4>kF-=WQ9`-H#Z!QpD_-zvZQ+<;xADJB3vh$!Tdg%BQOqNh1!7@Y;MT z`BmojyjifO+|(pSz1~?%(njsz(v8GI0l&kEnMJvEP6a0cDb6-=UN~Cf_9-4^KkK! zIU{nXdgjQ#U%5xsZY;N$I*@lCnf%&X13sKxb~iH}o3x8mW4&q5mYFS%$86d|H=XuG zkD1X=&Q0jNc76HMw{6!4V!IC?rx#D2I-w3}7I#C|y3cWQ3%aLI$a=ZA5xxNNPPerx z{sqB3g1;`w{=PbiEVi4si>y{6W?8)&i%tA#k+YF){YfF+eYOo1(*cvOIsm%|Nh-`HlgdmQYOOYvT*f; zhZ%~&%e(j3wzSQs3|99$;)N~gJ%a~!4Hrxo70>T5%Y2)E=Joq#7ecFFJUP(vT90>g zREZDWr^mj1&K$q$RnuXKCpiD%5PgYj<7oSjmbDOuVCKl z!bN$k8g&RqVszr!*Chj8ElkChM9Sr}@4l>U+IRev-|r-bx*?j@A8uW=w5%O@^2n6v z^84ur^1Do|SSS%Sc`^FdUHxhKr&h4r+d94Yt%LJ?5tgx<(^~jQ+aPe0-sYwz^B}6z z|Z^^!N;Mv*c33q!BFt9f?e#&3Hu?=?`qgUOyN)d5SI;hYX$@6GgdQS+{CyOM~~D#a;@=(-LC|xGnYQu-S}_Q1_l3b zl1o#tG_GX6dOwj%^|}LsRqgNmL3`=RXmHO80vE1-5a0hOEB{CIH+J`>oxdM1sJ&OS z>sB|taq#lJ3mhpIS3)(~cZ+*_#|9(ao{24AS!hUPT_=n}51(|Z7AJrI8>~Hl|D4nC z-Wn*P#FQ59^S93vq&x#F3WYunW)euTZm2V;x_0)4yJH@8XpC%d7$;JHPzv z$Mn4~<~7>BBCzJgcH*g>mohMi{mCUgQv)X}j`eAj+4JJ9@!j^Pm-I{{&pkP#N9RFN zHp$mTCq&z8GU*NO#qwO7$?L0aVfymR-bDy^aMdkExA;$&h8C8sUH|^eip9N8npe}V zLxI5Q>Y{`D(K@ZV&>e#p84IF ze)x)q&J|NYW0dMXq+oicz)5c%7mGC~EIH$r~EXXJJZZn3~_RHwI@24kp*j-T0>u2io z9k&{F;n{%HOFgLs;lUA27ZmA_CvPZhK6oDf+AulH0h2!iADbtp8wOJPyecRu) z#sdGrI+xQ)L)h2u&1lwLlxQvG{XSN+@Ws=!M-KILy2C`kzz+cfpQ&cx`l7D(u@hdl zjm31H{6RSB%b>hxP5)*#|IaWmPW?9q#;N}YW&4kIf8I}fd?Br9?V`I)*5s~GG`+HF z<7Vr$ezQXFrfpBlZ2NKF{wC}D?>#W@bZFiU`@9PLyaRI@F6nW<^TMK~OGVzzwGMu2 z^5!rb8QgQ>+3rU@-p)VYB>8o|rm*wab|=IMsf|9hOIdK?DDv&t!{mBN742JGbl^@u z+lA}jbHzyU-uKU^%z2e@WnnnQX1$8Is(bSwt#_v*qgo#r*UWtSDRI$C(X3u=s9%WR zDFeH9DG(#u6|-)jzKcB1Uk)q?oKANQ)4b`i&slb%>BeP=`1>~Wmx{oOzVmzEyos8^ zn`HRjaM(%mnT{ywiFE22R-AKCiN4|HPAT`dAi8XqsXdD9H!G}zTD*9uX?fFdJc(74 zJs0hJS*!5W&FN9nHEs6fjf8D{vA4W=K_KdR7Y3$q(X;iB6Hvx2M%SjX)AI+Y~^*Zsx!X`SZ= z5VhYY+?ca%Va?bs-`+N;x;5cjTZ|jtH12h;2HiTR#IB!OxRAVEVm@Ct zwMpZB8}?rl_TTfo)2i~(6LWfZoG@|B;&y2|`jz;v12mKE3|ZIo-o+d8)(=0vu}zO= zzcuOgys%WZHAA{?*U0P3KF?nCY{Xd4n{dzKhTBFenY~`M)sPB#x2_yr(fakGeZ6>{ zPgc>t5z_wy{YU@H&d;A4`u|Ae|2s^t{5WiCojI@Vnu_D2nwRt%(R^9S-W|*O)ak=M zxuc-d>CA;Yl%HOX7@O7YqwBJ@<(7;>`Lvg&VRQR#mDTw&k1_OKj5tcVKPmRWnCx3G z^5lc>y&aVPG`aoP;on=WII!l{^`_HTH$Ht1@~3y1zVOT{Q*2#Q6U0#8ZO6;O_5H}l zPekPL#4P)RJKdinuj^&_zNve)^lj%`Z5i5aLi*Ed3raXEFUt(QZ0D7O_p?Voeah`O ztxne&rSnF;FHoIfz9g~fDEweSmK zU#<5S%+vpMA(KFof6|K!1LU)Kb-Z@U3Iz(2)ShfR|7i$JguLrvv z(6H&y|75NjllE`zas0GLlb;ve4r=nphEB~`RNcSq*+9rYpT(hC$H8jtre_tTk9Ww% z29~UgrnO_VKHu@`jUG3KU3@s1u#a~G8g}`o4q}j~VMm~02ccp6pkce?V0(l+H%;LU z!<)u9Uy$!QD&nrTuCZ`muW6ifg@^kyT8E)wv!NkN2K_&Z+fQfOae2{0g~lcqg(LT% zo$b4ws-1M|v^W zESjGsmmVAW!Tql1*IP-1PAQLeE1jNGr;a{L-;%1AKtCiIPM>h zx&QTM#L%dJ86!XSM->|UjT0~|PF)cB`zS5`lszG?vJEP-(MhOmgI5={fg+bGB1g=X z`o+Z6i%Z%2vMkBlt&}ybBufM*tYG{tsRS1ohDG&9&H6Cc5bqh=_#HV!K3xp6Ci*+e zdZ+pt?9(ZcTh(C*RnUMst;z7YFm0x=&mk`E+T0h{TbWvIdidhn;Igxa+V*6gK6>ZF zG(op6TP8kFIy-k7^>T|(&N;2+FHPu^A6AijAXSfB@b5{WzK<;%cb=uJUbJ9>YGk_j zMu#!N&Z51ZggW=7Zv@4sI<}5KJhJtmJN;XJgSDMldeGTE$9?4e;orw@?YHw8Zb;i_ zmp%^jeOpwn_%ib0l_{OJO}={1y9f3x;aqqAAs^;l{3iH{i!%pYygU%oZvM3C{l6C- z(#xLrFcwK()E~S;Jq7=uOwMmm)=qysfA4@jt1n;ZOFH{|%YF9CHRc_(wR;1XU42LH zfqk}SPyd(0uGGnMjhNOBGm%#EO3^dA%c6GkrtCjdWAs!e)}jd4de=RVyXV>R@~!w? z%XW2=9UD15Z_D=3-QT7NM-O_{+;mMg-Et;zLd=LWU#_A3_)??#YTGO7*~bNAZ}0vn zes<}*A;vTHd7mLK$(#GU&CiQRf%QNp_~`^9MQYWWAVtmD)Z<*oqZQoEJ)BwhIu!kF z>i%2LP^<3HfbadI!C%8bRo|icQ3Q8r_uRWgMwF{nt{#h)_*xb zuD;I$zD_5CNeo^$xF-y5X#7WeCWWHuBS-V|f4jn=Fts?9?olZU#Nba`esb>67JZH!MwK7?N{c{iz{9@F#fqsJF+!8`gzF>_=Vdg z46HvtuVZl1-i(_`Y4=O48G-A*Fs{S0(G43N*wNx;7wNE7^Ge{;*WYV7f4kvAdx*2N zS<>DUuf`8iW22W9T!>B_=^-jfho5yvH*Y!OHX$uk0$n6D4L&S8J?*g*Uf1~ydJ6th z#ma6MG9OeW&BI1R!$$mV)A;8M_#aO^lm8^3__!EwsW8<%ARg2 zseS3#t4HILZr`>au37jktEIPTs`5a`PKCDq7N}EK`IZSQmn2SESTdco&h3$@<};d=OKfP& zMf1breVf02pZTg;>A`pd$1Y%2tmr=@U?!gtbfhgkI%o6>-0MjR##L?iSP#@&mkzVt z@+}UuH!NRzuw(Of-@31SkjCCwOt92{ z;rqc=N7ilmnnAI5Sh1yqbh6Q0<;fbg4{iL4FT-6r*|#`#&YUx4dE@Jq*H&tZG*i#7 z3>SA--uXI%#q&Kpduib2=+|X!xMh&J@vaWfcD}EVO~w>H6R2Tn{nGON4&bH6Bp;&#o1R&%C> zKJ4Fj@65F2X{$SDXOS<}8+)fmy#9{QCC`fnNyxLf{tyzYzF^z%K-TA@B=< zUkLm{;1>eF5cq|_F9d!e@C$)o2>e3e7XrT!_=UhP1b!j#3xQt<{6gRt0>2RWg}^Ta zej)G+f&cFic(00%nqRbiGwx10$}oYu>_p~v*jDm0y<-@KX+_M^YOmhSY{)Yi|TfH5tDjGcJ8g)>+ znU0jfQhp=(%Putsj!m6i${RcO^thzpqz`9GuJjsr*R-`Byjeo>sf>~f+v_3q3+s04 zZcp}X$DC*~@_0%EUyAy8dC9&u#|KZZUlpBYJjO(v!7* zNmeNQ>HUBgq|F~bf7|#$J)j)@=vIe2F4*lyH|F*!>HBVT$+NkwUSypjM~(U2l~6jn zXUAmYtkpBF*B3V#wQAO>I-Kt{pq{S=ex5%!vDy0cu&-g({0iYRy|Lb=ny1;M2BsRv zGzU6k(Zf4lFe#?Ynvz)K`rOqIdc~+8%9^banD)+lGk3t$V8XpQokkc>tXa40;c?%Y zZs_La$@#6Pz8-q2_v__tM{M2GoWILI3pQ@q;?x5Z@Nh-f89X8F^~rTZx2RgIomqe$ zIDTL!n{LR`=1o(L^-P5wEd@zwqwlQhfX@83cxG-%sPX!<8-wx1ck;(?uRXc6e8a=S zh2oLQekY&Px;`zQ*Y-MR0Ac#W#-4t*I~~^@9n!U-7;k$_ds}}Er*zv3BEis|{3&C% zta#4YHIs46w~tw1YpiPeSV<%4i`&_9_OLgPI?3x?KCQ^(FKN5n8pBC~H-DF*^!1tF zprmviYW`%;#-3by@6iu$ zKJ<6@O)P4EVbqNG)*MV$t?+^TJuA3M`6RvNBxDd$*bBmIQ1Lhdf&ts{mMn-8NE)h z9T@Abw?}U`Ts7hL$%$iqdpfl4IaQe5swqmI$-L`o+C|>7 z)jj5gKyC0?@`MVZv&S-XA5ma=Ax7xI2 zS(hPe6Hs5Dtl5yW+0%ac#P|m(U9Z(jt~IIDdv&plwYc-1SN8U`Wl5bU>!#5C=ln6M zxRtYQ*y;UwJL*g@KDjmSS&@DIq6hEewBr(bVVRfDj#}lcwYeR8%dv*MMdv4s)37VfzGo+)@e&JJ6al|6CNE0P^^;g& z^)b^w?B$fMopSH+#u#IRsVB5^CE&}VpT;y;zsk0uN8%-P)>3_kTDwlu7_UU08Evf_ zcg*7T>YTJ`QzzuhwzB(Wwwr@$UVU^$*SUnTx(IP~5$XMk5uVQ3Z13r{qnjUAzG&90 z^R5#gOCE^f>!&xn-e|gg#hlV@*+YyCdXFKdHg4^kyM8I+n>BA%!l7GvT-b-Qq?H3( zUccHTHo{pG?$N&6J;Nt_DerrBM5BtW zc1`aIJGU7!w^htMWja}iPQTfGUE?haRt}e}nrc6jKYPg{%AUQ~6Ng>n0#8rSoKKsM z(kt{+u1pn`_vL&rzaGBLHQw6!^Oa?FuRohQ;mmL69&I_cc=M(rSLT}fjJb}LCsCNA z&qGV<7|kU+uH87=cS820cI%fEtS&w_+24EPw2boW9M%o}GBH=G7U`r@aeZ8Q%tXmfyep%=NpL*=IW>7h-BjX)P~tB)#YL*wnq7`pp_M zrg72~j%V}fj8Z49TccxNUTs<1Fn9FA(h-chlimb3@^|&fuQQ{A!60u0Z*P&#{Ww~@ zTY(akwOT#D#*k5m7-#Fl?6nsg8_sFcWVK6Y!jmqp4L^g=-jeR-||-U zT~o0fVO&z&w1M-+l=GeoImFV1n@PU@>iYY9@Ng&ZR=*hXHZ8M)unBSbVg_~F z+XoX4pKFubcI{K<;c+tZg(1Uw4;s1X*o{`D40Jv1=6VY+bnK5R?6dFaV8_K-gKKS% zzdqYHa83y0J(9H6`3~B(sKe484JV8xo^7yts06mSdm*RGRNHSW-!JHN>LgN9v>S0= zkQW=Jt(7?Hz^LS<3e@Jz;ZN$!x;*oCkI+iQ)@}{krSJ7+lG_RToHlXg1*6+pxAg2r zSUm80-B59%Ad6sUtja!my5Hk%`FrH0b)WYZ+4A`bi&ssGe~mgg{cdLN!}jXtW6sgO zJU?KZ(D(Yff~zC1te90grbyM*IB34eCwZ~;eX%2PbM{XC0NJ@u=S8dP(?t5Tt@tMm zn-LtF5N+S3+`c&ef~?Eqheh&wRQlyJ*429&q6+2yUK>kVu9@NKKEFJF3F1|me%fih zFZ~>51W)b1CEqlP+qXWiT3>VP!?WGmq|V%R zrR(W!=Wd)Ml%{qW8ATqOOxs_h&qCRWi8*Il980l`vI}1-%DXxrs?bG)jG-%+r_`T) z$T<6K?;TU|L0t2d=U3CtvNz3UYI1SWZ`$Dh7XU~=x4$}UaSm$re$+EkN-WTX2TnA}?laNv0V((+N@;95aIf)=DZrGRNW{Dhq6DXaJxRh!u&2}a2T0!}Q11!`Z@8dck|8o2#!Q=B;?QWbASv87sM8!$^Qb<&%x zY>fS+Ce+3ALYSx^s}7rylcp8jYcWMkX{(SW!04_ktCJzeQhPGTRV>70^La$dIc)Nf zrOO65FR?0}lyl6?TWnY=N(wTC-CflT-JZ$JEVGVID@pbnhxXsy4t zUQ`t2iaE*XTg@30hKk>%5AS=?e4cHw3`Dsu0l~_J@=BIeF{S2__?{>T8Kbk_obWJL zcm}5UNU}jM`qH#xt`c1hvnuy*&gW-ItCpOivz1My{kF1LarXGiVmYSNn`CMeva5Pu zRaPr&UR3!bt3>T@X-Vz*;}5-GQKucUL-J%yn5i7~ds)n6S+|AqEv8!`u#+4HnncZ4 zQ9=A8Y9-5kZGcZ5wYi4q?H%*cx$jq4fOMT*pP9W$%limUo{b=Bs0?N9_%B|^I{+b^4v z=v7lJ%Px3E!sWCxd^5neiXBB<R)nuFkT2Xk4dN6dE{6eXa@$h8+&TzO~j=py8Rh&}h`7Ix3R34As)S^-e$$ZcftIGHRP%)zPQ`LfxREH4*8*^)Rxp zi==w}gF3eR!>#R4)Zx*#x5tbp&jdGf#a^=nY@fn*GTl|N>-an$Pc1{go;ko z>PV^eCOsLAXUqAPDP~OTAEoReENfr=(*{MID30u07xbW_$2rH$rBY_^gZZeI1*sE!Al#K+BwYu-vZo1_gyZky*c_Kt?LlP^8BN1s8*$sc^ESlu6J~4Dxiy3jj>S{|sP3YFE%^MyXQ8yd_BqN&ll${mKX?`(qP5H^nmmSG<{l+#j%l0i7 z8ujUDLdm7B!->s0^T#VEA+QgJDF4J*(5=1| zBUDq{X;a|m>O7f0le;drr3;9x0b6cg5>w(XGdu&P2Hh$QnfhQCZlOB3DRlJ?maQ&G ziAAw%!NR{SzFH%-k-p^MkYOO{V;zMRu;`KHLyb#Uz0D{nTR^e3tfEbm*LIM|gsvWL zWnSBubV7l15%I(zYZizsSi1nT61#{>d#fcDQ0Zi$q_eUdDWj>+N6iS3pfQGe>aC=* zJgHWP=7JP9>*-KV_SdXJTDG#R1!dPJ^N=g1Lt9bmGr>}u7LoIPk~H(gVY2Z2x;Rj_ zeM$>ptGMDY4KX^R@c{-`x5;-kX|YC~1>)1RViPS+kywe?DcV$JM_QkW9iqdvJ}0x5 zr3{waca*1}%^B^D?wQmi?Z+Q1#kIUSn{$aZ1znLAm<%&nJWWq|=6p(9u(V~nilLTR z6+@NbQ&afMLYk#54p_5KCk7DY{G2hj1aumR4t0p=4V7t#KT6eY>zl_O4P#TBo9*5_ z)GV}hfaCU6oP@e!;(Dk~IB#itG;{T7v&zuQI(mZIT-r@2k#9gJx~AD>uu6QnU=Vw^ zH`zXzqkzgro0`R@Guer&eTly)8GgKkXEEq}XA60^*8;Xkzin1D?r);Zv3N_{j<+Q^Jsv69h?X1BUc^mb7#iOHh z?l>9B@3cSRq;~w1%+(a;j-UM`WXzFtlJ?zM>IiilB`2ZWj@+uyqaCd}({{0$^9RL= zdMFu1+(5ciPiN{WMT0-DF!N19x^p5|A!Ks zGou=1j*RU(FJ8V!QG!98n641IP<|6Z?A2=a)`fPRs#M3)Vr$wpdT)RYit7(?Qv*A9a>}EB+5MMHXcBPhGIaxRBs#5l%B*M0# z?bV-jdy4m{62R_KpvqIB?l#l28A0kWOVu`TUZKo_ft@VXnnA);iq;z)sQa}Eo1J%_ zbs4;Ma8gGcu>xOjBNE&X4})DYjNQQ&L<$mfJ+cDE?f}u8xvmU5NdW z7_7lT)`G%sbsbsB!*)^&ZH>B`?NGvpoDs{^Sv2|MK3g7BlBNKT`@pXB1Z};Uu?6bQ zHPeKn{NhXz7RvzBEC+?W#2KOVIepjGm~)|$^InAo)tDLNP6o;21yxP9mqc{~_AKTr zIGWElX*tv;|k=S_E&xC5DA(qm9rj$HVLR)5ChCMl!ne}Fi1et%+m|MbDDY9bBVx>7VJ#D$tj`!}iuPzl!V{RC@b=byTS1phAd#&bl zExntn&9&)z)arNlUYeCiiiX7cdkgX1t9|n9h8OwS^|vkOJ0YNlzqfE;JLMaw$<RE#5U@asT!<~o<$ax2_~pxY+rGJ!hxl(l0-m> zZE4%W5aF?!Je1WPPhwqkt*(lTZM(A0Lgte8t|N4hLc0{fMr8E}87-N?GbY(~8#v## zmw7T>9owujP+-=C?GqtvXj4*B%2OI)ceJk8Z5hSQOXRnNcyL*mtH)0aw>kB;AlTK{ zE}hkXt>O2Urz&a{b*u9+`IurPgKLwe$|F_Qx;bquh4jv^4%i-oI}Iv?QQC=3c-s-Q zhdA~i%cy3y!YtI1sw$HxnaxZq+pjs;`;K<@Ifiv*{o(i;gK9W5Fxt8r|p7)QvaAxay2Tu6B(TTV%$9;r6@fp(iuD`SQ`lzEE6P5-WYFy=2=|*nJN47nJ9LyJVIM zpW*53(yCRrdfSo>DJ%%-3Z0d{=CEkJUIJ{Go>Rz19Hrmd-9iM1LST_6yfB2<(Z{6tx4t&)}F%Eb=U>mQ0TP40urNDJC3>rgU; zx3jxo=2X|7uDWJtSdyZYpu_nS9+g7Ikn||}Z<)QwaSLRg z(Of2O2!6Cj7wmRV&eLP_z)V%EBqtxXt6=TSk80J&>hnpucN=fl5X+n#8Jf}Na@TUG zG|mZ0og>&>gN7)Z>>M*eq@=TKb9CX9U82FHU1#1hd4}g57(5em zV{6+@3D}m%w=`^VeO3g`s=>9;`nY_?C2m6*#ecd(7yEg(9dqg}=VKM6Q;^!?GeZc{ zAfBuTuQ?wpiC_Y?l@>ID2t^^HAZAO!!Io3Xx&ds#q|I%slB|?L%8wHWaojwts_mhi zEX#A0GPr6VPrg#KFZK$-$9ub!^?~c!M;93wc38!?Oe7*@N==qMp9M^*1!RR*x}||x zb}Mb&azM3~Zp#+Nv5_H(ZD{<{CKYTIcM0XV9c>Pc5s|7pP$({Gs^57PddqD9g*T~~ z-x4DO<;IjL%!}>0xxQA-Il(qR&y*m`y1t~{atTrZ#|hB(+|dR1-L+JWi>ngp3Y`?Q zWU-}kUSw2YqN?2W5`#h=4?0Bln$3i<8Hwm1v2S^gr0Qr$|egdy#>L#?j@zjcI3E3d@DYjx8`pD;Lm^oR=&^ zbXC2R2sE|Y7E0RDT61UvYvI*PpIZCOUUD*L@@NEfY%erIM@JSlsU0T(G^t?cXjQJ7 zYX;Pwbdb5@B*wc1m>xUY2Tj1SlYS79ZVO2#94*7$lTF?#Oh1nFlyl1*RWqeZueX@H z+jq;cMZxAt&cP6^!EROW6CPWL-#$)vx~(*jWnc?k#Ik3#bS}^o%~;%6v8=MYUe3?J z*I~=9rOGeb2-q^AOIv-iQnB6{GPu8*rE+3_7Q9*!Do_}(r6QVBf0HYfbDJD00e&?i zg;=rI3t z0wQf&uuw&6)hr@gQ{@z{*If63N>{D*hB(6^x^6dk(=n_I4ypTF)-{c(WBu23ukrM?V`4^U+5JKe{+0YX|J%L^vVw8L^gq5R34mXg6 z%Ly4*%B#e!O&`E#0P!Mb&a=` z=0Jv02&k@RIcf#DAHvOlqVNGd5nSy|triA<^XM?3e7TfkQA)&AL68xt2QP2;T+ zuSPxz+4Fka8RX9t5t_mO|9P~|>d%FSKc|II`Txhy^?!(goN_a^R7rF?rsJQ7ZnV)P zTP$GymXT5~n{b10oeIsXDmDiq1LxHxd@*u8I^P zXv|D&14khRf%$RCegD(R4&q2fG%(+X0wXz6-LrB>NrTL|; zlN?Rn?U+YU{|9CdFHz_QgdF0^q{OvW8l zki{Aa5!ok}Epw@P(6XmB9LWmDW-bEXD$s99Qoq7-66K_^y>o<2R3<}g#)P9%u`1Om z-IG~gZzbx{Shu!y21zovEh~?VB*roUMt;8s_i7xuSu^PtSKC=yrm+s9dErU1twEBY zx6H}TG(E{~C#vJG^9O!s2S=$nsQvzSGP=^QN2X4NqWxVs%F6dqb$RCCP6I-@6HxJA zVHb^F#Xst?tY4N}9U5Y(93h9JE~y!X8zCSJ~HF3Tv*bO~;EaC2uMg7(-l zSz}qHk4eZ@PPTrdj%=NjyIxv{hTf%$;O#C8jnGBXjjHxo(Z#ZJjbY?|ynCE)Gw1xX zj`mb&&VTmKm@x3?bR4Tr?Qtx@=&_p7cao0w%oYmgFpNz_POLb`So*O?rBo@&Y2>(F!MX}RqYUwieXOB? zmXU47kr%^mUsR!KT5gLlfUUEFP*Q}py!mLW`JRNYt?Mg%*VZ8#Iu%!wq`k*f91L`k z)Kb1MYdThtpnf9HVlYw1{QOQw=j(Nux@av&&TaDW4QEQQs7tB1#PR)BmXac&NGH=f zyGzUBQqrZcQjlzcP_gFnYKx-NndW&HWXal=qJugSbAB?W%ApLCvPM@>qSd+rS*Hpq zC039@!FI01XDc5gQnHQ;k7U(2FR?YZ?vb1hr448*3P|ZpM`%{fM#1`l zfpp(k{fK0-OC_=>t;;NjDyPJ`y*dr!_-aR|8dzejKJ!Ddl`4tIWiFe-nO5Zl6J*4h zf5c%pz4=yYQe%sxi{oy#fXxYy%)(50f{1j7q5U(C9|8vkHM3M0G*VS91iFyK2YG`c zN9e$inriC_4jjS^y5f$~7EC8OtY@oMA%LsD zx@v#Bh>*ILRj9r-(qgf3!v2biX_}*&v?X}XnLss`w$8hSqQ;r%d1FDdgKxQ1kf(nd z-jUV(-pG|7Zi#$U$6V<7KYsLPJeF^d>iBaRZOb5Y4rj|j#sd-64zr6=su{Zzop7Or zeH7gpjVV1Um8igBdtGO&f?G?Bb+B_2osgbmd-at6Q5%8?PMx96LTe4#?l)}XldRM> z(_mDcv_Ngnt5AcGx2R&}`MYg&@|fIK61J0S41`Ji@@T@>D%PZgjVQ;ws5VBARgroj z8zyO&7tQn@;RL{e$^6ZoJ!|=T%gL5GbLr;@l#ie(6n}(I(pWu4Vm4JqaiWW(=l+)H6t~Xukbe6qJlevmq zBg=G>aw#we4zQcuN}Ek{vCTE&h&3=Kf^$T~l!|Bu_9Ouos{p`BMoN{1f|mJtYR#<+ zKKC3;>u1CYU`&ieI^rj&v2GDz%s|;Z#)l-KyrOcdY>{!igiI=B zBGNr;$U$Ug|E8oFmd-9uAc`RqS+!4H?0(OxG{l|kQiNycVG&-MG7S}%fLMD8Y)%$O zmIV;xNkp~bxIClVaV@Uer`7(eI~>hUv|?$tye5z+?$Px0Ejtn&t#F4Wlo~4dSi6dKGWl^YUk;zqm(XCNaump-Jgk+C#l(OF*k~ zc`k9!-E?bighzW6_^$W5z&wq#&QM7$yI4Zo6(afCyGoY=PguSuF;MR#H*+hh5uQ|q zN(I=)v`j%~=2_LPuV%H_(xvOc;y-=oMtUbF0~u-1jN1>f{lh9!Wf!w#tGZ;i<_R*9 zjYO0otxq$A7d^~ig=;<8k&(m)XDlR-RL|u@d4f)7>!5O~H)9Qk=whpgotz} zd6Qu8_H5-C4V>EMC%2s3aPgycnWa=nh+ZWf>!R5zyQ#)YBUqJgCq)MEeK=QUwsY&U(e2U3eIhcbA%~L2+e1AR#z(?*hQ<9Kh^$PtJf}Dt|}7@2kP@RH?%NkRY!^gK+ow{DL0!PgUTH{ zS(p25qN1=MS_O<1GOcU+B}HfL&g-9K`B(^=Y+%xh4LhQCFOJ`R&MagKSxv(LTzpn{j(Fr88Q`E{q%K z`rECvbqJUXAKmtI5ocDHU~ByP3QLCW|?(eqGSj%0raig~X&7R)rF1EkxXq3^3!Vx*WHlHy8hF$P zr$R2pE2&NWVn4$N$M*#}3J4$jgaKcDJY3WBgoUw>U_d!nLC z%~N*-9}$CrSvr0t+LA4)m)Um~TXwSvJ6p7a4p7*-mflcCf(GglCiQGV9UY0?^!y0*4ZXq~!tBw-!9+NO3S zgJt_BRg5xovC-;GehEYpdMj3u2%qjR~z;mT0w<~q3p?1JW# zuR6Cp`4i*KbSI>03k|LMRe#PZO!s_V)QM=@eqLN02)=< z=DzF};FHR-f0R=z8d1lRCaC3OaQ_yso}qYA*6wP=G3!u8>P}~nfFwqx)7#<%x=v$z z4pn5P^GA2gW3scVdJ<1=nWLO&OJ(6C)1C0>Le`QJYKj2b_e4-x#{>Re8vmgh}C-k!s@#mt3)g#L~a1cH@GUb z*&^Z|@vy5-jgj#9oTk;5kkCmDZdwMS)lVer(u=J^%BpMW=ou1Jr;~;d=Aw0_DtePm z0|(`#d&c_Wk7!njVU*98cW;!`^yb}?KQexS4r@&)Jxtdv^w_R9yQ~5OupddV@-20M zEg!7Z(#_4vc#WiB=as0-cA83ss&#ew(5h31QKb{B#;Fxpa3dQssHCmE+R{@inAIM0 zJI-omNpRwd)r33+3Rbsnvr8MwBU`b#)-c)Vj4DdcX>?tm=%^h{$?v*NQSH7tG;0x6 zZOz#pGnaHh+q!VmqE&-#`>tcu`DOuD11*zX!0f#_!ETh3ETKBzZEu&@4J;a-TWNNA z(oR=Or?Zfx`BgYm-71IJK398G^cUt=(PM-?Hy6<{Wtc7Mv_)Rk5{ji6si0wB#h)&7 zn(?=}3gZ*hD|U3gc%jO+xy&2@$UWElCSJPMsqiX#Ts>2vJFY?uzA1IJOb=!zVIWc z|0j8=h1_}vgUH$2{Xz_4u!=8TvP70MW^Y#UkBDkCNJS!3`cDE7KY`c>Ek#G$EM2V7 zTBZ{qfwT*jK(ep-!(bE{T3>q1sp9dzSYkmYfM1IGV5} zL;^WGCQ-MJNw%t@%(wVOSX7kt#rdaJT~*Xss__daoEMUmG25^Bg(3_^cjvt~D_2vh z9kDw43>;bCC|Hn~XfnX0g9|DtiJ(q+g=q^}OK^$*8%%vnt;c1s+rLH461$+qu~Ge=9? zLAggDa;PP%?+a)W9wESX$wy7CY3ewcKB3V9B7NJA14Au!@-uNXlUpimAamkfdsqxBG1>3kXqKM z%5fmA0q?-P?Py}#>#YLKzM^TL$5h#|eIa;>k!lbXOI^C!Y(BP`_JviF@?hcMtlU^1 zfl4q*8Is~iLt7-UGh#;mr6Q`If_Q@(9Tfp0ns4n0G)v0-sexIoDRW86+;Q@j+dFmv zf0Oi8t5YA_)zf;M7Bv-<+GtlK0)~h4i=B1&2GHx9%F{JX(oH?R9bbj3A*_d!*%Db^ zvdg#cA}$tXov4hT$5h0RTyg`IB4|}B{*<)dT2$?_E2yl@>19+h0&z4U4K0oK`Mp3Y)U7Cyr_N?iFju zEhBy`LPaIEic7UhrMgAR-_mD9@*5@7f{BU&RqxeCdQyjkB+E=E3s;3?JA#fwGI6&5 zhJN#>nqmLm0+BkMj&SvA8(maPmBi<)S5;YA*HNLa4HuySMKe>=>5gVwT8LSA`KH2q z61Sow2o<#>tN2i98X4U@iN8x@0w}9>cCLp1g=JYlsr7z^Q#znsMeFGr?$vr#3@hqa zD{!SMwxi)sH`S=(wEbaNopj!^B5HC+lu{8;tA^o2>*A@oT11ff_N`xq38nzb>qmXXmg#@UxdN9(PO4!3@3W^e!@c-EcIMCp5Et+8~eog4YM<#g6d#eX7g z90J>$_Cz!cE{EzIaI*@RP(j;Rafn2T39z>aStbt52yCN&)bK5iZho;+i%LI4?@xyO z=8rm5$=H^=MH>{do2MGtL1c_IgFe0YYSGj%s%o6wB;xW5eO6>7Y_H2wm9#bbGLv&4 zsoFN{F_DXNDp;_^5-_jfo!^QZNOf)2aJC-BoB+5q2Z>TF+QOP z%>e8UI}emLrmHnNf^p`CS!$XUNU*_W4r^&(HIfk)q{~G>uSRa?s>QdJ z44osxS5ErXAa-$=Wtt#pv%ZgBgN+=>sG)xrYgIwHT{X(1M$6`bjJfgc$TfI&mRBg$ zxkQZdq;swuIg*r|j~yZYu2mF33~;qT6_9pP50qNhazh(;5l%j1UTUwFTX2bCN&$jk zo1IN9i_%rmpISyeu~z2RU2IX$CD`IJWi^JiZu@T`ZWQgyacbjgx!ta)Bp8aE^BPUp zvN)BjDFF7tNzz+uW!w*emHe(Iw{j`XpR7=j^){9WSm^I09g#m`8bA>Za!VTvDhgZH zRZgrm|G8e3S84sQ1t#geSM?J-^)mBZ)pJb7l5It%b6ci0IUyZrHw21+b7PfRxh>zW zvqNrg8P@!io*v6|oSwSOI86v{D|fr~>v7rFlx9>$poj=^Ju&NR6krsAKBQ2ZI?6)` zU=vE!Xp-Y70Y|66R}3iNBbj9b!CHIk9@aru=j*;(sA)zO`YpYd?v5YPUa-p6rL$d6 z6Z>KKquq@vY9teb+!ozS9yE8WTL-u0ASuK)V7(S%?XRs#mQlYOlDmiAp|xI8$EzC~ zjAfS>y+^Zv=*Gx)tQV54B)O3ygPAA0@)9*i?D~pirY{ldF+an@ih46u%iI2WTZL_B zhk2O1Ic7nL>^icXsuZv4B_1AK4Yw9Er#7?dR9bE=hjI^1J=y%KtD#Qf!ORPKbc8%- zzsn3I46Z-hnuqSV;@NSS?d9~Rb^2-4yaqF#T`~ZkCLe+)a?#+2VQ_TLAxQroDjbnA3vOQO}i(maYjAuz;2#6br)=qKqj0ckjfG!&dhLQR}h1wvbn(&7+nfXP^uN%O|rIkvx4FZ-MM0nFmf$wDsmkjwzQ_xhLxGn}Kv zVi7Gmf=Pv)M9vM43NuvAQc3Cf%8W`^3#Tfs>t6*ySgIP)}lAAGvbOhm)DaE`>A$ARKt-MNz> zT7(utn7oh0ONBBy>=A%s#Dqa*jd=%gaaWASad56vE$vYz#zh&hY0@qG*gwtkHc@f9?pKd~jI&bP! z1ndY~nA5J;g7X?en}FCIpCkqph_oD~OHZAsqYC+?ul%@2b2oj z&*G8xr*%y!>384NH78HVti$KdA_Bj;#x^zQpl1iu$|g5 zqo~r4(As|;>bgH#DYkC6;UtW6>9E(>)odG-zFsxE%PwVgML%*3juObX7udkBC~
  • l2)uVekfexy-xf*fn?T9!} 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 z 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

    U{u1WY@~7m{I4O1l6Mpk(A4&!|8- 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

    P3t%O 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%0ANCu42O;!~oPGD_KXNV?*V+|j9&aD4t5nmRQ)!iV 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 z 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%0A&B@cJ|MITCdi`H}-KZVy?d>_|JOTCO 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ƺv)x9UV+lJUKrf5Gm5}(NRFWb@vVtg%Hx# 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 z%0A*RO@*~#{=FTD8DsZ%$;@9z8h_U~6LxZ7^I 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.l{ZHWGnbO z)HM?HQ)Y)N^R9)FL#%-{k^+tlrjWn|7+TvvFhq+bTsQ#1C2^1vB7g{L386rM z()w=BrkZxYDYxNn=;RrIwT}XgYZe5e5R5j11Y!09i>i|(4Ce8H2;pXQWul2Al?#Pn zuP}7TkOv>S_xE3abBm>cLq{|;w~*Gy9)IGVd(HGq#m3ftQVM3u=JK^Qliz&%{py-( zAkC!O`VD&Qk%#90_M4No`}H5>7P}qW@(Zhn4IA|2oCg*zT%50}ZfdE${-$dYolHs! z@c(l3-*?_+k45w6*EQ4)9yZc(Qd+s^UT`rmWV2aPUN)D#`OdphSW0PT5K>66v{KVH z*>w2OA@98T&e2C5t+jvP0S7kKHr#aUo!f4^V>X>eNhnjBOx^UDV~!dzYN*@YB`wj` zx6fH;oP6a~*YB|7uDMKFAo|K*-(8xq)6VCfcLo3;;(tHv(ga%0-&snlom(4|7`%s(2|*?@b(j&Q>w9(C#$0Xn3!lIG={KJ* zT)ncpQARq1RPYM}n)_`xZM&{D zU0FLltnW|&K!(9hBgXb0H>kev^3GM?FZy-N!12?DPbhX4HXJl*m#I5G_1=qrxNB0W z?BJ#$n~vHjo66SbYeo+ozRAd`*;KZns4I?D|g1K5+Y{$3I;7^AdN1{*LsO04=2uLTCaYQ7q{JeQW+$ z>R$fDqIZ8@r`KZ9uePNFz*-?_m9}C2;?jDMTTHF4s}bwEeB0uoHR&IIS-+^mK6F-d zpL)CK`njwBlccNIK9+;v*x zRS&NG=C@AZDhq`6k%^Tex1=430RDG>s8Pf68;#C*nliQ=)zA9$M=ogrroa^-A+SWG z&>#T-0K{x+C<2ke7$^vUSt|g|zUw*l&@x%1n}D^!4-sYbTF|uDWuFj*SSGF_y{3#d zG2GV=L&OqkT&Bt-s|BC<^S*M@4wD8JK@mY9^ciXznhtr?8MrA*2c*rct@^RGZIjkN zu)F*7FOWgatN_?l?@9^LvD*Fgc5B9UpiQAefdYX5gtchN;;!}UH<~=fG^^xxty|ws znn-cq{(bYAsx|HHKhOL1;U^v+H+nP*DQ)}dr=Oa#@zi(U`{2L>XTA9E=MOpJ2r1J) z{P5#tmtAq_VFz}sS-0(W+nsXS>94%>Qr1pstw)a}OD~%fufsq6NX^jUR{+C^MnK69$ zh*M8H<(liR*>mriV@D4Mt-9BD*^cw%lTVy`{`tG_zQ+|;Ubz;cryx_vWpYZqhKltwvhaYj#g%>>Wgf~4Pt0Yrg+igWt_A?^fAE3on(8;-d6R)Y zdH=l;BSwJsEGZ-?Vsu36n{U6m`>uQLf8fE9qengW;=lX%8+hiKvoE>il6T*E_ndRj z+Gd+=0OT*f&3oqG&+W9+ZU-K80069Bz3R##T(&kJb-F)Ydx5lkSxOy$5} zTN3^=HV84F{6CJ00J`AbD8{Vpbg-2zQ;@p=rUo1lpae#A9Cnwl`{)iS9TortXv#mD zP=^xbH`=a#_v=Ky1<_*iYqstzes;r}7w;6Rq=oVSqeetRw(WJFKAoF#5;l(y_5}`G z7Bq{28OYZJ5R_YF0w8JGi~;~i3Pcoa^4X=?Mf6nT%tRRwB@;wxu;s)O1fnOx#(IFevUon|?T7(dPq4?p zOdRHDN8=GjpD{3^knYk?*MI)1<)l5$wnYFS>ied~?(dA-&uSbB-n!K{ZX!BXNGXwp zY;35WalJEe3luhxqBTFReeMLc;Acc(=W@kge<}U=N_NsA1SZ;=5IHuB$0|270GSQ% zA)(g*TY@bS87fed*~&*SkcoE?QW|HCW(Gh@if{^okUHkT4laU1K)}qTwLl>x5FiU< zQf4x7nJfSpP-4nqQW`WGqrH%fLI9z`gvRJmuJ(t7lf=<~%0rTA$O-p##Y84%uxvtm zWjIOv4B_*V9LTuOjg3@k9VO%H}jH27C9up(UG;Es;9 z0Fch40ifg+0pRu5-gxY>r%yWNq_fXEAAu%JnB3StrfJ3H4~QojEBtFOKG z>eP)U_Z`sJbxY}VhKK|TAtV4SUb6VsJ8o-hZJYDRV}phc27oCWZM0_1%CA5FMg|)) zz_8&%x7=d0SKfI2u!Cl0QW9BN>L!u?hqNgaBy?AwgImtb|h3o0TQx zp$U2qJ*T1OhYT!`{Zihs$8R_RgbhquDFPvd>}TpE5*Z(<)=F4TV^cFT6KN1q`^EZ( z`ufHOUS45T+}IgUw;cO6ZHkBuk3uqbz7Vm}rQo zFcK=J;6MmC!q!EmK2FSk3|&K~HFLgDK+%kNR=RJn5wOp0daB(+}?~by?CvVgM2# z9gzV7rM2(-v+V8y5vS+>m8NHV#Z9;Yny6`1s-cmPd(E zGexdne)GS1Kb*`Y48SsZj~Wmi==$ch>~>usGXM-iA|fLJKzFeKOqr|$0G`{u|K9t3 z@X^PaOeUAF{_5*5ZASpW8E2fe%g#GXA&SMq0}nr(vc%V4fA!n1-!t=)B`W~HRo>8H zBab=e==%D)zHR-F`s>k`U3%$~C5xmbeWg!6`Q!~ZoCE-yOq=$=Ll3&eLMoL3Kmisa zN+C&TA%tbwLI}_Eg|IB!(aazO2nj->5NvX9g|Gzz>lwT4zSlnc7E4{Q&P%PPd#PW&=LLn_n$an0}1f-zyH0}7TX+k;a_FI>M~?%5sT)mt=;1lV?(R3=dcD5B=^y_%y{Wmisk!yYBM(3J z*yBF>_|xsT*#ZEC6abLTWq zxMSCycfRQ23p2L!-w)qA^X%E%ZMWSSv(Gr}phNDv|DK(8*?su%Q8RYl<=*=qoG@Y1 zfI)rkyyxyo8&9sTsa>~zos)7b#|roiiX=TE2sD+nID-FJ!4NBtGDR@rca^vFYM6^? zzQ^alHfMxOU>_t60vT-y)cyPGw0M=3u{9EiD2|?m2heYD!`}Cb>K5!?q*r_*YDZx8 z(9CA%RIU51SLAd@PP?=!HF7LjsNHiA;FD^fOCc8DMWl29bl#v{8#PbI5N5so-u zIGgcfq6e3SHig2jY}U&{p@KUT2*2V&VEi9smY|@>meDhks3)0K1`j37a*2j;LLCi? zbz;P-12sY*FrYx7j&EMn1rKv+1;9#SpYe_R-EYiVb}o!nB~ZtG+OC&RknPP zHM!l&Em{HrBnuR_1I8L`;+Rn|`K&bp*{Li5k?&y`iDc}^hyZ9AX~1kEJB1}AfCi8P z8N4EaC8Xv1ZBdq?F@0mMz)!2mmdMNn;cfT8^R1#9z6!&Dd}v z8ZDdjGIGS|I}8wY41}2z4=7K5G1n*8NSPRon}R)BnlM*X9Fbt}oqWw8giVFOB9G;y zT9&hw$UgiZ6kZWASGlUN{Oa=VBnPN$WmjC6cq{b6z>`CQ@yUcawNf$b-HH@@1cI-y z?A9K9rTpSvS{pwHDcoV#lvM?@?Gr$d`~VONx-v$F5LRs{>uZJWG}gbcqD2ungt*#f z*&qiBX!7wPyA0?u>NS=PR^pA}x=M~ydHWKN4$miA77r4}UF(I+lg&=VFa_Un#QVdG zjo(NpD4z%zGneVoVd|5&pw&SW=n1Rm`JU^hGdX55$&-i(WD4z>nza@HeDJ}Cwbixz&fMF!?e%Nh^VM?d##6T3 zeDlx0{&v~26{)mSa^10G$B!91s#GdEw$rDzwXLnhMh{DQbP zPsGeQV%)uU1*114<-5sx&NU@YqyWmwHxfDlQ;T-YK8=W> zj%?ZUveck$(9SV2kOCotyQKxfLU33DAO&`6W)PMTLYTVwW+N6X>!4DjN> z{&D${=ggQe{jJ|Wc~A!vfQ+PZ4e zBrTb^B_u##6xI)atd-f+h{nw7PJei-9FnQK;E^S(J5`^COpT2lUB2h@TVJ*Rv@~_s zd4r}7v8poSs)tr~mt3XI<}k>_Lde!W&ilV;$AXk)F#@q5;t8Xw?|i|VdPb6npBOCSJfGP^l569|h-9%DK+xY_w`VF`ikv=E3tE$W7hZfi=puJVPbtFaLw zmzEl=&Vp~*;+h8*H}$Kz^Tf7s1MG#%yz_9CR%rmVB%rjl=B7r+>Xv^jbZrUERg#6} zD%Gboog?|%;u0a(Wo;qwyKmO^ZLn)owy($%8Zii(wj{A&h4#q)nK_@VTe?P#AC%H0 zKm2jc%90-3FAq|9jH#3q$ch;(R15&J%8~O{l~#AEehn!h^rF?JwcTDi*yo8w;Jsuv zu2h0DZV-_|Nd7_i2MRWou7nIMLFLE)4lxSV1W}e!lUVwJ8WQ{tqiH}eNC058(8O*> zRKx_S40kLlE&RetN#-EeHQ0ldnK5NIZV1fe6}#rX)qd~$xM*SiADdymMKp{B8$bgB zAyDX?7hnsudYQlYtJLtV*>{aq-ZV3p%?V+-o~N~DfWQ9j*sZtS?)E$G`s26XIy={q zCIDz`YG9(0Tg+s058itF`R87sB&9Mb05Ist_xw!8wrl~c0IgxehA`8L6{{WFwo{H} zTjsnagd@|;JaEupL@0E2F|*m$o`~F%VupNGbt;n<#_A#jAR16c03tx7D9~QLdg+<} znEl)%Zn<-5DO za{2s-;bXL>HEY@}OJ*~fnwlyzX;R8;I$bJtcC2mh+oykXQ>)=HLxv8u?A*GJb^s-1 z5QKHX1s7CTS6_eA4cA(ofweQjM$?P;f-BAwKJ`|fq)^*2c=b2U|3 z3d4>Jqvk-cnW11ti9n_@ni2D6hypVEUzGd*+ks`<@kLr3Lx8f#%pE~C_N5}vI2xOCRAb^#o{6>EfHEp0ug;&pA_1dd7V@Fo+_b+VNAUEZh^b#}27 zWK1jof?1#_e*Z>x(|>@KGof37#|i*}1q$W5@4oX^vAg6*$8x0Sxog_jZnD`Ht*x!u zeAS-2?$X`4{((p4w6?YgU@0vKEQNp!h(Ju;>)Q`F-~b_FSz&K zJ9gP^rtf=}?VNeWY4_aoz`b|ezU$1r-R@3Hn5Eqd5Q#Vll#8$gc!@Kl68NYWJOfdz zOZgY(cLbv=HP#9OG7575h^UteR}eI{M_e3Md`!?%#l1aGmMhYUwuDilfdw{HK`}z? zXj$y8Da?CUSQeRR9FJtS-fkHQMBsI^OqoKBT5EPWztIeP(2fk~etv7myN}myeNbxR zp`vbb)#RPmJa?ZIB(tf)!tbir{BF05V-SIl51BzQ81ya>h_!NZ)r;pZc=(|QUwZwm zRcku{v8|zD@nf~pL>e^x`0ckPrN9=R=dsq3apCJcCap&E)?YYOkhMPV1=z|xZd%-1_UAEW$vsAI$vLetF zD(@Kmi1Bz#8kMlB7hV(5ZbAbvF;B@PjlBG5wFL zxpLK*4uz>(@wxEfy&th*F0$3c#+5L=EcqlTUp5?t+V#4GD-I5IjAU=ilieVM(Uk#! z$qP8XF#H`_A`{m~5j7l+S9zFA6vPq^KvKmHE=Mq7SCJJz=!Oo}r!ti*;tX3$H~#{@!B#cMNkW&taf8UeZ}~9MLukh;D?EJ2JYOzeZh&ASFpq0 zf>p~@mqhy$MS7sD5%KIH3S?+$Y?O9t2!zE9FTV8h*wLeg3>o74zHM6z z7cK;VhWdH{AksowCD(IHMJJW^eWjGrN&^Iv-qqtia=dwA}Qsax7~Kx zrI))}4IMm4T2lGS5|W7kfQ-4z6s!@km^0CK%U7J1{27Yei&5$xzoyg{h}8BlhJQ?i|IlM06iCh0B%}6Ixl)8Uq}H z@ggeo#aJL@5GxlL=FCN$e0BK3#4Dq4uP|&6IhIFZK@ua%2-puT+fhU(hp*vi#RqOM zGFwXtruecb*(uof5fF$FF+c*w3Se-0z_N{{A_&q5eT^cTFJzKZ?z!JAtu>G@kQt>` z#C}N!iTm0@E#stKM34lavKWVkirrIv>G&g*x(Vv0SGijd^<@l!DFJxk#IgB zQBW{E8*`*s&Xuzv6Gd0yxr@jl!C|9UN8cN|tmKp2v$ar8gb~LNFhNL}5$T2NqU-^f zc$Oin*vS^j0AwHrKp_Dn8XqW1z$nQ&lpYAo1j3{wVBB%7i=C{zQr)g+*KGDTS<_}t zf_4D_gcCNw24MpLqGVwK3jjt*VPP&50)<3j?6Dz-HT_0J$96i`cP(|>KVI?OUC%!9 z^Y6c*kib~zDwK*PfS~Ty@)gU6Hnp5S>&RNCp3!IW5zsH{b*s9(g3rKYc3wgOAhlxG zB}Y1>bv~WlbFv;;0?fdlpu}J19@AhwbcEQeDwC%NZ(^@aA+Zd;f+bwG1Ho^bh({cF=Z zZrrF9+2Ac~=k{)8ODU9At^$y|Zc}~ij{0`h8YIw#$j|DAhR*7u#hY)28$6;S{Me8CyF2aucHhC#^>U78;in#@-Wy7FsSe& zgVgol76PyVE$UiIYnEDRM+v|%z*B&>1fU>US`8>rSa!=u%VB@r8dij)+3V68SOT!Y ze;n9pghZv((r;43r-O+tX9h-OHE8g_hNh-3=6)rmByx7#e&-!`!1k4^ufFzL-}Njs z`FdJuB`y2XD=)k9qRTG7_|mO+*e+*_Q5#NSr2#-l*;(i&2BjHMcXbtn5b2bKELf3J zz8M$IEQO_&-eR*&vYE_BpMJXS4%(uS#2iV+CF_mmBnyatgVdtIRef#a>jz8Wl79%e@GpEw2u0ogRm6Rd|k^<`+ z>#OortJbXSDsh0vAclC znOxpXmS7;QhYcHc{q@(Me)7q;-Fe&9*IeJ&RCnbySF^M=Aqr`wQv(Lnq1js&v9Y-c z)0xKBRzxv;_{b3>$CwPq<;#~7<3Gbraph`+0 z<@t-gMq9G+&7-leu`%MNn#KTwcGs1@|4^o=`0d>6n3wG>MvJ-)QjKl?x}Q;)jUJd0 zSrghqE&EA#EVNq2Gmxo<%0W#nAY#k0uejps_ul?MO3BR9vKZ*RbI;jhuRXq;`}Lde zzSr8^(&_T#)?eC4KWD=i({5vx|MnYhuU2@^K_<<|wiCf9QTfHWa!O{|$M z+dBKqGrs=n%ZDC+X7G?g>^Y9ZZSFe8biKiDWT-Lq5>+mBF@9ZkBTHU^~y@MG@YZgJFxmXQP0GN=Z6Bs9+ z)v^hWRI)fUDKU5DbP#K-Wpj@RWx%S8IASDa)UQy9Wr%c}vbXe%9*U@=2WbH$3e5F- zZ&E#ux`eDTP_rU!8xyS;AZ)d6nOeQjcBC@yE=zcSe75q=ov_QT+VZcd@%ym$h!lCG zk)08{0otl#VaE$M@o&F%xhw3U+lboXsR5gT^)QhuoD3J&dn>+lnnx4Luu_4ESC?c$ z&vh}Ct$yo`*N!>%Z@>P&aLUw;h7TP|%qv!|zUJmTZn^XBYp%NHfCFba>D;o#iw^(m z(SIyh;CV_Z&$eyl`)AIcJ^PF^Q<==%FTdc3m)~AWYamIF$jKkIA7d+%g#(7i)i! z2Fdlhc;d>7v1(ne5GPwCDvdf7YD%b>RP-)6#pZJvM~I5=C4yGsHdvP2EF&e$G-2UQ)$v( zpVmHrfH`2qCm4GNEM5N-L$jz);2Hx*ikz+IO@TLJCAf zDguy*DD0)@yXkcHp+_G+@#K^La`+LaoO*J;x@PstmHX_sZ+CY=N(lf$+5n)H2@?=t z+?gT4+fw>UdA=qhCNkp6^E@#1^Q5$drL@^(6A^_b^0fj)B1)xF3l}W-^7FYHOxU2U zU;oa|P9d?aZ~t@8JHJ>c-uJ-6e>?8PvE#=8YbGMnL>d6nsT2T|N=2MZrwTK+m2eYCf>Z>;nLl!BPyOR}*1YJy#KeiQi|8V(~ay z)=1V_l)ka> z4toQMGv-7k=`hknJUIE}WUG3xxsZuhw7P7K1cf+b zND_e$G(yG1Ya5-)&`eBNch{axAJOY%q9eSLc>lkpYJB zgU9x7?yG@Fk?-qmCT{Zb9k1+o}m5z@pWqTmRd=_Hbj z`TK!aehVHq_o;p0_`!{NAcl;DUs$m1#C)^kfAm{n)R3&Nc=q7~m)y7fn5*We(y;gRejAKg zk+ul{x7aX!$J=XO`gGN_k^L_@swtQ1zVX?gZ+S+n)9K@84#-+?;y#UwyVqa)%!2D4 z{{y9S)d?f^+q@0{vT1ifYDae*JUTX2Wt$Bjpx;okhg48;pPTmDfJ{=)W6muwhMIpC{)$y5Z#U zlP65L_n}ATe)ZLEyX>-T>8jUWdvnaFkt0Wp{BrJ>5CjYZ0Hhp;fC=mkH=J_wEqA>2 z*4v|wIT`?7e)*+L+SzE*q%|GuJl|{S(<-EV(*0-;dwJtdG{8!$5v$nR* zbA3A{kNx|J3~<1HGbNi;1`hzh_)l1JSkoOC!s>e#nw)4B0HU%qVi^sGND5=o@+VjJ za>R6=kYZ-3u}Q=W@PkP`K}7Hit7y$C;TRuOu#+bP5&!{FaWxPjk?t-c2!W)Q{bZ98 zGMB1uC~A zvb1IqluA|>nV1E$K+o;+=e;GnD6`QX4r}&{;4Ah4aw(`908DD-H{PlhsVd7~y-at^ z7q!DN+k}<{egQPuK)mWFAPrIm=+9(Z5t9Mu41nUM8?XEI_dlL}?zw4Grb;O^k?XqM z-JN^wz3;`BUA)DXn~xkb8h}=;TA52{&N$%6`qJ7os)m?=y6MmtUUbA*>SD_04^7(wWI&Vow`M&3?g?!| z!?)jdn~y&D@69*gp|#p?|9xs3Y5{;igf+$xh{{q<{-^CARE83>$Ym2>7UEDDWL5T< z=$b?jS#MXyR7eonno)#w|Nn&k{?CIU2c(!m*2V z_^={TGV&qrXds>{D4{HP50huYmQ<1sC)Kesoh`brOi@LM0_MUlCWa>HRXmOm2l8UT zaUv!c>T#8P)(Fa|ZGUov_LLrzi-}(esTaPLqb8Pj6B39x?n00h##&X^x9qp?0T*3# z{)3M^deZTKM-;B-3TXlPh3MgtJM zoq+`~Yun0v^6`hOSGRAu)fUpSsn7`kQ>Jcw$L)81|K0c7ZMTDEJHDcPRW)GVKzQ4> zUEgOQ+jgXs%T}yfw|>24Szsy$7@G+I07z*w>t~;Qx^KU>V~#&=_{dQJ(Al}ZW8HcI z!G0lu#%qD^`$9-&Fty&4?*qX22^&21?099sn>IKRv#S+%buUVoaiC{Ym~E z!x#*xKB{Jb3GokHStc?J5sN}Mz|`S~m|TP97m$hVhOJ04y;P&&U|r;=`F>2?P;CLX$Wk7)0r}Y^0=wr`$EYl>)1}P{p!qIXmt3+2pGs#CJX|eqEWmm>6;`ni~6iNuL@CS!& zDicvfNnfN7|~O&im^bY1{7X?2^Lr ze7~i(>Bv0~s?Oy5H}uJ6)7LzD>;13Hx#9S$t~&l)&3;#Rr!6hR;k%2aJ+_#!%O*OP z%4$uPKqTC2lbM^2-E76WRrQ&sevPeynTY?o+Yvr5`uK#1sdjHV!8*oAq#@h#3eGQDETB!z5CQgd#woc%t%DQx2~< zeE3$Mw;yoh@24Cw`0raaWu)KP;ScU#`}!F*&3Ow-UOFYNIjL>#&)rp3_NYO5Rr1<9 zb2fR>hR4q6zp_IQt_SdnNA23W?c}Ou9d0&d4{Xji`%WKGowv#Ji=KPH4z(LiaON*_^I2zu!PyM@Zb?ZCuRn6Y zinV=O>t&T=zjf)zx}5D7ilc_u51rcj>*7*%wLPqF?)Ys}*$lYFuFWP@y>az0OKR}l zmRh|0*#5^XZ&=r*tMZv4Z5dm+!on+$9CYk1g*6>sb3=AWi!InKb-Rb}+V6l}2GnN3 zbv@{HuK<+VGEbHx-Jjymv79ALeW(MPT#lB0oyjW)T5K4N6#5n zo#C$aB`NXLeVcdPv}#4WH?TF+Qfs$&WO7+7lu8njP1X4XHZg&60;Mz|MZr%50YCzT z6(&I^4H?Om5@{NhG{g}SO1vxl95XJCLo&k)01%}RR=7!(6`JQ6D1w5dOP$DU2{i3P zW&zBMOeh?i3M;xkxV>uBu2|haHT@J|!6@8C->v)j6>u!W^o0Ov5**F;ND{#7PAq~L zB>(fDCx83>H>aF-`aSpF-_)n^yYGHnx_Hr{2Od=4(71f@BBhj43K%refd?M=(Wjqo zy7e{|KzE_r_q{K^{z@sOn6%P6?Xbg$(IZ!{TD4;7iW{!Krm?AI$^75EQn6$0I!$az z@Ct>sYgVz=Ldu(Oy6)fu4?Xyh0|yQmkgKYm_shJhOx2~AUE18z(%IQja^2@%cy8X}_4xV1d{xy` zk3aFZOU4NIPjnYUwiqL6HYw-sV5&VbQQk%;+yl% zJ!6A$V}Aej*TI7ZTyg1@HR`0l&z zy!@(bv-zCX+VyfCr9r( zB?cDoAY{)V6AnVDbg2W1Zltywe#!yjA%DqRnaPKtozG93+41rNRt8fewgQwOP}->o z1Vojw!K5~KuLz2z#ugzAeTpz@^f&{_0O4QPUhkJmXPr5FtF5-o4D z0N6sNoYdGcqgq>AlC2v&aPTJ|y{EMT0L!**+aA!?@1O$@Z0p-rDwPnCSRvxt?ryZi zNAJ8hW$GsT?Y7IA=U>p&+~gID#!D%MK*U21JUE?BTd6crh!g=*j;%_rV_TMO3n?$S z;DQS-zVLzj@4xZd8@~MXJ0a+jOD>$b_so1Y|L~lL0Km2_3Y1%_5LgwHivY2IJ!uLl zKiTV?R-EkRD6{e;Ph<46j7Ecp_r{L?kE4tm_Oj40`HN$1wd}or!cr68V)m&a&kkU?wbU zu$kBhJ;jhK+;jwhgZhf`n-j|~$zm{mV)Fh9UX@h85+}<8`J!l`at~ISEdeW@i~$>{ zJbD7m|8+!>B|WJRgN7y5JM+`DK4EIu3IRw)FX^ zqYqDKt2)|OpLgDQ%T}(~qPj*{768~%dd1?>CCl<@r{uZ}0+g4s9jCSiSP>B;f+oum zmTe;^tezZL6_|mPwj6%;-!C*YHVzy-8~|*~QeJ8QefGTPt~<^?=e(xI=7SEJl@a!H z|M~Z8ufKWHi6;ylJgBk0;i)H|-f@Q=M~)tO>utB+e&?Oc;G|OkOu#})A;W=ULbQ}} zmn~hsdgTfL`1zN4=bm%!>eZ`j8tY6dYgN9Qh<^R$SKGGNy6x3iT~l3c+qNlAwCA3C zKJny}=bm%^&_RR8PnuLJbYF1ZIdi}G?3P<@u`G+2^EFivMc6Shf@Rx6+5m`1@4x@P zZP`0)x1A|<%oNmq5K^)xQa%Ha*367Tm~Bo*jv9H`;RjxR*_Bsbe(A~on7v^B{M&E4 zW6qq%hYcMPsqvaLBA9(+A&_py6^fCW8_EOYLk5!wl#3_|$*gzg&{k{CbModM?3l}z zSHk#IenfAJS7BHv6d{98H5(T(C`);Rk^$|apw{v4T%v>fVy(-l5AD9No&Ls!>Nix z&%$9ZFNw{e6vD7)Nf;Z7h4}IiXGWhAkAfaYOc>$w%o9VKAq3%T7?w}75UgMyhOiKI zLUJb_o6wyY0G*uWaD7# z{$o*Tt#pl(QcS+$=6oF!xt^cNWDD;4TOYZ_s!v^Z{DpN;wZL7(8uKz&ovz7BStu4s zkpOABLz-(cHA13Nnt@TG)+AZO?ealhuYRFw6K?o6iGsaZk*D1R+eQf6BopZa4 zwyR{Rv!JAqDS;E(EJdUhYo!}&^8i2L0eMKNx6ExRZ%%HRuh{Qa+ucMiLMa1kWZ+M^7@YWO} zDbH0JgoTLEn1w#oY1dcCFsjwknl+*8s>T}8TAKr8?YaHxg~z0c1;Xfl7P0hv* z<%Ae)3}LF@3uYt~q!?4RnN5xpnOXo3x)yM5FoJNJhh+y3>Yg`WrVxNpfT>P~2*K9l zQUZX{QOydM2tYbtRdesX_x$JIPrmf>YaMIX>^@`qjyuiRa*M45(59PByXo4?2M!tl zL|XfY9(qVkP3Fay-^f?x_t|@|`M=K3E!u(%;uAREkp$8wf;l#;) zv3sYTw(r;4GGgdJ_C1jDFNYnv;ly$E4K=`e_=vI3J@?Fg_dodIe?NWu-FN%;X?^MC z7lsZQ0RTXB=4q!cS-upBgyXQH&W?`i>KXuzfJ}-=U3uB1!-ov~@|$nB*=);GPdjPJ zf+Zt|4;9k7;DWQ}Jo4Cr`M-@BH|~kY9-s5*qhEjbtrRVP{mWmbO_|ivxBrumJ@&*? zPki^o_ZuC!_kjlPouAz5 zt#{u`4eo#bd1q|B&5po4XvompZ@uxgmtPq*cGRwW?YjFeJAL-ecb0AKvg1xur)|cd zY-u4PBmC`ef7^49J<$?U2t?te(w1$zuB$a!mL#o!bZeishUPwIXDTK}1R#wPs~QA7+C8t(l-BZ_+N39yMW3GJCWIn@g^PA6;b;Hx!p4l*DTbWAB0h1Y+7>PUu0Du}~u$6cu z+q42m;Di8kV4(Ujp%8#@)|sb2^W-zT?6k|CyY2Sdg5Q7r_{Tz5cWYB0VMze!-+#b> z0RuUR=EtgRCYR0GmS7^^S3*c>SpZ=mZSXoUfvzJ*jZI}!&27yu{^!L$>6VKxyL9rT ziK|vF|7z}B)9qoyMtt@8=O-M0!ppC{QJu}-dh5M+-S^0a7hSN?lua}N09<#?H8)*< z{e$=2z0dv!DsQbcMpa-4lh8v&Dw>-l1%zlOIbY!kOt6r$?-Opw|3wBdIKT+Xgn0u7 zT?B8ctUwh#y&TO2Gu1M^hvR_1Rw%2GD{{z5}*hOm0Qs)M3V@L2*g5atxr4sA0Pbp^NlA@oxJhJ zwbj*{b?5r-6)RSJ`^{G;o^VogTOX|zAp#&VIgVplc0Ol{jk4C1M$49tueIInwzM>* zGb!yWHsOH)ihO2nZS6N;;DFA;`X7Jzk(rgJ06nVEOW8Kptyf*lA5V0_-BHEfw_;LLiJW z;{Sh{qzV&N&+p5gP-ccI*AvRA%gk=1L;W8Ce!aXjR3j=3UrDeSuex3c_)j0*qYeP{ zFw7-!29}=)-v<{=}D)@7v12Cp^OmkmTXAqg{5 z`J5#NA`Wp3ze=im$u=hNJSToLfWV$(6^DR?G=lLJad=<&Y!2@U^~MDB5BXU%`Qa5< z{!}ot7Rx|3cZJ)~B>819*r9zP$;Ok!6@Q9?X@aJd-4!(~i35^bJ z3W=m^>RKMS_x2M`KIQbY&ba!z>uPH9Yu2{AuAa2vxLtPIA?>69VCCvnZmBeV`|WKZ z5J3vb%9}8D+@nuE-qO+Fd zLT~SFi2tE_AL~{`OmMPu*yv z;bTU1b$3}pFa+!=<=D1mTWB#8AS%!AShaF(O+7HBQ>hb;YRti?uxXvsw@EwVvCh?cPYksJ^h zSFpw85tCBb}*?xI6-k(%74fU=t|0waIz;P8< zAH%RpWt3?UaX_QabGY`+ADm3oH@ysTaKs^#eve34nYTu@%wi#yn4sunoUfP|RrBWZ zU|3F+)eG%89GV?5pt^Di9=#?hUIQ~&xi>DvnBlLU^4ORFIhF>P6d9GWC(+9UJFBEF zjJ$n8CjcM}hfa`kA{jZjB7S7THk||u7&G}YDHsj`06@Hfqe&?S07e_oY()|>Y>fG7 z;Ef5|L#b%PCN3t+a;FstYJs zGbvYLU|L60L)jzEOoj#(Gbx1u{Q>!Yocj=BiAeDFB(q+z%>VY{hLl~7vcj16;F^fY zIPpoyqOa|gJ$v7g5_PBRvk-*93<>Q&NC z;N9s>Mw#)i2sJ9>6BS@7Zjuz?dhJ1i3?PM-V;R`VBL>MJfC-&!YLg?K$p-y=4+PagD zKQ5C_0m_=HtXC>&#VLqQJ}1?tpZZ+`i`;V$DKK5ba$bY$z-$X z6l;%^JAT5%apN|W0)Tu#vHA3^H`{t^DS*6EO?}hh#~e3v*1(Av1kfS}*NLHz~}4GAJq3=0rg2jR({^4$VTNsPp# z6`R^4RW-G3ecQI)e3OR8Mu5=H918=C965n?ETR>F5TyZxY@))K&D53AS_#0LAo3P5C?nIn;;0UbKRiz0Oj7?=PVqyvD!#LSE$fPT{KkAfX*+kgM*=j(60?mw@+ar99~pK;ddD^@N4 z>tB!4zPE0DS3aLJ+v&QVYe{S6$`wC+KX0QcliJ(ceczXk1O^mh)yh@hefxENZH=^S zGR+M)a7$V8ybI2mG5kOJ@LJ|NRfxb;gWIlQ(4T2_XYuQ|>(k5TPX`s+J!) z&Jr*il7J-Pt~5X=l!(c&xP(Y7Gx1>$b`*FR!aoB7X5a`!VuB`;txq71*j5-Ty}-$! ziUd8zj%SVw=afOc1d($*Fcn86ifsc^nGFlYKs*71*9pMP3P=e7OyNEf$Y>!bMH&Gm zFoSlP6ow_8*^pl}mZnySFlC~pNTmT_<1M!N=)dnj{P5!+{rBV5D^}-nnLbU8(eIKbxnJFp;YWzvu5;|G5rP(0H!TB-|XUx&mA#h zgk_=jONhv%0l@P-1i13b%Qo3`Q(yUW9)IG*)hDwbt3{>ehaJt7@vh`}*s9 z?z($z``U9J{O2aqHr;EF-3~nDkjpN(aL*aL2w`V(`AaUnqG;3_}~E2!)>WS_!0j%w`4ruQ0d9Y6?e08@#u-IIm=r%f9YS z;#M5Jw6mOBCS&5Tw_9R556{PjISj`vejLV&s1mG3prUMth2EQ;SZ4+g(Vwi1Sd-wg z_my#ZNUCtr8H{g&AfYN;=^PSGVv)y+Yr;!e{?5RejzJJhuW%h9EY=SY>exZ}M~IDs zXpEToRrZ|ANFm}a915%0))o_D7&8}BTtW#;MC~O~Svh)O{My8a-ocRUTdH>xvKKta;Td=x?eG4buU-jvBz=W}UN$`S%l zk^qwoLYh*k%$n6p|M=sNLk~Kzy1I(B2P~wWa*L&rBga1e*kiB1^zz3af6T067cN-5!;ah4 z)KqV~?RF2}d*`&xw*&wtwdGdZJ@v%1Z@ls9Pe1+A)Y!D$4m(bqG|9FFkY8Ps|JT2+ zN~Lq4eF;R$tFNg(|J<|I7fRJNH6MQT!IH(x{&vi9LP}OXrZP+vE*wl}oOC{?iA%-e zfPwuUdhotnHm`iw_r2z(rmL^HcBdV-`*QBr&CSg_?zDX>mHTGyS8aWonOIm(RaM@$ z?3(J@Bo)ORvP@+Ob+Kq61*WhB?F0r0Lo7xgisV`RoR|;+p$Dn`|8ayZN{I3R7!ydz ztbsH}nplW7LMFy>{92?EB^C=uV-bcYm6^hm_P_*yh&f%j(u`&qFI5vs9&=ze?l-f@ zeMJB)Eh%D_QZ^Zh(qm=zZ?<-O$oDJF|_(rtWZWo!QomC^PCv~1OtKuB<)FQ|7Eu$CvPxq#i})^Ae+gJ zA3kniQ(v!GvQVHYQkAG7Qr579OydC9G3scIgl=Nf-Eep3K%xZVxe^{lGA(O@SEt@2x z?RA12Tgsyjh-k7!v@>mJ2T!Q+p%)-t`=)Clu?4)`q=SNBW@L=0hNAG}AYdLs?g0b{ zF?_(#rdxqk!#!vq%(pks#%SYmV-Aj_M}jXU)m26mz=6Xa69OYSwaIzLvXx{8Ct#JP z=ft3UGLlf;s5mOJRH9pwVh|G#372;dGD8WdU=dLc!d%INzmjK+){Dn%GHI=uGYpn zzf|(NIzfOXK(GQGSFu3N5+#AwgutXd-x5$)SM!g5%-vbXkoXO^DYU_oNh=Mq% z+l0(g0Fw`-jjkbqOT~gMQVq5BTKit1XbVQvq}i5Mb8QuArIqKqT`6Iwt8;)z+Gipu zQF*>C?YgRJLi9Wzg^-L0!mQbq;}f+5h<`#=DVmf=*kSrb5h*VL&~ADZ)URlXXS zEXz(Zy8v(*?hp`PVsGCBc^Z6QLArsNKS9-%6x!q4gl{gUAPknTz>xN1O@x^NWTu|e z4tJMWpn*8Z1PsjRlhDGZKYpOQj?E1kk*aNmd0)$^JK3AhhC+w8W|d)+fy^<^XJQnL zsTu$R*37J#h*_WjCfj!2edFbG&OU$fqQ&bvy05w6>V5ayzow?TrKRPJ*{5$jZR+{w zUXaVzn%#tmw3SLSe8W^0Kh_6yl7#+0fTni zeYb{&CScvSZwnR4vTe%}LWtdW-+kYG_V(SPR?3pn)Uw88;C}+KaUh=K=`if?|Hu=J zfIuR?vE05Fzb2te2FNYMk|Dc~pjf#`0SLCODtks*6M8!;uZ&}`%=pL27V$ttN4NkG z07Mj~5@E~aD`dKs1rV_!WCSL#ghU(B*Qg7?$c)Uu7P5A!xE`1|)r=@)N)SnuIbh~O z2l+k`2ttpMGtGbk7)+@P2oM}H01DaBzVgejze_pkrl!XIXC1KfZoB%Pr?8jrq&j%$@APTHs9ia{r4R;W;lCAlX`9{=>)?cRB#jta*2mK z8tICU;n`?9VjvpKX>ZgT0+WO&?P++3z<3W@=;hj8TV+mF{Hu6e&!&|#!-|-=-VKiB zM{-wI?s<=SDpU@oA+F$j^wpmvoF*_1ifB=my&`&K@}>~BM(YO?=Yu9g6fV-!Fc{nw zsH&0v8p^kxBN~fG2<&okB2RQ40+b()O_<3QG8s%5A1e4nf{5ZyhI9g99|M&GBZB0h zWzpa#zDN#ZXollNo8u9~viAo9k;Ct}+&q|gEF0wj%g&X*9Lof2=rBplM*xZgP908l z%;6K4#p@-o9XpjuIl;@wC*tYb?HuW2Y_@YCVkV#xYb6mG zn0#-yJ@#M#(uzqTS^y*gSumi`iV*R|7hWcm6Q@i=L{bW+WCkgOa!U<$_4^-m@Qgk8 z2Bzw&EHL>cmsrEW4q=pV3Idu5Q zLa~r?94RdzMaoCuOeVeM^z8vydnI7h#OX|Sr#<#UM%%JJ`}Fgs#^xC_W&n_FTgF$( zS_42`Lqq$TwI6=)?v$yMHF>s^-*u0Dh?LTv1kzryu_iz3z=L<)b3ey%QjWz$Lq?1u zQpEJ*H{V@$>6MKQjZ>#gQod(dR+Qoz#3#g48?IeW&Te9z1Z0GfB8Rc5D5<$bSC_4J zhU9{)JTT<=A(ssPPm*(z1QV}f0AQ`aP!vF1f--4kjL4cR9umAgjNpniW(qJ$ypSS} z5+L9((j{hW!8Q=AL!J_-n@kLdqzSYV(qbt9QD(A$2+Cy&Jj4*S9{@lA=&86RF+L4Qk}xPB(j&;w2-G;3 zJ9PP-@psogZ$#` z2?%H?RL{b56>zOLAlBmyh84sZ0A#};SzSk6>kuhyv;ahAWD;mq0TT+gbf@mhQrAlN z#}~4rb^(ndUBg;Hyw1?L2-r^BeI^3{041Fp<`Bq=eA0x#Xg1A6Kt^V50!$2LN+Fn( zsf-~618IRQ0NPqw1%M?$c_k)g5^oWJi2xZ;n$2*{(?CdrSP*~-wC`oJ*~9xmbRwanr7Q}AmnrF*LJK}xnk*(Wh<60DHMvn@4LRINCVN% zJI~mD`{^mi@qGn|mTmjKKVjm;-xe->@4ffue)Xj#arLS-M;vj)$)}!DRb8`k#mav# zc%fJ*0zkk10}eav@T;%BX56^(ecIZ(y9)E>{WSZGvk-CF(#1sNI1T`4B3nvEjbOZA zWy8uG^OXN#Jniun10)qu4524*JJV5G!n#X`ukn#?*@u)+lH4!BZnQ zXr+eP%Yl&~OPJ)!n^^XckjMgbfl230@DL_oN>%scl%=&ML?)1eK>Mmor3oxn`AQvf*kS2(DwR%orK0C~g<=r^ND%|n z)z?*5S2Iznq4C1=FWPy>8K<3o`l+X$-mk6yv(G-c-S#^IfNcw<{FyWNI_j8Xi=Atf zU$TTTuZV~Tl|!K9d~oFym7#zHAtV4!Y+LR*|D3Q(#h@iQ{kFzb4G_%asGeU)XRF?jGMtR0;sxqRULSC4(Vl*6f8-WP$_)5dnD;WiBH;*CXvqDFq@h8Cc@GC4p8Z<@idO zxkVJFvjC`xNV$NRvK=P&m1q3102&xr6#{w0f)Sa8a{XLBzkJ1#S6_K~(2${h2K4ia z1=~(*B1DuzGU*+*-|2w;_CMvc(?0*~i)*gAy1Kr;*j<#iL;`^}1r>MA&MgnT#CRSYwEs zd~YIXFAA!PE@K8ZMN|Zk2F8F5G6QKLZE(_{eP)u zAR_n>#F3$p(X>NQ!MkiPFVg~o*wT?8GECY;LMn*|poerzO8O*R>m7j^LJ5d5c|J0# zhaxU%1cZ1bDpi~?8b8>!1Ej?iZq-6oWzS4w@|d&`2n^DgTQmZhB99!I z8zhhvAr2J?WEl>EkuAZzP=JU8jqwto5GX>LkLM7>!4HMDF~9}k@Rl^E2uw5B?8pJZ zu3!Mh63V1Ogq#WiVz*ehILy;UEEJ7vCRksF)e-^#Api>2#JT_|!rheuu^xC>m;fn^ zI7rYVN8BmmJs5o%K(I1dUJ0?1Uqx#z3A^G8k|H<(+sz1=+Eu9`8+HA-Ftn>jN)1`4 z1wi#CyQQjz6n=b}y4~!I6R__l=*aHRZzR{1DFg(GU{dRlfqiyb`pVjYtXu$Pz+2VzlUU9|uKm4RT50HJ|*CaO>GxEa^K04{tQyj-)W+@~QX${#- zrm?AE;>7V+TzcuY+izP{ohy}!8;;-b;tMYvGGt(}(5;n1X<5j=@=iJJ^dpb@YoSm` zrPF=-^!en2|Btl)4z#PN`p4n5X7=8v-G0+6>75jk009D_gpNoDLAr`G6$C}PQUxgr zf?YuY3sO`BQHu0lLWfY3kbe6)yUeWLA5-@1ea?-~_kH*CNY345%9>R^v(}oKrz=gR zv7?4Jw+*@WnrmBI+qRlC9sn5U-~86M7A~Ck_Xqy5dew#@ot>9`|Kc5&?i_~Uk{y@6 z_2wHLZ7l%6I0ME_&X=*nj+>tvsWoFi^guTDqC%>eQ-cZ)Q`D)gbn${Q?vx80X+(hP zjNBAJSWuTKt^uOScL7p{bhMzWno@SP65w1+!$?S};o=$+vDYyc+lI;YpMlRfktYRj zDHUffk=^U5c?uv9QZja{qm`qQME8C6^f-wg#f}@Bt+~n#yHf%q}o?)YHyxD zZ-MXoBS(&$J9o~rPd>G5*)E-(!$?X*jG`zg6sAm>GGVI`L9r+a2-I#(3pogrP_yRF_u%4#fOdbCuQGJKh#q%byS-N>Px3* zb){k|-Zmp*3vM|uU?MHhLN|@0to3y@zHWjAX3n(Lan3u6p3;V-GKscqU7_<$+5z`r z=2==#s-x0mSp6T*=$Mm1$ZXgPT&w`U+J|Df6UbREJ94C0<1NA6CZ`sy$9*EGZ!%g_AU#S6k0W zmGE!KqaCRd)LuG}@-zUb!gMAis2!jcVuP=L{c95^P8ibG3~|U%?GT{`2|Z*)f|5uT z#+aVCGh~va6d?d|MC1%)0tR2IP1ZGY=$&SfNJ=RrNF?;R2PEuL1_VGLAtI0n$Tj0J zsh2vb&@_+`GJ!;S3>EkQ0=0dHnM4ulbJYZhh$DXEv{NTcngW2FGsZX)SDHu)F>J)} z>uHpsHrDIALy@M_G;5s36mLB9I9Pp+?rME^*bJ zqiW20E4P#Cm&5-INPc5frSHgL8xlX zQfuFcq!9`oQf8TqxjauB766m5=a$|0GHHYLO#vhSgd_lfWTG<^?D!B-95TPPGX0C| zpT3u&Cj=n^NeLi;dmwvyp8QE++HQXHIJW)SeD3k!m3W~QK=wTT1K89R6u2NF;-sb) zlu(RKv-StCKw+;jnl98#jk?om$JK9K)o3z34S|p&6OyJ(n+6PJtp-x0K2!aU%6c+s zvqa=1U5P{@L&mrys)Zp4!5Dd-2Sf@2MPUuq?qTX1DUqR$!;xC-j7cm=O744T_H$6X z(UEpO;ph@&pfK{Uw`tL04W)&T?*80bdU(>*zvo3=vL)LM-cL0$aM6Z`=7qD z|M^F_kL01MSt1~T#~36~oU$vcw384(0tiuiLKy+0L?W^F_Ktzx?(MhVcJF|d!Bjz+1|ds z(W6GSwKj7EL{uAZ0su%F+R-**_;3JR@!D(O``&jSefZIVfqw3>_8~*Io;UxLlTTT= z-L^ssAZl)I2Ev64wmIyILn_T3mY$s*?S(>7r9P2#4H4I8W1v+tc0EI8c-?;~&uXq+ z9^@jIC7loJ6PJycImRQe{_OIqEP%F*(LhVu*o*m~{*6po))%CEW@ZzJh${Uy_l;iL zAqf&zXf99QWnj&1en8BlctEr+IIeZ+w`E*qg?98ye*2W6$2yZZv3m*@r z91zUkj%$qJPmc2FO#F0xiZKKjGbxJPS@h+@EHPFUydmT z(-%xAIb#THbJ8?@$MI>sRqA+aJ1fnUhc--|F2u?A&v{Dj(An^|+Av11XOIdVxQwZP zp#l)jJj@A+yUD6|+EC(A}Vh|#b0AL(RCIiPFe>`VE zajfH;rfZ1gX(NPoIh?K!fur6XTJtqaM@;9CIsjS?6Hi5)%n}mA(gYp@vqVKP4+0U8 zKt*D+qyqpz?M{&rTaOI`K#&O1^O;P-j<&WVj{Y*^2ua9&AAor&hLj+pVZ(=?^tIEX zu*x7|GAacIQyLNU^tRIiNFYN%CPg@AP91BJoOfdQi4>fBBn5gwP$~dG9K~uk`Z!8}d4)eR>n^Z11qUpRf%tjW`7kd$#8`hHMoYL;;n*7`lp5kMrdBq}zw0zx>@2T8;|4~UW| z@(QJ(xd}uPReL?I*2Ahb@2>Yng5$O@JZ7Ggl@V9YToH3|s^(@hucxe6E)@Z)x6)4C zV2rp0*+vw!QbQXhGiKDx)@(DZYaSSIqiM|c{)X*zUs9dw8q9h;WrW*&O-_rgf^>|H zZTS|V5~f|VUpn<LGJ?0B}>tter?9mU)zRT@xEqU1)QT(ni`$ z^oDb=LEUp&J!^%Al+NqisXTyExA(T17Jj>Rd2G0bKyI1z55GN|6Y?s1Se=a0J0P=cvxyBm&NPsksx9fv{FZa*1kFE)0lz-u-*WsI!7m3jw%{)^1Q_NShF@(*|Zsa$Cy z5RCDzuHMf+{`m9HKmY0}rvgAC1OPH-LhCA(f}~Nom^wMl$l0ZAdFZQG^J@K`gVLEL zR$z>}=3|5JQ?4*JE@wy_4eZ$8y6qLfw7HJK)caW%L|VAz+)N6RHAeZS0H~9U>#DZ8 z9YjLB(6R8C{%3y8n9o5Fhq!l5LITUfgp8?g6{4h|BnH-tfz^H>Hr;(@%f6dS6ZYWE zqp8;4{nBk+5B?Cs0b&6Xh=5wRKaug0j6~- za`?z$ZS8H`^TUDKy3apvZf^PRch5WVq!Ww9f+X?~*Kgcd4QpTf>enwg|Dr-r5R&4! zCStkr!}rFI9hD>!83#m(To9AUL|pR%@QGb|>1EG6`|K}&{i{8e@6o%tJ4uotC@owx z_l1|9N@NTG;l^u3OdB?AsztTMi?(g+Xjh{+WXO>J{Oh5x8r7=m$Oy&}33-aK zj8~!FI^;aKdU*&sW2jRu4T!L42kT292asj0jTvMF$NQW%sE*@uc+Kk4T*iH-KlL`B zQYdSy%am-(arErq{x~qq@7Z=|{cn`MlKrSrNiGltqZZu9_02SLt&xYFrKfLY2%x%O zFK#(>gSycTTj^l4tZhXi35hWxsEV)*fVq#z)RXPGZMlsArbDXAQX|eR_99Cvn+oi% z>m&DToxEepHjyX`esqeFSwD!nKE@c41nF+cgIW2>1T0fp>rxsK($bRhgKSn-Qc5mI zwCsbtjJP#tFEajZjmaf*dTHOE!k_bRa%#dUv0f^aM*wZR)5A2@= zV3ACUI}L(1U__5`ij*4lGb22JsNtPNDA!*#N6nyLO==Z|L;y*N1X6o)OO06# z2`CN$FyPFF-wc%*=>b*q=aeNGAW7rqmYo+h9z#<;(Dzt7eIS5C}o4plkjJTH9t-gblX?h_kqy!yjrb>j0Xk3Rt?LQ(&wMA-MD_;n6cwp zJBF`a_0gKuYetV9Gh}FIUw>7K=+)O=d-JXLrKCiJ{nhB4bHB|!CZZ&&)hg}72L^gx zc;<;|lP9$g8JR@=QYJvM*wg}mn>Vko_Vtb$JrY=u)M8-9>4*Rz0U44cU_qhOw`u*V z)vL!%7+0#aNfCB$?)G@l)Y7tU{pS=X!$*xFAQ6WEUZJTH^>2RT^=Bte8eeK3G0@Wm zloZR&%rAWW-rEB`J=3O7V=Zk-Z@1cdkpSabR45dJQghFy^?g0PLx&F!Dy>P>|LQ9* zPM$ci($XG9A@@A)`F%Y-t5$zHderEqmNt?CL{cmS0PyzPZ^yOjoO$yBAPQ>$P^dJ6 zsJ-;uvm=KOA31(vwZ8`$MAcdp%eJAz-hcP)b!*mazr&8mxrifPDg!02z4B6LN6YAO zlL1J?QL$74fY)DtW#ouqLxzq@;`p7n-unG*cYOWSlP|yg${+~7bkxxwf4p+oh~Yp| zCSg;hIgV?uzV_=)-&4DiVR+PY`_xB-jpaeJF_E>v zc>z;y02As!V?xn=8BL|&{OwFXxi(MwtaobMcdFr_ynrc1X$WUtXMsCyD^Yo!zW)SVD8N#Pe4}AU(D-U5oAOR^H5Sv%}43V2WDkMxK$0X^ej{Qz& zEu&?%*X$l{Rvy^J_Vr!JoAJ~p>JKc?MBp5e)IQ;oYn2W~+}c#ef>-bgd7_hi`>holH*KD?^}LqmrZB8}-18VyI!=<(f)=Qg)_z8n zWRJ^m2Hz2ktZ>%-Ya62PI&x%39f2#8~i%NbRYJj6ecmft%Wn6`@uHz z=RW)7GqqY35IOfyt>y**L@8vcT>0>W_wT&p&qGEI|M^dEojPr5k|a?Q`#iYm)|)Q7 z`1=q4>)+F-&rm^$FiBReUfnrj#N@WNN~Hyfnwu)?K40D6-dP`EI$t{o2i4q%q!fkG3!3Nd7QX(dS71Q_Uw_s-_-p7!<*1Xe0l)YTz|reCyp68`mjTfD3(i>SREZh5B$RZ)22-U0M0#NOh@5T z+ndpCxp8sFFs}>^2Pp<=yzD8Z`oysx21=$-JQEA{jGdHAJCS&dz0d=PE`Yr)dDn%v%95Q24 z*Xi7JpuS_8$i_S&sMS{tIdW2FCJ}1ud51FA_ShS#=gz^E*@&V83lS|4b?r4dih+TO zZ<+lzT_k70e|iX+?gb&B=P^b|QX(>gpa4M2J_^vF99do&D)6MeE?{(L7I)jDRMGvc z;fzO#C)JCEWq>S@womh87Y_COv(fSk+~Z) znW?d%x&7s85{DQjsAOwRqdi*jXT9-GKkdI{T9=`*3yxBjG629GQ*cNG>bN{oyBi<_ zDG<@*^_f*s2qc6AQv5@PD+vhnp2PJChXCqmFrS0j<|d_x>84TBsSA!=t6uNkb^56D zRC5dMH6>7!WJ_qkP6a7P^8ZUBvFSA$51~;#`m8i_C-vc?0**pR?w33s#3Df{%z1*A zsYu2l3rbz<*PZpPZ$I|rQ>B0t;7vFGc*gW;Cmws^>1Uj}e4qW$^M3l%pZxowhkta# zkNf(&&p+>yDN`mr@#y2lQt9WvzV+H`ufOfLx0Rd9eZ74rfAy5JzkSyAH{9^+-`-X# zR1QD<=w-X?eDlpWTzl>HpMCPlcfb4HQDev5ckew{Tz=)ou1zwIzjE@|PXERkK~TQs zrW-%{WOW!;A9~>5Jw1K9EZgbgOD>!;b$YGZ&pA(X7G#2mev#k)n_pdV*|h_`eZ{82 z_b$EQOGkd`mYaV1pMO6-W7g!yAA4-wnhi%DapZXyUeMOr#*qE__TOE6(ZyXGx`vJz zdch^6&Y<-hT0tKi_-zQ%^m4+SgC-+1$gCjyd7j^Dn$Gj-vbTyXS)QFN~rPfKLC`H_kZq zw3~l&!@nMSWZpLO?)uXoy4H2?y4x;4y!N_Lqel{nfBx<7=U;Te>Q!qzgd>kR`l_q1 z?Ca~l_nv!hyz$oEmhXPsA8zYf-?hUIOK$zeFUOA`^VaJtzV`L6ee%g_k;L0GFtqsNRHErj^=qYuA+ z`e~CVPJZj%w?6#nQzqm&=bU@OiO0lY5{0#szjDey{`L?jEkCvFYRh9!!;vX@}D$ z(wSRUaKR|iI_s4Bi5gv5ilsWogdQ9;n5y~))wuPgn8BDKvKkkxfiWaBB{ghdnsRL7 zp((*=u#aq8)$9!$5+z;!pXsqPEjPpLrZiX=p6NiHg>v6?CXsGmzyV6B$$PFs0@-$Bfhm;Zw{hB`~$MoMcE_hzhynMC&)r(#O{6a#04*1LT_JAV1-} zVBnSrDQ4xV`?f7TxaXn2c*Bb#k$}J?AV^Ncc)-F z@3YT5`=(oeym-mbIF5p1>C~^Byvxo@4?5&fAtVqK3dQeVeEDIA95iF*Y(z?AQmRzm z`{2V*KK^Xpyt!?ytpk01h358auf6{1C!YG{Z+_E0d-gl;y!FPLZ}s=}1%;qgDXm|- zv9qJ|z%L&7n_u7lm%IOb+wHe+x7~J^U3%I2wHq$I?E6E84N0PyaSo}rAwskv5_G2h zDQnuUrZa<-TOGv&dCZ4kqht<4XR=Rn>It&yJEQN&_;4}RqW}AH6ma7S^B`!dKJ4l& z)R8CzS4*ukjyV7V29hKzPCBG{>D>d5{I%R(6k+5sk_1E?fOymwt$ZnwKnxgxA29Ga zlHQ9)oej-=OhPCPZ)sY38u%rM27qw@1iK%iY6c-ni6l4lbbb8EC(~!n+Ofy12)3R#i+SZaThF=r>T9GR-{%Z5CsdA<40rweK=V@6}#~71D9qr96 z&B4acS4$BM=^SFe>RSIf0K`dT$yEs0`0?W|z2LmZeF!^%{_m=&+|C<0ss$@gW8@PkRx)= z1+sE;Q)^Rc&FWPjel#SCs|*+k8I+46j=H)w7R$vriVMZ^i!VI?^pj6+vv|ArR=zuG z^k^U=2}u%<969u=E5F~?-a#Vv3IR!pCajV*abRK@RY%!(oh!q@ zd3&7S{d^GicX_IgZA>_B5Xsq+A{~5X*8hC2;tc3!8)klQ>6}+00z}NnEM{Ow zz7u*~wZU`hU1Oh>;4sev@Jw8a)c)iu?aLf7Wa`UnepOBm^Egun&*h@UsPAzO94PBJG@|wnpl<9rjoDsiKhL z6msj=%M&!~ku;xbWr#KxLgjbsgF90`Pv;kIW9?|0{Z*X_vQ4>zv={k_pXmkV*7n$^ zTgHq|B4^e&mtPWZEpE0zrSTdm)LdC+s}STiBI1}E0#)NQ7T*TDyA9d+)4V zw0K^j(kzlhX$f^y9!Noq`<#FM^lv=#^z#>g|DvrXPWZ!bZ(F}^{pc}c9)0SWLytOw z`5qvDeZ`wkJ^g$X#eIF@Lk~aP)6;$UQAf_5H!n%x&G+6v?1&@w-f!PK?zr=^%deQT z^{jpNJ>a2#J@WL^&m3{+VFw&^U~@~`gAY8^-{0TfIdsMAubqCzne*o@xa^86UU~KP zYp%JPd3g4>&l#wS>#o0H+0tFEy87zPy*(Fv@BCl<{Fhf>dyU75WDLj!ApsL%Txn@} z{+Xw)xcsW^cG~68Ll1uDzyED(YC~ijHf{dbqYqD*JpQU{e)QHG?_71&56Q!8ufP7j zd;j{q^DjB%(8HE2-RTd%`^`m{UOIchqK>wXlTJGMg_mBw`uc0bP`>ucE1P<|kp}{O zM9*V#aWx=FTdpg zJwd|0r#GK>;d!ydU;O$PAHKhG^{1aR=C56|`ot4YUb6GD{r27WgLmG#{D+rqHD>(2 zU)b;RD=xd>+;is6ee1}>4nN|kFKsnpt6HsEs#KnT?)g_=dHvjT&Ka}Sn1BE4@o$}d z*0iZpc3QUcsi&UyuZJJ~(G6ENH@97R<+aD3^p*cU{^)-nd-RmkPv3v<{l9eF(I33? z-oQW~5FrX6iJ65Q3_yTXmLfesh)5C%Gy;(UI`tBeGBs$qBMV(~;)agAIF{XLHPpGI zdA9_bGnTZpQ>wqLD+CFFfz1wg(!?_=!Hsh?(wpc&4C_3~zM+l2>-x$;65V+V4H5HD z$G)fEaGPqhXd}IzB^osx2iqK7f+c9KjdpyTn$i|I0YKaGx`;0tlvdYFlX_ksf6SmL zcbIZ*B)uppt6kkScgpVv8Ix>tGR!llV|HC%4(V&|rd&CQ?)j`~v967F!-{o6k`Mei zao}u>5;NO>q>i$j=%mGD_wI1lU1vOjY2@3GHn-1+!5ox+(17U(KnM{1w%QX z(6B{41x$CWUsHPs>ac*d(FWdFkR`PPl0Zs{;EU)x=bYQz(l&P71d+r9uxaC_+wZ(< z(zK}pFcuPoY^s#kb@lcP45$Og6H#M+`OZ84c-I|&`okT+A3AJ==;;N3k3ahCA@&aRCn6C-%-nkG(@+2A4m&S7`j}%m zXSTg&A2|Xfb53-=djM9#%yM)U*{_Z+pz9&SHw|F3QnHQopb=qr6$hFkUE-T& z=Z1UBSH?^YHa&F&%&0>`0F**4Wd%YY0mwk=72*H_g(R=gzQ=Xps*j>~UoW*5M3Qg- zP;Uhua8&Df8AAkNCN@kU5i#cTIA-Jzw0+@59JVzj2_mXEG6CxB5Ubu004WRyq9}az z<(E%B{-jdD_dSm>Bq`h5TH~;G{ZDV%ZpjXnas|}Uza*1bNJ>ZwA}R!|+BX2?5i$VI z83V=$83J(T%OvU;I^qWxU2@*{E;#6mU!1Vj_~uHJ1X#ae!<%oubL^2veDQz-q)Y@! zfMoN=jURvf$+y3CPE(~Kr9_4;%`NYL@NN`E1N}7skR-X@tOwMAE%gj%CbjyHbfg?b zX#>s;dFuZ%`1WgbCn)*R2bZwc5d_Klk41oGXLOoP2PNW)122^C99_d0W@ zItY}+{_sUZ54>*OZD#@%S-=DdM3q#eR}G_0MvxK<0R~JGA^}P1c_4a#S77Mj*LlOH z$uKmjC8-)mAO?v(&j&>uh39?u+v_*1KkMwXuf6X2w$>H^3Zv-rwQGkC>Ad)&^E)~^ zY<6T{Uw4wkmtS_-FMshXKmZ0D8326v-UqX0Y#j>%V1yiyAxZ`)J%$Lr&uZ2F)oa%u zbM!H#a+ye~d6Zx9H+OX%eZ&#pzwC;p<|ZWR`9Al9fBfSgufO)X?|F=KkTQ{?si{)% z{Jr+t`^;~BbLg<4BJQ_aa5zJj{ikkpGx`qEeV35(FAQ?kr+k`H8qe%pPD8|cG}NF5 zr(uI2y+&8=MHgPE-#NfB_~k*Shlsf*Ir_JO^37Q2v}Jis;dW4eW=9gu;zUFwBnw(kaNyG04WmzlxS;?`g_%0Mv(N>L=Ct) zyBt7e%%cQp^4K^B0Eh^{LnsuH6A}aFgG{`(k>xpu@kx6JtUr0}Pkqn)rBL>zNVFVK z82|wQ07*naRAiyKH20vk#m8aqr~Uu@PV&iztmqL5leBCQknwgIN-~3%$qbzX!v-_H znV)38wfC|Ks74jmUzqu~9`W0!REO_Ux0xA`dbf}DArqKQe$31WbTURA$V`_VlZ&Ks z$T_`3W)Ft6zp2?W666p#(?RE>JnpYg2R2APtuHghP=cj-m7IP600`X+a~irMC5mWi zu-fgXo?m1-Ur&i_>#}cQrZ!FZ{IQGVs*K!K=ZClD)y3KJr7BWvNiC)gH7_y!U(6(v zS_#nsXbFHI6G1%a-njAG=X~$^=bkzAu*1K7?m11BibxVNvLi%XC^x_BZF;JB>H&t4jn;B!Ja!@D+M;?9TNhh8J0DZlEH{X2o zupvVLpim5cf9D@ota$wk2Yzw(tQjAD@ZM>seSPcs^8mo}u)U+bR4(0i`|ZV`@Pi** zI(yEXU3Xpf?mH`P{l%}2IO>>@qecXt|D|J&`NBb80D$}Mz2}V;uSeD1z~@m|14OkM zrX;}_i^F)sy7m2ieS7V_e6PKi$5Bi~%;U3X&N=`53&)Nhw|vjNKK|r`e?Rh{)vMRs zbKiY!!#Xef;gtZ;-qCW{!G}EY-zUe98~^uzK6vAgZ#eFRlL27U#!Y|}MG^B0dUsF6 zmZs)2Pe1+OLk%OCHWFmdAYz4mzH&A0Bn^UlK$KB&KMVAJOHd+oL7 zUVH5cM2U!+TAPNC7`|i7c{PUj%qWFdzZ)j?1Ub^!x z8#ZqG$xm)N^UTwmTAPcd;`tYzzj)j20pR|B{Qaq?oz3`X^KQHD3IK5& z-T%Np-d*|8-yit)$T4H&@?HM+!2LJha?8Po9dg>~r%szR?pMFP?aFJf`Pnai_3g9H zJms`Ah^VEddEe!GpLY6bjPvEY?{)WI@A~t-_ii;|!tJ;J;nE*me9W=O1HkApqqf^& z=e29r+;H7bo7*~mc-=L_Mvj2J_Uh^B^)MnSc)CB8f{jA&OQ-}`yXGWFp$@mO8oFK- ziBeYum{P3H002x?x&!64>&;QN&MV~pVU0H`Ax2QK4$OJ(2#gU`zB$__{lf}YI)O~J zQrag+%Vo6#nXHSPy>L^mXx3*{y-m&Gf(^njBE9N80I&?jwZ_ z5Fk6@Lg!bV6Od9aRWU@zAegTVCuKR;EyUc#%*-jR)(pD+f6cN+Xej%-+ikKN7^GCR z4apcIE5n&>G%T`A8CE)>UiFH34~dcpntKXT0I%^TL0D$Vb_`3CpA`|r8$m}8D@ZE1<3T7O@^ zUnnroC(v7x0pOZdYd`yRjSvFVaX|p(QmM7IH7FDSVE_FOm^XhLkTNI)|9$kai!Qlj z=?N$Jflo*s9UUWvkKmjieDJ})`R(s+z2z6ncHLw2=#fbra>jLd9{`*zIRa@Nc{ zNgdQ+1I-o=TQ+Xwl(yVbch5XP`=#566lA7NF?1(wNg8N|?65epjIJtxY?^Fcql~*b zEfd@Z8p~zJTE~o;p%;*dczNuw!+*8;_T!=tUN5v(2qlSx0Rbh1fFP}aApigqz$9_t ze$+3LLNer_pZYV7mJ$&JFm(n!I=d&UqdC+}UQV4f@zhgKDVED&97na9l(OI#Dy0eu zK|*%4cgi@7lSE1))Duu;?+^hQ+hNJ}P0j6crgmz`j@iqa-?VHS=c$WH<*xKGnawvS({xiLA(0Hj^1S1Q40Nsg%O!jOyb2~l zCPJzO?D~vZM77eNgw*SM7~_5*d-|Z{4?Ftj#pwr#S`|sU`HaTAk<}o`k&r;k#p(Og6T1`Ow#?sRU8 zzBxrDFO7(%H~%kJ0~em{N8R7fo|HCpmWKWe*AhbtgE6zb(kLc2qv%7%NrH^SxNl?9 zy$P7l3I!$;MS0SyiBh9sHvgz^0%`g(ARt1iQ|HL{APUJJH??E8Zxu$*tG@cX&G%j= zx;B9qkQ7oaX$2yc7HUTVHHajGjKCmEO?d)95Va_Z`Z$4KEMUORw($%Y0Wtt}3>_4v zZ0C>PgJFb#$Qdx7VE~K~5=j9d31TAPVQ=!ubK;|yD5}K?kpv!r*EYIi@o{X#Y=FLS z^?$ktsso;2tjI$0n@5+%EQIQ~TB(U75^_RHH=$FTylanx-9T(hNyjj#yqFirWR&MV zbI+em(HfeeX;3Eupx#i)d8*)ymK@BnS{*-Hrla&_(t~E-K|;ewSPLaD6 zlZJ{&zyMM2PM*f@kW6l@l!TsF?eG8RfBw6E%}0+s{_LrzN6k%TB7w+}p*mrhA-?p= zYpmeUo)}1mk?{=+OWWhGA24(@W1jchU_v zboXo&5^4hjL7^z648u4mloBZ=NrsGjJd7fc;^PlLoHlLxR$EPoqA&;w`|i8nop;^+ z*4uCSzTeT_F>c&gDJ3GdG&Qa5?Fqv$C^iESM?#bc#C(jx{`m{H`TiB(zvf5RZ8d(v zUVHC*&e`9XIC*kUPw$W+L&lCB8`i?05X_xD`;mV={M>WT_Vv}?c;k)byYEqpYnwK1 zTEDp~3))2=)36320OS9hsg0+LY_sa@5I#gdGprb=beqJ;o3Ffg!g!-lS| zO-CGYR3ei~rMzOro1L9Qnp#?~y!xth&N*w=%<0Q^-Q%>coj!f`)Nr6b2nwS{jOZWe zFO|v*wpk#geD&p*KmGW#88c=ywKQ+uxUr?JZQp(N{q1ePUHRdMO@%T?HfPo>Aw++F ze`{-N;0J(s{sk9&^XzZUoHujMoUPCJ>X|$3w&NQs-XNeuk2tcgzt8u*ci(zv^7JVr zsTc$Y9(?$YJMa49E6@Mr`kT)F_PN7`kJ@wZJ;OL2HgbrNqPu&2b92Xnd2?TS>AB}# zc!3!F{FlGF?GJYr$_36mnS`HzzUr0N-`H*0vi2dJ{eAt3AVyN4I(pfh{9-v%>lvBR zGz1RQ=FziptD~N{7!780xP^(C40HlBoiuAijcTCOQ%6cX)!Bs(9@BwJyI9|-rfjyB zg)dHc1EmyFO73}D<7W{zX1+xr5TIv;QtFd*0Wf!L1OTEl1!$;wz`T^bmxfPFZeI2x zJ0dA+vhxvL(_r7Ze;XW>H6oTmmIB&+s!rm3TiCsgiR_d4m2T+MCR(&?OsP4}?{;9(ZN+n}T{03H)88xp(#Pln* zvzF`AqznZ&5CB~R3kt_#3N_Q(3<^wNMaZp_-a?K_YK+bI_7|a!*eVvtpe%zY5QyR$ z@0{In*bUzBn+Be^75hcd93bPMPlt-Oik$3qV^dtR)kzgPs5mC%J|K%@#J9q1?=WIPYNg}^cES5?? z{n^im=%rU)IqR%5uKCe*!-fv~lq)C&f zOqs$MGRFV*xBEtp7;*3+hp1y-*R5T5#~=Q%-~Rj0pFjVYBab}ojI*A3`k8|cISAG1 zOaSU!QM))790i@hTb5`JxHiJ6vIDHtX(eYlT*;VnqNTJK~^M~CM*4|1536(<&tA+r5+-Y5Ps*@9Y_7T`|sbYzWfir z)WnKKAW4#e6bM4O$OusYNAL(a#4PFVp%LST9B@fx?lF=8DbWjf0WduX-Zq6X52Z+E z&YX48g%=h|0aNRZh&;wT&WXVD0!TuNLyqWi1O(!$i@Kdac<~P|3xc4zrA$(A&Iy?{ z-T+LJM8;>#+`l|yHWK+4RsnP@xMg3LI7*HY;dH4~BG4A_?0s#ss5kU$_ zl9&+$K9g}ZV1TJ_(Q0ESODuz%QwyL;Y9=4<$ZD{W71oU4<{-V3{+p3}^-OVass$`` zXcYBwE_Cm!bn0AiFV9gLz@WQUSF7<{^o}f?LNNP8xn0QEH+4_SL^N%G3IxSX_gx%! zb@8Sk;RPWPKzKrWOfUeFNQ@yOL&h1hn8Kc3Z^VSo11~GiID*0|0wCky5Y8c+veCc+ z2q_Mu${o<6OwuUf0sq@+@@*xb?zfHF=9iE*_~PAuJJ*By4+nfty4QAAP*8P!5R z@Pfc6B8H3*I4TbVSN8pjhaP!=l#JPpj6jJZG6_-&b?hO|n;yiEQb&EccVEV_j~^+UYv0 zlm;cWFCaIkh16Ao8RdosYuZ1|e+IoWe4fL&&ZRTv21_7RAfPT4MPtG2n_FrPWKfa0 zvO!uz7RR!4=W~h^cLdpoNfiJ{f)p{uVY2q^&5vJ|totkoN(?0s7{`(kMAKZomIgGw zQn5Y)l~aR6APA+}GXxSK!WbC%yxhUdL$K7AND_n`I7uRu1SIV-=|D_F6;wdarGyfA z$v6Q+iHs2q8^edr4U!tJep&Wy#(=990ZKq*h*HYLZ)#p}M9Y%XNJPkdM4NUFz*=*$i>-)g_0RUm0k$+3+JHd;brYB$tV zvR~#T+mHopsNN-Cw&#RqLnz36O}RoTv)akMjGTe{x=YAZbvmuETGkm~YCxtfMiu^l zyWEVJI^0;#7YIb#SA$B7sC-1DSROW8fny;^O6h^Hyu-P+Zk{`xn+DVHm85=T)aNf1#i zNDvD+kHTp2wu?{s`q$TfzNSzrjufySfo;^R0_keP^tJH z2LR@KlBhZ`pyai0U|_<;iRYbn-skJq63LGCw((nS#W_FhutUd=8TG(}fB)Sd{`}F( z5C8a=J2>M}SQ{9qCQ=GNj^a4*y&*$}6oV2_7XZW}5lMm^J?^!%v?50!8WHobw<` z5-BJW0th^hr`=YsGt>nmamEl)O2R|}a?j(55F}-0Hi+hHqh_sNAwxH7uH3w|x@d21 z0Uo+4(PjeZ|51Jlk*Z$pxlG5zcmN@zZop0~qA2E!bFR-TbkwpXBO;=dLP+6p&rN9o zaEw4^hGU_oLlO%`DJ?kLeXxeh;vR4Y$arHjq{9ZkQopUOTUqF=HE~UlL;1msf=+lJ zqzh@aDG{vCqLC8;?f(-2F$|dC}IpeKVaMgWRd_9DWj0$Sa{%#o!!3O38i@l z@uu-q>jpqI1x(dS>ITG=z;2bf2J6mdu$_5<41v;+fq6eugmy>Eg!_fQ&7VK_!i!%% z>PwY!a}virJzY0kckOMr-+t|nu9-b!=3z%2UMe+Tb>&q=LW(5teXdTU0wRJ)ggw1| zh)hbUOXtYAo}c#i^f1oa+uLus^`}4j(e>B<@Q1T!&jEmzmZpJfc=;7ST)%$f#LFh` zxyP;@9W5_D_sqeE9KbzJaRN*&-dE8%4P{+#C1!f<{vb^hC4#w7xSA8W`o^Rp6XjVY zI|FpfLH7;I=9;Tf0wc+GmODdgxe;{bqU1O~*X ziV+Br5eX4V?(s@fQ>Cd106->5wMPoUIAbVCN&qVP0U%HmGC+pXRHgK@E;2>)WQz|HbFQAMh1x<@i^4i9BKYmlsTmKPZ1VPdBJmd(>%mt7UfsCUh zjARj-mmJl!$s-^NuVK9#~<}(76gi-=XE`*eYmew7=T9|tj^nKF(_Y1<;AM=|k zBCH`w1mGxC&E4{8S;Yc`yl@G86Y7GmGbPp z{fWC~Xdg85iThV3?yv6jcdwRRYXCVQAPSugfhMI*50b`70A$ujNaewI*u~-6bo6t& z&((=3CP*)q?kZqlN$Tv$EJ!im)*l6hHaMHAUZxi)#KvYkf5+5q zN8G)gPY`l{rRs}JK-zLjJz&+k*;ry=?gAyI2#G=kc^Ts;9Cy_I`|Ueocq@`1AvrQh zKtuu%5e3QJcG0PH z#pQ3l@y1R&?F0aK|Mjm!J31CETzKF8_Z7<}rsw<+1VOP_QRBvqkCM1p zDwzNP6pBH)sR;l+T)A@c)M?YEP1|SxgQm}z_TnqAY`^W2TWU$`0BEkX^!D_1v^6tC&b*I4`m|hWDp#7`eq+TWk3ROjbI)6_ z&HUC<<@2@c&pq#a)sYSBR<*Wu?6%9&zuxq`?7WtZ`{+=iRX$n=lgvano!Sue zjom^(}AM$3ZSezyLV_0B8C*JZ7rQ zQk~QykFXzu*3#Br^2aVJfAW0z;WM?*UaM_>p9VI97y#tVZ}!?J1fymbC+-kT-mx%z zJ^{#R02x=#3J0s9VmB9LIKu=6?-Xj>3UA-hOx9f(49m0APro=X34>KY=etpG??oFFpJK7Ub<>0Gni$-He03azN2C8??AURB* z4!s^o1yj+0LY8H0<$5sT7B?fwp_p5*hDA0?ZH3s(3>&dtUK9p14};5$(>2F)l*QEu zpq(F}u)Hfk`n(a6N;feQ#9Jmb?{;o5b!qs2Vx`}|q0M%)Kgv3CIB#up^$t4c~0Ov+c8ElOJD1jIO5>j02 zLu8C|1TcGf>&QAH5=cbk97zfh#{iOuR1ba50i<4BNhIRPLUjT_wUSB67-Pto<5pk} z{MOm@XtR4E?Ll_1&=Nomm3qU~-kBhd{lwArscA3|F!%CcSC#=AJu(&K-e{C9nzcS? zrfF$=8((BnfL))stzD7>egH*HhJJDC7kJ0i;>?E!Ry@%E;ZxMpCx!L#0wD+=Sf#Tx zbC;(12bQNSXQg2>4iN-!<3a_nTe{kI7{(`sSwJPWkxZfxNGFyvWFBJ-rJiH}5Hd-T zZnW|<8P$xM5T-Ar^|y(?0!X0~nhXNa|4$Z}DVZe_an@+spNI?@a@TSxmE;Z&xgR2> zxiWTy&3-0iR4CYeAM3&onbD)X#YdeGYs_oiT4?|xRBjE(jJLhAx-{?MZSb@1N|9x% z=&cfTo9;f!HZjkzUPGXOCJ02jNJjwciu<4N0#j8%nQ>Npp#!>79diO<7fA__M6cd1 zHonh_9jv+Co3sx$jVz4by?u|k2rA`$oYgMb8?EL6ObmkbQBq&sLC7PO8b>|@SBg z(3rwpih-jtQ-E$N1V>`Qa4qI*$okx^=%cQk^89W?KIFKbOpHQFv$jS#`0ff1rJFdU z?Y8w8eTONyKszUL)s^EB(uyOMe9Baus{^x7uzmp2P`Q#N%CyjoI=Vzi3&1Ru$@y;@ z=&XZ)>4h%UQoC+iT^~YgP>ci6owv}@b%Se{hIC1v=3!wzLl6`fy2&A!9cD^9=0F){ zR4|#w>U0f6lu^y&!RV2lBB~LA%16^3LSSA%ac$(d$>06%x3B!+bsINq+-l6&zubNI z>8GB2(pSGeXYQOUuDEi=tFL)Jd+LcNg%oiVA&GVC)>Zqfs$EN$>~L%It!I4W8{041 z?!}j0+^}JTAOe7G7cc(#FMf685l8N^e2rOiP_$ia8zVY^(@4x;2r59h^+SdM+ zlTLo^skYE2@x=oV{>MN5xp2FACm#2ep5Cq(Uwr=PqmJHXw_OfB z=#c4i=FFTn{fVdkJAK-;5yOWGL4AF_U;gqj6DEvb`ThrwKKkE_&;4FgQ_~>_AN1hg z|GxJ=yYIj6{?9%4?4yr8{)gLdLk2w?*KgdkNv9lwdThExe z;@!7=@P7CE+b+1^yhk4S_pW>FvGbB0UU}`6)^hXhfB1FKRFNV{p;a1pK!YgNZI&)2 zb@6oLH2y)9Nxi(}ek!LC2{Ua_87NYk|4<6iwLcC4B}ply3Y7tXl!5>_svI{dC3%b! zNdgd(gh-lNT5kEnk6(E0rSE+G{7GXbtn1$l1ioY*V;ng$AR#3Q04n%?P%Pg6<%dVrIr@2zz6!e*REc@^{9EL9eC=9mSH`;y(+ui_k7Rel*R%euSyV|2|#9IVxDJk zkpp$K)H~A$hwKDGXb-0SFXPN6F4);B8BB=)1Tu^gA*5=q&p9IY)cSt=_rGsHZ_)UX zL*ghY20loNg;4V-l_bjn5-C4k{mBzAy}a|HCG9QE3=x6iI1xf9t>b%~Go~VQWLs{K zxufMBb)P{E7D<8`mj>;yxqvB}bz!>&5_X{7 zRv8bK03;=e1Q<6t{Spv? z(g2-SNRFjct+W!PJ<(`=cqs@}uNpvvPXBZ#(Euhz5HwJR03{J;e9gM`aU8d`w|Sl~ zNiN@GuU&W9^S}eXP$~Owzqw-fU3YtW`4g+wd_HaJv|^#i)p|p~a#Q7+A71&+Tkp)9 zH|L7We=uvtl=<_wQQ8X)Q~l&8*WZ5ooo~JV*4f`Y>%8;7S1OkW2Kvh7rmz+^H8mZ4 z$U!q^%m~98APyTg?9&fF*|c$UYe$S)+l#`l*WzC z5CM>J#vCTFl9Jl*yr;3zsA*>)kd?|zKhhsc(v?oj4_`LmWUZw;hS_=zHB`0EbF>vX zybjs%sO!yO%&$Jmr68pZwmr*9TUr+(Bjnk->MB>i)N%nCiT>DYo7TGB)wtxY-9xvo-Y$XzyN{z`n@7lrpzp~cJzJl5=LuDR8^OF!n}~M zC80{QN5tZgfCvP55c}2q&X5sA-Mz9>@TV;1O~bvgD_r$9_VpGjt^TBK zdHWPJyb zz`0*wK>!p+A3PVo@m$d4SElUBnnp;Fm`Li`kbL}7?X#EVKn;=zC(H!^kb(%L6p}oZ z%kL!f5*l_(mxt!Zo*J;KEB6jNWR1PU8+n6o%E)q2CPTq!gmeaBk-1e$E_QJ2f`L5t zp^fk$x&C`{v5Vb~M_1(vsWa(y`Pf;Clp>34KivhgroxOZz|?A3`dhO`x#@~EZKh*x za8IS3p`}2E9nl%7J9ml8*Mvj|o{v9L3 zZ;dsddr_v!jJ~GyX0Bx*rR|{G1O2brI8fsAu@&x88BibEiF4Gi&Ay04bAXx8=*PyZXwz?)vj*t5zL+&=;mpp1AG&IY7y- zJMVnSdFMXz_X2?u=?dt^Vs8$Yin!k z+O&Dx*sfC z%$JVZVW*vjjv9IY{eS(V#~&vYFPJ~)*c*PhXz`-%uI@NV7R_HUb;6WaUwe7a z-Itwl=9!~MbkzF0k3R8u>B~R;`Tkd4eTjMg;YS|xvM-Csl z?>>7M3ci#?$WmO14wI@J8L3lHluAkSSoNy@l$Za9@T8F%$_RsgA=RZoq>mKVZY3f~ zQmT_D$gPwClSG9e;LMBTP)G>?f#(r`1R_bk=Xo9%LNew{DTS2HAh8N?=yer(Uay^ zutiEDpi;5W+S&?&dIx%i5WeR()Xhq*I%v-E&bUb0p}qc)TQm znkpa!NwT>^p#7^vHgSz4wY9b|?yDDidb(PgTO^7res#-Fe=u(Dl<@%2H!$D@yrodF z<Hf| zGWF@!+A6rSDgvqE;I8w_X^Csv^xVOPiInPNV<^cSAZ}i&XLL8BuIDlis;v(e+3x2+ zjWrZ$bG5lgl9+olWB1YG4P9~FG*c1DxoHX3z%T&-Fvh?-=4{qXek4se3lR{BA&{iF z3dmT{5)5rE44qlucM=K71OS=wGXR3#iy1Q;H#!Vt1MO&7!9+K+NTDHuFmOfj1!c|@ z(eQ^rd$gDmK6OH+=lk6AYGLij!@dNFkNoH1>#w`v!<8S77(IOMtgRpX=fD2@*c0p5 zZ7!6&C<%+DrUxIm_uJ=O@ZIlx`|u+UJLagvzkbTsZ@TH01>4L|qyQ3%oN*LSo-*;8 ztFPK|>CON^Qh1&Z03sILD|Ywv3L%mt4uS$n6OT~sGzYCWRwE9lHJlcu9767RqahqP zI9YR1U7DP6{}_U%&&g8QeHqi4m`NOMd>LSv_96v7*`2?(=p|2eDw#qvNDa*awP31J z{I7H;rZ5W`h=>4?RlK1yyrDB-3Q$s&qK3%9D>LTlB1A;O?0%(erPUsa%@oHO-+da~ zQfW8FZBG_NrxOvhIZ3+lO1}^w5=qdh&navsNdU-DItX7gkBVwZP@Y|4W}U53IXVr2 zSu5pCG}5KTPMWED%C6M1p|SpG>-AIT!ni6fr>rt*4VEAdhp5(JrUBD&Y9(zp{#Yu zWB?=}_tC4cLMtF60GWh9q>}vI#+W|oT*?$OnO$SkDpM&*H)~T%icC%kApl6d4ov4` z8a(G%7R^i6a%(mQX#^qDV+&!7l|fBx1b{T}87v>$)uU)++L}a6M9j%b!RIpbzlEV!G*WiIWp%s(StqEnQqEvF>wOC``pa;KTXwjf6^ zkXiAhI;`bT%)IZ_V;dv7b*(^b+}nKVF27shwSSY9IszbTJqUnEqJnZnki;F$5wp5jj5_M657AI6I(rT_((%wuj$7R;+!g|A8NdAFn7(oLAcZ z*kH^&3ff3WSzR~q>Rmlg{a%J4^UI8+s8%a8c5GR4Tw&y77E}uBR>T`VgP;QdI7f^m zFu!H#*Mk}Rv7UDa{`-sYqc;fw+9$LvJCluCfIV*yJpSu=jQU?(5;d7h!|L&%HFBM_vH?1{B<{fe$*>S^q+L-svY61XAr;LUN0l>OgZT5m5Z|0#2 zcmSF_bp$j32$@eLi^bxxC!M_C7Z2>~>mNUUJOGNQws5;0uA4Taw{KwVn30skVYTK5 z$hm*cch5siD6SD<;Q7a%c=GOh?Ms}E88M>P-v=@hwf@$Y@+n_G<(T77@O;1Ivty6@ zG9r|VL0s*gI(^nvS6%h~$Dg*fwGQhX3M5I0?RQwR!;U)v5=ns|zj)BW-1lF8;hDeQ zbDtjsr9z2F0I;yyJ7&zN0}nppobO$@VdIAW{@U>2!-|D~h&+U$ZLKGra8ldQp(K+b zLx;s-zl`E)wRi6P1vgxG)2FLeH8(eRc6K6BwK~wz-hS5E=N@zH@lhg1j2P}A3v1P% z{p#1g$4SZ^m+rLF&N~4TkzkyQBpN?{!nN1j`0o4f6$<|7kz+j1lX3ODi!a%@VO?); ze@A<3OIv4cpw})iBd*3g1_w@~FYwsL3GV0r0>)E_`$rlFmkO)YIQ?2}Tj z-PAGpR0hq;MWgW49w!#gs#je3*y827U!2#CXn~nOsL2D6Bol-s0wSsXb3{@donz+Y zz8~~g`-xGxSn?!Fl73K-08tbL0Vf9iamXYHf^wl!0QhX^2@HuP-ffaP*|Q-9Y#U;IydOUJy4Gcl%GSo1w!YjL~XP8OG@*v}=Vp-m%_*-O() z&w+@f6pS(MbI&W7RmLQQtc5ia8G~eW2@w!SELJMdzx~F8Pdx!b?6A#tOBXEo;Ny31 zx%ZyF0RH&sgYUfi*6ayWcbLBbP(J_WTQ9x#dS4hX+>=dPv5yqJ1GAp3=#RsSC@BOuPyv{53rea)uRp_4^VfT(s|)LR6rd3C+Lb_-0W zl#P==8p|l^sd(K}MAUO8y^yxPxH^MtcFh2pP!ek?HcJl>BoP2IwGm7fK!I!i9kA$1 zOKJr*7|R~6o}Ge#D{tvvF5=WtIhC@cymG|!h8D85xs`LK78@eN{{H@Askm;#=hJ6S zJN&4_qgt56B1w|Yq3!qH|BvpT{vas*<<8$6d)!y|UB1UzXML-4$dDVZ`_T!*i|z(D_JpL{yd*RPVH5Mfi- zrk18+xm*Hi=gE*xD+e85=V|KKw$EJt&p?s%d#odRW|Ri0HU&Jn3qfu0M%akgvLGp6 zX7<&=FxdaRP?5qp?7j}Op#hDWHVlD)M3rJf<^lJRm$+9_Uyu+)0*Dw8FmCop&1*SB zlzeL(N||M-;Kan;0nB#7q(vKLpQ#a1n@)qvO#@Ilowcl6KUqe2a_R7hkayu&mkYQ{ zdh-7^pgpR1zm>t%`OsLEfzH9pSUb%jF1M+F%<^fYK8+qgtv1cTIQ3_0%R2c|ue3XZ z%eBpYb1-RiK6M=wt_lAp;~56!uDF$bA+JVMVi>fg}>K+5k@N3#iFNri@G- zc?@9wHXSkPG3lE2EPaevtCFR1%H?F$nWPwj)_Q86aR^cqO!+-A^5(*J+w#m{nRzLJz>&6WQMoXKxvM*=kcGo+4k0x{pt_H@ z*jKk#?)||&aJa>U8tQn!njADQxZz?Ook^pkjWgyfk;%EE-IiG+f_m|{T2Kufixp_{ zSyKxn0J0Y#P_MFBc*WtRvGcKc1TGzmyu^wv0O0wew_4+4=QSPlqhPCLZX*g~7gDLY z>)*fTNti@&Fl$-+7k(Iw-39;vWMTNiAnB8}J_2B#4V6<<5Uz#t*utD+TLJqYyC(i@m1F@c zazvzrL?TKvwr}3;92C{~{YQIOJm629UzxfWAGNsDJTzYWX8#ip$wUAEP>c|x&Hn){ z%gl^2qN|$Il^$Riz*R0rJO;DL4SCLCfXrvcBxU~AKU0P7+%!Drpgj9>eS;j8o#OJW zWlmF09EhY5fnMpEQE-kza+;vbj*FiZVH>msa(kt_gtY5MvSqu;f_2@?WUpmRS2hfm z7HmT&jdYtUtvSn;R%tCv-N#wem@zo2gXA_WV_~f_HFcz_wGJLNxH2ZT&g7?PFaOBG zl3Z@0R>Y~zGL0Z|n?xzCQzp0RnE(L5lyA=1a7F+`T*R?N*4a6aE zjROHm6q1xa=TWT&+#5D@7yw8iqNL_|UcvK8NANN=i4s71IiIJQ#WdbCzsPZabY-NXHV8l`001e0 zq`j0mLA%WyLLz0!FK$@7{wH_*WVao6-*@|c5)jwld2>YJ3HyF|Xv>g09{S@4t5+U# z(9sV)_Ru@4-vf`o_5iRzPrvG0ryqSPFW`%Byl}wMegE^?qaSZx*&cVC`h(N=U$XDl z4n6tlSD(D~&%f-6`ih>v|I&RAUVgZj_#^}aU<8mzCO8rlnBUUW^u(Lb{p{Xf)lhc# z_skhT`8$W7*<5TXCHRg&X~`2uVMoAn-r=Wc813_*Gwj z)$@3i$Rv)24(UAWn>9$z4FX=ZoJ+v`b94O{>a0ZpZz_b`kr|G z)u5^T`kQZct=$m#rCk;-yyxMEfAojH&Y3c0Q%}!t?|b;-Gfz2a>EgdX{@*`8`802- z{ORuxE}A@T+2Tb{z4ZJyufLg?Fg+%yTB)rlz?_Ci5vWm6i>FsajB@hF~K{q=!lsA`McrX$cag zInM>bod2vH?2wIti!zN_xuYVfBf01RjW(I!l5EeBa;Sar>()UM-bMB91-ZXN&<*b93vvpRK<5!b`t!;6dAMx1?Aq zazrV`VTT<&ZTh4Mlg1@+SS$t`*MGid^{VZ*S=iapCgRAF0SN%9;YlFr%2Y=uD;l`$ zk-h{O(AJo@(tH*@q786TdN+gRoOUVImlt`+41QgAv=b_y#MJO|+$i<$816+xeR^sB z9hFFgpibyh%M}oj0W)cxGSM_-wlRjev`Y;&pQfaDxYdEi8J^X{>Cn&23kb-DXASaB zOK~k{9%PcOTEkqj51kaoJRDXlDeYPt%y{C!5gbLz9CS4|slh;+muyN5X4MX4|8(`L zLr+M1k?Cy~jp%zij)&Rz2G`WK*NyN3KnvZmvp(#{?REDkPfe_z;Q$( z0+;=eq1nHe)Tl|*z6@YcYA-hjaU4yGC}}!!sy#Bk67v?JHD}qLq-NfZk}?C1!T@k1 zznCf{>E!F8)!%irLdeWmDQ$lvrIJpv+y|}zWq#B}y$~`pPCXL#qm10y8AN?EfTUe? z((w9!4K^SEs<2kJBC9h@3-!9GRBp4nl(D=8(T+LSCym-(Y@vyR3p_MTmU7uj4P7SJ zR@&VFwds)nK2`hTjWLDmQOf3d%e>YRKmz1u**^gN-LlrhD?@o@ILKP{!zUyO@!B6m zxVd@%OMVo9$3gEJ;Ym&s5QrEN zmqJQb@P?1_hKvj5995Wg6fnQ`;;(DZ-rl_IC_dxF^1QG5t)u#%{Y~Gyk788itOznm zV#Ht=A|#vM?|JCj-iQ8Om^dt%^RJdeuEau<*FJ?s|3pX#fTSc6))cETaBKnU(Pv8W zAQ;T#j&q*%bK{FZYEK7?VFzWNhDgsobPl=9nYZ+}t1+A>4O*>=Obakw%?ck;syEy> z0sh~FG$k&i;KP(>TZgU!cbY}1mCaq&1Pvy1|8J_KuH?oK8Wvg)0y0ls6F!)aKHXzM z-6Es-GmB~+|L`EH#O2ce(I?72$R`P=3me?(^xx7#y&SZ2-%2rz!*^K#2wLgsyaL7; zLn)$K1SAm|;|v&bDMhs}5eZ|6k^~5393%4ffEwZ}yY4Z2_Dqo^wQ7&YnI9BY zEYS0PDIx0XQGCyRPo0Y3GcIcVNsW+mk9o)#>gk1bp4&;dS}gYz)jvTl9tQ|J>_ZJJTAw&s_ zVyX#Af$x2==A-NHzNuU+oxabBE7yMX)4%`nC-?vQ;-k(HNt|}X!kScs>y&CE_)@14 zjSeBRG{ZbBmrK(ojUT8*LQs^5IEvdlntjhBvipIXY%ByK@;oj9{_xgn5g+wD$2{9utJr(b=;HNU)b z*KOy2VcD|v)q#5+dGylLzcpdlh}LrPw)^f~RgM09`L~B6Jn;BqmB151=m8xxpqAIS zTS9pMe_T1nt;Z9}JY*Jy<$t1@=|Q7$8sy4NGvguvLUY^$nLv+G6%Izrd|`N9>Xmxw{8cv;Q19;`HGf#~Kx>vEg)V7} zGZ4#t>fW+{pu2&GHNQD0ommBuK4*lCaZI9c_^5H?#*cmW`R9-P(w8dbk`xk={q^qq zR;*aD>#jR*zj)!e3FDI}?C$EGGh@a!^XCD?haY|XS6W&Ci*Xzxq7Y)q(p{D;-30)+ z=NF45HKs&Vjl$u>M~)gZwxzWh0D`~=fE{++WrrPi0f2$Nu2Q-AnP;9`{n^@iC(iTB zO=0h5eJUf_yyo0syUrJPKG`Uxq)ur!%Iey}m3B%OIwQW zq%UOfHQC7qx$glm1eS86i;$@Z3t>Bc7o8E!AB!;ZmrOW$l5taE~n%Mu#P`;E$F_IPLBQ$dYfFjTauZF4$LQ` z&FY%eP^Ti9?pyL0wPS!jDMtq7VfYpLsxYG|y>1@uUV^t9yw;CB_r~kx; z`&40l@_gEXM*Ni%rfgPP{r6l*pS*`Y zLnz~t4pte_ws8OTPd-qdu(UFM8vv-j{+HgrTq@VCgVqPIzo)$Gw^`E&WC06`!1{st z#60FP=6j3>zyih?LqNuXb6KmgrjgBa59UD&iJpNMZtMT&RapI04t=nH#RIV6Gx7dY z{hL25whr-T90;{_@e9B2d*zYR@OCfm<6KIK5*Yv&2@xv>i;ilVdk`xR=R;-#K<$m& zy6?UqTCqxe_Da*i)nMM&{KT(LT-m4F zE0jT^&j2$-P7m)SwQ2mS(L_$u%ugN0N67of)r5`7{D8Xb0V@LC1ucM=55> z#wHLT6JxTCXxQcd86+V9loCkPnF>=ZIsZ$og=Q`!B9tgmFKd-{7jNWTpX>%^*DlTx zIoGLm#MF^E;QP7_s!+x__YHLA3b`UO?jh$)*U#1Q%S1#7#5s7{#gm{!v&}H-ef=de zWJDMQK@b#M>q#JEiBKpO5l9LFAZ0SJ{{j0iUAlDK_%W13#Zr;mjcf@Kkb8`fnFD+k zPL&LSdnyzp)h?qP0YLQ~2=%@&WQ5FPsQ1t{Bh5Gmk6X~p5cWUh(Cv3#Rwx$`j9-tW z&HVK|&k-FWwJw3#oB>n|l>j8@Lqk<$0tlo|X!bb}x4fcy!#zga2Vz8$gpe|6ZE3mk z>ML5BD*(a|ip-EgX(5Klf=10YZ(CmrDCzQv#sD27fhTtW$2`y{=PGgIK2qL zCBMJ=-R@7X`tr%kr|vp>+PKHA{?>i}xqtcAI|bY$M2V6(Fb_FL&Wrzi?%$uTU;X<_ zelfXi{7y5s?N6$AJ@S_my1z80c|^5Z^E{R%fU{6CC;n-yISY-+Azl4f0E}TACL@Lo z`_@^f_FFt?Zj@zAfgbFO+b^PA7gB4ES#W0t!{z_f;@Ty?_T4(qs8ws(@D(`& z>bhw%Q^p*PL8(MW$iVX`tZ_g1^3liKc=OFa=<8{2Zebn)$QNIDVe_W$Bo+g`y_?sq z8|WX1qGaucwF7-ULWtJZP7#Mm(udqb=1ZAK5l2x{u2iC0w0YyEBuNy>gQ6cs(S7&c z7gqb@I0>Uj#BrfiSi5%pzI!eI!hr{toA^TyJ={`hTC)9i002^=?*ZwVI|E3;wOJHk zAzmgy7BkY2&XOtL|3R<(sszYzlYag`@Qki8H5hr_4rXW(5v{M{e|hEdHCU9`Aj<>I z872(CoG+X{#JWOA0~PhS&d-+ZSXze$9_C33DGe4*`O*0MQwrPvSU9IfEwi*(-2t5k zMF8nKKieB8+H8M0>c}xN89qS042QCxHn>Rd*{?Eu?HH!0DX+pXcPI1IeBf#=9lR#j zTj>@p z9n(&fBUP%7G`(^yNO=+)@wFpBgJ>Oc#=3!W%IKR+PAy-Zo{G(H^*;WKxVph>8Y7dK1IXTw`d<1=^5OfegpiOwaTyke%BZ*Z$=?pV z^PWGX8T$M9i+A|bcZKpWf7HU_xY6E-DOesZo%in4aO3xcU-|L(La)a#t0DOji zfB?uis$Q6JLC1`z5@ceqIc;PZ#d_C`=L}rNR+`LAYhAtX=xkHDO;JltX4)WYC!qoR zGOGmZ_{%!IDa(K87~XtswwwkGn?|DZpEQD_V8zkdPC}ahq>%|jyM{ptTT4UXN%2c2 zvl%n3cSbL#EOS7P>Ijv+GTn7BiZL2>FQs4BM@`+Qby%D-KW+B5J&Ppk8g1Cp+->FD z$?UrU8Mv3-5Cn}crk*5eB!x)tx0M3loO70CyMt1JDYYs?YFw#J2}(^;wP~nIhH@

    +vx-gA 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

    ML2BY(J7q0ck}+wXk! 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�QHq1J$EGM(cSw1i9vS0XAhllje_+M%;_ub18wx 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

    do#0iY=>>yT=T?=h{N4sHwa@S;PxxIs+CD+)s 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 YUm;&a_J*_%yZ`_I07*qoM6N<$g6a2w`~Uy| literal 0 HcmV?d00001 diff --git a/plan/spec-based-curation-v2-graphql-sdl.md b/plan/spec-based-curation-v2-graphql-sdl.md index e34956a96..fbe5e3f16 100644 --- a/plan/spec-based-curation-v2-graphql-sdl.md +++ b/plan/spec-based-curation-v2-graphql-sdl.md @@ -8,6 +8,10 @@ 기존 `curation_keyword`와 `curation_keyword_alcohol_ids`는 유연한 이관을 위해 그대로 둔다. 기존 Admin/Product endpoint도 변경하지 않는다. 신규 외부 API는 이후 phase에서 v2 endpoint로 추가한다. +### Flow Diagram + +![Spec-Based Curation V2 Flow](assets/spec-based-curation-v2-flow.png) + ### Phase Roadmap 1. **GraphQL SDL Foundation** From 54f137e9a28d040286973deb7bb3ab57a695d3f7 Mon Sep 17 00:00:00 2001 From: hgkim Date: Fri, 15 May 2026 16:33:37 +0900 Subject: [PATCH 04/33] =?UTF-8?q?feat:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20Product=20=EC=A1=B0=ED=9A=8C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...roductSpecBasedCurationDetailResponse.java | 23 ++ .../ProductSpecBasedCurationListResponse.java | 19 ++ .../exception/CurationExceptionCode.java | 3 +- .../service/CurationGraphqlExecutor.java | 8 + .../service/CurationPayloadValidator.java | 154 ++++++++++-- .../service/CurationResponseMaterializer.java | 238 ++++++++++++++++++ .../ProductSpecBasedCurationService.java | 120 +++++++++ .../service/SpecGraphqlQueryBuilder.java | 231 +++++++++++++++++ .../SpringCurationGraphqlExecutor.java | 35 +++ .../service/CurationPayloadValidatorTest.java | 235 +++++++++++++++++ .../CurationResponseMaterializerTest.java | 172 +++++++++++++ .../ProductSpecBasedCurationServiceTest.java | 188 ++++++++++++++ .../ProductSpecBasedCurationController.java | 28 +++ plan/spec-based-curation-v2-graphql-sdl.md | 38 ++- 14 files changed, 1470 insertions(+), 22 deletions(-) create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/ProductSpecBasedCurationDetailResponse.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/ProductSpecBasedCurationListResponse.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationGraphqlExecutor.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/ProductSpecBasedCurationService.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpecGraphqlQueryBuilder.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java create mode 100644 bottlenote-product-api/src/main/java/app/bottlenote/curation/controller/ProductSpecBasedCurationController.java diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/ProductSpecBasedCurationDetailResponse.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/ProductSpecBasedCurationDetailResponse.java new file mode 100644 index 000000000..3fe512960 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/ProductSpecBasedCurationDetailResponse.java @@ -0,0 +1,23 @@ +package app.bottlenote.curation.dto.response; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +public record ProductSpecBasedCurationDetailResponse( + Long id, + String name, + String description, + String coverImageUrl, + List imageUrls, + LocalDate exposureStartDate, + LocalDate exposureEndDate, + Integer displayOrder, + LocalDateTime createAt, + SpecMeta spec, + Object payload) { + + public record SpecMeta( + Long id, String code, String name, String container, Map responseSpec) {} +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/ProductSpecBasedCurationListResponse.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/ProductSpecBasedCurationListResponse.java new file mode 100644 index 000000000..c835b487b --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/response/ProductSpecBasedCurationListResponse.java @@ -0,0 +1,19 @@ +package app.bottlenote.curation.dto.response; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +public record ProductSpecBasedCurationListResponse( + Long id, + Long specId, + String specCode, + String specName, + String name, + String description, + String coverImageUrl, + List imageUrls, + LocalDate exposureStartDate, + LocalDate exposureEndDate, + Integer displayOrder, + LocalDateTime createAt) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationExceptionCode.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationExceptionCode.java index e31f34e3b..3370fb68d 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationExceptionCode.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationExceptionCode.java @@ -7,7 +7,8 @@ public enum CurationExceptionCode implements ExceptionCode { CURATION_SPEC_NOT_FOUND(HttpStatus.NOT_FOUND, "큐레이션 스펙을 찾을 수 없습니다."), CURATION_SPEC_DUPLICATE_CODE(HttpStatus.CONFLICT, "동일한 큐레이션 스펙 코드가 이미 존재합니다."), CURATION_NOT_FOUND(HttpStatus.NOT_FOUND, "큐레이션을 찾을 수 없습니다."), - CURATION_PAYLOAD_INVALID(HttpStatus.BAD_REQUEST, "큐레이션 payload가 스펙과 일치하지 않습니다."); + CURATION_PAYLOAD_INVALID(HttpStatus.BAD_REQUEST, "큐레이션 payload가 스펙과 일치하지 않습니다."), + CURATION_RESPONSE_INVALID(HttpStatus.INTERNAL_SERVER_ERROR, "큐레이션 응답이 스펙과 일치하지 않습니다."); private final HttpStatus httpStatus; private final String message; diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationGraphqlExecutor.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationGraphqlExecutor.java new file mode 100644 index 000000000..b0526e343 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationGraphqlExecutor.java @@ -0,0 +1,8 @@ +package app.bottlenote.curation.service; + +import java.util.Map; + +public interface CurationGraphqlExecutor { + + Map execute(Long curationId, int index, SpecGraphqlQueryBuilder.Result query); +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java index 284e30ffc..665430601 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java @@ -2,8 +2,10 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import org.springframework.stereotype.Component; @@ -29,35 +31,157 @@ public List validate(MapBackedSchema requestSpec, Object payload) { if (payloadBytes > MAX_PAYLOAD_BYTES) { return List.of("payload size must be <= " + MAX_PAYLOAD_BYTES + ", actual=" + payloadBytes); } - if (payloadNode.isArray()) { + + if ("array".equals(schema.path("x-container").asText()) || payloadNode.isArray()) { + if (!payloadNode.isArray()) { + return List.of("$ payload는 array여야 합니다."); + } if (payloadNode.isEmpty()) { return List.of("payload 배열은 비어 있을 수 없습니다."); } List errors = new ArrayList<>(); for (int i = 0; i < payloadNode.size(); i++) { - errors.addAll(validateObject(schema, payloadNode.get(i), "[" + i + "]")); + validateNode(schema, payloadNode.get(i), "$[" + i + "]", true, errors); } return errors; } - return validateObject(schema, payloadNode, "$"); + + List errors = new ArrayList<>(); + validateNode(schema, payloadNode, "$", true, errors); + return errors; } - private List validateObject(JsonNode schema, JsonNode payload, String path) { - if (!payload.isObject()) { - return List.of(path + " payload는 object여야 합니다."); + private void validateNode( + JsonNode schema, JsonNode payload, String path, boolean required, List errors) { + if (payload == null || payload.isMissingNode()) { + if (required) { + errors.add(path + " 필드는 필수입니다."); + } + return; + } + + boolean nullable = schema.path("nullable").asBoolean(false); + if (payload.isNull()) { + if (required && !nullable) { + errors.add(path + " 필드는 null일 수 없습니다."); + } + return; } - JsonNode required = schema.path("required"); - if (!required.isArray()) { - return List.of(); + + String type = schema.path("type").asText(""); + if (!matchesType(type, payload)) { + errors.add(path + " 타입이 " + type + "이어야 합니다."); + return; } - List errors = new ArrayList<>(); - for (JsonNode field : required) { - String fieldName = field.asText(); - if (!payload.hasNonNull(fieldName)) { - errors.add(path + "." + fieldName + " 필드는 필수입니다."); + + validateEnum(schema, payload, path, errors); + validateString(schema, payload, path, errors); + validateNumber(schema, payload, path, errors); + + if (payload.isObject()) { + validateObject(schema, payload, path, errors); + } + if (payload.isArray()) { + validateArray(schema, payload, path, errors); + } + } + + private void validateObject(JsonNode schema, JsonNode payload, String path, List errors) { + JsonNode requiredFields = schema.path("required"); + JsonNode properties = schema.path("properties"); + + if (requiredFields.isArray()) { + for (JsonNode field : requiredFields) { + String fieldName = field.asText(); + JsonNode value = payload.get(fieldName); + if (value == null || value.isNull()) { + errors.add(path + "." + fieldName + " 필드는 필수입니다."); + } } } - return errors; + + if (!properties.isObject()) { + return; + } + + Iterator names = properties.fieldNames(); + while (names.hasNext()) { + String name = names.next(); + JsonNode value = payload.get(name); + if (value == null) { + continue; + } + validateNode(properties.get(name), value, path + "." + name, false, errors); + } + } + + private void validateArray(JsonNode schema, JsonNode payload, String path, List errors) { + if (schema.has("minItems") && payload.size() < schema.get("minItems").asInt()) { + errors.add(path + " 배열 크기는 최소 " + schema.get("minItems").asInt() + "개여야 합니다."); + } + if (schema.has("maxItems") && payload.size() > schema.get("maxItems").asInt()) { + errors.add(path + " 배열 크기는 최대 " + schema.get("maxItems").asInt() + "개여야 합니다."); + } + + JsonNode itemSchema = schema.path("items"); + if (!itemSchema.isObject()) { + return; + } + for (int i = 0; i < payload.size(); i++) { + validateNode(itemSchema, payload.get(i), path + "[" + i + "]", true, errors); + } + } + + private void validateEnum(JsonNode schema, JsonNode payload, String path, List errors) { + JsonNode enumValues = schema.path("enum"); + if (!enumValues.isArray()) { + return; + } + for (JsonNode enumValue : enumValues) { + if (enumValue.equals(payload)) { + return; + } + } + errors.add(path + " 값이 허용된 enum이 아닙니다."); + } + + private void validateString(JsonNode schema, JsonNode payload, String path, List errors) { + if (!payload.isTextual()) { + return; + } + String value = payload.asText(); + if (schema.has("minLength") && value.length() < schema.get("minLength").asInt()) { + errors.add(path + " 문자열 길이는 최소 " + schema.get("minLength").asInt() + "자여야 합니다."); + } + if (schema.has("maxLength") && value.length() > schema.get("maxLength").asInt()) { + errors.add(path + " 문자열 길이는 최대 " + schema.get("maxLength").asInt() + "자여야 합니다."); + } + } + + private void validateNumber(JsonNode schema, JsonNode payload, String path, List errors) { + if (!payload.isNumber()) { + return; + } + BigDecimal value = payload.decimalValue(); + if (schema.has("minimum") && value.compareTo(schema.get("minimum").decimalValue()) < 0) { + errors.add(path + " 값은 최소 " + schema.get("minimum").asText() + " 이상이어야 합니다."); + } + if (schema.has("maximum") && value.compareTo(schema.get("maximum").decimalValue()) > 0) { + errors.add(path + " 값은 최대 " + schema.get("maximum").asText() + " 이하여야 합니다."); + } + } + + private boolean matchesType(String type, JsonNode payload) { + return switch (type) { + case "", "any" -> true; + case "object" -> payload.isObject(); + case "array" -> payload.isArray(); + case "string" -> payload.isTextual(); + case "integer" -> payload.isIntegralNumber(); + case "number" -> payload.isNumber(); + case "boolean" -> payload.isBoolean(); + default -> true; + }; } public record MapBackedSchema(Object value) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java new file mode 100644 index 000000000..a1603a9d5 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java @@ -0,0 +1,238 @@ +package app.bottlenote.curation.service; + +import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_RESPONSE_INVALID; + +import app.bottlenote.curation.exception.CurationException; +import app.bottlenote.curation.service.CurationPayloadValidator.MapBackedSchema; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class CurationResponseMaterializer { + + private static final String JSON_PATH_ROOT = "$"; + + private final ObjectMapper objectMapper; + private final SpecGraphqlQueryBuilder queryBuilder; + private final CurationGraphqlExecutor graphqlExecutor; + private final CurationPayloadValidator payloadValidator; + + public Object materialize(Long curationId, Map responseSpec, Object payload) { + JsonNode payloadNode = objectMapper.valueToTree(payload); + JsonNode responseSpecNode = objectMapper.valueToTree(responseSpec); + List queries = + queryBuilder.build(responseSpecNode, payloadNode); + + JsonNode hydrated = payloadNode; + for (int i = 0; i < queries.size(); i++) { + Map result = graphqlExecutor.execute(curationId, i, queries.get(i)); + hydrated = applyHydration(hydrated, queries.get(i), result); + } + + Object materialized = objectMapper.convertValue(hydrated, Object.class); + List errors = + payloadValidator.validate(new MapBackedSchema(responseSpec), materialized); + if (!errors.isEmpty()) { + throw new CurationException(CURATION_RESPONSE_INVALID); + } + return materialized; + } + + @SuppressWarnings("unchecked") + private JsonNode applyHydration( + JsonNode payload, SpecGraphqlQueryBuilder.Result query, Map result) { + if (payload == null || result == null || !(result.get("data") instanceof Map data)) { + return payload; + } + + Object raw = data.get(query.entryField()); + List hydrationList = normalizeHydration(raw); + if (hydrationList.isEmpty()) { + return payload; + } + + Map> byKey = indexByResultKey(hydrationList, query.resultKey()); + if (JSON_PATH_ROOT.equals(query.payloadPath())) { + return mergeSubtree(payload, query, byKey); + } + + JsonNode rootCopy = payload.deepCopy(); + JsonNode subtree = SpecGraphqlQueryBuilder.navigate(rootCopy, query.payloadPath()); + JsonNode merged = mergeSubtree(subtree, query, byKey); + if (merged != null) { + setAtPath(rootCopy, query.payloadPath(), merged); + } + return rootCopy; + } + + private List normalizeHydration(Object raw) { + if (raw instanceof List list) { + return list; + } + if (raw instanceof Map map) { + return List.of(map); + } + return List.of(); + } + + @SuppressWarnings("unchecked") + private Map> indexByResultKey(List list, String resultKey) { + Map> indexed = new HashMap<>(); + for (Object item : list) { + if (item instanceof Map map) { + Object key = map.get(resultKey); + if (key != null) { + indexed.put(normalizeKey(key), (Map) map); + } + } + } + return indexed; + } + + private JsonNode mergeSubtree( + JsonNode subtree, + SpecGraphqlQueryBuilder.Result query, + Map> byKey) { + if (subtree == null) { + return null; + } + if (subtree.isArray()) { + ArrayNode array = objectMapper.createArrayNode(); + subtree.forEach(element -> array.add(mergeElement(element, query, byKey))); + return array; + } + if (subtree.isObject()) { + return mergeElement(subtree, query, byKey); + } + return subtree; + } + + private JsonNode mergeElement( + JsonNode source, + SpecGraphqlQueryBuilder.Result query, + Map> byKey) { + if (!source.isObject()) { + return source; + } + ObjectNode node = ((ObjectNode) source).deepCopy(); + JsonNode joinNode = SpecGraphqlQueryBuilder.navigate(node, query.joinPath()); + if (joinNode == null || joinNode.isNull()) { + if (query.writeTo() != null && !node.has(query.writeTo())) { + node.set(query.writeTo(), objectMapper.nullNode()); + } + return node; + } + + if (query.writeTo() != null) { + node.set( + query.writeTo(), pickHydration(joinNode, byKey, query.writeMode(), query.resultKey())); + return node; + } + + Map hit = byKey.get(normalizeKey(jsonScalar(joinNode))); + if (hit != null) { + hit.forEach((key, value) -> node.set(key, objectMapper.valueToTree(value))); + } + return node; + } + + private JsonNode pickHydration( + JsonNode joinNode, + Map> byKey, + String writeMode, + String resultKey) { + if (SpecGraphqlQueryBuilder.WRITE_MODE_SINGLE.equals(writeMode)) { + Object key = joinNode.isArray() ? firstScalar(joinNode) : jsonScalar(joinNode); + Map hit = key == null ? null : byKey.get(normalizeKey(key)); + return hit == null + ? objectMapper.nullNode() + : objectMapper.valueToTree(withoutResultKey(hit, resultKey)); + } + + ArrayNode array = objectMapper.createArrayNode(); + if (joinNode.isArray()) { + joinNode.forEach(value -> appendIfHit(array, byKey, jsonScalar(value), resultKey)); + } else { + appendIfHit(array, byKey, jsonScalar(joinNode), resultKey); + } + return array; + } + + private Object firstScalar(JsonNode node) { + return node.isEmpty() ? null : jsonScalar(node.get(0)); + } + + private void appendIfHit( + ArrayNode array, Map> byKey, Object key, String resultKey) { + Map hit = byKey.get(normalizeKey(key)); + if (hit != null) { + array.add(objectMapper.valueToTree(withoutResultKey(hit, resultKey))); + } + } + + private Map withoutResultKey(Map hit, String resultKey) { + Map copy = new HashMap<>(hit); + copy.remove(resultKey); + return copy; + } + + private void setAtPath(JsonNode root, String path, JsonNode value) { + String trimmed = stripPathPrefix(path); + if (trimmed.isEmpty()) { + return; + } + String[] segments = trimmed.split("\\."); + JsonNode current = root; + for (int i = 0; i < segments.length - 1; i++) { + current = current.get(segments[i]); + if (current == null) { + return; + } + } + if (current instanceof ObjectNode objectNode) { + objectNode.set(segments[segments.length - 1], value); + } + } + + private String stripPathPrefix(String path) { + if (path.startsWith("$.")) { + return path.substring(2); + } + return JSON_PATH_ROOT.equals(path) ? "" : path; + } + + private Object normalizeKey(Object value) { + if (value instanceof Number number) { + return number.longValue(); + } + if (value == null) { + return null; + } + try { + return Long.parseLong(value.toString()); + } catch (NumberFormatException e) { + return value.toString(); + } + } + + private Object jsonScalar(JsonNode node) { + if (node.isIntegralNumber()) { + return node.asLong(); + } + if (node.isFloatingPointNumber()) { + return node.asDouble(); + } + if (node.isBoolean()) { + return node.asBoolean(); + } + return node.asText(); + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/ProductSpecBasedCurationService.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/ProductSpecBasedCurationService.java new file mode 100644 index 000000000..145b1e501 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/ProductSpecBasedCurationService.java @@ -0,0 +1,120 @@ +package app.bottlenote.curation.service; + +import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_NOT_FOUND; +import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_SPEC_NOT_FOUND; + +import app.bottlenote.curation.domain.Curation; +import app.bottlenote.curation.domain.CurationExtension; +import app.bottlenote.curation.domain.CurationExtensionRepository; +import app.bottlenote.curation.domain.CurationRepository; +import app.bottlenote.curation.domain.CurationSpec; +import app.bottlenote.curation.domain.CurationSpecRepository; +import app.bottlenote.curation.dto.response.ProductSpecBasedCurationDetailResponse; +import app.bottlenote.curation.dto.response.ProductSpecBasedCurationListResponse; +import app.bottlenote.curation.exception.CurationException; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ProductSpecBasedCurationService { + + private static final String DEFAULT_CONTAINER = "object"; + + private final CurationRepository curationRepository; + private final CurationSpecRepository curationSpecRepository; + private final CurationExtensionRepository curationExtensionRepository; + private final CurationResponseMaterializer responseMaterializer; + + @Transactional(readOnly = true) + public List listActiveCurations() { + List curations = + curationRepository.findAllByIsActiveTrueOrderByDisplayOrderAscIdAsc(); + Map specMap = + curationSpecRepository + .findAllByIdIn(curations.stream().map(Curation::getSpecId).collect(Collectors.toSet())) + .stream() + .collect(Collectors.toMap(CurationSpec::getId, Function.identity())); + return curations.stream() + .map(curation -> toListResponse(curation, specMap.get(curation.getSpecId()))) + .toList(); + } + + @Transactional(readOnly = true) + public ProductSpecBasedCurationDetailResponse getDetail(Long curationId) { + Curation curation = + curationRepository + .findById(curationId) + .filter(item -> Boolean.TRUE.equals(item.getIsActive())) + .orElseThrow(() -> new CurationException(CURATION_NOT_FOUND)); + CurationSpec spec = + curationSpecRepository + .findById(curation.getSpecId()) + .orElseThrow(() -> new CurationException(CURATION_SPEC_NOT_FOUND)); + CurationExtension extension = + curationExtensionRepository + .findByCurationId(curationId) + .orElseThrow(() -> new CurationException(CURATION_NOT_FOUND)); + Object materialized = + responseMaterializer.materialize( + curationId, spec.getResponseSpec(), extension.getPayload()); + return toDetailResponse(curation, spec, materialized); + } + + private ProductSpecBasedCurationListResponse toListResponse( + Curation curation, CurationSpec spec) { + return new ProductSpecBasedCurationListResponse( + curation.getId(), + curation.getSpecId(), + spec != null ? spec.getCode() : null, + spec != null ? spec.getName() : null, + curation.getName(), + curation.getDescription(), + curation.getCoverImageUrl(), + imageUrls(curation), + curation.getExposureStartDate(), + curation.getExposureEndDate(), + curation.getDisplayOrder(), + curation.getCreateAt()); + } + + private ProductSpecBasedCurationDetailResponse toDetailResponse( + Curation curation, CurationSpec spec, Object payload) { + return new ProductSpecBasedCurationDetailResponse( + curation.getId(), + curation.getName(), + curation.getDescription(), + curation.getCoverImageUrl(), + imageUrls(curation), + curation.getExposureStartDate(), + curation.getExposureEndDate(), + curation.getDisplayOrder(), + curation.getCreateAt(), + new ProductSpecBasedCurationDetailResponse.SpecMeta( + spec.getId(), spec.getCode(), spec.getName(), container(spec), spec.getResponseSpec()), + payload); + } + + private List imageUrls(Curation curation) { + return java.util.stream.Stream.of( + curation.getCoverImageUrl(), curation.getImageUrl2(), curation.getImageUrl3()) + .filter(Objects::nonNull) + .filter(imageUrl -> !imageUrl.isBlank()) + .toList(); + } + + private String container(CurationSpec spec) { + Object requestContainer = spec.getRequestSpec().get("x-container"); + if (requestContainer != null) { + return requestContainer.toString(); + } + Object responseContainer = spec.getResponseSpec().get("x-container"); + return responseContainer != null ? responseContainer.toString() : DEFAULT_CONTAINER; + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpecGraphqlQueryBuilder.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpecGraphqlQueryBuilder.java new file mode 100644 index 000000000..fe9555263 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpecGraphqlQueryBuilder.java @@ -0,0 +1,231 @@ +package app.bottlenote.curation.service; + +import com.fasterxml.jackson.databind.JsonNode; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.springframework.stereotype.Component; + +@Component +public class SpecGraphqlQueryBuilder { + + static final String WRITE_MODE_ARRAY = "array"; + static final String WRITE_MODE_SINGLE = "single"; + + private static final String META_KEY = "x-graphql"; + private static final String JSON_PATH_ROOT = "$"; + private static final String JSON_PATH_PREFIX = "$."; + private static final String DEFAULT_ARG_NAME = "id"; + private static final String DEFAULT_ARG_TYPE = "ID!"; + private static final String DEFAULT_RESULT_KEY = "alcoholId"; + + public List build(JsonNode responseSpec, JsonNode payload) { + List results = new ArrayList<>(); + walk(responseSpec, payload, results); + return results; + } + + static JsonNode navigate(JsonNode root, String path) { + if (root == null || path == null || JSON_PATH_ROOT.equals(path)) { + return root; + } + String trimmed = stripPathPrefix(path); + if (trimmed.isEmpty()) { + return root; + } + JsonNode current = root; + for (String segment : trimmed.split("\\.")) { + if (current == null) { + return null; + } + current = current.get(segment); + } + return current; + } + + private void walk(JsonNode node, JsonNode payload, List results) { + if (node == null || !node.isObject()) { + return; + } + JsonNode meta = node.get(META_KEY); + if (isEntryPointMeta(meta)) { + results.add(buildOne(node, meta, payload)); + return; + } + JsonNode properties = node.get("properties"); + if (properties != null && properties.isObject()) { + properties.properties().forEach(entry -> walk(entry.getValue(), payload, results)); + } + JsonNode items = node.get("items"); + if (items != null) { + walk(items, payload, results); + } + } + + private boolean isEntryPointMeta(JsonNode meta) { + return meta != null && meta.isObject() && meta.has("query"); + } + + private Result buildOne(JsonNode entry, JsonNode meta, JsonNode payload) { + String queryName = meta.get("query").asText(); + String argName = meta.path("argName").asText(DEFAULT_ARG_NAME); + String argType = meta.path("argType").asText(DEFAULT_ARG_TYPE); + String argFrom = meta.path("argFrom").asText(JSON_PATH_ROOT); + String writeTo = meta.has("writeTo") ? meta.get("writeTo").asText(null) : null; + String resultKey = meta.path("resultKey").asText(DEFAULT_RESULT_KEY); + String payloadPath = meta.path("payloadPath").asText(JSON_PATH_ROOT); + + JsonNode subPayload = navigate(payload, payloadPath); + Map variables = new LinkedHashMap<>(); + variables.put(argName, extractArg(subPayload, argFrom)); + + List selectionFields = + new ArrayList<>(collectSelection(resolveSelectionRoot(entry, writeTo))); + if (!selectionFields.contains(resultKey)) { + selectionFields.add(0, resultKey); + } + String query = + String.format( + "query Q($%s: %s) { %s(%s: $%s) { %s } }", + argName, argType, queryName, argName, argName, String.join(" ", selectionFields)); + return new Result( + query, + variables, + queryName, + argFrom, + writeTo, + resolveWriteMode(entry, writeTo), + resultKey, + payloadPath); + } + + private JsonNode resolveSelectionRoot(JsonNode entry, String writeTo) { + if (writeTo != null) { + JsonNode target = entry.path("properties").path(writeTo); + if (target.isMissingNode()) { + return entry; + } + return target.has("items") ? target.get("items") : target; + } + return "array".equals(entry.path("type").asText()) && entry.has("items") + ? entry.get("items") + : entry; + } + + private String resolveWriteMode(JsonNode entry, String writeTo) { + if (writeTo == null) { + return WRITE_MODE_ARRAY; + } + String type = entry.path("properties").path(writeTo).path("type").asText(); + return WRITE_MODE_ARRAY.equals(type) ? WRITE_MODE_ARRAY : WRITE_MODE_SINGLE; + } + + private List collectSelection(JsonNode node) { + List selections = new ArrayList<>(); + if (node == null || !node.path("properties").isObject()) { + return selections; + } + for (Map.Entry entry : node.path("properties").properties()) { + JsonNode meta = entry.getValue().get(META_KEY); + if (meta == null || isEntryPointMeta(meta)) { + continue; + } + selections.add(resolveFieldName(entry.getKey(), meta)); + } + return selections; + } + + private String resolveFieldName(String key, JsonNode meta) { + if (meta.isTextual()) { + return meta.asText(); + } + if (meta.isObject() && meta.has("field")) { + return meta.get("field").asText(key); + } + return key; + } + + private Object extractArg(JsonNode payload, String argFrom) { + if (payload == null) { + return null; + } + if (payload.isArray()) { + Set values = new LinkedHashSet<>(); + payload.forEach(element -> addFlat(values, readPath(element, argFrom))); + values.remove(null); + return new ArrayList<>(values); + } + Object value = readPath(payload, argFrom); + if (value instanceof List list) { + Set values = new LinkedHashSet<>(list); + values.remove(null); + return new ArrayList<>(values); + } + return value; + } + + private void addFlat(Set values, Object value) { + if (value == null) { + return; + } + if (value instanceof List list) { + list.forEach(item -> addFlat(values, item)); + return; + } + values.add(value); + } + + private Object readPath(JsonNode node, String path) { + JsonNode current = navigate(node, path); + return jsonToJava(current); + } + + private Object jsonToJava(JsonNode node) { + if (node == null || node.isNull()) { + return null; + } + if (node.isIntegralNumber()) { + return node.asLong(); + } + if (node.isFloatingPointNumber()) { + return node.asDouble(); + } + if (node.isBoolean()) { + return node.asBoolean(); + } + if (node.isTextual()) { + return node.asText(); + } + if (node.isArray()) { + List values = new ArrayList<>(); + node.forEach(child -> values.add(jsonToJava(child))); + return values; + } + if (node.isObject()) { + Map values = new LinkedHashMap<>(); + node.properties().forEach(entry -> values.put(entry.getKey(), jsonToJava(entry.getValue()))); + return values; + } + return null; + } + + private static String stripPathPrefix(String path) { + if (path.startsWith(JSON_PATH_PREFIX)) { + return path.substring(2); + } + return JSON_PATH_ROOT.equals(path) ? "" : path; + } + + public record Result( + String query, + Map variables, + String entryField, + String joinPath, + String writeTo, + String writeMode, + String resultKey, + String payloadPath) {} +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java new file mode 100644 index 000000000..69bfcd0ea --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java @@ -0,0 +1,35 @@ +package app.bottlenote.curation.service; + +import java.util.Map; +import lombok.RequiredArgsConstructor; +import org.springframework.graphql.ExecutionGraphQlRequest; +import org.springframework.graphql.ExecutionGraphQlResponse; +import org.springframework.graphql.ExecutionGraphQlService; +import org.springframework.graphql.support.DefaultExecutionGraphQlRequest; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +@Component +@RequiredArgsConstructor +public class SpringCurationGraphqlExecutor implements CurationGraphqlExecutor { + + private final ExecutionGraphQlService executionGraphQlService; + + @Override + public Map execute( + Long curationId, int index, SpecGraphqlQueryBuilder.Result query) { + ExecutionGraphQlRequest request = + new DefaultExecutionGraphQlRequest( + query.query(), + "Q", + query.variables(), + Map.of(), + "curation-" + curationId + "-" + index, + null); + ExecutionGraphQlResponse response = Mono.from(executionGraphQlService.execute(request)).block(); + if (response == null) { + return Map.of(); + } + return response.getExecutionResult().toSpecification(); + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java new file mode 100644 index 000000000..d746269bf --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java @@ -0,0 +1,235 @@ +package app.bottlenote.curation.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import app.bottlenote.curation.service.CurationPayloadValidator.MapBackedSchema; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.core.io.ClassPathResource; + +@Tag("unit") +@DisplayName("CurationPayloadValidator 단위 테스트") +class CurationPayloadValidatorTest { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final TypeReference> MAP_TYPE = new TypeReference<>() {}; + + private final CurationPayloadValidator validator = new CurationPayloadValidator(OBJECT_MAPPER); + + @Test + @DisplayName("추천 위스키 requestSpec은 유효한 BOTTLE_NOTE 배열 payload를 허용한다") + void validate_whenRecommendedWhiskyBottleNotePayloadIsValid_returnsEmptyErrors() + throws IOException { + Map requestSpec = schema("recommended_whisky.json", "Request"); + + List errors = + validator.validate( + new MapBackedSchema(requestSpec), List.of(recommendedItem("BOTTLE_NOTE"))); + + assertThat(errors).isEmpty(); + } + + @Test + @DisplayName("requestSpec의 x-container가 array이면 root payload는 비어 있거나 object일 수 없다") + void validate_whenArrayContainerIsEmptyOrObject_returnsContainerErrors() throws IOException { + Map requestSpec = schema("recommended_whisky.json", "Request"); + + List emptyErrors = validator.validate(new MapBackedSchema(requestSpec), List.of()); + List objectErrors = + validator.validate(new MapBackedSchema(requestSpec), recommendedItem("BOTTLE_NOTE")); + + assertThat(emptyErrors).containsExactly("payload 배열은 비어 있을 수 없습니다."); + assertThat(objectErrors).containsExactly("$ payload는 array여야 합니다."); + } + + @Test + @DisplayName("requestSpec은 required, enum, type 불일치를 상세 path로 검증한다") + void validate_whenRequiredEnumOrTypeInvalid_returnsDetailedErrors() throws IOException { + Map requestSpec = schema("recommended_whisky.json", "Request"); + Map invalid = + map("source", "UNKNOWN", "alcohol", map("korName", 123, "selectedTags", List.of("셰리"))); + + List errors = validator.validate(new MapBackedSchema(requestSpec), List.of(invalid)); + + assertThat(errors) + .contains("$[0].source 값이 허용된 enum이 아닙니다.", "$[0].alcohol.korName 타입이 string이어야 합니다."); + } + + @Test + @DisplayName("requestSpec은 중첩 배열의 maxItems, minLength, maxLength 경계값을 검증한다") + void validate_whenNestedArrayAndLengthBoundsInvalid_returnsErrors() throws IOException { + Map requestSpec = schema("recommended_whisky.json", "Request"); + Map invalid = + recommendedItem( + "BOTTLE_NOTE", + map( + "alcoholId", + 1, + "korName", + "가".repeat(101), + "selectedTags", + List.of( + "셰리", + "", + "오크", + "피트", + "과일", + "바닐라", + "꿀", + "초콜릿", + "몰트", + "스모키", + "꽃", + "견과", + "긴태그".repeat(11)))); + + List errors = validator.validate(new MapBackedSchema(requestSpec), List.of(invalid)); + + assertThat(errors) + .contains( + "$[0].alcohol.korName 문자열 길이는 최대 100자여야 합니다.", + "$[0].alcohol.selectedTags 배열 크기는 최대 12개여야 합니다.", + "$[0].alcohol.selectedTags[1] 문자열 길이는 최소 1자여야 합니다.", + "$[0].alcohol.selectedTags[12] 문자열 길이는 최대 30자여야 합니다."); + } + + @Test + @DisplayName("시음회 requestSpec은 숫자와 배열의 최솟값, 최댓값 경계를 검증한다") + void validate_whenTastingEventNumericAndArrayBoundsInvalid_returnsErrors() throws IOException { + Map requestSpec = schema("whisky_tasting_event.json", "Request"); + Map invalid = + tastingEventPayload( + 0, + 1000, + List.of( + recommendedItem("BOTTLE_NOTE"), + recommendedItem("MANUAL"), + recommendedItem("MANUAL"), + recommendedItem("MANUAL"), + recommendedItem("MANUAL"), + recommendedItem("MANUAL"), + recommendedItem("MANUAL"), + recommendedItem("MANUAL"), + recommendedItem("MANUAL"), + recommendedItem("MANUAL"), + recommendedItem("MANUAL"))); + + List errors = validator.validate(new MapBackedSchema(requestSpec), invalid); + + assertThat(errors) + .contains("$.capacity 값은 최대 999 이하여야 합니다.", "$.alcohols 배열 크기는 최대 10개여야 합니다."); + assertThat(errors).doesNotContain("$.entryFee 값은 최소 0 이상이어야 합니다."); + } + + @Test + @DisplayName("시음회 requestSpec은 최소 경계값을 만족하면 통과한다") + void validate_whenTastingEventMinimumBoundaryValid_returnsEmptyErrors() throws IOException { + Map requestSpec = schema("whisky_tasting_event.json", "Request"); + + List errors = + validator.validate( + new MapBackedSchema(requestSpec), + tastingEventPayload(0, 1, List.of(recommendedItem("BOTTLE_NOTE")))); + + assertThat(errors).isEmpty(); + } + + @Test + @DisplayName("responseSpec은 materialized stats가 들어간 추천 위스키 응답 payload를 허용한다") + void validate_whenRecommendedResponsePayloadMatchesResponseSpec_returnsEmptyErrors() + throws IOException { + Map responseSpec = schema("recommended_whisky.json", "Response"); + Map item = + recommendedItem( + "BOTTLE_NOTE", + map("alcoholId", 1, "korName", "테스트 위스키", "selectedTags", List.of("셰리"))); + item.put( + "stats", + map("rating", 4.2, "totalRatingsCount", 10, "reviewCount", 3, "totalPickCount", 8)); + + List errors = validator.validate(new MapBackedSchema(responseSpec), List.of(item)); + + assertThat(errors).isEmpty(); + } + + @Test + @DisplayName("responseSpec은 stats 내부 타입까지 검증한다") + void validate_whenResponseStatsTypeInvalid_returnsErrors() throws IOException { + Map responseSpec = schema("recommended_whisky.json", "Response"); + Map item = recommendedItem("BOTTLE_NOTE"); + item.put( + "stats", + map("rating", "4.2", "totalRatingsCount", "10", "reviewCount", 3, "totalPickCount", 8)); + + List errors = validator.validate(new MapBackedSchema(responseSpec), List.of(item)); + + assertThat(errors) + .contains( + "$[0].stats.rating 타입이 number이어야 합니다.", + "$[0].stats.totalRatingsCount 타입이 integer이어야 합니다."); + } + + private static Map schema(String resourceName, String suffix) throws IOException { + JsonNode root = + OBJECT_MAPPER.readTree( + new ClassPathResource("openapi/curation/" + resourceName).getInputStream()); + JsonNode schemas = root.path("components").path("schemas"); + JsonNode schema = + schemas.properties().stream() + .filter(entry -> entry.getKey().endsWith(suffix)) + .findFirst() + .map(Map.Entry::getValue) + .orElseThrow(); + return OBJECT_MAPPER.convertValue(schema, MAP_TYPE); + } + + private static Map recommendedItem(String source) { + return recommendedItem( + source, map("alcoholId", 1, "korName", "테스트 위스키", "selectedTags", List.of("셰리"))); + } + + private static Map recommendedItem(String source, Map alcohol) { + return map("source", source, "alcohol", alcohol, "comment", null); + } + + private static Map tastingEventPayload( + int entryFee, int capacity, List> alcohols) { + return map( + "eventDate", + "2026-06-15", + "eventTime", + "19:30", + "barAddress", + "서울 강남구 테헤란로 123", + "detailAddress", + "2층 도시남 바", + "isRecruiting", + true, + "entryFee", + entryFee, + "capacity", + capacity, + "applicationLink", + "https://forms.example.com/tasting", + "guideText", + "시작 10분 전 입장해 주세요.", + "alcohols", + alcohols); + } + + private static Map map(Object... values) { + Map map = new LinkedHashMap<>(); + for (int i = 0; i < values.length; i += 2) { + map.put((String) values[i], values[i + 1]); + } + return map; + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java new file mode 100644 index 000000000..56c0fdb0e --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java @@ -0,0 +1,172 @@ +package app.bottlenote.curation.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.core.io.ClassPathResource; + +@Tag("unit") +@DisplayName("CurationResponseMaterializer 단위 테스트") +class CurationResponseMaterializerTest { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final TypeReference> MAP_TYPE = new TypeReference<>() {}; + + @Test + @DisplayName("root array payload는 responseSpec.x-graphql 기준으로 BOTTLE_NOTE stats만 보강한다") + void materialize_whenRootArrayPayload_hydratesBottleNoteStatsOnly() throws IOException { + FakeCurationGraphqlExecutor executor = + new FakeCurationGraphqlExecutor( + List.of( + map( + "alcoholId", + "1", + "rating", + 4.2, + "totalRatingsCount", + 10, + "reviewCount", + 3, + "totalPickCount", + 8))); + CurationResponseMaterializer materializer = materializer(executor); + List> payload = + List.of( + item( + "BOTTLE_NOTE", + map("alcoholId", 1, "korName", "테스트", "selectedTags", List.of("셰리"))), + item("MANUAL", map("alcoholId", null, "korName", "수동", "selectedTags", List.of("오크")))); + + Object result = + materializer.materialize(1L, schema("recommended_whisky.json", "Response"), payload); + + JsonNode resultNode = OBJECT_MAPPER.valueToTree(result); + assertThat(executor.executedQueries()).hasSize(1); + assertThat(executor.executedQueries().get(0).query()).contains("alcohols(ids: $ids)"); + assertThat(executor.executedQueries().get(0).variables().get("ids")).isEqualTo(List.of(1L)); + assertThat(resultNode.get(0).path("stats").path("rating").asDouble()).isEqualTo(4.2); + assertThat(resultNode.get(0).path("stats").has("alcoholId")).isFalse(); + assertThat(resultNode.get(1).path("stats").isNull()).isTrue(); + assertThat(resultNode.get(1).path("alcohol").path("korName").asText()).isEqualTo("수동"); + } + + @Test + @DisplayName("object payload의 payloadPath=$.alcohols는 하위 alcohols 배열에만 stats를 보강한다") + void materialize_whenNestedPayloadPath_hydratesOnlyAlcoholSubtree() throws IOException { + FakeCurationGraphqlExecutor executor = + new FakeCurationGraphqlExecutor( + List.of( + map( + "alcoholId", + 7, + "rating", + 3.8, + "totalRatingsCount", + 4, + "reviewCount", + 1, + "totalPickCount", + 2))); + CurationResponseMaterializer materializer = materializer(executor); + Map payload = + map( + "eventDate", + "2026-06-15", + "eventTime", + "19:30", + "barAddress", + "서울 강남구", + "detailAddress", + "2층 도시남 바", + "isRecruiting", + true, + "entryFee", + 0, + "capacity", + 20, + "applicationLink", + "https://forms.example.com/tasting", + "guideText", + "안내", + "alcohols", + List.of( + item( + "BOTTLE_NOTE", + map("alcoholId", 7, "korName", "테스트", "selectedTags", List.of("셰리"))))); + + Object result = + materializer.materialize(2L, schema("whisky_tasting_event.json", "Response"), payload); + + JsonNode resultNode = OBJECT_MAPPER.valueToTree(result); + assertThat(executor.executedQueries().get(0).variables().get("ids")).isEqualTo(List.of(7L)); + assertThat(resultNode.path("eventDate").asText()).isEqualTo("2026-06-15"); + assertThat(resultNode.path("stats").isMissingNode()).isTrue(); + assertThat(resultNode.path("alcohols").get(0).path("stats").path("reviewCount").asInt()) + .isEqualTo(1); + } + + private static CurationResponseMaterializer materializer(FakeCurationGraphqlExecutor executor) { + return new CurationResponseMaterializer( + OBJECT_MAPPER, + new SpecGraphqlQueryBuilder(), + executor, + new CurationPayloadValidator(OBJECT_MAPPER)); + } + + private static Map schema(String resourceName, String suffix) throws IOException { + JsonNode root = + OBJECT_MAPPER.readTree( + new ClassPathResource("openapi/curation/" + resourceName).getInputStream()); + JsonNode schemas = root.path("components").path("schemas"); + JsonNode schema = + schemas.properties().stream() + .filter(entry -> entry.getKey().endsWith(suffix)) + .findFirst() + .map(Map.Entry::getValue) + .orElseThrow(); + return OBJECT_MAPPER.convertValue(schema, MAP_TYPE); + } + + private static Map item(String source, Map alcohol) { + return map("source", source, "alcohol", alcohol, "comment", null); + } + + private static Map map(Object... values) { + Map map = new LinkedHashMap<>(); + for (int i = 0; i < values.length; i += 2) { + map.put((String) values[i], values[i + 1]); + } + return map; + } + + private static final class FakeCurationGraphqlExecutor implements CurationGraphqlExecutor { + + private final List> alcohols; + private final List executedQueries = new ArrayList<>(); + + FakeCurationGraphqlExecutor(List> alcohols) { + this.alcohols = alcohols; + } + + @Override + public Map execute( + Long curationId, int index, SpecGraphqlQueryBuilder.Result query) { + executedQueries.add(query); + return map("data", map(query.entryField(), alcohols)); + } + + List executedQueries() { + return executedQueries; + } + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java new file mode 100644 index 000000000..269d1ba81 --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java @@ -0,0 +1,188 @@ +package app.bottlenote.curation.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import app.bottlenote.curation.domain.CurationSpec; +import app.bottlenote.curation.dto.request.CurationCreateRequest; +import app.bottlenote.curation.dto.request.CurationSpecCreateRequest; +import app.bottlenote.curation.dto.response.ProductSpecBasedCurationDetailResponse; +import app.bottlenote.curation.exception.CurationException; +import app.bottlenote.curation.exception.CurationExceptionCode; +import app.bottlenote.curation.fixture.InMemoryCurationExtensionRepository; +import app.bottlenote.curation.fixture.InMemoryCurationRepository; +import app.bottlenote.curation.fixture.InMemoryCurationSpecRepository; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.time.LocalDate; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.core.io.ClassPathResource; + +@Tag("unit") +@DisplayName("ProductSpecBasedCurationService 단위 테스트") +class ProductSpecBasedCurationServiceTest { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final TypeReference> MAP_TYPE = new TypeReference<>() {}; + + InMemoryCurationSpecRepository specRepository; + InMemoryCurationRepository curationRepository; + InMemoryCurationExtensionRepository extensionRepository; + CurationV2Service curationV2Service; + ProductSpecBasedCurationService productService; + + @BeforeEach + void setUp() { + specRepository = new InMemoryCurationSpecRepository(); + curationRepository = new InMemoryCurationRepository(); + extensionRepository = new InMemoryCurationExtensionRepository(); + curationV2Service = + new CurationV2Service(specRepository, curationRepository, extensionRepository); + CurationResponseMaterializer materializer = + new CurationResponseMaterializer( + OBJECT_MAPPER, + new SpecGraphqlQueryBuilder(), + new FixedGraphqlExecutor(), + new CurationPayloadValidator(OBJECT_MAPPER)); + productService = + new ProductSpecBasedCurationService( + curationRepository, specRepository, extensionRepository, materializer); + } + + @Test + @DisplayName("Product v2 목록은 활성 큐레이션만 displayOrder, id 순서로 반환한다") + void listActiveCurations_whenMixedStatus_returnsOnlyActiveItemsInDisplayOrder() + throws IOException { + CurationSpec spec = createSpec(); + Long laterId = createCuration(spec.getId(), "뒤", 20, true); + createCuration(spec.getId(), "비활성", 1, false); + Long firstId = createCuration(spec.getId(), "앞", 1, true); + + var result = productService.listActiveCurations(); + + assertThat(result).hasSize(2); + assertThat(result).extracting("id").containsExactly(firstId, laterId); + assertThat(result.get(0).specCode()).isEqualTo("RECOMMENDED_WHISKY"); + assertThat(result.get(0).imageUrls()).containsExactly("https://cdn.example.com/cover.jpg"); + } + + @Test + @DisplayName("Product v2 상세는 spec meta와 responseSpec 기준으로 stats가 보강된 payload를 반환한다") + void getDetail_whenCurationExists_returnsMaterializedPayload() throws IOException { + CurationSpec spec = createSpec(); + Long curationId = createCuration(spec.getId(), "상세", 1, true); + + ProductSpecBasedCurationDetailResponse result = productService.getDetail(curationId); + + JsonNode payload = OBJECT_MAPPER.valueToTree(result.payload()); + assertThat(result.spec().code()).isEqualTo("RECOMMENDED_WHISKY"); + assertThat(result.spec().container()).isEqualTo("array"); + assertThat(result.spec().responseSpec()).containsKey("properties"); + assertThat(payload.get(0).path("stats").path("totalPickCount").asInt()).isEqualTo(8); + assertThat(payload.get(0).path("stats").has("alcoholId")).isFalse(); + assertThat(payload.get(1).path("stats").isNull()).isTrue(); + } + + @Test + @DisplayName("비활성 큐레이션 상세 조회는 Product v2에서 찾을 수 없다") + void getDetail_whenCurationInactive_throwsNotFound() throws IOException { + CurationSpec spec = createSpec(); + Long curationId = createCuration(spec.getId(), "비활성", 1, false); + + assertThatThrownBy(() -> productService.getDetail(curationId)) + .isInstanceOf(CurationException.class) + .hasFieldOrPropertyWithValue("exceptionCode", CurationExceptionCode.CURATION_NOT_FOUND); + } + + private CurationSpec createSpec() throws IOException { + return curationV2Service.createSpec( + new CurationSpecCreateRequest( + "RECOMMENDED_WHISKY", + "추천 위스키", + "추천 설명", + schema("recommended_whisky.json", "Request"), + schema("recommended_whisky.json", "Response"), + "alcohol", + 2)); + } + + private Long createCuration(Long specId, String name, int displayOrder, boolean active) { + return curationV2Service + .createCuration( + new CurationCreateRequest( + specId, + name, + "설명", + List.of("https://cdn.example.com/cover.jpg"), + LocalDate.of(2026, 6, 1), + LocalDate.of(2026, 6, 30), + displayOrder, + active, + List.of( + item( + "BOTTLE_NOTE", + map("alcoholId", 1, "korName", "테스트", "selectedTags", List.of("셰리"))), + item( + "MANUAL", + map("alcoholId", null, "korName", "수동", "selectedTags", List.of("오크")))))) + .getId(); + } + + private static Map schema(String resourceName, String suffix) throws IOException { + JsonNode root = + OBJECT_MAPPER.readTree( + new ClassPathResource("openapi/curation/" + resourceName).getInputStream()); + JsonNode schemas = root.path("components").path("schemas"); + JsonNode schema = + schemas.properties().stream() + .filter(entry -> entry.getKey().endsWith(suffix)) + .findFirst() + .map(Map.Entry::getValue) + .orElseThrow(); + return OBJECT_MAPPER.convertValue(schema, MAP_TYPE); + } + + private static Map item(String source, Map alcohol) { + return map("source", source, "alcohol", alcohol, "comment", null); + } + + private static Map map(Object... values) { + Map map = new LinkedHashMap<>(); + for (int i = 0; i < values.length; i += 2) { + map.put((String) values[i], values[i + 1]); + } + return map; + } + + private static final class FixedGraphqlExecutor implements CurationGraphqlExecutor { + + @Override + public Map execute( + Long curationId, int index, SpecGraphqlQueryBuilder.Result query) { + return map( + "data", + map( + query.entryField(), + List.of( + map( + "alcoholId", + 1, + "rating", + 4.2, + "totalRatingsCount", + 10, + "reviewCount", + 3, + "totalPickCount", + 8)))); + } + } +} diff --git a/bottlenote-product-api/src/main/java/app/bottlenote/curation/controller/ProductSpecBasedCurationController.java b/bottlenote-product-api/src/main/java/app/bottlenote/curation/controller/ProductSpecBasedCurationController.java new file mode 100644 index 000000000..c9c073784 --- /dev/null +++ b/bottlenote-product-api/src/main/java/app/bottlenote/curation/controller/ProductSpecBasedCurationController.java @@ -0,0 +1,28 @@ +package app.bottlenote.curation.controller; + +import app.bottlenote.curation.service.ProductSpecBasedCurationService; +import app.bottlenote.global.data.response.GlobalResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v2/curations") +@RequiredArgsConstructor +public class ProductSpecBasedCurationController { + + private final ProductSpecBasedCurationService productSpecBasedCurationService; + + @GetMapping + public ResponseEntity getCurations() { + return GlobalResponse.ok(productSpecBasedCurationService.listActiveCurations()); + } + + @GetMapping("/{curationId}") + public ResponseEntity getCuration(@PathVariable Long curationId) { + return GlobalResponse.ok(productSpecBasedCurationService.getDetail(curationId)); + } +} diff --git a/plan/spec-based-curation-v2-graphql-sdl.md b/plan/spec-based-curation-v2-graphql-sdl.md index fbe5e3f16..35f197ec2 100644 --- a/plan/spec-based-curation-v2-graphql-sdl.md +++ b/plan/spec-based-curation-v2-graphql-sdl.md @@ -255,6 +255,30 @@ - Size: L - Status: [x] done +### Phase 3 Task 1: Product v2 query + response materialization + +- Acceptance: + - Product v2 목록/상세 API를 `/api/v2/curations`, `/api/v2/curations/{curationId}`로 추가한다. + - 기존 Product `/api/v1/curations` keyword endpoint는 변경하지 않는다. + - 상세 응답은 header + spec meta + materialized payload 구조로 반환한다. + - `responseSpec.x-graphql` 메타를 읽어 GraphQL query를 생성하고 서버 내부 GraphQL executor로 실행한다. + - `BOTTLE_NOTE` 항목은 `alcohol.alcoholId`로 stats를 보강하고, `MANUAL` 또는 `alcoholId = null` 항목은 GraphQL 조회 대상으로 넘기지 않는다. + - root array 스펙과 `payloadPath = $.alcohols` object 스펙을 모두 지원한다. + - Admin 저장 시점 request payload는 requestSpec 기준으로 required, enum, type, string length, array min/max items, numeric min/max를 검증한다. + - Product 조회 시점 materialized payload는 responseSpec 기준으로 다시 검증한다. +- Verification: + - `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationPayloadValidatorTest' --tests 'app.bottlenote.curation.service.CurationResponseMaterializerTest' --tests 'app.bottlenote.curation.service.ProductSpecBasedCurationServiceTest'` + - `./gradlew :bottlenote-product-api:compileJava` + - `./gradlew check_rule_test` +- Files: + - `bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java` + - `bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpecGraphqlQueryBuilder.java` + - `bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java` + - `bottlenote-mono/src/main/java/app/bottlenote/curation/service/ProductSpecBasedCurationService.java` + - `bottlenote-product-api/src/main/java/app/bottlenote/curation/controller/ProductSpecBasedCurationController.java` +- Size: L +- Status: [x] done + ## Progress Log - 2026-05-15 Task 1 완료: Spring GraphQL starter alias를 version catalog에 추가하고, `bottlenote-mono`에 GraphQL runtime dependency를 연결했다. SDL 경로는 `bottlenote-mono/src/main/resources/graphql/schema.graphqls`로 확정했다. 검증: `./gradlew :bottlenote-mono:compileJava` 성공, `./gradlew :bottlenote-product-api:compileJava` 성공, `git diff -- git.environment-variables/storage/mysql/changelog/` 변경 없음. @@ -272,6 +296,7 @@ - 2026-05-15 Phase 2 Task 3 추가 완료: Liquibase insert seed 대신 admin-api startup resource sync를 추가했다. `CurationSpecResourceReader`가 `bottlenote-mono/src/main/resources/openapi/curation/*.json` 3종을 읽고, `CurationSpecResourceSyncService`가 `code` 기준으로 `curation_spec`을 생성 또는 갱신한다. admin-api runner는 `curation.spec-sync.enabled=${CURATION_SPEC_SYNC_ENABLED:true}`로 제어된다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-admin-api:compileKotlin :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationSpecResourceSyncServiceTest'` 성공, `./gradlew check_rule_test` 성공. - 2026-05-15 Phase 2 Task 2 완료: `bottlenote-mono`에 curation v2 Entity, domain repository interface, JPA repository, `CurationV2Service`, focused fake repository와 unit test를 추가했다. `request_spec`, `response_spec`, `payload` JSON 컬럼은 기존 의존성인 Hypersistence `JsonType`으로 매핑했다. `check_rule_test`에서 서비스 메서드 파라미터 5개 제한과 DTO 패키지/네이밍 규칙이 먼저 실패해 service 입력을 `dto.request`의 `*Request` record로 묶었다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationV2ServiceTest' check_rule_test` 성공, focused 테스트 4개 통과. - 2026-05-15 Phase 2 Task 3 완료: 기존 Admin `/curations` endpoint는 유지하고, 신규 spec 기반 Admin surface를 `/spec-based-curations`와 `/curation-specs`로 추가했다. admin-api의 context-path가 이미 `/admin/api/v1`이므로 컨트롤러 path에 `/v2` prefix를 붙이지 않는다. 스펙 API는 목록/상세를 제공한다. 등록/수정은 `specId`로 `curation_spec`을 조회하고, `imageUrls` 1~3장을 정규화해 첫 번째 이미지를 `cover_image_url`에 저장하며, payload는 `curation_extension.payload`에 저장한다. 새 의존성 없이 requestSpec의 required field와 payload 크기를 검증하는 `CurationPayloadValidator`를 추가했다. 검증: `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.AdminSpecBasedCurationServiceTest' :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` 성공, service 테스트 5개와 RestDocs 테스트 6개 통과. `./gradlew check_rule_test` 성공. +- 2026-05-15 Phase 3 Task 1 완료: Product v2 조회 API `/api/v2/curations`, `/api/v2/curations/{curationId}`를 추가하고, `responseSpec.x-graphql` 기반 materializer를 도입했다. materializer는 GraphQL query/variables를 responseSpec에서 만들고, Spring GraphQL executor를 통해 내부 실행한 뒤 payload의 `stats` 위치에 병합한다. root array와 `payloadPath = $.alcohols` object payload를 모두 지원하며, `MANUAL` 또는 `alcoholId = null` 항목은 stats를 null로 둔다. `CurationPayloadValidator`는 requestSpec/responseSpec 공통 검증기로 확장해 required, enum, type, minLength/maxLength, minItems/maxItems, minimum/maximum을 검증한다. 검증: focused 테스트 13개 통과, `./gradlew :bottlenote-product-api:compileJava` 성공, `./gradlew check_rule_test` 성공. ## Current Decision Summary @@ -283,15 +308,16 @@ - `MANUAL` 항목처럼 `alcoholId = null`인 payload는 후속 Product hydration 단계에서 GraphQL 조회 대상으로 넘기지 않는다. - 기존 `curation_keyword`, `curation_keyword_alcohol_ids`, 기존 curation endpoint는 유지한다. - 신규 schema 변경은 Phase 2 Task 1에서 `git.environment-variables/storage/mysql/changelog/` 아래 changelog로 추가했고, 개발 DB와 운영 DB에 Liquibase CLI로 적용했다. -- Phase 2 Task 3에서 Admin spec 기반 endpoint를 추가했다. 최종 URL은 admin-api context-path를 포함해 `/admin/api/v1/curation-specs`, `/admin/api/v1/spec-based-curations`다. Product v2 endpoint는 아직 만들지 않았다. +- Phase 2 Task 3에서 Admin spec 기반 endpoint를 추가했다. 최종 URL은 admin-api context-path를 포함해 `/admin/api/v1/curation-specs`, `/admin/api/v1/spec-based-curations`다. +- Phase 3 Task 1에서 Product spec 기반 endpoint를 추가했다. 최종 URL은 `/api/v2/curations`, `/api/v2/curations/{curationId}`다. ## Next Work -### Next: Phase 3 - Product V2 Query + Hydration +### Next: Phase 3 - Product V2 API Documentation + Runtime Smoke -다음 작업은 Product에서 신규 curation v2를 조회하고 GraphQL hydration 결과를 조립하는 것이다. +다음 작업은 Product v2 API 문서화와 실제 기동 smoke 검증이다. -- Product v2 목록/상세 API를 추가한다. -- 저장 payload를 response spec과 GraphQL hydration 결과로 앱 응답 형태로 조립한다. -- `source = BOTTLE_NOTE` 항목만 stats를 보강하고 `source = MANUAL` 항목은 stats를 생략한다. +- Product v2 목록/상세 API RestDocs 또는 OpenAPI 문서를 추가한다. +- `.env` 기반 product-api 기동 후 `/api/v2/curations`, `/api/v2/curations/{curationId}`를 실제 DB 데이터로 호출한다. +- 응답 payload가 `responseSpec`과 일치하고 `stats`가 의도대로 병합되는지 runtime smoke로 확인한다. - 기존 curation keyword endpoint는 계속 유지한다. From 5d9369de09e374a259837482f9a44ce605d1710d Mon Sep 17 00:00:00 2001 From: hgkim Date: Fri, 15 May 2026 16:56:16 +0900 Subject: [PATCH 05/33] =?UTF-8?q?docs:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20Product=20API=20=EB=AC=B8=EC=84=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...roductSpecBasedCurationControllerTest.java | 194 ++++++++++++++++++ plan/spec-based-curation-v2-graphql-sdl.md | 33 ++- 2 files changed, 222 insertions(+), 5 deletions(-) create mode 100644 bottlenote-product-api/src/test/java/app/docs/curation/RestProductSpecBasedCurationControllerTest.java diff --git a/bottlenote-product-api/src/test/java/app/docs/curation/RestProductSpecBasedCurationControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/curation/RestProductSpecBasedCurationControllerTest.java new file mode 100644 index 000000000..719fa230a --- /dev/null +++ b/bottlenote-product-api/src/test/java/app/docs/curation/RestProductSpecBasedCurationControllerTest.java @@ -0,0 +1,194 @@ +package app.docs.curation; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.JsonFieldType.ARRAY; +import static org.springframework.restdocs.payload.JsonFieldType.BOOLEAN; +import static org.springframework.restdocs.payload.JsonFieldType.NUMBER; +import static org.springframework.restdocs.payload.JsonFieldType.OBJECT; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import app.bottlenote.curation.controller.ProductSpecBasedCurationController; +import app.bottlenote.curation.dto.response.ProductSpecBasedCurationDetailResponse; +import app.bottlenote.curation.dto.response.ProductSpecBasedCurationListResponse; +import app.bottlenote.curation.service.ProductSpecBasedCurationService; +import app.docs.AbstractRestDocs; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("Product spec 기반 큐레이션 v2 API 문서화 테스트") +class RestProductSpecBasedCurationControllerTest extends AbstractRestDocs { + + private final ProductSpecBasedCurationService productSpecBasedCurationService = + mock(ProductSpecBasedCurationService.class); + + @Override + protected Object initController() { + return new ProductSpecBasedCurationController(productSpecBasedCurationService); + } + + @Test + @DisplayName("spec 기반 큐레이션 v2 목록을 조회할 수 있다") + void getCurations() throws Exception { + when(productSpecBasedCurationService.listActiveCurations()) + .thenReturn( + List.of( + new ProductSpecBasedCurationListResponse( + 1L, + 1L, + "RECOMMENDED_WHISKY", + "추천 위스키", + "비 오는 날 위스키", + "스모키 위스키 추천", + "https://cdn.example.com/cover.jpg", + List.of( + "https://cdn.example.com/cover.jpg", "https://cdn.example.com/second.jpg"), + LocalDate.of(2026, 6, 1), + LocalDate.of(2026, 6, 30), + 1, + LocalDateTime.of(2026, 5, 15, 12, 0)))); + + mockMvc + .perform(get("/api/v2/curations")) + .andExpect(status().isOk()) + .andDo( + document( + "curation/v2/list", + responseFields( + fieldWithPath("success").type(BOOLEAN).description("응답 성공 여부"), + fieldWithPath("code").type(NUMBER).description("응답 코드"), + fieldWithPath("data").type(ARRAY).description("spec 기반 큐레이션 목록"), + fieldWithPath("data[].id").type(NUMBER).description("큐레이션 ID"), + fieldWithPath("data[].specId").type(NUMBER).description("큐레이션 스펙 ID"), + fieldWithPath("data[].specCode").description("큐레이션 스펙 코드"), + fieldWithPath("data[].specName").description("큐레이션 스펙명"), + fieldWithPath("data[].name").description("큐레이션 이름"), + fieldWithPath("data[].description").description("큐레이션 설명").optional(), + fieldWithPath("data[].coverImageUrl").description("대표 이미지 URL"), + fieldWithPath("data[].imageUrls").type(ARRAY).description("큐레이션 이미지 URL 목록"), + fieldWithPath("data[].exposureStartDate") + .type(ARRAY) + .description("노출 시작일") + .optional(), + fieldWithPath("data[].exposureEndDate") + .type(ARRAY) + .description("노출 종료일") + .optional(), + fieldWithPath("data[].displayOrder").type(NUMBER).description("노출 순서"), + fieldWithPath("data[].createAt").type(ARRAY).description("생성 일시"), + fieldWithPath("errors").type(ARRAY).description("에러 목록"), + fieldWithPath("meta.serverEncoding").ignored(), + fieldWithPath("meta.serverVersion").ignored(), + fieldWithPath("meta.serverPathVersion").ignored(), + fieldWithPath("meta.serverResponseTime").ignored()))); + } + + @Test + @DisplayName("spec 기반 큐레이션 v2 상세를 materialized payload로 조회할 수 있다") + void getCuration() throws Exception { + when(productSpecBasedCurationService.getDetail(1L)) + .thenReturn( + new ProductSpecBasedCurationDetailResponse( + 1L, + "비 오는 날 위스키", + "스모키 위스키 추천", + "https://cdn.example.com/cover.jpg", + List.of("https://cdn.example.com/cover.jpg"), + LocalDate.of(2026, 6, 1), + LocalDate.of(2026, 6, 30), + 1, + LocalDateTime.of(2026, 5, 15, 12, 0), + new ProductSpecBasedCurationDetailResponse.SpecMeta( + 1L, + "RECOMMENDED_WHISKY", + "추천 위스키", + "array", + map("type", "object", "x-container", "array")), + List.of( + item( + "BOTTLE_NOTE", + map("alcoholId", 1, "korName", "테스트 위스키", "selectedTags", List.of("셰리")), + map( + "rating", + 4.2, + "totalRatingsCount", + 10, + "reviewCount", + 3, + "totalPickCount", + 8)), + item( + "MANUAL", + map("alcoholId", null, "korName", "수동 위스키", "selectedTags", List.of("오크")), + null)))); + + mockMvc + .perform(get("/api/v2/curations/{curationId}", 1L)) + .andExpect(status().isOk()) + .andDo( + document( + "curation/v2/detail", + pathParameters(parameterWithName("curationId").description("큐레이션 ID")), + responseFields( + fieldWithPath("success").type(BOOLEAN).description("응답 성공 여부"), + fieldWithPath("code").type(NUMBER).description("응답 코드"), + fieldWithPath("data").type(OBJECT).description("큐레이션 상세"), + fieldWithPath("data.id").type(NUMBER).description("큐레이션 ID"), + fieldWithPath("data.name").description("큐레이션 이름"), + fieldWithPath("data.description").description("큐레이션 설명").optional(), + fieldWithPath("data.coverImageUrl").description("대표 이미지 URL"), + fieldWithPath("data.imageUrls").type(ARRAY).description("큐레이션 이미지 URL 목록"), + fieldWithPath("data.exposureStartDate") + .type(ARRAY) + .description("노출 시작일") + .optional(), + fieldWithPath("data.exposureEndDate") + .type(ARRAY) + .description("노출 종료일") + .optional(), + fieldWithPath("data.displayOrder").type(NUMBER).description("노출 순서"), + fieldWithPath("data.createAt").type(ARRAY).description("생성 일시"), + fieldWithPath("data.spec").type(OBJECT).description("스펙 메타"), + fieldWithPath("data.spec.id").type(NUMBER).description("스펙 ID"), + fieldWithPath("data.spec.code").description("스펙 코드"), + fieldWithPath("data.spec.name").description("스펙명"), + fieldWithPath("data.spec.container") + .description("payload 컨테이너 타입(array 또는 object)"), + subsectionWithPath("data.spec.responseSpec") + .type(OBJECT) + .description("Product 응답 검증 기준 OpenAPI response schema"), + subsectionWithPath("data.payload") + .type(ARRAY) + .description("responseSpec 기준으로 materialized 된 payload"), + fieldWithPath("errors").type(ARRAY).description("에러 목록"), + fieldWithPath("meta.serverEncoding").ignored(), + fieldWithPath("meta.serverVersion").ignored(), + fieldWithPath("meta.serverPathVersion").ignored(), + fieldWithPath("meta.serverResponseTime").ignored()))); + } + + private static Map item( + String source, Map alcohol, Map stats) { + return map("source", source, "alcohol", alcohol, "comment", "추천 코멘트", "stats", stats); + } + + private static Map map(Object... values) { + Map map = new LinkedHashMap<>(); + for (int i = 0; i < values.length; i += 2) { + map.put((String) values[i], values[i + 1]); + } + return map; + } +} diff --git a/plan/spec-based-curation-v2-graphql-sdl.md b/plan/spec-based-curation-v2-graphql-sdl.md index 35f197ec2..b9e3fec3c 100644 --- a/plan/spec-based-curation-v2-graphql-sdl.md +++ b/plan/spec-based-curation-v2-graphql-sdl.md @@ -279,6 +279,28 @@ - Size: L - Status: [x] done +### Phase 3 Task 2: Product v2 API docs + runtime smoke + +- Acceptance: + - Product v2 목록/상세 API RestDocs 테스트를 추가한다. + - `/api/v2/curations` 문서에는 spec 기반 큐레이션 목록 응답 구조를 남긴다. + - `/api/v2/curations/{curationId}` 문서에는 header, spec meta, materialized payload 구조를 남긴다. + - `.env` 기반 product-api 기동 후 `/api/v2/curations` runtime smoke를 수행한다. + - 실제 DB에 smoke row가 없으면 임시 row를 생성해 상세 조회까지 검증하고, 검증 후 삭제한다. + - smoke는 `BOTTLE_NOTE` stats 병합과 `MANUAL` stats null 처리를 확인한다. +- Verification: + - `./gradlew :bottlenote-product-api:test --tests 'app.docs.curation.RestProductSpecBasedCurationControllerTest'` + - `./gradlew :bottlenote-product-api:asciidoctor` + - `./gradlew check_rule_test` + - `.env` 기반 `./gradlew :bottlenote-product-api:bootRun` + - `GET /api/v2/curations` HTTP 200 + - `GET /api/v2/curations/{curationId}` HTTP 200 +- Files: + - `bottlenote-product-api/src/test/java/app/docs/curation/RestProductSpecBasedCurationControllerTest.java` + - `plan/spec-based-curation-v2-graphql-sdl.md` +- Size: M +- Status: [x] done + ## Progress Log - 2026-05-15 Task 1 완료: Spring GraphQL starter alias를 version catalog에 추가하고, `bottlenote-mono`에 GraphQL runtime dependency를 연결했다. SDL 경로는 `bottlenote-mono/src/main/resources/graphql/schema.graphqls`로 확정했다. 검증: `./gradlew :bottlenote-mono:compileJava` 성공, `./gradlew :bottlenote-product-api:compileJava` 성공, `git diff -- git.environment-variables/storage/mysql/changelog/` 변경 없음. @@ -297,6 +319,7 @@ - 2026-05-15 Phase 2 Task 2 완료: `bottlenote-mono`에 curation v2 Entity, domain repository interface, JPA repository, `CurationV2Service`, focused fake repository와 unit test를 추가했다. `request_spec`, `response_spec`, `payload` JSON 컬럼은 기존 의존성인 Hypersistence `JsonType`으로 매핑했다. `check_rule_test`에서 서비스 메서드 파라미터 5개 제한과 DTO 패키지/네이밍 규칙이 먼저 실패해 service 입력을 `dto.request`의 `*Request` record로 묶었다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationV2ServiceTest' check_rule_test` 성공, focused 테스트 4개 통과. - 2026-05-15 Phase 2 Task 3 완료: 기존 Admin `/curations` endpoint는 유지하고, 신규 spec 기반 Admin surface를 `/spec-based-curations`와 `/curation-specs`로 추가했다. admin-api의 context-path가 이미 `/admin/api/v1`이므로 컨트롤러 path에 `/v2` prefix를 붙이지 않는다. 스펙 API는 목록/상세를 제공한다. 등록/수정은 `specId`로 `curation_spec`을 조회하고, `imageUrls` 1~3장을 정규화해 첫 번째 이미지를 `cover_image_url`에 저장하며, payload는 `curation_extension.payload`에 저장한다. 새 의존성 없이 requestSpec의 required field와 payload 크기를 검증하는 `CurationPayloadValidator`를 추가했다. 검증: `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.AdminSpecBasedCurationServiceTest' :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` 성공, service 테스트 5개와 RestDocs 테스트 6개 통과. `./gradlew check_rule_test` 성공. - 2026-05-15 Phase 3 Task 1 완료: Product v2 조회 API `/api/v2/curations`, `/api/v2/curations/{curationId}`를 추가하고, `responseSpec.x-graphql` 기반 materializer를 도입했다. materializer는 GraphQL query/variables를 responseSpec에서 만들고, Spring GraphQL executor를 통해 내부 실행한 뒤 payload의 `stats` 위치에 병합한다. root array와 `payloadPath = $.alcohols` object payload를 모두 지원하며, `MANUAL` 또는 `alcoholId = null` 항목은 stats를 null로 둔다. `CurationPayloadValidator`는 requestSpec/responseSpec 공통 검증기로 확장해 required, enum, type, minLength/maxLength, minItems/maxItems, minimum/maximum을 검증한다. 검증: focused 테스트 13개 통과, `./gradlew :bottlenote-product-api:compileJava` 성공, `./gradlew check_rule_test` 성공. +- 2026-05-15 Phase 3 Task 2 완료: Product v2 목록/상세 RestDocs 테스트를 추가했고, `curation/v2/list`, `curation/v2/detail` 스니펫이 생성되는 것을 확인했다. `./gradlew :bottlenote-product-api:asciidoctor check_rule_test` 성공으로 `product-api.html` 생성과 rule test 통과를 확인했다. runtime smoke는 `.env` 기반 product-api를 8080에서 기동해 `GET /api/v2/curations` HTTP 200을 확인했다. 개발 DB에 active spec 기반 큐레이션이 0건이어서 `CODEX_RUNTIME_SMOKE_20260515` 임시 row를 생성한 뒤 `GET /api/v2/curations` HTTP 200, `GET /api/v2/curations/1` HTTP 200, list count=1, detail spec=`RECOMMENDED_WHISKY`, payload_count=2, BOTTLE_NOTE stats keys=`rating,reviewCount,totalPickCount,totalRatingsCount`, MANUAL stats null을 확인했다. 검증 후 임시 row는 삭제했고 삭제 확인 count=0, bootRun 프로세스도 종료했다. ## Current Decision Summary @@ -313,11 +336,11 @@ ## Next Work -### Next: Phase 3 - Product V2 API Documentation + Runtime Smoke +### Next: Phase 3 - Product V2 Runtime Hardening -다음 작업은 Product v2 API 문서화와 실제 기동 smoke 검증이다. +다음 작업은 실제 운영 응답 안전성을 높이는 보강이다. -- Product v2 목록/상세 API RestDocs 또는 OpenAPI 문서를 추가한다. -- `.env` 기반 product-api 기동 후 `/api/v2/curations`, `/api/v2/curations/{curationId}`를 실제 DB 데이터로 호출한다. -- 응답 payload가 `responseSpec`과 일치하고 `stats`가 의도대로 병합되는지 runtime smoke로 확인한다. +- `responseSpec` 불일치 시 내부 로그에 curationId/specCode/error path를 남긴다. +- Product v2 상세 조회에서 GraphQL executor error가 있을 때의 실패 정책을 명확히 한다. +- exposure date filtering을 Product 목록/상세에 적용할지 정책 결정 후 구현한다. - 기존 curation keyword endpoint는 계속 유지한다. From b6658c80322b5f3e519946eaeea40f3158c7fc79 Mon Sep 17 00:00:00 2001 From: hgkim Date: Fri, 15 May 2026 17:07:07 +0900 Subject: [PATCH 06/33] =?UTF-8?q?chore:=20=ED=99=98=EA=B2=BD=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EC=84=9C=EB=B8=8C=EB=AA=A8=EB=93=88=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- git.environment-variables | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git.environment-variables b/git.environment-variables index 03212f4ff..350b4b324 160000 --- a/git.environment-variables +++ b/git.environment-variables @@ -1 +1 @@ -Subproject commit 03212f4ff7f450220448ab1850bf2cd67c319110 +Subproject commit 350b4b3245ca7c0dda5ec34feee9f41dc3204066 From b98f08933926608f5542f4ac219fc2c88481c606 Mon Sep 17 00:00:00 2001 From: hgkim Date: Fri, 15 May 2026 17:42:20 +0900 Subject: [PATCH 07/33] =?UTF-8?q?test:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20=ED=86=B5=ED=95=A9=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AdminSpecBasedCurationIntegrationTest.kt | 168 ++++++++++++++ ...oductSpecBasedCurationIntegrationTest.java | 213 ++++++++++++++++++ 2 files changed, 381 insertions(+) create mode 100644 bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt create mode 100644 bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt new file mode 100644 index 000000000..e492b3d9f --- /dev/null +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt @@ -0,0 +1,168 @@ +package app.integration.curation + +import app.IntegrationTestSupport +import app.bottlenote.curation.domain.CurationSpecRepository +import app.bottlenote.curation.service.CurationSpecResourceSyncService +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Tag +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.MediaType + +@Tag("admin_integration") +@DisplayName("[integration] Admin Spec Based Curation API 통합 테스트") +class AdminSpecBasedCurationIntegrationTest : IntegrationTestSupport() { + @Autowired + private lateinit var curationSpecResourceSyncService: CurationSpecResourceSyncService + + @Autowired + private lateinit var curationSpecRepository: CurationSpecRepository + + private lateinit var accessToken: String + + @BeforeEach + fun setUp() { + val admin = adminUserTestFactory.persistRootAdmin() + accessToken = getAccessToken(admin) + curationSpecResourceSyncService.sync() + } + + @Nested + @DisplayName("큐레이션 스펙 조회 API") + inner class CurationSpecs { + @Test + @DisplayName("활성 큐레이션 스펙 목록을 조회할 수 있다") + fun listSpecsSuccess() { + val result = mockMvcTester + .get() + .uri("/curation-specs") + .header("Authorization", "Bearer $accessToken") + .exchange() + + assertThat(result).hasStatusOk() + assertThat(dataNode(result).map { it.path("code").asText() }) + .contains("RECOMMENDED_WHISKY") + } + + @Test + @DisplayName("큐레이션 스펙 상세에서 requestSpec과 responseSpec을 조회할 수 있다") + fun getSpecDetailSuccess() { + val specId = recommendedSpecId() + + assertThat( + mockMvcTester + .get() + .uri("/curation-specs/$specId") + .header("Authorization", "Bearer $accessToken") + ).hasStatusOk() + .bodyJson() + .extractingPath("$.data.responseSpec.properties.stats.x-graphql.query") + .isEqualTo("alcohols") + } + } + + @Nested + @DisplayName("spec 기반 큐레이션 생성 API") + inner class CreateSpecBasedCuration { + @Test + @DisplayName("request spec의 maxItems 경계값 이내 payload는 생성할 수 있다") + fun create_whenPayloadMatchesRequestSpec_returnsCreated() { + val request = createRequest(validPayload(selectedTags = List(12) { index -> "태그$index" })) + + assertThat( + mockMvcTester + .post() + .uri("/spec-based-curations") + .header("Authorization", "Bearer $accessToken") + .contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(request)) + ).hasStatusOk() + .bodyJson() + .extractingPath("$.data.code") + .isEqualTo("CURATION_CREATED") + } + + @Test + @DisplayName("request spec의 required 필드가 없으면 400을 반환한다") + fun create_whenRequiredFieldMissing_returnsBadRequest() { + val payload = mapOf( + "alcohol" to mapOf( + "korName" to "필수값 테스트", + "selectedTags" to listOf("오크") + ) + ) + + assertBadRequest(createRequest(payload)) + } + + @Test + @DisplayName("request spec의 enum 값이 아니면 400을 반환한다") + fun create_whenEnumValueInvalid_returnsBadRequest() { + val payload = validPayload(source = "UNKNOWN_SOURCE") + + assertBadRequest(createRequest(payload)) + } + + @Test + @DisplayName("request spec의 maxItems를 초과하면 400을 반환한다") + fun create_whenSelectedTagsExceedsMaxItems_returnsBadRequest() { + val payload = validPayload(selectedTags = List(13) { index -> "태그$index" }) + + assertBadRequest(createRequest(payload)) + } + + @Test + @DisplayName("request spec의 minLength보다 짧은 배열 항목이면 400을 반환한다") + fun create_whenSelectedTagBelowMinLength_returnsBadRequest() { + val payload = validPayload(selectedTags = listOf("")) + + assertBadRequest(createRequest(payload)) + } + } + + private fun assertBadRequest(request: Map) { + assertThat( + mockMvcTester + .post() + .uri("/spec-based-curations") + .header("Authorization", "Bearer $accessToken") + .contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(request)) + ).hasStatus4xxClientError() + .bodyJson() + .extractingPath("$.code") + .isEqualTo(400) + } + + private fun createRequest(payload: Any): Map = mapOf( + "specId" to recommendedSpecId(), + "name" to "통합 테스트 큐레이션", + "description" to "request spec 검증 테스트", + "imageUrls" to listOf("https://cdn.example.com/cover.jpg"), + "exposureStartDate" to "2026-06-01", + "exposureEndDate" to "2026-06-30", + "displayOrder" to 1, + "isActive" to true, + "payload" to listOf(payload) + ) + + private fun validPayload( + source: String = "BOTTLE_NOTE", + selectedTags: List = listOf("셰리", "오크") + ): Map = mapOf( + "source" to source, + "alcohol" to mapOf( + "alcoholId" to 1L, + "korName" to "검증 위스키", + "selectedTags" to selectedTags + ), + "comment" to "테스트 코멘트" + ) + + private fun dataNode(result: org.springframework.test.web.servlet.assertj.MvcTestResult) = mapper.valueToTree(parseResponse(result).data) + + private fun recommendedSpecId(): Long = curationSpecRepository.findByCode("RECOMMENDED_WHISKY").orElseThrow().id +} diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java b/bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java new file mode 100644 index 000000000..fea0175d1 --- /dev/null +++ b/bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java @@ -0,0 +1,213 @@ +package app.bottlenote.curation.integration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.http.MediaType.APPLICATION_JSON; + +import app.bottlenote.IntegrationTestSupport; +import app.bottlenote.alcohols.domain.Alcohol; +import app.bottlenote.alcohols.fixture.AlcoholTestFactory; +import app.bottlenote.curation.domain.CurationSpec; +import app.bottlenote.curation.domain.CurationSpecRepository; +import app.bottlenote.curation.dto.request.CurationCreateRequest; +import app.bottlenote.curation.service.AdminSpecBasedCurationService; +import app.bottlenote.curation.service.CurationSpecResourceSyncService; +import app.bottlenote.global.data.response.GlobalResponse; +import app.bottlenote.picks.fixture.PicksTestFactory; +import app.bottlenote.rating.fixture.RatingTestFactory; +import app.bottlenote.review.fixture.ReviewTestFactory; +import app.bottlenote.user.domain.User; +import app.bottlenote.user.fixture.UserTestFactory; +import com.fasterxml.jackson.databind.JsonNode; +import java.time.LocalDate; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.web.servlet.assertj.MvcTestResult; + +@Tag("integration") +@DisplayName("[integration] Product Spec Based Curation API 통합 테스트") +class ProductSpecBasedCurationIntegrationTest extends IntegrationTestSupport { + + @Autowired private CurationSpecResourceSyncService curationSpecResourceSyncService; + @Autowired private CurationSpecRepository curationSpecRepository; + @Autowired private AdminSpecBasedCurationService adminSpecBasedCurationService; + @Autowired private AlcoholTestFactory alcoholTestFactory; + @Autowired private UserTestFactory userTestFactory; + @Autowired private RatingTestFactory ratingTestFactory; + @Autowired private ReviewTestFactory reviewTestFactory; + @Autowired private PicksTestFactory picksTestFactory; + + private CurationSpec recommendedSpec; + + @BeforeEach + void setUp() { + curationSpecResourceSyncService.sync(); + recommendedSpec = curationSpecRepository.findByCode("RECOMMENDED_WHISKY").orElseThrow(); + } + + @Nested + @DisplayName("큐레이션 목록 조회 API") + class ListCurations { + + @Test + @DisplayName("활성 큐레이션만 displayOrder와 id 순서로 조회할 수 있다") + void listActiveCurations_whenMixedStatus_returnsOnlyActiveItemsInDisplayOrder() + throws Exception { + // given + Long laterId = createCuration("뒤 큐레이션", 20, true, List.of(manualItem("뒤"))); + createCuration("비활성 큐레이션", 1, false, List.of(manualItem("비활성"))); + Long firstId = createCuration("앞 큐레이션", 1, true, List.of(manualItem("앞"))); + + // when + MvcTestResult result = + mockMvcTester.get().uri("/api/v2/curations").contentType(APPLICATION_JSON).exchange(); + + // then + JsonNode data = dataNode(result); + assertThat(data).hasSize(2); + assertThat(data.get(0).path("id").asLong()).isEqualTo(firstId); + assertThat(data.get(1).path("id").asLong()).isEqualTo(laterId); + assertThat(data.get(0).path("specCode").asText()).isEqualTo("RECOMMENDED_WHISKY"); + assertThat(data.get(0).path("imageUrls").get(0).asText()) + .isEqualTo("https://cdn.example.com/cover.jpg"); + } + + @Test + @DisplayName("활성 큐레이션이 없으면 빈 배열을 반환한다") + void listActiveCurations_whenNoActiveCuration_returnsEmptyArray() throws Exception { + // when + MvcTestResult result = + mockMvcTester.get().uri("/api/v2/curations").contentType(APPLICATION_JSON).exchange(); + + // then + assertThat(dataNode(result)).isEmpty(); + } + } + + @Nested + @DisplayName("큐레이션 상세 조회 API") + class GetCurationDetail { + + @Test + @DisplayName("BOTTLE_NOTE 항목은 GraphQL로 통계를 보강하고 MANUAL 항목은 stats를 null로 응답한다") + void getDetail_whenBottleNoteAndManualItems_returnsPayloadMatchingResponseSpec() + throws Exception { + // given + Alcohol alcohol = + alcoholTestFactory.persistAlcoholWithName("통합 테스트 위스키", "Integration Whisky"); + User userA = userTestFactory.persistUser(); + User userB = userTestFactory.persistUser(); + ratingTestFactory.persistRating(userA, alcohol, 4); + ratingTestFactory.persistRating(userB, alcohol, 5); + reviewTestFactory.persistReview(userA, alcohol); + picksTestFactory.persistPicks(alcohol.getId(), userA.getId()); + Long curationId = + createCuration( + "상세 큐레이션", 1, true, List.of(bottleNoteItem(alcohol), manualItem("수동 위스키"))); + + // when + MvcTestResult result = + mockMvcTester + .get() + .uri("/api/v2/curations/{curationId}", curationId) + .contentType(APPLICATION_JSON) + .exchange(); + + // then + JsonNode data = dataNode(result); + JsonNode payload = data.path("payload"); + assertThat(data.path("id").asLong()).isEqualTo(curationId); + assertThat(data.path("spec").path("code").asText()).isEqualTo("RECOMMENDED_WHISKY"); + assertThat(data.path("spec").path("container").asText()).isEqualTo("array"); + assertThat(payload).hasSize(2); + assertThat(payload.get(0).path("stats").path("rating").asDouble()).isEqualTo(4.5); + assertThat(payload.get(0).path("stats").path("totalRatingsCount").asLong()).isEqualTo(2L); + assertThat(payload.get(0).path("stats").path("reviewCount").asLong()).isEqualTo(1L); + assertThat(payload.get(0).path("stats").path("totalPickCount").asLong()).isEqualTo(1L); + assertThat(payload.get(0).path("stats").has("alcoholId")).isFalse(); + assertThat(payload.get(1).path("stats").isNull()).isTrue(); + } + + @Test + @DisplayName("비활성 큐레이션 상세 조회는 404를 반환한다") + void getDetail_whenInactiveCuration_returnsNotFound() { + // given + Long curationId = createCuration("비활성 상세", 1, false, List.of(manualItem("비활성"))); + + // when & then + assertThat(mockMvcTester.get().uri("/api/v2/curations/{curationId}", curationId)) + .hasStatus4xxClientError() + .bodyJson() + .extractingPath("$.code") + .isEqualTo(404); + } + + @Test + @DisplayName("존재하지 않는 큐레이션 상세 조회는 404를 반환한다") + void getDetail_whenMissingCuration_returnsNotFound() { + assertThat(mockMvcTester.get().uri("/api/v2/curations/{curationId}", 999999L)) + .hasStatus4xxClientError() + .bodyJson() + .extractingPath("$.code") + .isEqualTo(404); + } + } + + private Long createCuration( + String name, int displayOrder, boolean active, List> payload) { + return adminSpecBasedCurationService + .create( + new CurationCreateRequest( + recommendedSpec.getId(), + name, + "통합 테스트 큐레이션", + List.of("https://cdn.example.com/cover.jpg"), + LocalDate.of(2026, 6, 1), + LocalDate.of(2026, 6, 30), + displayOrder, + active, + payload)) + .targetId(); + } + + private JsonNode dataNode(MvcTestResult result) throws Exception { + result.assertThat().hasStatusOk(); + GlobalResponse response = + mapper.readValue(result.getResponse().getContentAsString(), GlobalResponse.class); + return mapper.valueToTree(response.getData()); + } + + private Map bottleNoteItem(Alcohol alcohol) { + return item( + "BOTTLE_NOTE", + map( + "alcoholId", + alcohol.getId(), + "korName", + alcohol.getKorName(), + "selectedTags", + List.of("셰리", "오크"))); + } + + private Map manualItem(String name) { + return item("MANUAL", map("alcoholId", null, "korName", name, "selectedTags", List.of("오크"))); + } + + private Map item(String source, Map alcohol) { + return map("source", source, "alcohol", alcohol, "comment", "테스트 코멘트"); + } + + private Map map(Object... values) { + Map map = new LinkedHashMap<>(); + for (int i = 0; i < values.length; i += 2) { + map.put((String) values[i], values[i + 1]); + } + return map; + } +} From 3bb18951e7eb5ea1576469d9f24599193bcc77f4 Mon Sep 17 00:00:00 2001 From: hgkim Date: Fri, 15 May 2026 17:42:35 +0900 Subject: [PATCH 08/33] =?UTF-8?q?deps:=20=ED=99=98=EA=B2=BD=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EC=84=9C=EB=B8=8C=EB=AA=A8=EB=93=88=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- git.environment-variables | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git.environment-variables b/git.environment-variables index 350b4b324..25cd6fd39 160000 --- a/git.environment-variables +++ b/git.environment-variables @@ -1 +1 @@ -Subproject commit 350b4b3245ca7c0dda5ec34feee9f41dc3204066 +Subproject commit 25cd6fd399ee579a3b1a6aebc690a669114749cc From 55895949d0afbac029e92ce52e8e04de300ba7eb Mon Sep 17 00:00:00 2001 From: hgkim Date: Fri, 15 May 2026 18:18:52 +0900 Subject: [PATCH 09/33] =?UTF-8?q?deps:=20=ED=99=98=EA=B2=BD=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EC=84=9C=EB=B8=8C=EB=AA=A8=EB=93=88=20=EC=B5=9C?= =?UTF-8?q?=EC=8B=A0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- git.environment-variables | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git.environment-variables b/git.environment-variables index 25cd6fd39..8dd662e15 160000 --- a/git.environment-variables +++ b/git.environment-variables @@ -1 +1 @@ -Subproject commit 25cd6fd399ee579a3b1a6aebc690a669114749cc +Subproject commit 8dd662e15c098c2e57c36a2604a1ba42fceed9f1 From fe6a379e1b7dc9a9d46bbca6d814188524c0a702 Mon Sep 17 00:00:00 2001 From: hgkim Date: Fri, 15 May 2026 20:35:38 +0900 Subject: [PATCH 10/33] =?UTF-8?q?fix:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20=EB=A6=AC=EB=B7=B0=20=EC=A7=80=EC=A0=81=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AdminSpecBasedCurationIntegrationTest.kt | 8 +++ .../dto/request/CurationCreateRequest.java | 10 ++-- .../dto/request/CurationUpdateRequest.java | 14 ++--- .../CurationAlcoholGraphqlResolver.java | 55 +++++++++++++++++-- .../CurationAlcoholGraphqlService.java | 46 ++++++++++++++++ .../custom/code/ValidExceptionCode.java | 9 +++ .../constant/MaliciousPathPattern.java | 5 ++ .../picks/domain/PicksRepository.java | 5 ++ .../response/AlcoholPicksCountResponse.java | 3 + .../picks/repository/JpaPicksRepository.java | 17 ++++++ .../rating/domain/RatingRepository.java | 3 + .../response/AlcoholRatingStatsResponse.java | 3 + .../repository/JpaRatingRepository.java | 18 ++++++ .../review/domain/ReviewRepository.java | 4 ++ .../response/AlcoholReviewCountResponse.java | 3 + .../repository/JpaReviewRepository.java | 18 ++++++ .../CurationAlcoholGraphqlResolverTest.java | 31 +++++++++++ .../fixture/InMemoryReviewRepository.java | 14 +++++ .../src/main/resources/application.yml | 2 +- .../picks/fake/FakePicksRepository.java | 14 +++++ .../fixture/InMemoryRatingRepository.java | 14 +++++ .../fixture/InMemoryReviewRepository.java | 14 +++++ .../SecurityConfigIntegrationTest.java | 7 +++ 23 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/picks/dto/response/AlcoholPicksCountResponse.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/rating/dto/response/AlcoholRatingStatsResponse.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/review/dto/response/AlcoholReviewCountResponse.java diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt index e492b3d9f..6593a0768 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt @@ -98,6 +98,14 @@ class AdminSpecBasedCurationIntegrationTest : IntegrationTestSupport() { assertBadRequest(createRequest(payload)) } + @Test + @DisplayName("요청 DTO 필수 필드가 없으면 400을 반환한다") + fun create_whenRequestRequiredFieldMissing_returnsBadRequest() { + val request = createRequest(validPayload()) - "name" + + assertBadRequest(request) + } + @Test @DisplayName("request spec의 enum 값이 아니면 400을 반환한다") fun create_whenEnumValueInvalid_returnsBadRequest() { diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationCreateRequest.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationCreateRequest.java index 453163fa2..584d6f1ce 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationCreateRequest.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationCreateRequest.java @@ -8,17 +8,17 @@ import java.util.List; public record CurationCreateRequest( - @NotNull(message = "큐레이션 스펙 ID는 필수입니다.") Long specId, - @NotBlank(message = "큐레이션 이름은 필수입니다.") String name, + @NotNull(message = "CURATION_SPEC_ID_REQUIRED") Long specId, + @NotBlank(message = "CURATION_NAME_REQUIRED") String name, String description, - @NotEmpty(message = "큐레이션 이미지는 최소 1개 이상이어야 합니다.") - @Size(max = 3, message = "큐레이션 이미지는 최대 3개까지 등록할 수 있습니다.") + @NotEmpty(message = "CURATION_IMAGE_URLS_REQUIRED") + @Size(max = 3, message = "CURATION_IMAGE_URLS_MAX_SIZE") List imageUrls, LocalDate exposureStartDate, LocalDate exposureEndDate, Integer displayOrder, Boolean isActive, - @NotNull(message = "payload는 필수입니다.") Object payload) { + @NotNull(message = "CURATION_PAYLOAD_REQUIRED") Object payload) { public CurationCreateRequest { displayOrder = displayOrder != null ? displayOrder : 0; diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationUpdateRequest.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationUpdateRequest.java index a4ac309c7..642232651 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationUpdateRequest.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationUpdateRequest.java @@ -8,14 +8,14 @@ import java.util.List; public record CurationUpdateRequest( - @NotNull(message = "큐레이션 스펙 ID는 필수입니다.") Long specId, - @NotBlank(message = "큐레이션 이름은 필수입니다.") String name, + @NotNull(message = "CURATION_SPEC_ID_REQUIRED") Long specId, + @NotBlank(message = "CURATION_NAME_REQUIRED") String name, String description, - @NotEmpty(message = "큐레이션 이미지는 최소 1개 이상이어야 합니다.") - @Size(max = 3, message = "큐레이션 이미지는 최대 3개까지 등록할 수 있습니다.") + @NotEmpty(message = "CURATION_IMAGE_URLS_REQUIRED") + @Size(max = 3, message = "CURATION_IMAGE_URLS_MAX_SIZE") List imageUrls, LocalDate exposureStartDate, LocalDate exposureEndDate, - @NotNull(message = "노출 순서는 필수입니다.") Integer displayOrder, - @NotNull(message = "활성화 상태는 필수입니다.") Boolean isActive, - @NotNull(message = "payload는 필수입니다.") Object payload) {} + @NotNull(message = "CURATION_DISPLAY_ORDER_REQUIRED") Integer displayOrder, + @NotNull(message = "CURATION_IS_ACTIVE_REQUIRED") Boolean isActive, + @NotNull(message = "CURATION_PAYLOAD_REQUIRED") Object payload) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolver.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolver.java index 4b8d36c49..123e4da16 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolver.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolver.java @@ -2,9 +2,15 @@ import app.bottlenote.alcohols.domain.Alcohol; import app.bottlenote.curation.service.CurationAlcoholGraphqlService; +import app.bottlenote.rating.dto.response.AlcoholRatingStatsResponse; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.graphql.data.method.annotation.Argument; +import org.springframework.graphql.data.method.annotation.BatchMapping; import org.springframework.graphql.data.method.annotation.QueryMapping; import org.springframework.graphql.data.method.annotation.SchemaMapping; import org.springframework.stereotype.Controller; @@ -30,23 +36,64 @@ public String regionName(Alcohol alcohol) { return curationAlcoholGraphqlService.regionName(alcohol); } - @SchemaMapping(typeName = "Alcohol", field = "rating") + @BatchMapping(typeName = "Alcohol", field = "rating") + public Map ratings(List alcohols) { + Map stats = + curationAlcoholGraphqlService.ratingStats(alcohols); + return mapByAlcohol(alcohols, alcohol -> ratingStatsOf(stats, alcohol).rating()); + } + + @BatchMapping(typeName = "Alcohol", field = "totalRatingsCount") + public Map totalRatingsCounts(List alcohols) { + Map stats = + curationAlcoholGraphqlService.ratingStats(alcohols); + return mapByAlcohol(alcohols, alcohol -> ratingStatsOf(stats, alcohol).totalRatingsCount()); + } + + @BatchMapping(typeName = "Alcohol", field = "reviewCount") + public Map reviewCounts(List alcohols) { + Map counts = curationAlcoholGraphqlService.reviewCounts(alcohols); + return mapByAlcohol(alcohols, alcohol -> counts.getOrDefault(alcohol.getId(), 0L)); + } + + @BatchMapping(typeName = "Alcohol", field = "totalPickCount") + public Map totalPickCounts(List alcohols) { + Map counts = curationAlcoholGraphqlService.pickCounts(alcohols); + return mapByAlcohol(alcohols, alcohol -> counts.getOrDefault(alcohol.getId(), 0L)); + } + public Double rating(Alcohol alcohol) { return curationAlcoholGraphqlService.rating(alcohol); } - @SchemaMapping(typeName = "Alcohol", field = "totalRatingsCount") public Long totalRatingsCount(Alcohol alcohol) { return curationAlcoholGraphqlService.totalRatingsCount(alcohol); } - @SchemaMapping(typeName = "Alcohol", field = "reviewCount") public Long reviewCount(Alcohol alcohol) { return curationAlcoholGraphqlService.reviewCount(alcohol); } - @SchemaMapping(typeName = "Alcohol", field = "totalPickCount") public Long totalPickCount(Alcohol alcohol) { return curationAlcoholGraphqlService.totalPickCount(alcohol); } + + private Map mapByAlcohol(List alcohols, Function mapper) { + if (alcohols == null || alcohols.isEmpty()) { + return Map.of(); + } + return alcohols.stream() + .collect( + Collectors.toMap( + Function.identity(), mapper, (left, right) -> left, LinkedHashMap::new)); + } + + private AlcoholRatingStatsResponse ratingStatsOf( + Map stats, Alcohol alcohol) { + if (alcohol == null || alcohol.getId() == null) { + return new AlcoholRatingStatsResponse(null, 0.0, 0L); + } + return stats.getOrDefault( + alcohol.getId(), new AlcoholRatingStatsResponse(alcohol.getId(), 0.0, 0L)); + } } diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationAlcoholGraphqlService.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationAlcoholGraphqlService.java index 8c664e352..2df3be819 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationAlcoholGraphqlService.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationAlcoholGraphqlService.java @@ -4,10 +4,13 @@ import app.bottlenote.alcohols.domain.AlcoholQueryRepository; import app.bottlenote.picks.constant.PicksStatus; import app.bottlenote.picks.domain.PicksRepository; +import app.bottlenote.picks.dto.response.AlcoholPicksCountResponse; import app.bottlenote.rating.domain.RatingRepository; +import app.bottlenote.rating.dto.response.AlcoholRatingStatsResponse; import app.bottlenote.review.constant.ReviewActiveStatus; import app.bottlenote.review.constant.ReviewDisplayStatus; import app.bottlenote.review.domain.ReviewRepository; +import app.bottlenote.review.dto.response.AlcoholReviewCountResponse; import java.util.List; import java.util.Map; import java.util.Objects; @@ -90,6 +93,49 @@ public Long totalPickCount(Alcohol alcohol) { return picksRepository.countByAlcoholIdAndStatus(alcoholId, PicksStatus.PICK); } + @Transactional(readOnly = true) + public Map ratingStats(List alcohols) { + List alcoholIds = alcoholIdsOf(alcohols); + if (alcoholIds.isEmpty()) { + return Map.of(); + } + return ratingRepository.findStatsByAlcoholIds(alcoholIds).stream() + .collect(Collectors.toMap(AlcoholRatingStatsResponse::alcoholId, Function.identity())); + } + + @Transactional(readOnly = true) + public Map reviewCounts(List alcohols) { + List alcoholIds = alcoholIdsOf(alcohols); + if (alcoholIds.isEmpty()) { + return Map.of(); + } + return reviewRepository + .countByAlcoholIdsAndActiveStatusAndStatus( + alcoholIds, ReviewActiveStatus.ACTIVE, ReviewDisplayStatus.PUBLIC) + .stream() + .collect( + Collectors.toMap( + AlcoholReviewCountResponse::alcoholId, AlcoholReviewCountResponse::reviewCount)); + } + + @Transactional(readOnly = true) + public Map pickCounts(List alcohols) { + List alcoholIds = alcoholIdsOf(alcohols); + if (alcoholIds.isEmpty()) { + return Map.of(); + } + return picksRepository.countByAlcoholIdsAndStatus(alcoholIds, PicksStatus.PICK).stream() + .collect( + Collectors.toMap( + AlcoholPicksCountResponse::alcoholId, AlcoholPicksCountResponse::totalPickCount)); + } + + private List alcoholIdsOf(List alcohols) { + return alcohols == null + ? List.of() + : alcohols.stream().map(this::alcoholIdOf).filter(Objects::nonNull).distinct().toList(); + } + private Long alcoholIdOf(Alcohol alcohol) { if (alcohol == null) { return null; diff --git a/bottlenote-mono/src/main/java/app/bottlenote/global/exception/custom/code/ValidExceptionCode.java b/bottlenote-mono/src/main/java/app/bottlenote/global/exception/custom/code/ValidExceptionCode.java index 184ea2019..2d40a5ddd 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/global/exception/custom/code/ValidExceptionCode.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/global/exception/custom/code/ValidExceptionCode.java @@ -98,6 +98,15 @@ public enum ValidExceptionCode implements ExceptionCode { BANNER_SORT_ORDER_MINIMUM(HttpStatus.BAD_REQUEST, "정렬 순서는 0 이상이어야 합니다."), BANNER_IS_ACTIVE_REQUIRED(HttpStatus.BAD_REQUEST, "활성화 상태는 필수입니다."), + // CURATION + CURATION_SPEC_ID_REQUIRED(HttpStatus.BAD_REQUEST, "큐레이션 스펙 ID는 필수입니다."), + CURATION_NAME_REQUIRED(HttpStatus.BAD_REQUEST, "큐레이션 이름은 필수입니다."), + CURATION_IMAGE_URLS_REQUIRED(HttpStatus.BAD_REQUEST, "큐레이션 이미지는 최소 1개 이상이어야 합니다."), + CURATION_IMAGE_URLS_MAX_SIZE(HttpStatus.BAD_REQUEST, "큐레이션 이미지는 최대 3개까지 등록할 수 있습니다."), + CURATION_DISPLAY_ORDER_REQUIRED(HttpStatus.BAD_REQUEST, "노출 순서는 필수입니다."), + CURATION_IS_ACTIVE_REQUIRED(HttpStatus.BAD_REQUEST, "활성화 상태는 필수입니다."), + CURATION_PAYLOAD_REQUIRED(HttpStatus.BAD_REQUEST, "payload는 필수입니다."), + // REGION REGION_KOR_NAME_REQUIRED(HttpStatus.BAD_REQUEST, "지역 한글명은 필수입니다."), REGION_ENG_NAME_REQUIRED(HttpStatus.BAD_REQUEST, "지역 영문명은 필수입니다."), diff --git a/bottlenote-mono/src/main/java/app/bottlenote/global/security/constant/MaliciousPathPattern.java b/bottlenote-mono/src/main/java/app/bottlenote/global/security/constant/MaliciousPathPattern.java index ab4037430..98157f628 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/global/security/constant/MaliciousPathPattern.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/global/security/constant/MaliciousPathPattern.java @@ -40,6 +40,11 @@ public enum MaliciousPathPattern { SERVER_STATUS("/server-status", "Apache 서버 상태"), SERVER_INFO("/server-info", "Apache 서버 정보"), + // 내부 전용 엔드포인트 + GRAPHQL("/graphql", "내부 GraphQL 엔드포인트"), + GRAPHIQL("/graphiql", "GraphiQL 탐색 UI"), + GRAPHIQL_ASSETS("/graphiql/**", "GraphiQL 탐색 UI 리소스"), + // 백업/덤프 파일 (루트 경로만 차단, ** 뒤에 패턴 불가) SQL_FILE("/*.sql", "루트 SQL 덤프 파일"), BAK_FILE("/*.bak", "루트 백업 파일"), diff --git a/bottlenote-mono/src/main/java/app/bottlenote/picks/domain/PicksRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/picks/domain/PicksRepository.java index 62c8d2251..2fc0ee42a 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/picks/domain/PicksRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/picks/domain/PicksRepository.java @@ -1,6 +1,8 @@ package app.bottlenote.picks.domain; import app.bottlenote.picks.constant.PicksStatus; +import app.bottlenote.picks.dto.response.AlcoholPicksCountResponse; +import java.util.List; import java.util.Optional; public interface PicksRepository { @@ -9,5 +11,8 @@ public interface PicksRepository { Long countByAlcoholIdAndStatus(Long alcoholId, PicksStatus status); + List countByAlcoholIdsAndStatus( + List alcoholIds, PicksStatus status); + Picks save(Picks picks); } diff --git a/bottlenote-mono/src/main/java/app/bottlenote/picks/dto/response/AlcoholPicksCountResponse.java b/bottlenote-mono/src/main/java/app/bottlenote/picks/dto/response/AlcoholPicksCountResponse.java new file mode 100644 index 000000000..61164407f --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/picks/dto/response/AlcoholPicksCountResponse.java @@ -0,0 +1,3 @@ +package app.bottlenote.picks.dto.response; + +public record AlcoholPicksCountResponse(Long alcoholId, Long totalPickCount) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/picks/repository/JpaPicksRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/picks/repository/JpaPicksRepository.java index d8850f981..347751e44 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/picks/repository/JpaPicksRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/picks/repository/JpaPicksRepository.java @@ -1,12 +1,29 @@ package app.bottlenote.picks.repository; import app.bottlenote.common.annotation.JpaRepositoryImpl; +import app.bottlenote.picks.constant.PicksStatus; import app.bottlenote.picks.domain.Picks; import app.bottlenote.picks.domain.PicksRepository; +import app.bottlenote.picks.dto.response.AlcoholPicksCountResponse; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; @JpaRepositoryImpl public interface JpaPicksRepository extends PicksRepository, JpaRepository { Optional findByAlcoholIdAndUserId(Long alcoholId, Long userId); + + @Override + @Query( + """ + select new app.bottlenote.picks.dto.response.AlcoholPicksCountResponse(p.alcoholId, count(p)) + from picks p + where p.alcoholId in :alcoholIds + and p.status = :status + group by p.alcoholId + """) + List countByAlcoholIdsAndStatus( + @Param("alcoholIds") List alcoholIds, @Param("status") PicksStatus status); } diff --git a/bottlenote-mono/src/main/java/app/bottlenote/rating/domain/RatingRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/rating/domain/RatingRepository.java index 80c1b6710..00ef5c1e6 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/rating/domain/RatingRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/rating/domain/RatingRepository.java @@ -3,6 +3,7 @@ import app.bottlenote.global.service.cursor.PageResponse; import app.bottlenote.rating.domain.Rating.RatingId; import app.bottlenote.rating.dto.dsl.RatingListFetchCriteria; +import app.bottlenote.rating.dto.response.AlcoholRatingStatsResponse; import app.bottlenote.rating.dto.response.RatingListFetchResponse; import app.bottlenote.rating.dto.response.UserRatingResponse; import java.util.List; @@ -27,5 +28,7 @@ public interface RatingRepository { Long countByAlcoholId(Long alcoholId); + List findStatsByAlcoholIds(List alcoholIds); + boolean existsByAlcoholId(Long alcoholId); } diff --git a/bottlenote-mono/src/main/java/app/bottlenote/rating/dto/response/AlcoholRatingStatsResponse.java b/bottlenote-mono/src/main/java/app/bottlenote/rating/dto/response/AlcoholRatingStatsResponse.java new file mode 100644 index 000000000..e8864d9c4 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/rating/dto/response/AlcoholRatingStatsResponse.java @@ -0,0 +1,3 @@ +package app.bottlenote.rating.dto.response; + +public record AlcoholRatingStatsResponse(Long alcoholId, Double rating, Long totalRatingsCount) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/rating/repository/JpaRatingRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/rating/repository/JpaRatingRepository.java index ec47dd094..7da308102 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/rating/repository/JpaRatingRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/rating/repository/JpaRatingRepository.java @@ -4,7 +4,9 @@ import app.bottlenote.rating.domain.Rating; import app.bottlenote.rating.domain.Rating.RatingId; import app.bottlenote.rating.domain.RatingRepository; +import app.bottlenote.rating.dto.response.AlcoholRatingStatsResponse; import app.bottlenote.rating.dto.response.UserRatingResponse; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -42,6 +44,22 @@ Optional fetchUserRating( "select count(r) from rating r where r.id.alcoholId = :alcoholId and r.ratingPoint.rating > 0.0") Long countByAlcoholId(@Param("alcoholId") Long alcoholId); + @Override + @Query( + """ + select new app.bottlenote.rating.dto.response.AlcoholRatingStatsResponse( + r.id.alcoholId, + coalesce(avg(r.ratingPoint.rating), 0.0), + count(r) + ) + from rating r + where r.id.alcoholId in :alcoholIds + and r.ratingPoint.rating > 0.0 + group by r.id.alcoholId + """) + List findStatsByAlcoholIds( + @Param("alcoholIds") List alcoholIds); + @Override @Query( "select case when count(r) > 0 then true else false end from rating r where r.id.alcoholId = :alcoholId") diff --git a/bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java index 58619d31d..c996debe1 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java @@ -5,6 +5,7 @@ import app.bottlenote.review.constant.ReviewActiveStatus; import app.bottlenote.review.constant.ReviewDisplayStatus; import app.bottlenote.review.dto.request.ReviewPageableRequest; +import app.bottlenote.review.dto.response.AlcoholReviewCountResponse; import app.bottlenote.review.dto.response.ReviewExploreItem; import app.bottlenote.review.dto.response.ReviewListResponse; import app.bottlenote.review.facade.payload.ReviewInfo; @@ -35,6 +36,9 @@ PageResponse getReviewsByMe( Long countByAlcoholIdAndActiveStatusAndStatus( Long alcoholId, ReviewActiveStatus activeStatus, ReviewDisplayStatus status); + List countByAlcoholIdsAndActiveStatusAndStatus( + List alcoholIds, ReviewActiveStatus activeStatus, ReviewDisplayStatus status); + boolean existsById(Long reviewId); boolean existsByAlcoholId(Long alcoholId); diff --git a/bottlenote-mono/src/main/java/app/bottlenote/review/dto/response/AlcoholReviewCountResponse.java b/bottlenote-mono/src/main/java/app/bottlenote/review/dto/response/AlcoholReviewCountResponse.java new file mode 100644 index 000000000..d382c8fb6 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/review/dto/response/AlcoholReviewCountResponse.java @@ -0,0 +1,3 @@ +package app.bottlenote.review.dto.response; + +public record AlcoholReviewCountResponse(Long alcoholId, Long reviewCount) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/review/repository/JpaReviewRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/review/repository/JpaReviewRepository.java index b39f64f23..69c213b84 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/review/repository/JpaReviewRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/review/repository/JpaReviewRepository.java @@ -1,7 +1,10 @@ package app.bottlenote.review.repository; +import app.bottlenote.review.constant.ReviewActiveStatus; +import app.bottlenote.review.constant.ReviewDisplayStatus; import app.bottlenote.review.domain.Review; import app.bottlenote.review.domain.ReviewRepository; +import app.bottlenote.review.dto.response.AlcoholReviewCountResponse; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; @@ -23,6 +26,21 @@ public interface JpaReviewRepository @Query("select r from review r where r.userId = :userId") List findByUserId(@Param("userId") Long userId); + @Override + @Query( + """ + select new app.bottlenote.review.dto.response.AlcoholReviewCountResponse(r.alcoholId, count(r)) + from review r + where r.alcoholId in :alcoholIds + and r.activeStatus = :activeStatus + and r.status = :status + group by r.alcoholId + """) + List countByAlcoholIdsAndActiveStatusAndStatus( + @Param("alcoholIds") List alcoholIds, + @Param("activeStatus") ReviewActiveStatus activeStatus, + @Param("status") ReviewDisplayStatus status); + @Override @Query( "select case when count(r) > 0 then true else false end from review r where r.alcoholId = :alcoholId") diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolverTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolverTest.java index 4394359e9..e1bfb73d0 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolverTest.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolverTest.java @@ -12,11 +12,13 @@ import app.bottlenote.picks.constant.PicksStatus; import app.bottlenote.picks.domain.Picks; import app.bottlenote.picks.domain.PicksRepository; +import app.bottlenote.picks.dto.response.AlcoholPicksCountResponse; import app.bottlenote.rating.domain.Rating; import app.bottlenote.rating.domain.Rating.RatingId; import app.bottlenote.rating.domain.RatingPoint; import app.bottlenote.rating.domain.RatingRepository; import app.bottlenote.rating.dto.dsl.RatingListFetchCriteria; +import app.bottlenote.rating.dto.response.AlcoholRatingStatsResponse; import app.bottlenote.rating.dto.response.RatingListFetchResponse; import app.bottlenote.rating.dto.response.UserRatingResponse; import app.bottlenote.review.constant.ReviewActiveStatus; @@ -71,6 +73,10 @@ void alcohols_whenManualItemAlcoholIdIsNull_excludesNullAndMissingIdsAndResolves assertThat(resolver.totalRatingsCount(alcohol)).isEqualTo(2L); assertThat(resolver.reviewCount(alcohol)).isEqualTo(1L); assertThat(resolver.totalPickCount(alcohol)).isEqualTo(1L); + assertThat(resolver.ratings(alcohols)).containsEntry(alcohol, 4.0); + assertThat(resolver.totalRatingsCounts(alcohols)).containsEntry(alcohol, 2L); + assertThat(resolver.reviewCounts(alcohols)).containsEntry(alcohol, 1L); + assertThat(resolver.totalPickCounts(alcohols)).containsEntry(alcohol, 1L); } private static Alcohol alcohol(Long alcoholId) { @@ -172,6 +178,19 @@ public Long countByAlcoholId(Long alcoholId) { .count(); } + @Override + public List findStatsByAlcoholIds(List alcoholIds) { + return alcoholIds.stream() + .map( + alcoholId -> + new AlcoholRatingStatsResponse( + alcoholId, + findAverageRatingByAlcoholId(alcoholId), + countByAlcoholId(alcoholId))) + .filter(stats -> stats.totalRatingsCount() > 0) + .toList(); + } + @Override public boolean existsByAlcoholId(Long alcoholId) { return ratings.values().stream() @@ -199,6 +218,18 @@ public Long countByAlcoholIdAndStatus(Long alcoholId, PicksStatus status) { .count(); } + @Override + public List countByAlcoholIdsAndStatus( + List alcoholIds, PicksStatus status) { + return alcoholIds.stream() + .map( + alcoholId -> + new AlcoholPicksCountResponse( + alcoholId, countByAlcoholIdAndStatus(alcoholId, status))) + .filter(count -> count.totalPickCount() > 0) + .toList(); + } + @Override public Picks save(Picks pick) { picks.add(pick); diff --git a/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java b/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java index 8313db102..4a6484cf3 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java @@ -7,6 +7,7 @@ import app.bottlenote.review.domain.Review; import app.bottlenote.review.domain.ReviewRepository; import app.bottlenote.review.dto.request.ReviewPageableRequest; +import app.bottlenote.review.dto.response.AlcoholReviewCountResponse; import app.bottlenote.review.dto.response.ReviewExploreItem; import app.bottlenote.review.dto.response.ReviewListResponse; import app.bottlenote.review.facade.payload.ReviewInfo; @@ -86,6 +87,19 @@ public Long countByAlcoholIdAndActiveStatusAndStatus( .count(); } + @Override + public List countByAlcoholIdsAndActiveStatusAndStatus( + List alcoholIds, ReviewActiveStatus activeStatus, ReviewDisplayStatus status) { + return alcoholIds.stream() + .map( + alcoholId -> + new AlcoholReviewCountResponse( + alcoholId, + countByAlcoholIdAndActiveStatusAndStatus(alcoholId, activeStatus, status))) + .filter(count -> count.reviewCount() > 0) + .toList(); + } + @Override public boolean existsById(Long reviewId) { return database.containsKey(reviewId); diff --git a/bottlenote-product-api/src/main/resources/application.yml b/bottlenote-product-api/src/main/resources/application.yml index 170570de7..1418c0ded 100644 --- a/bottlenote-product-api/src/main/resources/application.yml +++ b/bottlenote-product-api/src/main/resources/application.yml @@ -88,7 +88,7 @@ spring: on-profile: default,local graphql: graphiql: - enabled: true + enabled: false path: /graphiql logging: diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/picks/fake/FakePicksRepository.java b/bottlenote-product-api/src/test/java/app/bottlenote/picks/fake/FakePicksRepository.java index 8f1525d49..40e1f76ee 100644 --- a/bottlenote-product-api/src/test/java/app/bottlenote/picks/fake/FakePicksRepository.java +++ b/bottlenote-product-api/src/test/java/app/bottlenote/picks/fake/FakePicksRepository.java @@ -3,7 +3,9 @@ import app.bottlenote.picks.constant.PicksStatus; import app.bottlenote.picks.domain.Picks; import app.bottlenote.picks.domain.PicksRepository; +import app.bottlenote.picks.dto.response.AlcoholPicksCountResponse; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -34,6 +36,18 @@ public Long countByAlcoholIdAndStatus(Long alcoholId, PicksStatus status) { .count(); } + @Override + public List countByAlcoholIdsAndStatus( + List alcoholIds, PicksStatus status) { + return alcoholIds.stream() + .map( + alcoholId -> + new AlcoholPicksCountResponse( + alcoholId, countByAlcoholIdAndStatus(alcoholId, status))) + .filter(count -> count.totalPickCount() > 0) + .toList(); + } + @Override public Picks save(Picks picks) { long id = picksDatabase.size() + 1L; diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/rating/fixture/InMemoryRatingRepository.java b/bottlenote-product-api/src/test/java/app/bottlenote/rating/fixture/InMemoryRatingRepository.java index 72724d172..56fc34618 100644 --- a/bottlenote-product-api/src/test/java/app/bottlenote/rating/fixture/InMemoryRatingRepository.java +++ b/bottlenote-product-api/src/test/java/app/bottlenote/rating/fixture/InMemoryRatingRepository.java @@ -5,6 +5,7 @@ import app.bottlenote.rating.domain.Rating.RatingId; import app.bottlenote.rating.domain.RatingRepository; import app.bottlenote.rating.dto.dsl.RatingListFetchCriteria; +import app.bottlenote.rating.dto.response.AlcoholRatingStatsResponse; import app.bottlenote.rating.dto.response.RatingListFetchResponse; import app.bottlenote.rating.dto.response.UserRatingResponse; import java.util.HashMap; @@ -75,6 +76,19 @@ public Long countByAlcoholId(Long alcoholId) { .count(); } + @Override + public List findStatsByAlcoholIds(List alcoholIds) { + return alcoholIds.stream() + .map( + alcoholId -> + new AlcoholRatingStatsResponse( + alcoholId, + findAverageRatingByAlcoholId(alcoholId), + countByAlcoholId(alcoholId))) + .filter(stats -> stats.totalRatingsCount() > 0) + .toList(); + } + @Override public boolean existsByAlcoholId(Long alcoholId) { return ratings.values().stream() diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java b/bottlenote-product-api/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java index eaf99d4db..82721334c 100644 --- a/bottlenote-product-api/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java +++ b/bottlenote-product-api/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java @@ -7,6 +7,7 @@ import app.bottlenote.review.domain.Review; import app.bottlenote.review.domain.ReviewRepository; import app.bottlenote.review.dto.request.ReviewPageableRequest; +import app.bottlenote.review.dto.response.AlcoholReviewCountResponse; import app.bottlenote.review.dto.response.ReviewExploreItem; import app.bottlenote.review.dto.response.ReviewListResponse; import app.bottlenote.review.facade.payload.ReviewInfo; @@ -88,6 +89,19 @@ public Long countByAlcoholIdAndActiveStatusAndStatus( .count(); } + @Override + public List countByAlcoholIdsAndActiveStatusAndStatus( + List alcoholIds, ReviewActiveStatus activeStatus, ReviewDisplayStatus status) { + return alcoholIds.stream() + .map( + alcoholId -> + new AlcoholReviewCountResponse( + alcoholId, + countByAlcoholIdAndActiveStatusAndStatus(alcoholId, activeStatus, status))) + .filter(count -> count.reviewCount() > 0) + .toList(); + } + @Override public boolean existsById(Long reviewId) { return database.containsKey(reviewId); diff --git a/bottlenote-product-api/src/test/java/app/global/security/SecurityConfigIntegrationTest.java b/bottlenote-product-api/src/test/java/app/global/security/SecurityConfigIntegrationTest.java index 3a0ffeec3..808209004 100644 --- a/bottlenote-product-api/src/test/java/app/global/security/SecurityConfigIntegrationTest.java +++ b/bottlenote-product-api/src/test/java/app/global/security/SecurityConfigIntegrationTest.java @@ -63,6 +63,13 @@ void tearDownLogCapture() { .noneMatch(msg -> msg != null && msg.contains("NoResourceFoundException")); } + @Test + @DisplayName("내부 GraphQL 엔드포인트는 외부 HTTP 접근을 차단한다") + void 내부_GraphQL_엔드포인트_외부_접근_차단() { + mockMvcTester.get().uri("/graphiql").exchange().assertThat().hasStatus(FORBIDDEN); + mockMvcTester.post().uri("/graphql").exchange().assertThat().hasStatus(FORBIDDEN); + } + @Test @DisplayName("정상 API 경로는 차단되지 않는다") void 정상_API_경로_허용() { From cab82b83947b2b6ab387d89e30fb077713ed50ab Mon Sep 17 00:00:00 2001 From: hgkim Date: Sun, 17 May 2026 18:37:41 +0900 Subject: [PATCH 11/33] =?UTF-8?q?fix:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20=EC=9A=B4=EC=98=81=20=ED=95=98=EB=93=9C?= =?UTF-8?q?=EB=8B=9D=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../curation/domain/CurationRepository.java | 5 ++ .../exception/CurationExceptionCode.java | 3 +- .../repository/JpaCurationRepository.java | 27 +++++++++ .../service/CurationResponseMaterializer.java | 30 +++++++++- .../ProductSpecBasedCurationService.java | 9 ++- .../SpringCurationGraphqlExecutor.java | 23 +++++++- .../fixture/InMemoryCurationRepository.java | 24 ++++++++ .../CurationResponseMaterializerTest.java | 42 +++++++++++++- .../ProductSpecBasedCurationServiceTest.java | 39 ++++++++++++- ...oductSpecBasedCurationIntegrationTest.java | 57 ++++++++++++++++++- plan/spec-based-curation-v2-graphql-sdl.md | 15 +++-- 11 files changed, 251 insertions(+), 23 deletions(-) diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationRepository.java index 059bd2493..cb24aecef 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/domain/CurationRepository.java @@ -1,6 +1,7 @@ package app.bottlenote.curation.domain; import app.bottlenote.common.annotation.DomainRepository; +import java.time.LocalDate; import java.util.List; import java.util.Optional; import org.springframework.data.domain.Page; @@ -13,6 +14,10 @@ public interface CurationRepository { List findAllByIsActiveTrueOrderByDisplayOrderAscIdAsc(); + List findAllVisibleOn(LocalDate today); + + Optional findVisibleById(Long id, LocalDate today); + Page searchForAdmin(String keyword, Boolean isActive, Pageable pageable); Curation save(Curation curation); diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationExceptionCode.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationExceptionCode.java index 3370fb68d..151571522 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationExceptionCode.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/exception/CurationExceptionCode.java @@ -8,7 +8,8 @@ public enum CurationExceptionCode implements ExceptionCode { CURATION_SPEC_DUPLICATE_CODE(HttpStatus.CONFLICT, "동일한 큐레이션 스펙 코드가 이미 존재합니다."), CURATION_NOT_FOUND(HttpStatus.NOT_FOUND, "큐레이션을 찾을 수 없습니다."), CURATION_PAYLOAD_INVALID(HttpStatus.BAD_REQUEST, "큐레이션 payload가 스펙과 일치하지 않습니다."), - CURATION_RESPONSE_INVALID(HttpStatus.INTERNAL_SERVER_ERROR, "큐레이션 응답이 스펙과 일치하지 않습니다."); + CURATION_RESPONSE_INVALID(HttpStatus.INTERNAL_SERVER_ERROR, "큐레이션 응답이 스펙과 일치하지 않습니다."), + CURATION_GRAPHQL_EXECUTION_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "큐레이션 GraphQL 보강에 실패했습니다."); private final HttpStatus httpStatus; private final String message; diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationRepository.java index 70db59308..c6f6971ae 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/repository/JpaCurationRepository.java @@ -3,17 +3,44 @@ import app.bottlenote.common.annotation.JpaRepositoryImpl; import app.bottlenote.curation.domain.Curation; import app.bottlenote.curation.domain.CurationRepository; +import java.time.LocalDate; import java.util.List; +import java.util.Optional; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; @JpaRepositoryImpl public interface JpaCurationRepository extends CurationRepository, JpaRepository { List findAllByIsActiveTrueOrderByDisplayOrderAscIdAsc(); + @Override + @Query( + """ + SELECT c + FROM curation c + WHERE c.isActive = true + AND (c.exposureStartDate IS NULL OR c.exposureStartDate <= :today) + AND (c.exposureEndDate IS NULL OR c.exposureEndDate >= :today) + ORDER BY c.displayOrder ASC, c.id ASC + """) + List findAllVisibleOn(@Param("today") LocalDate today); + + @Override + @Query( + """ + SELECT c + FROM curation c + WHERE c.id = :id + AND c.isActive = true + AND (c.exposureStartDate IS NULL OR c.exposureStartDate <= :today) + AND (c.exposureEndDate IS NULL OR c.exposureEndDate >= :today) + """) + Optional findVisibleById(@Param("id") Long id, @Param("today") LocalDate today); + @Query( """ SELECT c diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java index a1603a9d5..f490ba544 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java @@ -12,10 +12,12 @@ import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor +@Slf4j public class CurationResponseMaterializer { private static final String JSON_PATH_ROOT = "$"; @@ -25,7 +27,8 @@ public class CurationResponseMaterializer { private final CurationGraphqlExecutor graphqlExecutor; private final CurationPayloadValidator payloadValidator; - public Object materialize(Long curationId, Map responseSpec, Object payload) { + public Object materialize( + Long curationId, String specCode, Map responseSpec, Object payload) { JsonNode payloadNode = objectMapper.valueToTree(payload); JsonNode responseSpecNode = objectMapper.valueToTree(responseSpec); List queries = @@ -34,6 +37,7 @@ public Object materialize(Long curationId, Map responseSpec, Obj JsonNode hydrated = payloadNode; for (int i = 0; i < queries.size(); i++) { Map result = graphqlExecutor.execute(curationId, i, queries.get(i)); + assertNoGraphqlErrors(curationId, specCode, queries.get(i), result); hydrated = applyHydration(hydrated, queries.get(i), result); } @@ -41,11 +45,35 @@ public Object materialize(Long curationId, Map responseSpec, Obj List errors = payloadValidator.validate(new MapBackedSchema(responseSpec), materialized); if (!errors.isEmpty()) { + log.error( + "Curation responseSpec mismatch. curationId={}, specCode={}, errors={}", + curationId, + specCode, + errors); throw new CurationException(CURATION_RESPONSE_INVALID); } return materialized; } + private void assertNoGraphqlErrors( + Long curationId, + String specCode, + SpecGraphqlQueryBuilder.Result query, + Map result) { + if (result == null || !(result.get("errors") instanceof List errors) || errors.isEmpty()) { + return; + } + log.error( + "Curation GraphQL hydration failed. curationId={}, specCode={}, payloadPath={}, entryField={}, errors={}", + curationId, + specCode, + query.payloadPath(), + query.entryField(), + errors); + throw new CurationException( + app.bottlenote.curation.exception.CurationExceptionCode.CURATION_GRAPHQL_EXECUTION_FAILED); + } + @SuppressWarnings("unchecked") private JsonNode applyHydration( JsonNode payload, SpecGraphqlQueryBuilder.Result query, Map result) { diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/ProductSpecBasedCurationService.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/ProductSpecBasedCurationService.java index 145b1e501..acfb24ce1 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/ProductSpecBasedCurationService.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/ProductSpecBasedCurationService.java @@ -12,6 +12,7 @@ import app.bottlenote.curation.dto.response.ProductSpecBasedCurationDetailResponse; import app.bottlenote.curation.dto.response.ProductSpecBasedCurationListResponse; import app.bottlenote.curation.exception.CurationException; +import java.time.LocalDate; import java.util.List; import java.util.Map; import java.util.Objects; @@ -34,8 +35,7 @@ public class ProductSpecBasedCurationService { @Transactional(readOnly = true) public List listActiveCurations() { - List curations = - curationRepository.findAllByIsActiveTrueOrderByDisplayOrderAscIdAsc(); + List curations = curationRepository.findAllVisibleOn(LocalDate.now()); Map specMap = curationSpecRepository .findAllByIdIn(curations.stream().map(Curation::getSpecId).collect(Collectors.toSet())) @@ -50,8 +50,7 @@ public List listActiveCurations() { public ProductSpecBasedCurationDetailResponse getDetail(Long curationId) { Curation curation = curationRepository - .findById(curationId) - .filter(item -> Boolean.TRUE.equals(item.getIsActive())) + .findVisibleById(curationId, LocalDate.now()) .orElseThrow(() -> new CurationException(CURATION_NOT_FOUND)); CurationSpec spec = curationSpecRepository @@ -63,7 +62,7 @@ public ProductSpecBasedCurationDetailResponse getDetail(Long curationId) { .orElseThrow(() -> new CurationException(CURATION_NOT_FOUND)); Object materialized = responseMaterializer.materialize( - curationId, spec.getResponseSpec(), extension.getPayload()); + curationId, spec.getCode(), spec.getResponseSpec(), extension.getPayload()); return toDetailResponse(curation, spec, materialized); } diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java index 69bfcd0ea..241a710b1 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java @@ -1,7 +1,11 @@ package app.bottlenote.curation.service; +import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_GRAPHQL_EXECUTION_FAILED; + +import app.bottlenote.curation.exception.CurationException; import java.util.Map; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.graphql.ExecutionGraphQlRequest; import org.springframework.graphql.ExecutionGraphQlResponse; import org.springframework.graphql.ExecutionGraphQlService; @@ -11,6 +15,7 @@ @Component @RequiredArgsConstructor +@Slf4j public class SpringCurationGraphqlExecutor implements CurationGraphqlExecutor { private final ExecutionGraphQlService executionGraphQlService; @@ -28,7 +33,23 @@ public Map execute( null); ExecutionGraphQlResponse response = Mono.from(executionGraphQlService.execute(request)).block(); if (response == null) { - return Map.of(); + log.error( + "Curation GraphQL hydration returned null response. curationId={}, queryIndex={}, payloadPath={}, entryField={}", + curationId, + index, + query.payloadPath(), + query.entryField()); + throw new CurationException(CURATION_GRAPHQL_EXECUTION_FAILED); + } + if (!response.getExecutionResult().getErrors().isEmpty()) { + log.error( + "Curation GraphQL hydration returned errors. curationId={}, queryIndex={}, payloadPath={}, entryField={}, errors={}", + curationId, + index, + query.payloadPath(), + query.entryField(), + response.getExecutionResult().getErrors()); + throw new CurationException(CURATION_GRAPHQL_EXECUTION_FAILED); } return response.getExecutionResult().toSpecification(); } diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationRepository.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationRepository.java index dc6102b7a..5b7fbb6be 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationRepository.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/InMemoryCurationRepository.java @@ -2,6 +2,7 @@ import app.bottlenote.curation.domain.Curation; import app.bottlenote.curation.domain.CurationRepository; +import java.time.LocalDate; import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -29,6 +30,22 @@ public List findAllByIsActiveTrueOrderByDisplayOrderAscIdAsc() { .toList(); } + @Override + public List findAllVisibleOn(LocalDate today) { + return database.values().stream() + .filter(curation -> Boolean.TRUE.equals(curation.getIsActive())) + .filter(curation -> isVisibleOn(curation, today)) + .sorted(Comparator.comparing(Curation::getDisplayOrder).thenComparing(Curation::getId)) + .toList(); + } + + @Override + public Optional findVisibleById(Long id, LocalDate today) { + return findById(id) + .filter(curation -> Boolean.TRUE.equals(curation.getIsActive())) + .filter(curation -> isVisibleOn(curation, today)); + } + @Override public Page searchForAdmin(String keyword, Boolean isActive, Pageable pageable) { List all = @@ -60,4 +77,11 @@ public Curation save(Curation curation) { public void delete(Curation curation) { database.remove(curation.getId()); } + + private boolean isVisibleOn(Curation curation, LocalDate today) { + return (curation.getExposureStartDate() == null + || !curation.getExposureStartDate().isAfter(today)) + && (curation.getExposureEndDate() == null + || !curation.getExposureEndDate().isBefore(today)); + } } diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java index 56c0fdb0e..2bd3e4685 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java @@ -1,7 +1,10 @@ package app.bottlenote.curation.service; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import app.bottlenote.curation.exception.CurationException; +import app.bottlenote.curation.exception.CurationExceptionCode; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -48,7 +51,8 @@ void materialize_whenRootArrayPayload_hydratesBottleNoteStatsOnly() throws IOExc item("MANUAL", map("alcoholId", null, "korName", "수동", "selectedTags", List.of("오크")))); Object result = - materializer.materialize(1L, schema("recommended_whisky.json", "Response"), payload); + materializer.materialize( + 1L, "RECOMMENDED_WHISKY", schema("recommended_whisky.json", "Response"), payload); JsonNode resultNode = OBJECT_MAPPER.valueToTree(result); assertThat(executor.executedQueries()).hasSize(1); @@ -105,7 +109,8 @@ void materialize_whenNestedPayloadPath_hydratesOnlyAlcoholSubtree() throws IOExc map("alcoholId", 7, "korName", "테스트", "selectedTags", List.of("셰리"))))); Object result = - materializer.materialize(2L, schema("whisky_tasting_event.json", "Response"), payload); + materializer.materialize( + 2L, "WHISKY_TASTING_EVENT", schema("whisky_tasting_event.json", "Response"), payload); JsonNode resultNode = OBJECT_MAPPER.valueToTree(result); assertThat(executor.executedQueries().get(0).variables().get("ids")).isEqualTo(List.of(7L)); @@ -115,7 +120,29 @@ void materialize_whenNestedPayloadPath_hydratesOnlyAlcoholSubtree() throws IOExc .isEqualTo(1); } - private static CurationResponseMaterializer materializer(FakeCurationGraphqlExecutor executor) { + @Test + @DisplayName("GraphQL 실행 errors가 있으면 부분 응답을 만들지 않고 실패한다") + void materialize_whenGraphqlResultHasErrors_throwsExecutionFailed() throws IOException { + CurationResponseMaterializer materializer = materializer(new ErrorGraphqlExecutor()); + List> payload = + List.of( + item( + "BOTTLE_NOTE", + map("alcoholId", 1, "korName", "테스트", "selectedTags", List.of("셰리")))); + + assertThatThrownBy( + () -> + materializer.materialize( + 1L, + "RECOMMENDED_WHISKY", + schema("recommended_whisky.json", "Response"), + payload)) + .isInstanceOf(CurationException.class) + .hasFieldOrPropertyWithValue( + "exceptionCode", CurationExceptionCode.CURATION_GRAPHQL_EXECUTION_FAILED); + } + + private static CurationResponseMaterializer materializer(CurationGraphqlExecutor executor) { return new CurationResponseMaterializer( OBJECT_MAPPER, new SpecGraphqlQueryBuilder(), @@ -169,4 +196,13 @@ List executedQueries() { return executedQueries; } } + + private static final class ErrorGraphqlExecutor implements CurationGraphqlExecutor { + + @Override + public Map execute( + Long curationId, int index, SpecGraphqlQueryBuilder.Result query) { + return map("errors", List.of(map("message", "forced graphql error"))); + } + } } diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java index 269d1ba81..43c98c14d 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java @@ -58,12 +58,16 @@ void setUp() { } @Test - @DisplayName("Product v2 목록은 활성 큐레이션만 displayOrder, id 순서로 반환한다") + @DisplayName("Product v2 목록은 활성이고 노출 기간에 포함된 큐레이션만 displayOrder, id 순서로 반환한다") void listActiveCurations_whenMixedStatus_returnsOnlyActiveItemsInDisplayOrder() throws IOException { CurationSpec spec = createSpec(); Long laterId = createCuration(spec.getId(), "뒤", 20, true); createCuration(spec.getId(), "비활성", 1, false); + createCuration( + spec.getId(), "미노출", 1, true, LocalDate.now().plusDays(1), LocalDate.now().plusDays(5)); + createCuration( + spec.getId(), "노출종료", 1, true, LocalDate.now().minusDays(5), LocalDate.now().minusDays(1)); Long firstId = createCuration(spec.getId(), "앞", 1, true); var result = productService.listActiveCurations(); @@ -102,6 +106,19 @@ void getDetail_whenCurationInactive_throwsNotFound() throws IOException { .hasFieldOrPropertyWithValue("exceptionCode", CurationExceptionCode.CURATION_NOT_FOUND); } + @Test + @DisplayName("노출 기간 밖 큐레이션 상세 조회는 Product v2에서 찾을 수 없다") + void getDetail_whenCurationOutsideExposureWindow_throwsNotFound() throws IOException { + CurationSpec spec = createSpec(); + Long curationId = + createCuration( + spec.getId(), "미노출", 1, true, LocalDate.now().plusDays(1), LocalDate.now().plusDays(5)); + + assertThatThrownBy(() -> productService.getDetail(curationId)) + .isInstanceOf(CurationException.class) + .hasFieldOrPropertyWithValue("exceptionCode", CurationExceptionCode.CURATION_NOT_FOUND); + } + private CurationSpec createSpec() throws IOException { return curationV2Service.createSpec( new CurationSpecCreateRequest( @@ -115,6 +132,22 @@ private CurationSpec createSpec() throws IOException { } private Long createCuration(Long specId, String name, int displayOrder, boolean active) { + return createCuration( + specId, + name, + displayOrder, + active, + LocalDate.now().minusDays(1), + LocalDate.now().plusDays(1)); + } + + private Long createCuration( + Long specId, + String name, + int displayOrder, + boolean active, + LocalDate exposureStartDate, + LocalDate exposureEndDate) { return curationV2Service .createCuration( new CurationCreateRequest( @@ -122,8 +155,8 @@ private Long createCuration(Long specId, String name, int displayOrder, boolean name, "설명", List.of("https://cdn.example.com/cover.jpg"), - LocalDate.of(2026, 6, 1), - LocalDate.of(2026, 6, 30), + exposureStartDate, + exposureEndDate, displayOrder, active, List.of( diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java b/bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java index fea0175d1..5b53d0e3b 100644 --- a/bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java +++ b/bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java @@ -56,12 +56,26 @@ void setUp() { class ListCurations { @Test - @DisplayName("활성 큐레이션만 displayOrder와 id 순서로 조회할 수 있다") + @DisplayName("활성이고 노출 기간에 포함된 큐레이션만 displayOrder와 id 순서로 조회할 수 있다") void listActiveCurations_whenMixedStatus_returnsOnlyActiveItemsInDisplayOrder() throws Exception { // given Long laterId = createCuration("뒤 큐레이션", 20, true, List.of(manualItem("뒤"))); createCuration("비활성 큐레이션", 1, false, List.of(manualItem("비활성"))); + createCuration( + "미노출 큐레이션", + 1, + true, + LocalDate.now().plusDays(1), + LocalDate.now().plusDays(5), + List.of(manualItem("미노출"))); + createCuration( + "노출종료 큐레이션", + 1, + true, + LocalDate.now().minusDays(5), + LocalDate.now().minusDays(1), + List.of(manualItem("노출종료"))); Long firstId = createCuration("앞 큐레이션", 1, true, List.of(manualItem("앞"))); // when @@ -148,6 +162,27 @@ void getDetail_whenInactiveCuration_returnsNotFound() { .isEqualTo(404); } + @Test + @DisplayName("노출 기간 밖 큐레이션 상세 조회는 404를 반환한다") + void getDetail_whenOutsideExposureWindow_returnsNotFound() { + // given + Long curationId = + createCuration( + "미노출 상세", + 1, + true, + LocalDate.now().plusDays(1), + LocalDate.now().plusDays(5), + List.of(manualItem("미노출"))); + + // when & then + assertThat(mockMvcTester.get().uri("/api/v2/curations/{curationId}", curationId)) + .hasStatus4xxClientError() + .bodyJson() + .extractingPath("$.code") + .isEqualTo(404); + } + @Test @DisplayName("존재하지 않는 큐레이션 상세 조회는 404를 반환한다") void getDetail_whenMissingCuration_returnsNotFound() { @@ -161,6 +196,22 @@ void getDetail_whenMissingCuration_returnsNotFound() { private Long createCuration( String name, int displayOrder, boolean active, List> payload) { + return createCuration( + name, + displayOrder, + active, + LocalDate.now().minusDays(1), + LocalDate.now().plusDays(1), + payload); + } + + private Long createCuration( + String name, + int displayOrder, + boolean active, + LocalDate exposureStartDate, + LocalDate exposureEndDate, + List> payload) { return adminSpecBasedCurationService .create( new CurationCreateRequest( @@ -168,8 +219,8 @@ private Long createCuration( name, "통합 테스트 큐레이션", List.of("https://cdn.example.com/cover.jpg"), - LocalDate.of(2026, 6, 1), - LocalDate.of(2026, 6, 30), + exposureStartDate, + exposureEndDate, displayOrder, active, payload)) diff --git a/plan/spec-based-curation-v2-graphql-sdl.md b/plan/spec-based-curation-v2-graphql-sdl.md index b9e3fec3c..f5888f657 100644 --- a/plan/spec-based-curation-v2-graphql-sdl.md +++ b/plan/spec-based-curation-v2-graphql-sdl.md @@ -308,7 +308,7 @@ - 2026-05-15 Task 3 완료: `bottlenote-mono`에 `CurationAlcoholGraphqlResolver`와 `CurationAlcoholGraphqlService`를 추가해 `Alcohol` field resolver를 연결했다. `rating`/`totalRatingsCount`는 rating repository 집계, `reviewCount`는 `ACTIVE` + `PUBLIC` review count, `totalPickCount`는 `PICK` 상태 count로 계산한다. `alcoholId = null`인 `MANUAL` 항목과 존재하지 않는 alcohol id는 GraphQL 조회 결과에서 제외하는 정책을 resolver 테스트명과 검증에 남겼다. 검증: `./gradlew :bottlenote-mono:compileJava` 성공, `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.graphql.CurationGraphqlSchemaTest' --tests 'app.bottlenote.curation.graphql.CurationAlcoholGraphqlResolverTest'` 성공, `./gradlew :bottlenote-product-api:compileJava` 성공, `git diff -- git.environment-variables/storage/mysql/changelog/` 변경 없음. - 2026-05-15 추가 반영: `curation_demo/spec`의 OpenAPI 3.0 JSON 스펙 3종을 `bottlenote-mono/src/main/resources/openapi/curation/`에 그대로 추가했다. 대상은 `RECOMMENDED_WHISKY`, `WHISKY_PAIRING`, `WHISKY_TASTING_EVENT`이며 `x-curation`, `x-form-style`, `x-field-style`, `x-graphql` 메타를 포함한다. 검증: 원본 파일과 `cmp -s` 3건 일치, `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.CurationOpenApiSpecResourceTest'` 성공. - 2026-05-15 Task 4 완료: `.env`에 `SPRING_PROFILES_ACTIVE=local`을 추가하고 Redis를 로컬 `bottle-note-redis` 컨테이너(`localhost:26379`, no auth)로 연결하도록 수정했다. `set -a; source .env; set +a; ./gradlew :bottlenote-product-api:bootRun`으로 product API가 8080에서 기동했고, 로그에서 GraphQL schema 1개 로드, unmapped field 없음, `POST /graphql` 매핑, Redis connection success를 확인했다. smoke 결과: `GET /actuator/health` HTTP 200 및 Redis UP, `POST /graphql { __typename }` HTTP 200, 기존 `GET /api/v1/curations?cursor=0&pageSize=1` HTTP 200, changelog diff 변경 없음. -- 2026-05-15 GraphiQL 운영 확인: `spring.graphql.graphiql.enabled=true`, `spring.graphql.graphiql.path=/graphiql`를 local/default profile에 추가해 브라우저 기반 GraphQL query console을 열 수 있게 했다. `GET /graphql`은 HTTP 405가 맞고, query 실행은 `POST /graphql` 또는 `/graphiql` UI를 사용한다. +- 2026-05-15 GraphiQL 운영 확인: `spring.graphql.graphiql.enabled=true`, `spring.graphql.graphiql.path=/graphiql`를 local/default profile에 추가해 브라우저 기반 GraphQL query console을 열 수 있게 했다. `GET /graphql`은 HTTP 405가 맞고, query 실행은 `POST /graphql` 또는 `/graphiql` UI를 사용한다. 2026-05-17 운영 하드닝에서 이 결정은 철회했다. 현재는 GraphQL을 내부 hydration boundary로만 유지하기 위해 GraphiQL을 비활성화하고 `/graphql`, `/graphiql`, `/graphiql/**` 외부 HTTP 접근을 403으로 차단한다. - 2026-05-15 GraphQL browser smoke: Chrome에서 `/graphiql?path=/graphql`로 직접 쿼리를 실행했다. `[1, 999999]`는 존재하는 `1`만 반환했고, `[1, 1, 2]`는 중복 제거 후 `1, 2`만 반환했다. `[]`는 빈 배열을 반환했다. `[3, 1, 999999, 1, 2]`는 요청 순서 기준으로 `3, 1, 2`를 반환했고 없는 id와 중복 id를 제외했다. - 2026-05-15 GraphQL boundary smoke: Chrome에서 `picks` field 요청 시 `Field 'picks' in type 'Alcohol' is undefined` validation error가 발생했다. `[1, null]` 입력은 `[ID!]!` 제약에 의해 `ids[1] ... must not be null` validation error가 발생했다. `engName`, `imageUrl`, `regionName`, `korCategory`, `cask`, `abv`, `volume`, `rating`, `totalRatingsCount`, `reviewCount`, `totalPickCount` 전체 field hydration도 정상 확인했다. - 2026-05-15 Task 5 완료: final verification 중 `check_rule_test`가 먼저 product-api 테스트 fake repository compile error로 실패했다. 원인은 `PicksRepository`, `RatingRepository`, `ReviewRepository`에 Phase 1 stats count 메서드를 추가하면서 product-api 테스트 fake 3곳이 새 인터페이스 시그니처를 구현하지 않은 것이었다. `FakePicksRepository`, `InMemoryRatingRepository`, `InMemoryReviewRepository`에 count/average 메서드를 추가했다. @@ -320,6 +320,8 @@ - 2026-05-15 Phase 2 Task 3 완료: 기존 Admin `/curations` endpoint는 유지하고, 신규 spec 기반 Admin surface를 `/spec-based-curations`와 `/curation-specs`로 추가했다. admin-api의 context-path가 이미 `/admin/api/v1`이므로 컨트롤러 path에 `/v2` prefix를 붙이지 않는다. 스펙 API는 목록/상세를 제공한다. 등록/수정은 `specId`로 `curation_spec`을 조회하고, `imageUrls` 1~3장을 정규화해 첫 번째 이미지를 `cover_image_url`에 저장하며, payload는 `curation_extension.payload`에 저장한다. 새 의존성 없이 requestSpec의 required field와 payload 크기를 검증하는 `CurationPayloadValidator`를 추가했다. 검증: `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.AdminSpecBasedCurationServiceTest' :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` 성공, service 테스트 5개와 RestDocs 테스트 6개 통과. `./gradlew check_rule_test` 성공. - 2026-05-15 Phase 3 Task 1 완료: Product v2 조회 API `/api/v2/curations`, `/api/v2/curations/{curationId}`를 추가하고, `responseSpec.x-graphql` 기반 materializer를 도입했다. materializer는 GraphQL query/variables를 responseSpec에서 만들고, Spring GraphQL executor를 통해 내부 실행한 뒤 payload의 `stats` 위치에 병합한다. root array와 `payloadPath = $.alcohols` object payload를 모두 지원하며, `MANUAL` 또는 `alcoholId = null` 항목은 stats를 null로 둔다. `CurationPayloadValidator`는 requestSpec/responseSpec 공통 검증기로 확장해 required, enum, type, minLength/maxLength, minItems/maxItems, minimum/maximum을 검증한다. 검증: focused 테스트 13개 통과, `./gradlew :bottlenote-product-api:compileJava` 성공, `./gradlew check_rule_test` 성공. - 2026-05-15 Phase 3 Task 2 완료: Product v2 목록/상세 RestDocs 테스트를 추가했고, `curation/v2/list`, `curation/v2/detail` 스니펫이 생성되는 것을 확인했다. `./gradlew :bottlenote-product-api:asciidoctor check_rule_test` 성공으로 `product-api.html` 생성과 rule test 통과를 확인했다. runtime smoke는 `.env` 기반 product-api를 8080에서 기동해 `GET /api/v2/curations` HTTP 200을 확인했다. 개발 DB에 active spec 기반 큐레이션이 0건이어서 `CODEX_RUNTIME_SMOKE_20260515` 임시 row를 생성한 뒤 `GET /api/v2/curations` HTTP 200, `GET /api/v2/curations/1` HTTP 200, list count=1, detail spec=`RECOMMENDED_WHISKY`, payload_count=2, BOTTLE_NOTE stats keys=`rating,reviewCount,totalPickCount,totalRatingsCount`, MANUAL stats null을 확인했다. 검증 후 임시 row는 삭제했고 삭제 확인 count=0, bootRun 프로세스도 종료했다. +- 2026-05-17 Copilot review 대응 완료: GraphiQL default/local 비활성화, `/graphql`/`/graphiql`/`/graphiql/**` denyAll 차단, GraphQL stats field N+1 제거를 위한 `@BatchMapping` + `IN ... GROUP BY` 집계, Curation create/update Bean Validation enum message 수정을 반영했다. Copilot review thread 4건은 코드 확인 후 GitHub에서 resolved 처리했다. 검증: `/verify full` 범위로 compile, rule, unit, build, integration, admin integration 모두 성공. +- 2026-05-17 Product V2 Runtime Hardening 완료: Product v2 목록/상세에 `isActive = true`와 `exposureStartDate <= today <= exposureEndDate` 정책을 적용했다. `exposureStartDate` 또는 `exposureEndDate`가 null이면 열린 구간으로 처리한다. GraphQL executor가 null response 또는 execution errors를 반환하면 부분 응답을 만들지 않고 `CURATION_GRAPHQL_EXECUTION_FAILED`로 fail-closed 처리한다. responseSpec 검증 실패 시 내부 로그에 `curationId`, `specCode`, validator error path를 남긴다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-product-api:compileJava :bottlenote-mono:compileTestJava :bottlenote-product-api:compileTestJava` 성공, focused unit/integration + `check_rule_test` 성공. ## Current Decision Summary @@ -333,14 +335,15 @@ - 신규 schema 변경은 Phase 2 Task 1에서 `git.environment-variables/storage/mysql/changelog/` 아래 changelog로 추가했고, 개발 DB와 운영 DB에 Liquibase CLI로 적용했다. - Phase 2 Task 3에서 Admin spec 기반 endpoint를 추가했다. 최종 URL은 admin-api context-path를 포함해 `/admin/api/v1/curation-specs`, `/admin/api/v1/spec-based-curations`다. - Phase 3 Task 1에서 Product spec 기반 endpoint를 추가했다. 최종 URL은 `/api/v2/curations`, `/api/v2/curations/{curationId}`다. +- 2026-05-17 기준 Product v2 endpoint는 노출 기간 필터를 적용한다. `isActive = true`이고 오늘 날짜가 노출 시작/종료일 사이에 있는 큐레이션만 목록/상세에서 조회된다. null 노출일은 열린 구간으로 본다. +- GraphQL hydration 실패는 Product v2 상세 응답에서 부분 성공으로 처리하지 않는다. 내부 로그를 남기고 500 계열 `CURATION_GRAPHQL_EXECUTION_FAILED`로 닫는다. ## Next Work -### Next: Phase 3 - Product V2 Runtime Hardening +### Next: Release Verification -다음 작업은 실제 운영 응답 안전성을 높이는 보강이다. +Product V2 Runtime Hardening까지 이번 브랜치에 반영했다. 다음 작업은 배포 전 검증과 PR 상태 확인이다. -- `responseSpec` 불일치 시 내부 로그에 curationId/specCode/error path를 남긴다. -- Product v2 상세 조회에서 GraphQL executor error가 있을 때의 실패 정책을 명확히 한다. -- exposure date filtering을 Product 목록/상세에 적용할지 정책 결정 후 구현한다. +- CI 결과를 확인한다. +- 필요하면 `.env` 기반 product-api runtime smoke를 한 번 더 수행한다. - 기존 curation keyword endpoint는 계속 유지한다. From 8c67525efaaad3b29041ac87c5a320613ac155ad Mon Sep 17 00:00:00 2001 From: hgkim Date: Sun, 17 May 2026 18:48:33 +0900 Subject: [PATCH 12/33] =?UTF-8?q?fix:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20=EB=A6=AC=EB=B7=B0=20=ED=95=98=EB=93=9C?= =?UTF-8?q?=EB=8B=9D=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CurationPayloadValidator.java | 2 +- .../SpringCurationGraphqlExecutor.java | 19 ++++++++++++++++++- .../service/CurationPayloadValidatorTest.java | 13 +++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java index 665430601..72793031c 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java @@ -32,7 +32,7 @@ public List validate(MapBackedSchema requestSpec, Object payload) { return List.of("payload size must be <= " + MAX_PAYLOAD_BYTES + ", actual=" + payloadBytes); } - if ("array".equals(schema.path("x-container").asText()) || payloadNode.isArray()) { + if ("array".equals(schema.path("x-container").asText())) { if (!payloadNode.isArray()) { return List.of("$ payload는 array여야 합니다."); } diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java index 241a710b1..d88fc2f6a 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java @@ -3,6 +3,7 @@ import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_GRAPHQL_EXECUTION_FAILED; import app.bottlenote.curation.exception.CurationException; +import java.time.Duration; import java.util.Map; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -18,6 +19,8 @@ @Slf4j public class SpringCurationGraphqlExecutor implements CurationGraphqlExecutor { + private static final Duration GRAPHQL_EXECUTION_TIMEOUT = Duration.ofSeconds(3); + private final ExecutionGraphQlService executionGraphQlService; @Override @@ -31,7 +34,21 @@ public Map execute( Map.of(), "curation-" + curationId + "-" + index, null); - ExecutionGraphQlResponse response = Mono.from(executionGraphQlService.execute(request)).block(); + ExecutionGraphQlResponse response; + try { + response = + Mono.from(executionGraphQlService.execute(request)).block(GRAPHQL_EXECUTION_TIMEOUT); + } catch (RuntimeException e) { + log.error( + "Curation GraphQL hydration execution failed. curationId={}, queryIndex={}, payloadPath={}, entryField={}, timeout={}", + curationId, + index, + query.payloadPath(), + query.entryField(), + GRAPHQL_EXECUTION_TIMEOUT, + e); + throw new CurationException(CURATION_GRAPHQL_EXECUTION_FAILED); + } if (response == null) { log.error( "Curation GraphQL hydration returned null response. curationId={}, queryIndex={}, payloadPath={}, entryField={}", diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java index d746269bf..1a2659a4c 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java @@ -50,6 +50,19 @@ void validate_whenArrayContainerIsEmptyOrObject_returnsContainerErrors() throws assertThat(objectErrors).containsExactly("$ payload는 array여야 합니다."); } + @Test + @DisplayName("requestSpec의 x-container가 object이면 root payload 배열을 허용하지 않는다") + void validate_whenObjectContainerReceivesArray_returnsRootTypeError() throws IOException { + Map requestSpec = schema("whisky_tasting_event.json", "Request"); + + List errors = + validator.validate( + new MapBackedSchema(requestSpec), + List.of(tastingEventPayload(0, 1, List.of(recommendedItem("BOTTLE_NOTE"))))); + + assertThat(errors).containsExactly("$ 타입이 object이어야 합니다."); + } + @Test @DisplayName("requestSpec은 required, enum, type 불일치를 상세 path로 검증한다") void validate_whenRequiredEnumOrTypeInvalid_returnsDetailedErrors() throws IOException { From 63c4bf4a5b3040c6f301576e10bc7361ba802a84 Mon Sep 17 00:00:00 2001 From: hgkim Date: Sun, 17 May 2026 19:24:42 +0900 Subject: [PATCH 13/33] =?UTF-8?q?docs:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20=EB=AC=B8=EC=84=9C=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/docs/asciidoc/admin-api.adoc | 4 + .../admin-curations/spec-based-curations.adoc | 134 ++++++++++++++++++ .../src/docs/asciidoc/api/curation/v2.adoc | 61 ++++++++ .../src/docs/asciidoc/product-api.adoc | 3 + 4 files changed, 202 insertions(+) create mode 100644 bottlenote-admin-api/src/docs/asciidoc/api/admin-curations/spec-based-curations.adoc create mode 100644 bottlenote-product-api/src/docs/asciidoc/api/curation/v2.adoc diff --git a/bottlenote-admin-api/src/docs/asciidoc/admin-api.adoc b/bottlenote-admin-api/src/docs/asciidoc/admin-api.adoc index 53cef55a7..f76f521dd 100644 --- a/bottlenote-admin-api/src/docs/asciidoc/admin-api.adoc +++ b/bottlenote-admin-api/src/docs/asciidoc/admin-api.adoc @@ -70,6 +70,10 @@ include::api/admin-curations/curations.adoc[] ''' +include::api/admin-curations/spec-based-curations.adoc[] + +''' + == Users API include::api/admin-users/users.adoc[] diff --git a/bottlenote-admin-api/src/docs/asciidoc/api/admin-curations/spec-based-curations.adoc b/bottlenote-admin-api/src/docs/asciidoc/api/admin-curations/spec-based-curations.adoc new file mode 100644 index 000000000..941a8a1ce --- /dev/null +++ b/bottlenote-admin-api/src/docs/asciidoc/api/admin-curations/spec-based-curations.adoc @@ -0,0 +1,134 @@ +=== 큐레이션 스펙 목록 조회 === + +- 리소스 OpenAPI spec에서 동기화된 큐레이션 스펙 목록을 조회합니다. +- 큐레이션 생성/수정 payload는 이 스펙의 requestSpec 기준으로 검증됩니다. + +[source] +---- +GET /admin/api/v1/curation-specs +---- + +[discrete] +==== 요청 예시 ==== + +include::{snippets}/admin/curation-specs/list/curl-request.adoc[] +include::{snippets}/admin/curation-specs/list/http-request.adoc[] + +[discrete] +==== 응답 예시 ==== + +include::{snippets}/admin/curation-specs/list/response-body.adoc[] + +''' + +=== 큐레이션 스펙 상세 조회 === + +- 특정 큐레이션 스펙의 requestSpec, responseSpec 상세를 조회합니다. + +[source] +---- +GET /admin/api/v1/curation-specs/{specId} +---- + +[discrete] +==== 요청 예시 ==== + +include::{snippets}/admin/curation-specs/detail/curl-request.adoc[] +include::{snippets}/admin/curation-specs/detail/http-request.adoc[] + +[discrete] +==== 응답 예시 ==== + +include::{snippets}/admin/curation-specs/detail/response-body.adoc[] + +''' + +=== Spec 기반 큐레이션 목록 조회 === + +- spec 기반 큐레이션 목록을 페이지네이션으로 조회합니다. +- 키워드와 활성 상태 조건으로 필터링할 수 있습니다. + +[source] +---- +GET /admin/api/v1/spec-based-curations +---- + +[discrete] +==== 요청 예시 ==== + +include::{snippets}/admin/spec-based-curations/list/curl-request.adoc[] +include::{snippets}/admin/spec-based-curations/list/http-request.adoc[] + +[discrete] +==== 응답 예시 ==== + +include::{snippets}/admin/spec-based-curations/list/response-body.adoc[] + +''' + +=== Spec 기반 큐레이션 상세 조회 === + +- 특정 spec 기반 큐레이션의 메타 정보, 스펙, 원본 payload를 조회합니다. + +[source] +---- +GET /admin/api/v1/spec-based-curations/{curationId} +---- + +[discrete] +==== 요청 예시 ==== + +include::{snippets}/admin/spec-based-curations/detail/curl-request.adoc[] +include::{snippets}/admin/spec-based-curations/detail/http-request.adoc[] + +[discrete] +==== 응답 예시 ==== + +include::{snippets}/admin/spec-based-curations/detail/response-body.adoc[] + +''' + +=== Spec 기반 큐레이션 생성 === + +- 선택한 spec의 requestSpec 기준으로 payload를 검증한 뒤 큐레이션을 생성합니다. + +[source] +---- +POST /admin/api/v1/spec-based-curations +---- + +[discrete] +==== 요청 예시 ==== + +include::{snippets}/admin/spec-based-curations/create/curl-request.adoc[] +include::{snippets}/admin/spec-based-curations/create/http-request.adoc[] +include::{snippets}/admin/spec-based-curations/create/request-body.adoc[] + +[discrete] +==== 응답 예시 ==== + +include::{snippets}/admin/spec-based-curations/create/response-body.adoc[] + +''' + +=== Spec 기반 큐레이션 수정 === + +- 기존 spec 기반 큐레이션의 메타 정보와 payload를 수정합니다. +- 수정 payload도 requestSpec 기준으로 검증됩니다. + +[source] +---- +PUT /admin/api/v1/spec-based-curations/{curationId} +---- + +[discrete] +==== 요청 예시 ==== + +include::{snippets}/admin/spec-based-curations/update/curl-request.adoc[] +include::{snippets}/admin/spec-based-curations/update/http-request.adoc[] +include::{snippets}/admin/spec-based-curations/update/request-body.adoc[] + +[discrete] +==== 응답 예시 ==== + +include::{snippets}/admin/spec-based-curations/update/response-body.adoc[] diff --git a/bottlenote-product-api/src/docs/asciidoc/api/curation/v2.adoc b/bottlenote-product-api/src/docs/asciidoc/api/curation/v2.adoc new file mode 100644 index 000000000..706898f7d --- /dev/null +++ b/bottlenote-product-api/src/docs/asciidoc/api/curation/v2.adoc @@ -0,0 +1,61 @@ +=== Spec 기반 큐레이션 v2 목록 조회 === + +- OpenAPI spec 기반으로 등록된 Product 큐레이션 목록을 조회합니다. +- 활성 상태이고 노출 기간에 포함된 큐레이션만 displayOrder, id 순서로 반환합니다. +- 상세 payload는 별도 상세 조회에서 responseSpec 기준으로 materialize 됩니다. + +[source] +---- +GET /api/v2/curations +---- + +[discrete] +==== 요청 예시 ==== + +include::{snippets}/curation/v2/list/curl-request.adoc[] +include::{snippets}/curation/v2/list/http-request.adoc[] + +[discrete] +==== 응답 파라미터 ==== + +include::{snippets}/curation/v2/list/response-fields.adoc[] + +[discrete] +==== 응답 예시 ==== + +include::{snippets}/curation/v2/list/response-body.adoc[] + +''' + +=== Spec 기반 큐레이션 v2 상세 조회 === + +- 특정 spec 기반 큐레이션의 상세 정보를 조회합니다. +- `payload`는 responseSpec 기준으로 검증된 materialized 응답입니다. +- `BOTTLE_NOTE` 항목은 GraphQL hydration으로 통계가 보강되고, `MANUAL` 항목은 수동 payload를 그대로 반환합니다. +- 비활성 상태이거나 노출 기간 밖의 큐레이션은 조회되지 않습니다. + +[source] +---- +GET /api/v2/curations/{curationId} +---- + +[discrete] +==== 경로 파라미터 ==== + +include::{snippets}/curation/v2/detail/path-parameters.adoc[] + +[discrete] +==== 요청 예시 ==== + +include::{snippets}/curation/v2/detail/curl-request.adoc[] +include::{snippets}/curation/v2/detail/http-request.adoc[] + +[discrete] +==== 응답 파라미터 ==== + +include::{snippets}/curation/v2/detail/response-fields.adoc[] + +[discrete] +==== 응답 예시 ==== + +include::{snippets}/curation/v2/detail/response-body.adoc[] diff --git a/bottlenote-product-api/src/docs/asciidoc/product-api.adoc b/bottlenote-product-api/src/docs/asciidoc/product-api.adoc index e45fe5126..db4722f19 100644 --- a/bottlenote-product-api/src/docs/asciidoc/product-api.adoc +++ b/bottlenote-product-api/src/docs/asciidoc/product-api.adoc @@ -96,6 +96,9 @@ include::api/alcohols/categories.adoc[] ''' include::api/alcohols/curations.adoc[] +''' +include::api/curation/v2.adoc[] + ''' include::api/alcohols/popular.adoc[] From dc9cc8516d2cf8c5fdd7bfcbafe876fe8f80db6f Mon Sep 17 00:00:00 2001 From: hgkim Date: Sun, 17 May 2026 19:28:55 +0900 Subject: [PATCH 14/33] =?UTF-8?q?fix:=20=EB=B0=B0=EC=B9=98=20nonce=20salt?= =?UTF-8?q?=20=EA=B8=B0=EB=B3=B8=EA=B0=92=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bottlenote-batch/src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bottlenote-batch/src/main/resources/application.yml b/bottlenote-batch/src/main/resources/application.yml index eb51386a1..ffeeb09e8 100644 --- a/bottlenote-batch/src/main/resources/application.yml +++ b/bottlenote-batch/src/main/resources/application.yml @@ -80,4 +80,4 @@ security: jwt: secret-key: ${JWT_SECRET_KEY} nonce: - salt: ${NONCE_SALT} + salt: ${NONCE_SALT:bottle-note-secure-salt-2024} From f65bcc631730f33812a86b9d9a8623c34268e14f Mon Sep 17 00:00:00 2001 From: hgkim Date: Sun, 17 May 2026 20:36:51 +0900 Subject: [PATCH 15/33] =?UTF-8?q?docs:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20=EB=8D=B0=EB=AA=A8=20=EA=B3=84=ED=9A=8D=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + plan/curation-v2-display-demo-runbook.md | 100 +++++++++++++++ plan/curation-v2-display-demo.md | 153 +++++++++++++++++++++++ 3 files changed, 256 insertions(+) create mode 100644 plan/curation-v2-display-demo-runbook.md create mode 100644 plan/curation-v2-display-demo.md diff --git a/.gitignore b/.gitignore index c8bd096a6..5f7507780 100644 --- a/.gitignore +++ b/.gitignore @@ -83,6 +83,9 @@ docs/modules/admin-api/pages/ docs/modules/admin-api/examples/ docs/_site/ +# Local static demo workspace +.example/ + # 기존 Jekyll 빌드 결과물 (Antora 전환 후 삭제 예정) docs/admin-api.html docs/index.html diff --git a/plan/curation-v2-display-demo-runbook.md b/plan/curation-v2-display-demo-runbook.md new file mode 100644 index 000000000..74836a61f --- /dev/null +++ b/plan/curation-v2-display-demo-runbook.md @@ -0,0 +1,100 @@ +# Curation V2 Display Demo Runbook + +## Purpose + +이 문서는 ignored workspace인 `.example/display`에 구성한 Bottlenote curation v2 정적 데모 실행 방법과 검증 결과를 기록한다. 데모 파일은 local/development 전용 credential을 포함할 수 있으므로 git에 추적하지 않는다. + +## Workspace + +- Demo root: `.example/display` +- Entry page: `.example/display/index.html` +- Environment config: `.example/display/js/config.js` +- API adapter: `.example/display/js/api.js` +- Git tracking policy: `.example/` is ignored by `.gitignore` + +## Environment Switching + +`js/config.js`의 `displayConfig.active` 값으로 대상 환경을 바꾼다. + +```js +export const displayConfig = { + active: 'development', + environments: { + local: { /* local admin/product base URL */ }, + development: { /* development admin/product base URL */ }, + }, +}; +``` + +화면에서 환경 선택 UI는 제공하지 않는다. 데모를 새 환경으로 확인하려면 config 파일을 수정한 뒤 브라우저를 새로고침한다. + +## Authentication + +- Admin API 요청은 `api.login()`이 먼저 `/admin/api/v1/auth/login`을 호출한다. +- access token은 `sessionStorage`에 저장한다. +- token은 파일에 쓰지 않는다. +- 401 응답을 받으면 저장된 token을 지우고 한 번 재로그인한다. + +## Local Static Server + +```bash +python3 -m http.server 8097 --directory .example/display +``` + +확인 URL: + +- `http://127.0.0.1:8097/index.html` +- `http://127.0.0.1:8097/specs.html` +- `http://127.0.0.1:8097/curations.html` +- `http://127.0.0.1:8097/curation-new.html` +- `http://127.0.0.1:8097/curation-detail.html?id=2` + +## Development Smoke Result + +Executed at: 2026-05-17 + +- Static pages: + - `index.html`: HTTP 200 + - `specs.html`: HTTP 200 + - `curations.html`: HTTP 200 + - `curation-detail.html?id=2`: HTTP 200 +- Admin login: + - `/admin/api/v1/auth/login`: HTTP 200 + - access token present: yes +- Admin specs: + - `/admin/api/v1/curation-specs`: HTTP 200 + - count: 3 + - first spec keys: `id`, `code`, `name`, `description`, `hydratorKey`, `version`, `isActive`, `requestSpec`, `responseSpec` +- Admin curation list before demo create: + - `/admin/api/v1/spec-based-curations?keyword=&isActive=&page=0&size=50`: HTTP 200 + - count: 0 +- Product curation list before demo create: + - `/api/v2/curations`: HTTP 200 + - count: 0 +- Invalid create smoke: + - `/admin/api/v1/spec-based-curations`: HTTP 400 + - error code: `CURATION_PAYLOAD_REQUIRED` +- Valid create smoke: + - created name: `CODEX_DISPLAY_SMOKE_20260517` + - targetId: 2 +- Admin detail: + - `/admin/api/v1/spec-based-curations/2`: HTTP 200 + - spec: `RECOMMENDED_WHISKY` + - payload type: array + - payload count: 1 +- Product detail: + - `/api/v2/curations/2`: HTTP 200 + - spec: `RECOMMENDED_WHISKY` + - payload type: array + - payload count: 1 + - first payload `stats`: `null` because the smoke item uses `source=MANUAL` + +## Git Tracking Check + +Expected `git status --short --ignored .example`: + +```text +!! .example/ +``` + +Only `.gitignore`, this plan document, and this runbook should be tracked for the demo workflow. `.example/display/**` must remain ignored. diff --git a/plan/curation-v2-display-demo.md b/plan/curation-v2-display-demo.md new file mode 100644 index 000000000..cd1d286cb --- /dev/null +++ b/plan/curation-v2-display-demo.md @@ -0,0 +1,153 @@ +# Plan: Curation V2 Display Demo + +## Overview + +Bottlenote repository 안에 curation demo 프로젝트의 `display` 정적 데모 화면을 이식한다. 목적은 spec 기반 curation v2의 Admin/Product API 계약이 실제 화면 흐름에서 올바르게 동작하는지 확인하는 것이다. + +데모는 애플리케이션 빌드/배포 산출물에 포함하지 않고, `.example/display` 아래에 둔다. 원본 curation demo의 화면 구조와 UX는 가능한 유지하되, 더 나은 표현이 필요한 부분은 현재 Bottlenote curation v2 API 계약에 맞춰 조정한다. API adapter는 데모 서버 계약이 아니라 현재 Bottlenote 프로젝트의 Admin/Product endpoint와 응답 형식을 기준으로 작성한다. + +## Assumptions + +- `.exmale/display`는 오타이며 최종 대상 경로는 `.example/display`이다. +- 구현 시작 시 Bottlenote repository는 `main` 기준 최신으로 전환하고 `git pull`, submodule update를 먼저 수행한다. +- `git.environment-variables` submodule도 최신 main revision으로 맞춘 뒤 작업한다. +- 원본 curation demo의 디자인과 화면 흐름은 가능한 유지한다. 다만 Bottlenote 응답 구조를 더 명확하게 보여주기 위한 UI 조정은 허용한다. +- 환경 전환은 화면 선택 UI를 만들지 않고 config 파일 하나의 active 값으로 제어한다. +- 지원 환경은 `local`, `development` 두 개다. +- 각 환경 config에는 product/admin base URL, admin login credential, active flag를 둔다. +- admin token은 데모 페이지가 자동 로그인으로 로딩해 보관하고 이후 admin API 요청에 자동으로 붙인다. +- local/development 서버 기동 여부는 데모가 책임지지 않는다. 데모는 API 호출 실패를 화면에 명확히 표시한다. +- 데모는 정적 파일이며 Spring Boot runtime, Gradle build artifact, API 문서 산출물에는 포함하지 않는다. +- 현재 `.gitignore`에는 `.example/`가 없으므로, 구현 단계에서 `.example/`를 ignore 대상으로 추가해야 한다. + +## Success Criteria + +- `.example/display` 아래에서 정적 데모 페이지가 열리고 원본 display의 주요 화면을 제공한다. +- config 파일에서 `active` 환경을 `local` 또는 `development`로 바꾸면 같은 화면이 해당 API base URL을 사용한다. +- development 환경에서 admin login이 자동 수행되고 access token이 이후 Admin API 요청의 `Authorization: Bearer` 헤더에 자동 반영된다. +- 스펙 목록 화면에서 `GET /admin/api/v1/curation-specs` 응답의 3개 spec이 표시된다. +- 스펙 상세 또는 카드 확장 영역에서 `requestSpec`, `responseSpec`, `hydratorKey`, `version`, `isActive`가 확인 가능하다. +- 큐레이션 목록 화면에서 Admin `GET /admin/api/v1/spec-based-curations`와 Product `GET /api/v2/curations`의 결과 차이를 구분해 확인할 수 있다. +- 큐레이션 생성 화면은 현재 Bottlenote Admin create contract에 맞는 payload를 생성한다. +- 생성 요청 실패 시 HTTP status, 서버 error code/message, validation 실패 위치를 화면에 표시한다. +- 생성 성공 후 상세 화면에서 Admin detail payload와 Product detail materialized payload를 비교해 볼 수 있다. +- Product 응답 payload가 `responseSpec`의 의도와 맞는지 사람이 확인할 수 있도록 raw JSON과 모바일 미리보기를 함께 제공한다. +- local 서버가 꺼져 있거나 CORS/auth/API 오류가 발생하면 빈 화면이 아니라 원인 진단 메시지를 표시한다. +- `.example/` 경로는 git에 추적되지 않도록 ignore 처리된다. 단, 필요하면 별도 문서에 실행 방법만 추적한다. + +## Impact Scope + +- Repository state: + - 작업 시작 전 `main` 최신화와 submodule 최신화가 필요하다. + - 기존 `feat/curation` 브랜치 상태에서 바로 구현하지 않는다. + +- Static demo files: + - 새 경로: `.example/display/**` + - 원본 참조: `/Users/hgkim/workspace/etc/curation_demo/curation_demo/display/**` + - 주요 구성: HTML, CSS, JS modules, widgets, environment config, API adapter + +- API surfaces: + - Admin login: `/admin/api/v1/auth/login` + - Admin specs: `/admin/api/v1/curation-specs`, `/admin/api/v1/curation-specs/{specId}` + - Admin spec-based curation: `/admin/api/v1/spec-based-curations`, `/admin/api/v1/spec-based-curations/{curationId}` + - Product curation v2: `/api/v2/curations`, `/api/v2/curations/{curationId}` + +- Security: + - credential은 static config에 들어가므로 이 데모는 local/development 전용이다. + - production credential이나 production base URL은 포함하지 않는다. + - token은 브라우저 메모리 또는 sessionStorage 수준으로만 보관하고 파일에 쓰지 않는다. + +- Persistence/schema: + - DB schema 변경 없음. + - seed/migration 변경 없음. + - 데모를 통한 생성 요청은 development/local DB에 실제 데이터를 만들 수 있으므로 화면에서 대상 환경을 명확히 표시해야 한다. + +- Build/deploy: + - Gradle module 변경 없음. + - Spring Boot app packaging 변경 없음. + - 배포 workflow 변경 없음. + +- Tests/verification: + - 정적 파일 문법 검증 또는 간단한 smoke 실행이 필요하다. + - 가능하면 local static server로 페이지를 열고 development API 대상 스펙 목록 조회, 로그인, curation 목록 조회를 확인한다. + - 브라우저 기반 전체 검증은 필요 시 별도 단계로 수행한다. + +- Documentation: + - `.example/`가 ignore되면 repo에 데모 실행 문서를 남길 별도 위치가 필요할 수 있다. + - 실행 문서에는 config 전환 방법, local/development base URL, 자동 로그인 동작, 주의사항을 적는다. + +## Tasks + +### Task 1: Repository baseline sync +- Acceptance: 작업 브랜치가 최신 `main` 기준에서 시작되고, `git.environment-variables` submodule도 최신 main revision을 가리킨다. +- Acceptance: 동기화 후 기존 curation v2 API 파일과 계획 문서가 사라지지 않는다. +- Verification: `git status --short --branch`, `git rev-parse --short HEAD`, `git submodule status --recursive` +- Files: repository state only; submodule gitlink only if upstream revision changed +- Size: S +- Status: [x] done + +### Task 2: Ignored display workspace +- Acceptance: `.example/`가 git ignore 대상이 되고, `.example/display` 정적 페이지 기본 구조가 준비된다. +- Acceptance: `display.config.js` 하나로 `active: "local" | "development"`를 제어하며 production 환경은 포함하지 않는다. +- Acceptance: config에는 product/admin base URL과 admin login credential이 들어가고, token은 브라우저 메모리 또는 `sessionStorage`에만 저장된다. +- Verification: `git status --ignored --short .example .gitignore`, static server root에서 `index.html` 로드 확인 +- Files: `.gitignore` tracked; `.example/display/index.html`, `.example/display/js/config.js`, `.example/display/js/api.js` ignored +- Size: M +- Status: [x] done + +### Task 3: Spec browsing screens +- Acceptance: 원본 display의 navigation, common style, specs/curations 목록 화면이 Bottlenote API 응답 구조에 맞게 동작한다. +- Acceptance: development 환경에서 자동 로그인 후 `GET /admin/api/v1/curation-specs`가 3개 spec을 표시한다. +- Acceptance: spec 카드에서 `requestSpec`, `responseSpec`, `hydratorKey`, `version`, `isActive`를 확인할 수 있다. +- Verification: static server + development config로 specs 화면 조회, browser console error 없음 +- Files: `.example/display/specs.html`, `.example/display/curations.html`, `.example/display/css/**`, `.example/display/js/nav.js`, `.example/display/js/specs.js`, `.example/display/js/curations.js` ignored +- Size: M +- Status: [x] done + +### Checkpoint: after Tasks 1-3 +- [x] `main` and submodule baseline confirmed +- [x] `.example/` is ignored +- [x] development specs list returns HTTP 200 and renders 3 specs +- [x] no credential or token is tracked by git + +### Task 4: Curation creation flow +- Acceptance: 원본 `curation-new.html`의 동적 form UX를 가능한 유지하면서 Bottlenote Admin `POST /admin/api/v1/spec-based-curations` request body를 생성한다. +- Acceptance: request payload는 선택된 spec의 `requestSpec` 기준으로 구성되고, 기본 정보와 payload가 현재 `CurationCreateRequest` 계약에 맞게 전송된다. +- Acceptance: 실패 시 HTTP status, server error code/message, validation 실패 위치를 화면에 표시한다. +- Verification: development config에서 intentionally invalid payload 요청 후 validation error 표시 확인, valid payload 요청은 사용자 승인 데이터로 smoke 가능 +- Files: `.example/display/curation-new.html`, `.example/display/js/curation-new.js`, `.example/display/js/widgets/**`, `.example/display/js/styles.js` ignored +- Size: M +- Status: [x] done + +### Task 5: Detail comparison screen +- Acceptance: 상세 화면에서 Admin detail 응답과 Product detail 응답을 같은 curation id 기준으로 조회해 비교한다. +- Acceptance: Admin raw payload, Product materialized payload, `responseSpec`를 동시에 확인할 수 있다. +- Acceptance: 모바일 미리보기는 Product 응답을 기준으로 표시하고, hydration 결과가 없거나 null인 항목을 구분해 보여준다. +- Verification: existing or newly created curation id로 admin/product detail HTTP 200 확인, raw JSON과 preview 렌더 확인 +- Files: `.example/display/curation-detail.html`, `.example/display/js/curation-detail.js`, `.example/display/js/mobile-preview.js`, `.example/display/js/widgets/**` ignored +- Size: M +- Status: [x] done + +### Task 6: Demo verification notes +- Acceptance: ignored demo 실행 방법, config 전환 방법, 자동 로그인 동작, local/development 주의사항이 tracked 문서에 남는다. +- Acceptance: development API 기준 specs list, admin curations list, product curations list, login token injection smoke 결과가 기록된다. +- Acceptance: `.example/` 아래 credential/token이 git에 추적되지 않는다는 증거가 남는다. +- Verification: `git status --short --ignored .example`, `curl` 또는 browser smoke 결과 기록, `git diff --check` +- Files: tracked documentation under `plan/` or `docs/`; ignored `.example/display/**` remains untracked +- Size: S +- Status: [x] done + +### Checkpoint: after Tasks 4-6 +- [x] create flow maps to Admin request contract +- [x] detail screen compares Admin and Product responses +- [x] development smoke completed with token auto-loading +- [x] tracked diff excludes `.example/display/**` + +## Progress Log + +- 2026-05-17 Task 1 완료: `main`으로 전환 후 `git pull`로 `dc9cc851`까지 fast-forward했고, `git.environment-variables` submodule은 `8dd662e15c098c2e57c36a2604a1ba42fceed9f1` 상태임을 확인했다. 최신 main 기준 작업 브랜치 `codex/curation-v2-display-demo`를 생성했다. 검증: `git status --short --branch`, `git rev-parse --short HEAD`, `git submodule status --recursive`. +- 2026-05-17 Task 2 완료: `.gitignore`에 `.example/`를 추가했고 원본 curation demo display를 `.example/display`로 복사했다. `js/config.js`는 `active` 기반 local/development 전환을 제공하고, `js/api.js`는 Bottlenote Admin/Product base URL, admin 자동 로그인, sessionStorage token 저장, GlobalResponse unwrap을 담당한다. 검증: `git status --short --ignored .example .gitignore plan/curation-v2-display-demo.md`, `node --check .example/display/js/api.js`, `node --check .example/display/js/config.js`, `node --check .example/display/js/nav.js`. +- 2026-05-17 Task 3 완료: specs 화면은 Admin `/curation-specs` 응답의 `requestSpec`, `responseSpec`, `hydratorKey`, `version`, `isActive`를 표시하고, curations 화면은 Admin `/spec-based-curations`와 Product `/api/v2/curations`를 나란히 조회하도록 조정했다. 정적 서버 `localhost:8097`에서 `index.html`, `specs.html`, `curations.html` HTTP 200을 확인했다. development API smoke는 specs=200 count=3, admin_curations=200 count=0, product_curations=200 count=0. +- 2026-05-17 Task 4 완료: `curation-new.html` 기본 노출 기간을 현재 dev smoke에 맞게 2026-05-17~2026-12-31로 바꾸고, submit body에서 DTO에 없는 `coverImageUrl`을 제거했다. 오류 표시는 `HTTP status`, server `code/status/message`를 노출하도록 조정했다. development Admin create invalid smoke는 HTTP 400, `CURATION_PAYLOAD_REQUIRED`를 확인했다. +- 2026-05-17 Task 5 완료: 상세 화면을 Admin raw detail과 Product materialized detail 비교 화면으로 단순화했다. development에 `CODEX_DISPLAY_SMOKE_20260517` 큐레이션을 생성했고 `targetId=2`를 받았다. Admin detail HTTP 200, Product detail HTTP 200, Admin payload array count=1, Product payload array count=1, MANUAL 항목 `stats=null`을 확인했다. 정적 상세 페이지 `curation-detail.html?id=2`도 HTTP 200으로 서빙됐다. +- 2026-05-17 Task 6 완료: `plan/curation-v2-display-demo-runbook.md`에 ignored demo 실행 방법, config 전환, 자동 로그인, development smoke 결과, git tracking policy를 기록했다. `.example/`는 `!! .example/`로 ignored 상태이고, tracked diff에는 `.example/display/**`가 포함되지 않는다. From 1b8fbf44d2f8f8b5a03ad2be7e81bf17f9f5d428 Mon Sep 17 00:00:00 2001 From: hgkim Date: Mon, 18 May 2026 09:18:19 +0900 Subject: [PATCH 16/33] =?UTF-8?q?refactor:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20=EC=A0=80=EC=9E=A5=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EB=8B=A8=EC=9D=BC=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/CurationSpecCreateRequest.java | 12 -- .../curation/service/CurationV2Service.java | 101 ------------- .../fixture/CurationFixtureFactory.java | 76 ++++++++++ .../AdminSpecBasedCurationServiceTest.java | 25 ++- .../service/CurationV2ServiceTest.java | 142 ------------------ .../ProductSpecBasedCurationServiceTest.java | 29 ++-- plan/spec-based-curation-v2-graphql-sdl.md | 10 +- 7 files changed, 109 insertions(+), 286 deletions(-) delete mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationSpecCreateRequest.java delete mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationV2Service.java create mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/CurationFixtureFactory.java delete mode 100644 bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationV2ServiceTest.java diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationSpecCreateRequest.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationSpecCreateRequest.java deleted file mode 100644 index 04fce36db..000000000 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/CurationSpecCreateRequest.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.bottlenote.curation.dto.request; - -import java.util.Map; - -public record CurationSpecCreateRequest( - String code, - String name, - String description, - Map requestSpec, - Map responseSpec, - String hydratorKey, - Integer version) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationV2Service.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationV2Service.java deleted file mode 100644 index 1a2ebf129..000000000 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationV2Service.java +++ /dev/null @@ -1,101 +0,0 @@ -package app.bottlenote.curation.service; - -import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_NOT_FOUND; -import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_SPEC_DUPLICATE_CODE; -import static app.bottlenote.curation.exception.CurationExceptionCode.CURATION_SPEC_NOT_FOUND; - -import app.bottlenote.curation.domain.Curation; -import app.bottlenote.curation.domain.CurationExtension; -import app.bottlenote.curation.domain.CurationExtensionRepository; -import app.bottlenote.curation.domain.CurationRepository; -import app.bottlenote.curation.domain.CurationSpec; -import app.bottlenote.curation.domain.CurationSpecRepository; -import app.bottlenote.curation.dto.request.CurationCreateRequest; -import app.bottlenote.curation.dto.request.CurationSpecCreateRequest; -import app.bottlenote.curation.exception.CurationException; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class CurationV2Service { - - private final CurationSpecRepository curationSpecRepository; - private final CurationRepository curationRepository; - private final CurationExtensionRepository curationExtensionRepository; - - @Transactional - public CurationSpec createSpec(CurationSpecCreateRequest command) { - if (curationSpecRepository.existsByCode(command.code())) { - throw new CurationException(CURATION_SPEC_DUPLICATE_CODE); - } - - CurationSpec curationSpec = - CurationSpec.builder() - .code(command.code()) - .name(command.name()) - .description(command.description()) - .requestSpec(command.requestSpec()) - .responseSpec(command.responseSpec()) - .hydratorKey(command.hydratorKey()) - .version(command.version() != null ? command.version() : 1) - .isActive(true) - .build(); - return curationSpecRepository.save(curationSpec); - } - - @Transactional - public Curation createCuration(CurationCreateRequest command) { - CurationSpec curationSpec = getSpec(command.specId()); - Curation curation = - Curation.builder() - .specId(curationSpec.getId()) - .name(command.name()) - .description(command.description()) - .coverImageUrl(command.imageUrls().get(0)) - .imageUrl2(command.imageUrls().size() > 1 ? command.imageUrls().get(1) : null) - .imageUrl3(command.imageUrls().size() > 2 ? command.imageUrls().get(2) : null) - .exposureStartDate(command.exposureStartDate()) - .exposureEndDate(command.exposureEndDate()) - .displayOrder(command.displayOrder() != null ? command.displayOrder() : 0) - .isActive(command.isActive()) - .build(); - - Curation saved = curationRepository.save(curation); - curationExtensionRepository.save( - CurationExtension.builder() - .curationId(saved.getId()) - .specId(curationSpec.getId()) - .payload(command.payload()) - .build()); - return saved; - } - - @Transactional(readOnly = true) - public CurationSpec getSpec(Long specId) { - return curationSpecRepository - .findById(specId) - .orElseThrow(() -> new CurationException(CURATION_SPEC_NOT_FOUND)); - } - - @Transactional(readOnly = true) - public Curation getCuration(Long curationId) { - return curationRepository - .findById(curationId) - .orElseThrow(() -> new CurationException(CURATION_NOT_FOUND)); - } - - @Transactional(readOnly = true) - public CurationExtension getExtension(Long curationId) { - return curationExtensionRepository - .findByCurationId(curationId) - .orElseThrow(() -> new CurationException(CURATION_NOT_FOUND)); - } - - @Transactional(readOnly = true) - public List findActiveCurations() { - return curationRepository.findAllByIsActiveTrueOrderByDisplayOrderAscIdAsc(); - } -} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/CurationFixtureFactory.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/CurationFixtureFactory.java new file mode 100644 index 000000000..647258a5a --- /dev/null +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/CurationFixtureFactory.java @@ -0,0 +1,76 @@ +package app.bottlenote.curation.fixture; + +import app.bottlenote.curation.domain.Curation; +import app.bottlenote.curation.domain.CurationExtension; +import app.bottlenote.curation.domain.CurationExtensionRepository; +import app.bottlenote.curation.domain.CurationRepository; +import app.bottlenote.curation.domain.CurationSpec; +import app.bottlenote.curation.domain.CurationSpecRepository; +import app.bottlenote.curation.dto.request.CurationCreateRequest; +import java.util.LinkedHashMap; +import java.util.Map; + +public class CurationFixtureFactory { + + private final CurationSpecRepository curationSpecRepository; + private final CurationRepository curationRepository; + private final CurationExtensionRepository curationExtensionRepository; + + public CurationFixtureFactory( + CurationSpecRepository curationSpecRepository, + CurationRepository curationRepository, + CurationExtensionRepository curationExtensionRepository) { + this.curationSpecRepository = curationSpecRepository; + this.curationRepository = curationRepository; + this.curationExtensionRepository = curationExtensionRepository; + } + + public CurationSpec saveSpec( + String code, + String name, + String description, + Map requestSpec, + Map responseSpec, + String hydratorKey, + Integer version) { + return curationSpecRepository.save( + CurationSpec.builder() + .code(code) + .name(name) + .description(description) + .requestSpec(copyOf(requestSpec)) + .responseSpec(copyOf(responseSpec)) + .hydratorKey(hydratorKey) + .version(version != null ? version : 1) + .isActive(true) + .build()); + } + + public Curation saveCuration(CurationCreateRequest request) { + Curation saved = + curationRepository.save( + Curation.builder() + .specId(request.specId()) + .name(request.name()) + .description(request.description()) + .coverImageUrl(request.imageUrls().get(0)) + .imageUrl2(request.imageUrls().size() > 1 ? request.imageUrls().get(1) : null) + .imageUrl3(request.imageUrls().size() > 2 ? request.imageUrls().get(2) : null) + .exposureStartDate(request.exposureStartDate()) + .exposureEndDate(request.exposureEndDate()) + .displayOrder(request.displayOrder()) + .isActive(request.isActive()) + .build()); + curationExtensionRepository.save( + CurationExtension.builder() + .curationId(saved.getId()) + .specId(request.specId()) + .payload(request.payload()) + .build()); + return saved; + } + + private static Map copyOf(Map value) { + return value != null ? new LinkedHashMap<>(value) : new LinkedHashMap<>(); + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/AdminSpecBasedCurationServiceTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/AdminSpecBasedCurationServiceTest.java index 63fb08971..42058a5ae 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/AdminSpecBasedCurationServiceTest.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/AdminSpecBasedCurationServiceTest.java @@ -6,11 +6,11 @@ import app.bottlenote.curation.domain.CurationSpec; import app.bottlenote.curation.dto.request.CurationCreateRequest; import app.bottlenote.curation.dto.request.CurationSearchRequest; -import app.bottlenote.curation.dto.request.CurationSpecCreateRequest; import app.bottlenote.curation.dto.request.CurationUpdateRequest; import app.bottlenote.curation.dto.response.AdminSpecBasedCurationDetailResponse; import app.bottlenote.curation.exception.CurationException; import app.bottlenote.curation.exception.CurationExceptionCode; +import app.bottlenote.curation.fixture.CurationFixtureFactory; import app.bottlenote.curation.fixture.InMemoryCurationExtensionRepository; import app.bottlenote.curation.fixture.InMemoryCurationRepository; import app.bottlenote.curation.fixture.InMemoryCurationSpecRepository; @@ -31,7 +31,7 @@ class AdminSpecBasedCurationServiceTest { InMemoryCurationSpecRepository curationSpecRepository; InMemoryCurationRepository curationRepository; InMemoryCurationExtensionRepository curationExtensionRepository; - CurationV2Service curationV2Service; + CurationFixtureFactory curationFixtureFactory; AdminSpecBasedCurationService adminSpecBasedCurationService; @BeforeEach @@ -40,8 +40,8 @@ void setUp() { curationRepository = new InMemoryCurationRepository(); curationExtensionRepository = new InMemoryCurationExtensionRepository(); ObjectMapper objectMapper = new ObjectMapper(); - curationV2Service = - new CurationV2Service( + curationFixtureFactory = + new CurationFixtureFactory( curationSpecRepository, curationRepository, curationExtensionRepository); adminSpecBasedCurationService = new AdminSpecBasedCurationService( @@ -145,15 +145,14 @@ void setUp() { } private CurationSpec createSpec() { - return curationV2Service.createSpec( - new CurationSpecCreateRequest( - "RECOMMENDED_WHISKY", - "추천 위스키", - null, - Map.of("type", "object", "required", List.of("source", "alcohol")), - Map.of("type", "object"), - "alcohol", - 1)); + return curationFixtureFactory.saveSpec( + "RECOMMENDED_WHISKY", + "추천 위스키", + null, + Map.of("type", "object", "required", List.of("source", "alcohol")), + Map.of("type", "object"), + "alcohol", + 1); } private CurationCreateRequest createRequest(Long specId) { diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationV2ServiceTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationV2ServiceTest.java deleted file mode 100644 index 871565436..000000000 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationV2ServiceTest.java +++ /dev/null @@ -1,142 +0,0 @@ -package app.bottlenote.curation.service; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import app.bottlenote.curation.domain.Curation; -import app.bottlenote.curation.domain.CurationExtension; -import app.bottlenote.curation.domain.CurationSpec; -import app.bottlenote.curation.dto.request.CurationCreateRequest; -import app.bottlenote.curation.dto.request.CurationSpecCreateRequest; -import app.bottlenote.curation.exception.CurationException; -import app.bottlenote.curation.exception.CurationExceptionCode; -import app.bottlenote.curation.fixture.InMemoryCurationExtensionRepository; -import app.bottlenote.curation.fixture.InMemoryCurationRepository; -import app.bottlenote.curation.fixture.InMemoryCurationSpecRepository; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.time.LocalDate; -import java.util.List; -import java.util.Map; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -@Tag("unit") -@DisplayName("CurationV2Service 단위 테스트") -class CurationV2ServiceTest { - - InMemoryCurationSpecRepository curationSpecRepository; - InMemoryCurationRepository curationRepository; - InMemoryCurationExtensionRepository curationExtensionRepository; - CurationV2Service curationV2Service; - - @BeforeEach - void setUp() { - curationSpecRepository = new InMemoryCurationSpecRepository(); - curationRepository = new InMemoryCurationRepository(); - curationExtensionRepository = new InMemoryCurationExtensionRepository(); - curationV2Service = - new CurationV2Service( - curationSpecRepository, curationRepository, curationExtensionRepository); - } - - @Test - @DisplayName("새 큐레이션 스펙을 저장할 수 있다") - void createSpec_신규_스펙_저장() { - CurationSpec result = - curationV2Service.createSpec( - new CurationSpecCreateRequest( - "RECOMMENDED_WHISKY", - "추천 위스키", - "개인화 추천", - Map.of("type", "object", "required", List.of("source", "alcohol")), - Map.of("type", "object"), - "BOTTLE_NOTE", - null)); - - assertThat(result.getId()).isNotNull(); - assertThat(result.getVersion()).isEqualTo(1); - assertThat(result.getIsActive()).isTrue(); - } - - @Test - @DisplayName("중복 코드로 큐레이션 스펙을 저장하면 예외가 발생한다") - void createSpec_중복_코드_예외() { - curationV2Service.createSpec( - new CurationSpecCreateRequest( - "RECOMMENDED_WHISKY", - "추천 위스키", - null, - Map.of("type", "object", "required", List.of("source", "alcohol")), - Map.of("type", "object"), - "BOTTLE_NOTE", - 1)); - - assertThatThrownBy( - () -> - curationV2Service.createSpec( - new CurationSpecCreateRequest( - "RECOMMENDED_WHISKY", "중복 추천", null, Map.of(), Map.of(), "BOTTLE_NOTE", 1))) - .isInstanceOf(CurationException.class) - .hasFieldOrPropertyWithValue( - "exceptionCode", CurationExceptionCode.CURATION_SPEC_DUPLICATE_CODE); - } - - @Test - @DisplayName("큐레이션 저장 시 본문과 payload 확장을 함께 저장한다") - void createCuration_본문과_payload_저장() { - CurationSpec spec = - curationV2Service.createSpec( - new CurationSpecCreateRequest( - "RECOMMENDED_WHISKY", - "추천 위스키", - null, - Map.of("type", "object", "required", List.of("source", "alcohol")), - Map.of("type", "object"), - "BOTTLE_NOTE", - 1)); - - Curation curation = - curationV2Service.createCuration( - new CurationCreateRequest( - spec.getId(), - "비 오는 날 위스키", - "스모키 위스키 추천", - List.of("https://cdn.example.com/cover.jpg"), - LocalDate.of(2026, 5, 15), - LocalDate.of(2026, 6, 15), - 10, - true, - Map.of("source", "BOTTLE_NOTE", "alcohol", Map.of("korName", "테스트")))); - - CurationExtension extension = curationV2Service.getExtension(curation.getId()); - - assertThat(curation.getSpecId()).isEqualTo(spec.getId()); - assertThat(curation.getDisplayOrder()).isEqualTo(10); - assertThat(extension.getSpecId()).isEqualTo(spec.getId()); - assertThat(new ObjectMapper().valueToTree(extension.getPayload()).path("source").asText()) - .isEqualTo("BOTTLE_NOTE"); - } - - @Test - @DisplayName("존재하지 않는 스펙으로 큐레이션을 저장하면 예외가 발생한다") - void createCuration_스펙_없음_예외() { - assertThatThrownBy( - () -> - curationV2Service.createCuration( - new CurationCreateRequest( - 999L, - "없는 스펙", - null, - List.of("https://cdn.example.com/cover.jpg"), - null, - null, - 0, - true, - Map.of()))) - .isInstanceOf(CurationException.class) - .hasFieldOrPropertyWithValue( - "exceptionCode", CurationExceptionCode.CURATION_SPEC_NOT_FOUND); - } -} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java index 43c98c14d..e46c58a60 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java @@ -5,10 +5,10 @@ import app.bottlenote.curation.domain.CurationSpec; import app.bottlenote.curation.dto.request.CurationCreateRequest; -import app.bottlenote.curation.dto.request.CurationSpecCreateRequest; import app.bottlenote.curation.dto.response.ProductSpecBasedCurationDetailResponse; import app.bottlenote.curation.exception.CurationException; import app.bottlenote.curation.exception.CurationExceptionCode; +import app.bottlenote.curation.fixture.CurationFixtureFactory; import app.bottlenote.curation.fixture.InMemoryCurationExtensionRepository; import app.bottlenote.curation.fixture.InMemoryCurationRepository; import app.bottlenote.curation.fixture.InMemoryCurationSpecRepository; @@ -36,7 +36,7 @@ class ProductSpecBasedCurationServiceTest { InMemoryCurationSpecRepository specRepository; InMemoryCurationRepository curationRepository; InMemoryCurationExtensionRepository extensionRepository; - CurationV2Service curationV2Service; + CurationFixtureFactory curationFixtureFactory; ProductSpecBasedCurationService productService; @BeforeEach @@ -44,8 +44,8 @@ void setUp() { specRepository = new InMemoryCurationSpecRepository(); curationRepository = new InMemoryCurationRepository(); extensionRepository = new InMemoryCurationExtensionRepository(); - curationV2Service = - new CurationV2Service(specRepository, curationRepository, extensionRepository); + curationFixtureFactory = + new CurationFixtureFactory(specRepository, curationRepository, extensionRepository); CurationResponseMaterializer materializer = new CurationResponseMaterializer( OBJECT_MAPPER, @@ -120,15 +120,14 @@ void getDetail_whenCurationOutsideExposureWindow_throwsNotFound() throws IOExcep } private CurationSpec createSpec() throws IOException { - return curationV2Service.createSpec( - new CurationSpecCreateRequest( - "RECOMMENDED_WHISKY", - "추천 위스키", - "추천 설명", - schema("recommended_whisky.json", "Request"), - schema("recommended_whisky.json", "Response"), - "alcohol", - 2)); + return curationFixtureFactory.saveSpec( + "RECOMMENDED_WHISKY", + "추천 위스키", + "추천 설명", + schema("recommended_whisky.json", "Request"), + schema("recommended_whisky.json", "Response"), + "alcohol", + 2); } private Long createCuration(Long specId, String name, int displayOrder, boolean active) { @@ -148,8 +147,8 @@ private Long createCuration( boolean active, LocalDate exposureStartDate, LocalDate exposureEndDate) { - return curationV2Service - .createCuration( + return curationFixtureFactory + .saveCuration( new CurationCreateRequest( specId, name, diff --git a/plan/spec-based-curation-v2-graphql-sdl.md b/plan/spec-based-curation-v2-graphql-sdl.md index f5888f657..5d292be1b 100644 --- a/plan/spec-based-curation-v2-graphql-sdl.md +++ b/plan/spec-based-curation-v2-graphql-sdl.md @@ -218,16 +218,19 @@ - `bottlenote-mono`에 `curation_spec`, `curation`, `curation_extension`에 대응되는 Entity를 추가한다. - Repository는 domain interface + JPA implementation 패턴을 따른다. - JSON 컬럼은 기존 Hypersistence `JsonType` 기반 매핑을 사용한다. - - Admin command가 재사용할 persistence service를 추가하되, REST endpoint는 아직 만들지 않는다. + - ~~Admin command가 재사용할 persistence service를 추가하되, REST endpoint는 아직 만들지 않는다.~~ + - 정정: Admin command 저장 경로는 `AdminSpecBasedCurationService`로 단일화하고, mono에는 Entity + Repository + 테스트 fixture만 유지한다. - Verification: - `./gradlew :bottlenote-mono:compileJava` - - `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationV2ServiceTest'` + - ~~`./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationV2ServiceTest'`~~ + - `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.AdminSpecBasedCurationServiceTest' --tests 'app.bottlenote.curation.service.ProductSpecBasedCurationServiceTest' --tests 'app.bottlenote.curation.service.CurationResponseMaterializerTest'` - `./gradlew check_rule_test` - Files: - `bottlenote-mono/src/main/java/app/bottlenote/curation/domain/*` - `bottlenote-mono/src/main/java/app/bottlenote/curation/dto/request/*` - `bottlenote-mono/src/main/java/app/bottlenote/curation/repository/*` - - `bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationV2Service.java` + - ~~`bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationV2Service.java`~~ + - `bottlenote-mono/src/test/java/app/bottlenote/curation/fixture/CurationFixtureFactory.java` - `bottlenote-mono/src/test/java/app/bottlenote/curation/**` - Size: M - Status: [x] done @@ -322,6 +325,7 @@ - 2026-05-15 Phase 3 Task 2 완료: Product v2 목록/상세 RestDocs 테스트를 추가했고, `curation/v2/list`, `curation/v2/detail` 스니펫이 생성되는 것을 확인했다. `./gradlew :bottlenote-product-api:asciidoctor check_rule_test` 성공으로 `product-api.html` 생성과 rule test 통과를 확인했다. runtime smoke는 `.env` 기반 product-api를 8080에서 기동해 `GET /api/v2/curations` HTTP 200을 확인했다. 개발 DB에 active spec 기반 큐레이션이 0건이어서 `CODEX_RUNTIME_SMOKE_20260515` 임시 row를 생성한 뒤 `GET /api/v2/curations` HTTP 200, `GET /api/v2/curations/1` HTTP 200, list count=1, detail spec=`RECOMMENDED_WHISKY`, payload_count=2, BOTTLE_NOTE stats keys=`rating,reviewCount,totalPickCount,totalRatingsCount`, MANUAL stats null을 확인했다. 검증 후 임시 row는 삭제했고 삭제 확인 count=0, bootRun 프로세스도 종료했다. - 2026-05-17 Copilot review 대응 완료: GraphiQL default/local 비활성화, `/graphql`/`/graphiql`/`/graphiql/**` denyAll 차단, GraphQL stats field N+1 제거를 위한 `@BatchMapping` + `IN ... GROUP BY` 집계, Curation create/update Bean Validation enum message 수정을 반영했다. Copilot review thread 4건은 코드 확인 후 GitHub에서 resolved 처리했다. 검증: `/verify full` 범위로 compile, rule, unit, build, integration, admin integration 모두 성공. - 2026-05-17 Product V2 Runtime Hardening 완료: Product v2 목록/상세에 `isActive = true`와 `exposureStartDate <= today <= exposureEndDate` 정책을 적용했다. `exposureStartDate` 또는 `exposureEndDate`가 null이면 열린 구간으로 처리한다. GraphQL executor가 null response 또는 execution errors를 반환하면 부분 응답을 만들지 않고 `CURATION_GRAPHQL_EXECUTION_FAILED`로 fail-closed 처리한다. responseSpec 검증 실패 시 내부 로그에 `curationId`, `specCode`, validator error path를 남긴다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-product-api:compileJava :bottlenote-mono:compileTestJava :bottlenote-product-api:compileTestJava` 성공, focused unit/integration + `check_rule_test` 성공. +- 2026-05-18 리팩토링 완료: `CurationV2Service`와 `CurationSpecCreateRequest`를 제거해 검증 없는 운영 저장 경로를 닫았다. 단위 테스트의 spec/curation 생성은 `CurationFixtureFactory`로 이동했고, 실제 Admin 저장 경로는 `AdminSpecBasedCurationService`로 단일화했다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-mono:compileTestJava` 성공, focused curation unit 13개 성공, `./gradlew check_rule_test` 성공, `./gradlew unit_test` 성공. ## Current Decision Summary From e7c59825a38e065ecefc5dfd4e921e2635f64ce6 Mon Sep 17 00:00:00 2001 From: hgkim Date: Mon, 18 May 2026 10:03:48 +0900 Subject: [PATCH 17/33] =?UTF-8?q?feat:=20=EC=96=B4=EB=93=9C=EB=AF=BC=20API?= =?UTF-8?q?=20=EB=B2=84=EC=A0=84=20prefix=20=EA=B8=B0=EB=B0=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/AdminApiVersionConfig.kt | 28 +++ .../app/global/security/SecurityConfig.kt | 2 +- .../src/main/resources/application.yml | 2 +- plan/admin-api-v2-curation-endpoints.md | 220 ++++++++++++++++++ 4 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 bottlenote-admin-api/src/main/kotlin/app/global/config/AdminApiVersionConfig.kt create mode 100644 plan/admin-api-v2-curation-endpoints.md diff --git a/bottlenote-admin-api/src/main/kotlin/app/global/config/AdminApiVersionConfig.kt b/bottlenote-admin-api/src/main/kotlin/app/global/config/AdminApiVersionConfig.kt new file mode 100644 index 000000000..dff9bf084 --- /dev/null +++ b/bottlenote-admin-api/src/main/kotlin/app/global/config/AdminApiVersionConfig.kt @@ -0,0 +1,28 @@ +package app.global.config + +import app.bottlenote.curation.presentation.AdminCurationSpecController +import app.bottlenote.curation.presentation.AdminSpecBasedCurationController +import org.springframework.context.annotation.Configuration +import org.springframework.web.servlet.config.annotation.PathMatchConfigurer +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer + +@Configuration +class AdminApiVersionConfig : WebMvcConfigurer { + override fun configurePathMatch(configurer: PathMatchConfigurer) { + configurer.addPathPrefix("/v1") { controllerType -> + isLegacyAdminController(controllerType) + } + } + + private fun isLegacyAdminController(controllerType: Class<*>): Boolean = controllerType.packageName.startsWith("app.bottlenote") && + controllerType.packageName.contains(".presentation") && + controllerType.simpleName.endsWith("Controller") && + !excludedControllers.contains(controllerType) + + private companion object { + private val excludedControllers = setOf( + AdminCurationSpecController::class.java, + AdminSpecBasedCurationController::class.java + ) + } +} diff --git a/bottlenote-admin-api/src/main/kotlin/app/global/security/SecurityConfig.kt b/bottlenote-admin-api/src/main/kotlin/app/global/security/SecurityConfig.kt index dba37f817..11ea4cee8 100644 --- a/bottlenote-admin-api/src/main/kotlin/app/global/security/SecurityConfig.kt +++ b/bottlenote-admin-api/src/main/kotlin/app/global/security/SecurityConfig.kt @@ -31,7 +31,7 @@ class SecurityConfig( auth .requestMatchers(*MaliciousPathPattern.getAllPatterns()) .denyAll() - .requestMatchers("/auth/login", "/auth/refresh") + .requestMatchers("/v1/auth/login", "/v1/auth/refresh") .permitAll() .requestMatchers("/actuator/**") .permitAll() diff --git a/bottlenote-admin-api/src/main/resources/application.yml b/bottlenote-admin-api/src/main/resources/application.yml index 37aec8d13..0c8fd9ede 100644 --- a/bottlenote-admin-api/src/main/resources/application.yml +++ b/bottlenote-admin-api/src/main/resources/application.yml @@ -10,7 +10,7 @@ app: # 애플리케이션 및 배포 정보 server: port: ${SERVER_PORT:8080} servlet: - context-path: /admin/api/v1 + context-path: /admin/api encoding: charset: UTF-8 compression: diff --git a/plan/admin-api-v2-curation-endpoints.md b/plan/admin-api-v2-curation-endpoints.md new file mode 100644 index 000000000..1b54d982d --- /dev/null +++ b/plan/admin-api-v2-curation-endpoints.md @@ -0,0 +1,220 @@ +# Plan: Admin API V2 Curation Endpoints + +## Overview + +Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.servlet.context-path=/admin/api/v1`에 version이 박혀 있어서 신규 spec 기반 큐레이션 endpoint가 `/admin/api/v1/spec-based-curations` 형태로 노출된다. 앞으로는 context-path를 `/admin/api`로 낮추고, 기존 Admin API는 controller mapping에서 `/v1`을 명시하며, 신규 spec 기반 큐레이션 API는 `/v2` surface로 노출한다. + +최종 목표는 기존 legacy Admin API를 `/admin/api/v1/**`로 유지하면서, 신규 spec 기반 큐레이션 관리는 `/admin/api/v2/curations`, `/admin/api/v2/curation-specs`로 고정하는 것이다. + +### Assumptions + +- admin-api 전체 context-path는 `/admin/api`로 변경한다. +- 기존 Admin v1 API는 깨지지 않도록 모든 기존 controller mapping에 `/v1` prefix를 명시한다. +- 기존 spec 기반 endpoint `/admin/api/v1/spec-based-curations`, `/admin/api/v1/curation-specs`는 호환 alias로 남기지 않는다. +- spec 기반 큐레이션 본문 관리는 `/admin/api/v2/curations`로 노출한다. +- 큐레이션 스펙 관리는 `/admin/api/v2/curation-specs`로 노출한다. +- Product API `/api/v2/curations`는 이번 변경 범위가 아니다. +- DB schema, GraphQL SDL, payload validation, Product materializer 로직은 이번 변경 범위가 아니다. + +### Success Criteria + +- `bottlenote-admin-api`의 `server.servlet.context-path`가 `/admin/api`로 변경된다. +- 기존 Admin v1 controller들은 최종 URL이 기존과 동일하게 `/admin/api/v1/**`로 유지된다. +- spec 기반 큐레이션 관리 API 최종 URL은 다음과 같다. + - `GET /admin/api/v2/curation-specs` + - `GET /admin/api/v2/curation-specs/{specId}` + - `GET /admin/api/v2/curations` + - `GET /admin/api/v2/curations/{curationId}` + - `POST /admin/api/v2/curations` + - `PUT /admin/api/v2/curations/{curationId}` +- `/admin/api/v1/spec-based-curations`와 `/admin/api/v1/curation-specs`는 더 이상 canonical endpoint가 아니다. +- Admin RestDocs snippets와 문서 경로/설명이 신규 `/v2` endpoint 기준으로 갱신된다. +- Admin integration test가 신규 `/v2` endpoint로 생성/조회/검증을 수행한다. +- `.example/display` 데모의 Admin API 호출 경로가 신규 `/admin/api/v2` endpoint 기준으로 갱신된다. +- `./gradlew :bottlenote-admin-api:compileKotlin :bottlenote-admin-api:compileTestKotlin`가 성공한다. +- `./gradlew :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'`가 성공한다. +- `./gradlew admin_integration_test --tests 'app.integration.curation.AdminSpecBasedCurationIntegrationTest'`가 성공한다. +- `./gradlew check_rule_test`가 성공한다. + +### Impact Scope + +- `bottlenote-admin-api` + - `src/main/resources/application.yml`: context-path 변경. + - `src/main/kotlin/app/bottlenote/**/presentation/*Controller.kt`: 기존 v1 surface 보존을 위한 `/v1` prefix 반영. + - `src/main/kotlin/app/bottlenote/curation/presentation/AdminCurationSpecController.kt`: `/v2/curation-specs`로 변경. + - `src/main/kotlin/app/bottlenote/curation/presentation/AdminSpecBasedCurationController.kt`: `/v2/curations`로 변경. + - `src/test/kotlin/app/docs/**`: RestDocs URI와 snippets 갱신 가능. + - `src/test/kotlin/app/integration/**`: context-path 변화에 따른 URI 갱신 가능. +- `.example/display` + - Admin API base path 또는 endpoint 조합이 `/admin/api/v2/curations`, `/admin/api/v2/curation-specs`를 사용하도록 갱신된다. +- `plan/spec-based-curation-v2-graphql-sdl.md` + - 기존 `/admin/api/v1/spec-based-curations`, `/admin/api/v1/curation-specs` 결정 내용을 취소선 + 정정으로 갱신한다. +- `bottlenote-mono` + - 서비스, 도메인, repository, GraphQL hydration 로직은 변경하지 않는다. +- Persistence + - schema migration 없음. +- Security + - Admin security 정책은 기존 `anyRequest().authenticated()` 구조를 유지한다. 단, `auth/login`, `auth/refresh` 최종 URL이 `/admin/api/v1/auth/*`로 유지되도록 mapping을 점검한다. +- API compatibility + - 기존 Admin v1 API는 유지한다. + - 기존 spec 기반 임시 endpoint는 호환 alias 없이 신규 `/v2`로 이동한다. + +### Open Questions + +- 없음. 사용자 확인 사항: + - context-path는 `/admin/api`로 낮춘다. + - 기존 spec 기반 v1 endpoint alias는 남기지 않는다. + - spec 관리는 `/v2/curation-specs`로 간다. + +## Dependency Analysis + +1. `context-path`를 `/admin/api`로 낮추면 기존 Admin controller mapping이 그대로일 경우 최종 URL이 `/admin/api/{path}`로 바뀌어 v1 API가 깨진다. +2. 기존 v1 API를 보존하려면 모든 legacy Admin controller에 `/v1` prefix가 적용되어야 한다. +3. 모든 controller 파일을 직접 수정하면 변경량이 커지므로, 중앙 Web MVC path prefix 설정으로 legacy Admin controller에 `/v1`을 적용하고 spec 기반 curation v2 controller만 제외하는 방향을 우선한다. +4. v2 curation controller는 명시적으로 `/v2/curation-specs`, `/v2/curations`를 갖는다. +5. Security permit matcher는 context-path를 제외한 servlet path 기준으로 동작하므로 `/v1/auth/login`, `/v1/auth/refresh` 기준으로 갱신한다. +6. MockMvc 기반 docs/integration test는 context-path가 아니라 controller mapping을 직접 호출하므로 기존 Admin v1 테스트 URI도 `/v1/**`로 갱신해야 한다. + +## Tasks + +### Task 1: Admin API versioning foundation + +- Acceptance: + - admin-api `server.servlet.context-path`가 `/admin/api`로 변경된다. + - legacy Admin presentation controller에는 중앙 설정으로 `/v1` prefix가 적용된다. + - spec 기반 curation v2 controller는 `/v1` prefix 대상에서 제외된다. + - Admin security permit matcher가 `/v1/auth/login`, `/v1/auth/refresh`를 허용한다. +- Verification: + - `./gradlew :bottlenote-admin-api:compileKotlin :bottlenote-admin-api:compileTestKotlin` +- Files: + - `bottlenote-admin-api/src/main/resources/application.yml` + - `bottlenote-admin-api/src/main/kotlin/app/global/security/SecurityConfig.kt` + - `bottlenote-admin-api/src/main/kotlin/app/global/config/*` +- Size: S +- Status: [x] done + +### Task 2: Curation v2 admin endpoint remapping + +- Acceptance: + - `AdminCurationSpecController`가 `/v2/curation-specs`를 제공한다. + - `AdminSpecBasedCurationController`가 `/v2/curations`를 제공한다. + - `/v1/curation-specs`, `/v1/spec-based-curations` alias는 만들지 않는다. +- Verification: + - `./gradlew :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` + - `./gradlew admin_integration_test --tests 'app.integration.curation.AdminSpecBasedCurationIntegrationTest'` +- Files: + - `bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminCurationSpecController.kt` + - `bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminSpecBasedCurationController.kt` + - `bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt` + - `bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt` +- Size: M +- Status: [ ] not done + +### Checkpoint: after Tasks 1-2 + +- [ ] Admin Kotlin compile/test compile passes +- [ ] Curation v2 docs test passes +- [ ] Curation v2 admin integration test passes + +### Task 3: Preserve core Admin v1 auth/common/user/help routes in tests + +- Acceptance: + - Auth docs/integration tests call `/v1/auth/**`. + - File upload tests call `/v1/s3/**`. + - User and help tests call `/v1/users`, `/v1/helps/**`. + - Existing final URLs remain `/admin/api/v1/**`. +- Verification: + - `./gradlew :bottlenote-admin-api:test --tests 'app.docs.auth.AuthControllerDocsTest' --tests 'app.docs.file.AdminImageUploadControllerDocsTest' --tests 'app.docs.user.AdminUsersControllerDocsTest' --tests 'app.docs.help.AdminHelpControllerDocsTest'` + - `./gradlew admin_integration_test --tests 'app.integration.auth.AdminAuthIntegrationTest' --tests 'app.integration.file.AdminImageUploadIntegrationTest' --tests 'app.integration.user.AdminUsersIntegrationTest' --tests 'app.integration.help.AdminHelpIntegrationTest'` +- Files: + - `bottlenote-admin-api/src/test/kotlin/app/docs/auth/*` + - `bottlenote-admin-api/src/test/kotlin/app/docs/file/*` + - `bottlenote-admin-api/src/test/kotlin/app/docs/user/*` + - `bottlenote-admin-api/src/test/kotlin/app/docs/help/*` + - `bottlenote-admin-api/src/test/kotlin/app/integration/auth/*` + - `bottlenote-admin-api/src/test/kotlin/app/integration/file/*` + - `bottlenote-admin-api/src/test/kotlin/app/integration/user/*` + - `bottlenote-admin-api/src/test/kotlin/app/integration/help/*` +- Size: M +- Status: [ ] not done + +### Task 4: Preserve Admin v1 alcohol/reference routes in tests + +- Acceptance: + - Alcohol, distillery, region, tasting-tag docs/integration tests call `/v1/**`. + - Reference data endpoints remain under `/admin/api/v1`. +- Verification: + - `./gradlew :bottlenote-admin-api:test --tests 'app.docs.alcohols.*'` + - `./gradlew admin_integration_test --tests 'app.integration.alcohols.*' --tests 'app.integration.region.*'` +- Files: + - `bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/*` + - `bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/*` + - `bottlenote-admin-api/src/test/kotlin/app/integration/region/*` +- Size: M +- Status: [ ] not done + +### Task 5: Preserve Admin v1 banner and legacy curation routes in tests + +- Acceptance: + - Banner docs/integration tests call `/v1/banners/**`. + - Legacy Admin curation docs/integration tests call `/v1/curations/**`. + - Spec 기반 curation v2와 legacy curation v1이 `/admin/api/v2/curations` vs `/admin/api/v1/curations`로 명확히 분리된다. +- Verification: + - `./gradlew :bottlenote-admin-api:test --tests 'app.docs.banner.AdminBannerControllerDocsTest' --tests 'app.docs.curation.AdminCurationControllerDocsTest'` + - `./gradlew admin_integration_test --tests 'app.integration.banner.AdminBannerIntegrationTest' --tests 'app.integration.curation.AdminCurationIntegrationTest'` +- Files: + - `bottlenote-admin-api/src/test/kotlin/app/docs/banner/*` + - `bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminCurationControllerDocsTest.kt` + - `bottlenote-admin-api/src/test/kotlin/app/integration/banner/*` + - `bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminCurationIntegrationTest.kt` +- Size: M +- Status: [ ] not done + +### Checkpoint: after Tasks 3-5 + +- [ ] Existing Admin v1 docs tests pass +- [ ] Existing Admin v1 integration tests pass +- [ ] Legacy `/admin/api/v1/curations` and new `/admin/api/v2/curations` are both represented in tests + +### Task 6: Demo and planning documents update + +- Acceptance: + - `.example/display` Admin base URL and endpoint calls use `/admin/api` + `/v1` or `/v2` consistently. + - Spec 기반 curation demo calls `/v2/curation-specs` and `/v2/curations`. + - Architecture/demo text no longer points to `/admin/api/v1/spec-based-curations`. + - `plan/spec-based-curation-v2-graphql-sdl.md` records the endpoint decision change with 취소선 + 정정. +- Verification: + - `curl -s http://localhost:8098/curation-architecture.html` + - `rg -n "spec-based-curations|/admin/api/v1/curation-specs" .example/display plan/spec-based-curation-v2-graphql-sdl.md` returns no stale canonical references except historical struck-through notes. +- Files: + - `.example/display/js/config.js` + - `.example/display/js/api.js` + - `.example/display/js/*.js` + - `plan/spec-based-curation-v2-graphql-sdl.md` + - `plan/admin-api-v2-curation-endpoints.md` +- Size: M +- Status: [ ] not done + +### Task 7: Final verification and commit + +- Acceptance: + - Admin API versioning change is committed as one coherent commit after verification. + - No unintended `bottlenote-mono`, Product API, DB changelog, or GraphQL SDL changes are included. + - Git diff shows only Admin API endpoint/versioning docs and demo path updates. +- Verification: + - `./gradlew :bottlenote-admin-api:compileKotlin :bottlenote-admin-api:compileTestKotlin` + - `./gradlew :bottlenote-admin-api:test` + - `./gradlew admin_integration_test` + - `./gradlew check_rule_test` + - `git diff --check` +- Files: + - `bottlenote-admin-api/**` + - `.example/display/**` + - `plan/admin-api-v2-curation-endpoints.md` + - `plan/spec-based-curation-v2-graphql-sdl.md` +- Size: S +- Status: [ ] not done + +## Progress Log + +- 2026-05-18: Task 1 완료. admin-api context-path를 `/admin/api`로 낮추고, `AdminApiVersionConfig`에서 legacy Admin presentation controller에 중앙 `/v1` prefix를 적용했다. spec 기반 curation controller 2개는 prefix 대상에서 제외했고, Security permit matcher를 `/v1/auth/login`, `/v1/auth/refresh`로 갱신했다. 검증: `./gradlew :bottlenote-admin-api:compileKotlin :bottlenote-admin-api:compileTestKotlin` 성공. From f5e540beb7460a36416dc40d58eed15ee4ab1f64 Mon Sep 17 00:00:00 2001 From: hgkim Date: Mon, 18 May 2026 10:09:04 +0900 Subject: [PATCH 18/33] =?UTF-8?q?feat:=20=EC=96=B4=EB=93=9C=EB=AF=BC=20?= =?UTF-8?q?=ED=81=90=EB=A0=88=EC=9D=B4=EC=85=98=20v2=20=EA=B2=BD=EB=A1=9C?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AdminCurationSpecController.kt | 2 +- .../AdminSpecBasedCurationController.kt | 2 +- ...dminSpecBasedCurationControllerDocsTest.kt | 24 +++++++++---------- .../AdminSpecBasedCurationIntegrationTest.kt | 8 +++---- plan/admin-api-v2-curation-endpoints.md | 5 ++-- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminCurationSpecController.kt b/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminCurationSpecController.kt index 2ae760b0f..309163f93 100644 --- a/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminCurationSpecController.kt +++ b/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminCurationSpecController.kt @@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @RestController -@RequestMapping("/curation-specs") +@RequestMapping("/v2/curation-specs") class AdminCurationSpecController( private val adminSpecBasedCurationService: AdminSpecBasedCurationService ) { diff --git a/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminSpecBasedCurationController.kt b/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminSpecBasedCurationController.kt index c84cbb364..b8f988b8f 100644 --- a/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminSpecBasedCurationController.kt +++ b/bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminSpecBasedCurationController.kt @@ -17,7 +17,7 @@ import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @RestController -@RequestMapping("/spec-based-curations") +@RequestMapping("/v2/curations") class AdminSpecBasedCurationController( private val adminSpecBasedCurationService: AdminSpecBasedCurationService ) { diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt index 61f37f023..56c3ef593 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt @@ -58,11 +58,11 @@ class AdminSpecBasedCurationControllerDocsTest { fun listSpecs() { given(adminSpecBasedCurationService.listSpecs()).willReturn(listOf(specResponse())) - assertThat(mvc.get().uri("/curation-specs")) + assertThat(mvc.get().uri("/v2/curation-specs")) .hasStatusOk() .apply( document( - "admin/curation-specs/list", + "admin/v2/curation-specs/list", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()) ) @@ -74,11 +74,11 @@ class AdminSpecBasedCurationControllerDocsTest { fun getSpecDetail() { given(adminSpecBasedCurationService.getSpecDetail(anyLong())).willReturn(specResponse()) - assertThat(mvc.get().uri("/curation-specs/{specId}", 1L)) + assertThat(mvc.get().uri("/v2/curation-specs/{specId}", 1L)) .hasStatusOk() .apply( document( - "admin/curation-specs/detail", + "admin/v2/curation-specs/detail", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()) ) @@ -91,11 +91,11 @@ class AdminSpecBasedCurationControllerDocsTest { given(adminSpecBasedCurationService.search(any(CurationSearchRequest::class.java))) .willReturn(GlobalResponse.fromPage(PageImpl(listOf(listResponse())))) - assertThat(mvc.get().uri("/spec-based-curations?keyword=&isActive=true&page=0&size=20")) + assertThat(mvc.get().uri("/v2/curations?keyword=&isActive=true&page=0&size=20")) .hasStatusOk() .apply( document( - "admin/spec-based-curations/list", + "admin/v2/curations/list", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()) ) @@ -107,11 +107,11 @@ class AdminSpecBasedCurationControllerDocsTest { fun getDetail() { given(adminSpecBasedCurationService.getDetail(anyLong())).willReturn(detailResponse()) - assertThat(mvc.get().uri("/spec-based-curations/{curationId}", 1L)) + assertThat(mvc.get().uri("/v2/curations/{curationId}", 1L)) .hasStatusOk() .apply( document( - "admin/spec-based-curations/detail", + "admin/v2/curations/detail", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()) ) @@ -125,14 +125,14 @@ class AdminSpecBasedCurationControllerDocsTest { .willReturn(AdminResultResponse.of(AdminResultResponse.ResultCode.CURATION_CREATED, 1L)) assertThat( - mvc.post().uri("/spec-based-curations") + mvc.post().uri("/v2/curations") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(createRequest())) ) .hasStatusOk() .apply( document( - "admin/spec-based-curations/create", + "admin/v2/curations/create", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()) ) @@ -146,14 +146,14 @@ class AdminSpecBasedCurationControllerDocsTest { .willReturn(AdminResultResponse.of(AdminResultResponse.ResultCode.CURATION_UPDATED, 1L)) assertThat( - mvc.put().uri("/spec-based-curations/{curationId}", 1L) + mvc.put().uri("/v2/curations/{curationId}", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(updateRequest())) ) .hasStatusOk() .apply( document( - "admin/spec-based-curations/update", + "admin/v2/curations/update", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()) ) diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt index 6593a0768..6a516ca11 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt @@ -38,7 +38,7 @@ class AdminSpecBasedCurationIntegrationTest : IntegrationTestSupport() { fun listSpecsSuccess() { val result = mockMvcTester .get() - .uri("/curation-specs") + .uri("/v2/curation-specs") .header("Authorization", "Bearer $accessToken") .exchange() @@ -55,7 +55,7 @@ class AdminSpecBasedCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/curation-specs/$specId") + .uri("/v2/curation-specs/$specId") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -75,7 +75,7 @@ class AdminSpecBasedCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/spec-based-curations") + .uri("/v2/curations") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -135,7 +135,7 @@ class AdminSpecBasedCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/spec-based-curations") + .uri("/v2/curations") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) diff --git a/plan/admin-api-v2-curation-endpoints.md b/plan/admin-api-v2-curation-endpoints.md index 1b54d982d..8be3aeaee 100644 --- a/plan/admin-api-v2-curation-endpoints.md +++ b/plan/admin-api-v2-curation-endpoints.md @@ -101,14 +101,14 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv - `/v1/curation-specs`, `/v1/spec-based-curations` alias는 만들지 않는다. - Verification: - `./gradlew :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` - - `./gradlew admin_integration_test --tests 'app.integration.curation.AdminSpecBasedCurationIntegrationTest'` + - `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.curation.AdminSpecBasedCurationIntegrationTest'` - Files: - `bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminCurationSpecController.kt` - `bottlenote-admin-api/src/main/kotlin/app/bottlenote/curation/presentation/AdminSpecBasedCurationController.kt` - `bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt` - `bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt` - Size: M -- Status: [ ] not done +- Status: [x] done ### Checkpoint: after Tasks 1-2 @@ -218,3 +218,4 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv ## Progress Log - 2026-05-18: Task 1 완료. admin-api context-path를 `/admin/api`로 낮추고, `AdminApiVersionConfig`에서 legacy Admin presentation controller에 중앙 `/v1` prefix를 적용했다. spec 기반 curation controller 2개는 prefix 대상에서 제외했고, Security permit matcher를 `/v1/auth/login`, `/v1/auth/refresh`로 갱신했다. 검증: `./gradlew :bottlenote-admin-api:compileKotlin :bottlenote-admin-api:compileTestKotlin` 성공. +- 2026-05-18: Task 2 완료. spec 기반 admin curation controller를 `/v2/curations`, spec 조회 controller를 `/v2/curation-specs`로 변경하고 RestDocs/integration 테스트 URI와 snippet 경로를 v2 기준으로 갱신했다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.curation.AdminSpecBasedCurationIntegrationTest'` 성공. root aggregate `admin_integration_test --tests ...`는 `--tests` 옵션을 받지 않아 모듈 Test 태스크 명령으로 정정했다. From 788174eecbc25747b3f326aa00bf6e4efe119d46 Mon Sep 17 00:00:00 2001 From: hgkim Date: Mon, 18 May 2026 10:17:05 +0900 Subject: [PATCH 19/33] =?UTF-8?q?test:=20=EC=96=B4=EB=93=9C=EB=AF=BC=20v1?= =?UTF-8?q?=20=EA=B8=B0=EB=B3=B8=20=EA=B2=BD=EB=A1=9C=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=20=EB=B3=B4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/docs/auth/AuthControllerDocsTest.kt | 8 ++-- .../AdminImageUploadControllerDocsTest.kt | 2 +- .../docs/help/AdminHelpControllerDocsTest.kt | 6 +-- .../docs/user/AdminUsersControllerDocsTest.kt | 2 +- .../auth/AdminAuthIntegrationTest.kt | 38 +++++++++---------- .../file/AdminImageUploadIntegrationTest.kt | 14 +++---- .../help/AdminHelpIntegrationTest.kt | 24 ++++++------ .../user/AdminUsersIntegrationTest.kt | 16 ++++---- plan/admin-api-v2-curation-endpoints.md | 5 ++- 9 files changed, 58 insertions(+), 57 deletions(-) diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/auth/AuthControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/auth/AuthControllerDocsTest.kt index b1bd14ea1..358cf6074 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/auth/AuthControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/auth/AuthControllerDocsTest.kt @@ -67,7 +67,7 @@ class AuthControllerDocsTest { // when & then assertThat( - mvc.post().uri("/auth/login") + mvc.post().uri("/v1/auth/login") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request)) ) @@ -107,7 +107,7 @@ class AuthControllerDocsTest { // when & then assertThat( - mvc.post().uri("/auth/refresh") + mvc.post().uri("/v1/auth/refresh") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request)) ) @@ -145,7 +145,7 @@ class AuthControllerDocsTest { // when & then assertThat( - mvc.delete().uri("/auth/withdraw") + mvc.delete().uri("/v1/auth/withdraw") .header("Authorization", "Bearer test_access_token") ) .hasStatusOk() @@ -197,7 +197,7 @@ class AuthControllerDocsTest { // when & then assertThat( - mvc.post().uri("/auth/signup") + mvc.post().uri("/v1/auth/signup") .header("Authorization", "Bearer test_access_token") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request)) diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/file/AdminImageUploadControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/file/AdminImageUploadControllerDocsTest.kt index 9489151db..74f3d50ef 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/file/AdminImageUploadControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/file/AdminImageUploadControllerDocsTest.kt @@ -76,7 +76,7 @@ class AdminImageUploadControllerDocsTest { // when & then assertThat( - mvc.get().uri("/s3/presign-url") + mvc.get().uri("/v1/s3/presign-url") .header("Authorization", "Bearer test_access_token") .param("rootPath", "admin/banner") .param("uploadSize", "2") diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/help/AdminHelpControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/help/AdminHelpControllerDocsTest.kt index f61ce7526..b4d3f42d8 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/help/AdminHelpControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/help/AdminHelpControllerDocsTest.kt @@ -82,7 +82,7 @@ class AdminHelpControllerDocsTest { // when & then assertThat( - mvc.get().uri("/helps") + mvc.get().uri("/v1/helps") .header("Authorization", "Bearer test_access_token") .param("status", StatusType.WAITING.name) .param("type", HelpType.WHISKEY.name) @@ -152,7 +152,7 @@ class AdminHelpControllerDocsTest { // when & then assertThat( - mvc.get().uri("/helps/{helpId}", 1L) + mvc.get().uri("/v1/helps/{helpId}", 1L) .header("Authorization", "Bearer test_access_token") ) .hasStatusOk() @@ -212,7 +212,7 @@ class AdminHelpControllerDocsTest { // when & then assertThat( - mvc.post().uri("/helps/{helpId}/answer", 1L) + mvc.post().uri("/v1/helps/{helpId}/answer", 1L) .header("Authorization", "Bearer test_access_token") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request)) diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/user/AdminUsersControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/user/AdminUsersControllerDocsTest.kt index abd0d3ef0..05bf87d95 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/user/AdminUsersControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/user/AdminUsersControllerDocsTest.kt @@ -67,7 +67,7 @@ class AdminUsersControllerDocsTest { // when & then assertThat( - mvc.get().uri("/users?keyword=&status=ACTIVE&sortType=CREATED_AT&sortOrder=DESC&page=0&size=20") + mvc.get().uri("/v1/users?keyword=&status=ACTIVE&sortType=CREATED_AT&sortOrder=DESC&page=0&size=20") ) .hasStatusOk() .apply( diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/auth/AdminAuthIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/auth/AdminAuthIntegrationTest.kt index 37280ee08..6a18a651d 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/auth/AdminAuthIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/auth/AdminAuthIntegrationTest.kt @@ -29,7 +29,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/login") + .uri("/v1/auth/login") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ).hasStatusOk() @@ -40,7 +40,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/login") + .uri("/v1/auth/login") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ).hasStatusOk() @@ -63,7 +63,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/login") + .uri("/v1/auth/login") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ).hasStatus4xxClientError() @@ -82,7 +82,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/login") + .uri("/v1/auth/login") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ).hasStatus4xxClientError() @@ -105,7 +105,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/login") + .uri("/v1/auth/login") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ).hasStatus4xxClientError() @@ -127,7 +127,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/login") + .uri("/v1/auth/login") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ).hasStatusOk() @@ -153,7 +153,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { val loginResult = mockMvcTester .post() - .uri("/auth/login") + .uri("/v1/auth/login") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(loginRequest)) .exchange() @@ -167,7 +167,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/refresh") + .uri("/v1/auth/refresh") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ).hasStatusOk() @@ -186,7 +186,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/refresh") + .uri("/v1/auth/refresh") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ).hasStatus4xxClientError() @@ -210,7 +210,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/auth/withdraw") + .uri("/v1/auth/withdraw") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -229,7 +229,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/auth/withdraw") + .uri("/v1/auth/withdraw") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() .bodyJson() @@ -260,7 +260,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/signup") + .uri("/v1/auth/signup") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -272,7 +272,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/signup") + .uri("/v1/auth/signup") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request.plus("email" to "another@bottlenote.com"))) @@ -301,7 +301,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/signup") + .uri("/v1/auth/signup") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -330,7 +330,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/signup") + .uri("/v1/auth/signup") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -359,7 +359,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/signup") + .uri("/v1/auth/signup") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -385,7 +385,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/signup") + .uri("/v1/auth/signup") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ).hasStatus4xxClientError() @@ -413,7 +413,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/signup") + .uri("/v1/auth/signup") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -442,7 +442,7 @@ class AdminAuthIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/auth/signup") + .uri("/v1/auth/signup") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/file/AdminImageUploadIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/file/AdminImageUploadIntegrationTest.kt index ff65ef61b..8a3752bb8 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/file/AdminImageUploadIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/file/AdminImageUploadIntegrationTest.kt @@ -38,7 +38,7 @@ class AdminImageUploadIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/s3/presign-url") + .uri("/v1/s3/presign-url") .header("Authorization", "Bearer $accessToken") .param("rootPath", "admin/test") .param("uploadSize", "1") @@ -55,7 +55,7 @@ class AdminImageUploadIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/s3/presign-url") + .uri("/v1/s3/presign-url") .header("Authorization", "Bearer $accessToken") .param("rootPath", "admin/test") .param("uploadSize", "3") @@ -72,7 +72,7 @@ class AdminImageUploadIntegrationTest : IntegrationTestSupport() { val result = mockMvcTester .get() - .uri("/s3/presign-url") + .uri("/v1/s3/presign-url") .header("Authorization", "Bearer $accessToken") .param("rootPath", "admin/test") .param("uploadSize", "2") @@ -103,7 +103,7 @@ class AdminImageUploadIntegrationTest : IntegrationTestSupport() { val result = mockMvcTester .get() - .uri("/s3/presign-url") + .uri("/v1/s3/presign-url") .header("Authorization", "Bearer $accessToken") .param("rootPath", "admin/test") .param("uploadSize", "1") @@ -134,7 +134,7 @@ class AdminImageUploadIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/s3/presign-url") + .uri("/v1/s3/presign-url") .param("rootPath", "admin/test") .param("uploadSize", "1") ).hasStatus4xxClientError() @@ -151,7 +151,7 @@ class AdminImageUploadIntegrationTest : IntegrationTestSupport() { val result = mockMvcTester .get() - .uri("/s3/presign-url") + .uri("/v1/s3/presign-url") .header("Authorization", "Bearer $accessToken") .param("rootPath", "admin/upload-test") .param("uploadSize", "1") @@ -200,7 +200,7 @@ class AdminImageUploadIntegrationTest : IntegrationTestSupport() { val result = mockMvcTester .get() - .uri("/s3/presign-url") + .uri("/v1/s3/presign-url") .header("Authorization", "Bearer $accessToken") .param("rootPath", "admin/multi-upload") .param("uploadSize", "3") diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/help/AdminHelpIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/help/AdminHelpIntegrationTest.kt index 1c1a56c8f..180adcb62 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/help/AdminHelpIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/help/AdminHelpIntegrationTest.kt @@ -45,7 +45,7 @@ class AdminHelpIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/helps") + .uri("/v1/helps") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -64,7 +64,7 @@ class AdminHelpIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/helps") + .uri("/v1/helps") .header("Authorization", "Bearer $accessToken") .param("status", StatusType.WAITING.name) ).hasStatusOk() @@ -85,7 +85,7 @@ class AdminHelpIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/helps") + .uri("/v1/helps") .header("Authorization", "Bearer $accessToken") .param("type", HelpType.WHISKEY.name) ).hasStatusOk() @@ -99,7 +99,7 @@ class AdminHelpIntegrationTest : IntegrationTestSupport() { fun getHelpListWithoutAuth() { // when & then assertThat( - mockMvcTester.get().uri("/helps") + mockMvcTester.get().uri("/v1/helps") ).hasStatus4xxClientError() } } @@ -118,7 +118,7 @@ class AdminHelpIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/helps/${help.id}") + .uri("/v1/helps/${help.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -128,7 +128,7 @@ class AdminHelpIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/helps/${help.id}") + .uri("/v1/helps/${help.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -143,7 +143,7 @@ class AdminHelpIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/helps/99999") + .uri("/v1/helps/99999") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() .bodyJson() @@ -172,7 +172,7 @@ class AdminHelpIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/helps/${help.id}/answer") + .uri("/v1/helps/${help.id}/answer") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -184,7 +184,7 @@ class AdminHelpIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/helps/${help.id}/answer") + .uri("/v1/helps/${help.id}/answer") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -211,7 +211,7 @@ class AdminHelpIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/helps/${help.id}/answer") + .uri("/v1/helps/${help.id}/answer") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -235,7 +235,7 @@ class AdminHelpIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/helps/99999/answer") + .uri("/v1/helps/99999/answer") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -262,7 +262,7 @@ class AdminHelpIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/helps/${help.id}/answer") + .uri("/v1/helps/${help.id}/answer") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/user/AdminUsersIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/user/AdminUsersIntegrationTest.kt index 107390eb1..4610bc42f 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/user/AdminUsersIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/user/AdminUsersIntegrationTest.kt @@ -56,7 +56,7 @@ class AdminUsersIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/users") + .uri("/v1/users") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -75,7 +75,7 @@ class AdminUsersIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/users") + .uri("/v1/users") .param("keyword", "검색대상") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() @@ -95,7 +95,7 @@ class AdminUsersIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/users") + .uri("/v1/users") .param("keyword", "searchtarget") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() @@ -116,7 +116,7 @@ class AdminUsersIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/users") + .uri("/v1/users") .param("status", "ACTIVE") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() @@ -140,7 +140,7 @@ class AdminUsersIntegrationTest : IntegrationTestSupport() { // when val result = mockMvcTester .get() - .uri("/users") + .uri("/v1/users") .param("keyword", user.nickName) .header("Authorization", "Bearer $accessToken") .exchange() @@ -175,7 +175,7 @@ class AdminUsersIntegrationTest : IntegrationTestSupport() { // when & then (리뷰 많은 순 DESC -> userB가 먼저) val result = mockMvcTester .get() - .uri("/users") + .uri("/v1/users") .param("sortType", "REVIEW_COUNT") .param("sortOrder", "DESC") .header("Authorization", "Bearer $accessToken") @@ -198,7 +198,7 @@ class AdminUsersIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/users") + .uri("/v1/users") .param("page", "0") .param("size", "2") .header("Authorization", "Bearer $accessToken") @@ -216,7 +216,7 @@ class AdminUsersIntegrationTest : IntegrationTestSupport() { @DisplayName("인증 없이 요청하면 실패한다") fun requestWithoutAuth() { assertThat( - mockMvcTester.get().uri("/users") + mockMvcTester.get().uri("/v1/users") ).hasStatus4xxClientError() } } diff --git a/plan/admin-api-v2-curation-endpoints.md b/plan/admin-api-v2-curation-endpoints.md index 8be3aeaee..4d65e4f48 100644 --- a/plan/admin-api-v2-curation-endpoints.md +++ b/plan/admin-api-v2-curation-endpoints.md @@ -125,7 +125,7 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv - Existing final URLs remain `/admin/api/v1/**`. - Verification: - `./gradlew :bottlenote-admin-api:test --tests 'app.docs.auth.AuthControllerDocsTest' --tests 'app.docs.file.AdminImageUploadControllerDocsTest' --tests 'app.docs.user.AdminUsersControllerDocsTest' --tests 'app.docs.help.AdminHelpControllerDocsTest'` - - `./gradlew admin_integration_test --tests 'app.integration.auth.AdminAuthIntegrationTest' --tests 'app.integration.file.AdminImageUploadIntegrationTest' --tests 'app.integration.user.AdminUsersIntegrationTest' --tests 'app.integration.help.AdminHelpIntegrationTest'` + - `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.auth.AdminAuthIntegrationTest' --tests 'app.integration.file.AdminImageUploadIntegrationTest' --tests 'app.integration.user.AdminUsersIntegrationTest' --tests 'app.integration.help.AdminHelpIntegrationTest'` - Files: - `bottlenote-admin-api/src/test/kotlin/app/docs/auth/*` - `bottlenote-admin-api/src/test/kotlin/app/docs/file/*` @@ -136,7 +136,7 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv - `bottlenote-admin-api/src/test/kotlin/app/integration/user/*` - `bottlenote-admin-api/src/test/kotlin/app/integration/help/*` - Size: M -- Status: [ ] not done +- Status: [x] done ### Task 4: Preserve Admin v1 alcohol/reference routes in tests @@ -219,3 +219,4 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv - 2026-05-18: Task 1 완료. admin-api context-path를 `/admin/api`로 낮추고, `AdminApiVersionConfig`에서 legacy Admin presentation controller에 중앙 `/v1` prefix를 적용했다. spec 기반 curation controller 2개는 prefix 대상에서 제외했고, Security permit matcher를 `/v1/auth/login`, `/v1/auth/refresh`로 갱신했다. 검증: `./gradlew :bottlenote-admin-api:compileKotlin :bottlenote-admin-api:compileTestKotlin` 성공. - 2026-05-18: Task 2 완료. spec 기반 admin curation controller를 `/v2/curations`, spec 조회 controller를 `/v2/curation-specs`로 변경하고 RestDocs/integration 테스트 URI와 snippet 경로를 v2 기준으로 갱신했다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.curation.AdminSpecBasedCurationIntegrationTest'` 성공. root aggregate `admin_integration_test --tests ...`는 `--tests` 옵션을 받지 않아 모듈 Test 태스크 명령으로 정정했다. +- 2026-05-18: Task 3 완료. auth, file, user, help docs/integration 테스트 요청 URI를 `/v1/**` 기준으로 갱신해 기존 Admin v1 최종 URL 보존을 검증했다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.auth.AuthControllerDocsTest' --tests 'app.docs.file.AdminImageUploadControllerDocsTest' --tests 'app.docs.user.AdminUsersControllerDocsTest' --tests 'app.docs.help.AdminHelpControllerDocsTest'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.auth.AdminAuthIntegrationTest' --tests 'app.integration.file.AdminImageUploadIntegrationTest' --tests 'app.integration.user.AdminUsersIntegrationTest' --tests 'app.integration.help.AdminHelpIntegrationTest'` 성공. From 05bbd66695b7a725ddbac1323fb61ecae2077b3e Mon Sep 17 00:00:00 2001 From: hgkim Date: Mon, 18 May 2026 10:20:25 +0900 Subject: [PATCH 20/33] =?UTF-8?q?test:=20=EC=96=B4=EB=93=9C=EB=AF=BC=20v1?= =?UTF-8?q?=20=EC=A3=BC=EB=A5=98=20=EA=B2=BD=EB=A1=9C=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=20=EB=B3=B4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AdminAlcoholsControllerDocsTest.kt | 14 ++--- .../AdminDistilleryControllerDocsTest.kt | 12 ++-- .../alcohols/AdminRegionControllerDocsTest.kt | 2 +- .../AdminTastingTagControllerDocsTest.kt | 14 ++--- .../alcohols/AdminAlcoholsIntegrationTest.kt | 62 +++++++++---------- .../AdminDistilleryIntegrationTest.kt | 24 +++---- .../AdminReferenceDataIntegrationTest.kt | 22 +++---- .../AdminTastingTagIntegrationTest.kt | 44 ++++++------- .../region/AdminRegionIntegrationTest.kt | 16 ++--- plan/admin-api-v2-curation-endpoints.md | 5 +- 10 files changed, 108 insertions(+), 107 deletions(-) diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminAlcoholsControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminAlcoholsControllerDocsTest.kt index dfe76ceb2..92f87e92a 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminAlcoholsControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminAlcoholsControllerDocsTest.kt @@ -63,7 +63,7 @@ class AdminAlcoholsControllerDocsTest { // when & then assertThat( - mvc.get().uri("/alcohols") + mvc.get().uri("/v1/alcohols") .param("keyword", "글렌") .param("category", AlcoholCategoryGroup.SINGLE_MALT.name) .param("regionId", "1") @@ -77,7 +77,7 @@ class AdminAlcoholsControllerDocsTest { .extractingPath("$.success").isEqualTo(true) assertThat( - mvc.get().uri("/alcohols") + mvc.get().uri("/v1/alcohols") .param("keyword", "글렌") .param("category", AlcoholCategoryGroup.SINGLE_MALT.name) .param("regionId", "1") @@ -141,7 +141,7 @@ class AdminAlcoholsControllerDocsTest { // when & then assertThat( - mvc.get().uri("/alcohols/{alcoholId}", 1L) + mvc.get().uri("/v1/alcohols/{alcoholId}", 1L) ) .hasStatusOk() .apply( @@ -211,7 +211,7 @@ class AdminAlcoholsControllerDocsTest { // when & then assertThat( - mvc.post().uri("/alcohols") + mvc.post().uri("/v1/alcohols") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -276,7 +276,7 @@ class AdminAlcoholsControllerDocsTest { // when & then assertThat( - mvc.put().uri("/alcohols/{alcoholId}", 1L) + mvc.put().uri("/v1/alcohols/{alcoholId}", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -354,7 +354,7 @@ class AdminAlcoholsControllerDocsTest { // when & then assertThat( - mvc.get().uri("/alcohols/categories/reference") + mvc.get().uri("/v1/alcohols/categories/reference") ) .hasStatusOk() .apply( @@ -407,7 +407,7 @@ class AdminAlcoholsControllerDocsTest { // when & then assertThat( - mvc.delete().uri("/alcohols/{alcoholId}", 1L) + mvc.delete().uri("/v1/alcohols/{alcoholId}", 1L) ) .hasStatusOk() .apply( diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminDistilleryControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminDistilleryControllerDocsTest.kt index 65ed9acdd..854fd2952 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminDistilleryControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminDistilleryControllerDocsTest.kt @@ -68,7 +68,7 @@ class AdminDistilleryControllerDocsTest { .willReturn(response) assertThat( - mvc.get().uri("/distilleries?keyword=&page=0&size=20&sortOrder=ASC") + mvc.get().uri("/v1/distilleries?keyword=&page=0&size=20&sortOrder=ASC") ).hasStatusOk() .apply( document( @@ -123,7 +123,7 @@ class AdminDistilleryControllerDocsTest { given(distilleryService.getDetail(anyLong())).willReturn(item) assertThat( - mvc.get().uri("/distilleries/{distilleryId}", 1L) + mvc.get().uri("/v1/distilleries/{distilleryId}", 1L) ).hasStatusOk() .apply( document( @@ -164,7 +164,7 @@ class AdminDistilleryControllerDocsTest { ) assertThat( - mvc.post().uri("/distilleries") + mvc.post().uri("/v1/distilleries") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ).hasStatusOk() @@ -196,7 +196,7 @@ class AdminDistilleryControllerDocsTest { ) assertThat( - mvc.put().uri("/distilleries/{distilleryId}", 1L) + mvc.put().uri("/v1/distilleries/{distilleryId}", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ).hasStatusOk() @@ -225,7 +225,7 @@ class AdminDistilleryControllerDocsTest { val request = mapOf("sortOrder" to 5) assertThat( - mvc.patch().uri("/distilleries/{distilleryId}/sort-order", 1L) + mvc.patch().uri("/v1/distilleries/{distilleryId}/sort-order", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ).hasStatusOk() @@ -250,7 +250,7 @@ class AdminDistilleryControllerDocsTest { given(distilleryService.delete(anyLong())).willReturn(result) assertThat( - mvc.delete().uri("/distilleries/{distilleryId}", 1L) + mvc.delete().uri("/v1/distilleries/{distilleryId}", 1L) ).hasStatusOk() .apply( document( diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminRegionControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminRegionControllerDocsTest.kt index eaf776773..e42c357d6 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminRegionControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminRegionControllerDocsTest.kt @@ -56,7 +56,7 @@ class AdminRegionControllerDocsTest { // when & then assertThat( - mvc.get().uri("/regions?keyword=&page=0&size=20&sortOrder=ASC") + mvc.get().uri("/v1/regions?keyword=&page=0&size=20&sortOrder=ASC") ) .hasStatusOk() .apply( diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminTastingTagControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminTastingTagControllerDocsTest.kt index 3cfa10f2b..c28a15a4d 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminTastingTagControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminTastingTagControllerDocsTest.kt @@ -71,7 +71,7 @@ class AdminTastingTagControllerDocsTest { // when & then assertThat( - mvc.get().uri("/tasting-tags?keyword=&page=0&size=20&sortOrder=ASC") + mvc.get().uri("/v1/tasting-tags?keyword=&page=0&size=20&sortOrder=ASC") ) .hasStatusOk() .apply( @@ -150,7 +150,7 @@ class AdminTastingTagControllerDocsTest { given(tastingTagService.getTagDetail(anyLong())).willReturn(response) // when & then - assertThat(mvc.get().uri("/tasting-tags/{tagId}", 1L)) + assertThat(mvc.get().uri("/v1/tasting-tags/{tagId}", 1L)) .hasStatusOk() .apply( document( @@ -223,7 +223,7 @@ class AdminTastingTagControllerDocsTest { // when & then assertThat( - mvc.post().uri("/tasting-tags") + mvc.post().uri("/v1/tasting-tags") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -281,7 +281,7 @@ class AdminTastingTagControllerDocsTest { // when & then assertThat( - mvc.put().uri("/tasting-tags/{tagId}", 1L) + mvc.put().uri("/v1/tasting-tags/{tagId}", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -334,7 +334,7 @@ class AdminTastingTagControllerDocsTest { given(tastingTagService.deleteTag(anyLong())).willReturn(response) // when & then - assertThat(mvc.delete().uri("/tasting-tags/{tagId}", 1L)) + assertThat(mvc.delete().uri("/v1/tasting-tags/{tagId}", 1L)) .hasStatusOk() .apply( document( @@ -380,7 +380,7 @@ class AdminTastingTagControllerDocsTest { // when & then assertThat( - mvc.post().uri("/tasting-tags/{tagId}/alcohols", 1L) + mvc.post().uri("/v1/tasting-tags/{tagId}/alcohols", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -427,7 +427,7 @@ class AdminTastingTagControllerDocsTest { // when & then assertThat( - mvc.delete().uri("/tasting-tags/{tagId}/alcohols", 1L) + mvc.delete().uri("/v1/tasting-tags/{tagId}/alcohols", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminAlcoholsIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminAlcoholsIntegrationTest.kt index a678a6f1f..101c7a18a 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminAlcoholsIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminAlcoholsIntegrationTest.kt @@ -80,7 +80,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols") + .uri("/v1/alcohols") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -104,7 +104,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols") + .uri("/v1/alcohols") .header("Authorization", "Bearer $accessToken") .param("keyword", keyword) ).hasStatusOk() @@ -124,7 +124,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols") + .uri("/v1/alcohols") .header("Authorization", "Bearer $accessToken") .param("category", category.name) ).hasStatusOk() @@ -148,7 +148,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols") + .uri("/v1/alcohols") .header("Authorization", "Bearer $accessToken") .param("sortType", sortType.name) .param("sortOrder", sortOrder.name) @@ -177,7 +177,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols") + .uri("/v1/alcohols") .header("Authorization", "Bearer $accessToken") .param("page", page.toString()) .param("size", size.toString()) @@ -201,7 +201,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols") + .uri("/v1/alcohols") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -220,7 +220,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols") + .uri("/v1/alcohols") .header("Authorization", "Bearer $accessToken") .param("includeDeleted", "true") ).hasStatusOk() @@ -245,7 +245,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols/categories/reference") + .uri("/v1/alcohols/categories/reference") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -264,7 +264,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols/categories/reference") + .uri("/v1/alcohols/categories/reference") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -286,7 +286,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -297,7 +297,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -315,7 +315,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { val result = mockMvcTester .get() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") assertThat(result) @@ -328,7 +328,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols/999999") + .uri("/v1/alcohols/999999") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } @@ -366,7 +366,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/alcohols") + .uri("/v1/alcohols") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -408,7 +408,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { val createResult = mockMvcTester .post() - .uri("/alcohols") + .uri("/v1/alcohols") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -425,7 +425,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols/$alcoholId") + .uri("/v1/alcohols/$alcoholId") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -463,7 +463,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/alcohols") + .uri("/v1/alcohols") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -483,7 +483,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/alcohols") + .uri("/v1/alcohols") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -518,7 +518,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/alcohols") + .uri("/v1/alcohols") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -559,7 +559,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -604,7 +604,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -617,7 +617,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -657,7 +657,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -667,7 +667,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -708,7 +708,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -718,7 +718,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -755,7 +755,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/alcohols/999999") + .uri("/v1/alcohols/999999") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -776,7 +776,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -791,7 +791,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/alcohols/999999") + .uri("/v1/alcohols/999999") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } @@ -808,7 +808,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } @@ -825,7 +825,7 @@ class AdminAlcoholsIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/alcohols/${alcohol.id}") + .uri("/v1/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminDistilleryIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminDistilleryIntegrationTest.kt index 1489139f7..868cb715f 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminDistilleryIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminDistilleryIntegrationTest.kt @@ -41,7 +41,7 @@ class AdminDistilleryIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/distilleries/${distillery.id}") + .uri("/v1/distilleries/${distillery.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -55,7 +55,7 @@ class AdminDistilleryIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/distilleries/999999") + .uri("/v1/distilleries/999999") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() .bodyJson() @@ -79,7 +79,7 @@ class AdminDistilleryIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/distilleries") + .uri("/v1/distilleries") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -101,7 +101,7 @@ class AdminDistilleryIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/distilleries") + .uri("/v1/distilleries") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -122,7 +122,7 @@ class AdminDistilleryIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/distilleries") + .uri("/v1/distilleries") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -148,7 +148,7 @@ class AdminDistilleryIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/distilleries/${distillery.id}") + .uri("/v1/distilleries/${distillery.id}") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -169,7 +169,7 @@ class AdminDistilleryIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/distilleries/999999") + .uri("/v1/distilleries/999999") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -192,7 +192,7 @@ class AdminDistilleryIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .patch() - .uri("/distilleries/${distillery.id}/sort-order") + .uri("/v1/distilleries/${distillery.id}/sort-order") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -211,7 +211,7 @@ class AdminDistilleryIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .patch() - .uri("/distilleries/${distillery.id}/sort-order") + .uri("/v1/distilleries/${distillery.id}/sort-order") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -230,7 +230,7 @@ class AdminDistilleryIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .patch() - .uri("/distilleries/${distillery.id}/sort-order") + .uri("/v1/distilleries/${distillery.id}/sort-order") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -252,7 +252,7 @@ class AdminDistilleryIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/distilleries/${distillery.id}") + .uri("/v1/distilleries/${distillery.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -266,7 +266,7 @@ class AdminDistilleryIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/distilleries/999999") + .uri("/v1/distilleries/999999") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() .bodyJson() diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminReferenceDataIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminReferenceDataIntegrationTest.kt index 0853ac063..30e460666 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminReferenceDataIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminReferenceDataIntegrationTest.kt @@ -30,7 +30,7 @@ class AdminReferenceDataIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/tasting-tags?page=0&size=20") + .uri("/v1/tasting-tags?page=0&size=20") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -41,7 +41,7 @@ class AdminReferenceDataIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/tasting-tags?page=0&size=10") + .uri("/v1/tasting-tags?page=0&size=10") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -54,7 +54,7 @@ class AdminReferenceDataIntegrationTest : IntegrationTestSupport() { fun getTastingTagsWithoutAuth() { // when & then - 방어로직: 인증 없이 요청 시 실패 assertThat( - mockMvcTester.get().uri("/tasting-tags") + mockMvcTester.get().uri("/v1/tasting-tags") ).hasStatus4xxClientError() } } @@ -72,7 +72,7 @@ class AdminReferenceDataIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/regions?page=0&size=20") + .uri("/v1/regions?page=0&size=20") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -90,7 +90,7 @@ class AdminReferenceDataIntegrationTest : IntegrationTestSupport() { val result = mockMvcTester .get() - .uri("/regions?page=0&size=10") + .uri("/v1/regions?page=0&size=10") .header("Authorization", "Bearer $accessToken") assertThat(result) @@ -106,7 +106,7 @@ class AdminReferenceDataIntegrationTest : IntegrationTestSupport() { // 방어로직: 인증 없이 요청 시 실패 assertThat( - mockMvcTester.get().uri("/regions") + mockMvcTester.get().uri("/v1/regions") ).hasStatus4xxClientError() } @@ -120,7 +120,7 @@ class AdminReferenceDataIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/regions?page=0&size=10") + .uri("/v1/regions?page=0&size=10") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -142,7 +142,7 @@ class AdminReferenceDataIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/distilleries?page=0&size=20") + .uri("/v1/distilleries?page=0&size=20") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -160,7 +160,7 @@ class AdminReferenceDataIntegrationTest : IntegrationTestSupport() { val result = mockMvcTester .get() - .uri("/distilleries?keyword=&page=0&size=20") + .uri("/v1/distilleries?keyword=&page=0&size=20") .header("Authorization", "Bearer $accessToken") assertThat(result) @@ -171,7 +171,7 @@ class AdminReferenceDataIntegrationTest : IntegrationTestSupport() { // 방어로직: 인증 없이 요청 시 실패 assertThat( - mockMvcTester.get().uri("/distilleries") + mockMvcTester.get().uri("/v1/distilleries") ).hasStatus4xxClientError() } @@ -185,7 +185,7 @@ class AdminReferenceDataIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/distilleries?page=0&size=20") + .uri("/v1/distilleries?page=0&size=20") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminTastingTagIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminTastingTagIntegrationTest.kt index e78ae78fa..af07ba931 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminTastingTagIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/AdminTastingTagIntegrationTest.kt @@ -42,7 +42,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/tasting-tags/${tag.id}") + .uri("/v1/tasting-tags/${tag.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -52,7 +52,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/tasting-tags/${tag.id}") + .uri("/v1/tasting-tags/${tag.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -71,7 +71,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/tasting-tags/${leafTag.id}") + .uri("/v1/tasting-tags/${leafTag.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -81,7 +81,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/tasting-tags/${leafTag.id}") + .uri("/v1/tasting-tags/${leafTag.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -101,7 +101,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/tasting-tags/${tag.id}") + .uri("/v1/tasting-tags/${tag.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -116,7 +116,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/tasting-tags/999999") + .uri("/v1/tasting-tags/999999") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } @@ -140,7 +140,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/tasting-tags") + .uri("/v1/tasting-tags") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -166,7 +166,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/tasting-tags") + .uri("/v1/tasting-tags") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -191,7 +191,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/tasting-tags") + .uri("/v1/tasting-tags") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -216,7 +216,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/tasting-tags") + .uri("/v1/tasting-tags") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -243,7 +243,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/tasting-tags/${tag.id}") + .uri("/v1/tasting-tags/${tag.id}") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -270,7 +270,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/tasting-tags/${targetTag.id}") + .uri("/v1/tasting-tags/${targetTag.id}") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -291,7 +291,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/tasting-tags/999999") + .uri("/v1/tasting-tags/999999") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -312,7 +312,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/tasting-tags/${tag.id}") + .uri("/v1/tasting-tags/${tag.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -331,7 +331,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/tasting-tags/${parent.id}") + .uri("/v1/tasting-tags/${parent.id}") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } @@ -348,7 +348,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/tasting-tags/${tag.id}") + .uri("/v1/tasting-tags/${tag.id}") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } @@ -360,7 +360,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/tasting-tags/999999") + .uri("/v1/tasting-tags/999999") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } @@ -383,7 +383,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/tasting-tags/${tag.id}/alcohols") + .uri("/v1/tasting-tags/${tag.id}/alcohols") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -409,7 +409,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/tasting-tags/${tag.id}/alcohols") + .uri("/v1/tasting-tags/${tag.id}/alcohols") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -430,7 +430,7 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/tasting-tags/${tag.id}/alcohols") + .uri("/v1/tasting-tags/${tag.id}/alcohols") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -445,13 +445,13 @@ class AdminTastingTagIntegrationTest : IntegrationTestSupport() { @DisplayName("인증 없이 요청 시 실패한다") fun requestWithoutAuth() { // when & then - assertThat(mockMvcTester.get().uri("/tasting-tags/1")) + assertThat(mockMvcTester.get().uri("/v1/tasting-tags/1")) .hasStatus4xxClientError() assertThat( mockMvcTester .post() - .uri("/tasting-tags") + .uri("/v1/tasting-tags") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(mapOf("korName" to "테스트", "engName" to "Test"))) ).hasStatus4xxClientError() diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/region/AdminRegionIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/region/AdminRegionIntegrationTest.kt index b467f1921..fe5cb75d9 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/region/AdminRegionIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/region/AdminRegionIntegrationTest.kt @@ -40,7 +40,7 @@ class AdminRegionIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/regions/${region.id}") + .uri("/v1/regions/${region.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -53,7 +53,7 @@ class AdminRegionIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/regions/999999") + .uri("/v1/regions/999999") .header("Authorization", "Bearer $accessToken") ).hasStatus(404) } @@ -76,7 +76,7 @@ class AdminRegionIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/regions") + .uri("/v1/regions") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -98,7 +98,7 @@ class AdminRegionIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/regions") + .uri("/v1/regions") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -125,7 +125,7 @@ class AdminRegionIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/regions/${region.id}") + .uri("/v1/regions/${region.id}") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -146,7 +146,7 @@ class AdminRegionIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/regions/${region.id}") + .uri("/v1/regions/${region.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -162,7 +162,7 @@ class AdminRegionIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/regions/${root.id}") + .uri("/v1/regions/${root.id}") .header("Authorization", "Bearer $accessToken") ).hasStatus(409) } @@ -181,7 +181,7 @@ class AdminRegionIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .patch() - .uri("/regions/${region.id}/sort-order") + .uri("/v1/regions/${region.id}/sort-order") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) diff --git a/plan/admin-api-v2-curation-endpoints.md b/plan/admin-api-v2-curation-endpoints.md index 4d65e4f48..b72737d64 100644 --- a/plan/admin-api-v2-curation-endpoints.md +++ b/plan/admin-api-v2-curation-endpoints.md @@ -145,13 +145,13 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv - Reference data endpoints remain under `/admin/api/v1`. - Verification: - `./gradlew :bottlenote-admin-api:test --tests 'app.docs.alcohols.*'` - - `./gradlew admin_integration_test --tests 'app.integration.alcohols.*' --tests 'app.integration.region.*'` + - `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.alcohols.*' --tests 'app.integration.region.*'` - Files: - `bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/*` - `bottlenote-admin-api/src/test/kotlin/app/integration/alcohols/*` - `bottlenote-admin-api/src/test/kotlin/app/integration/region/*` - Size: M -- Status: [ ] not done +- Status: [x] done ### Task 5: Preserve Admin v1 banner and legacy curation routes in tests @@ -220,3 +220,4 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv - 2026-05-18: Task 1 완료. admin-api context-path를 `/admin/api`로 낮추고, `AdminApiVersionConfig`에서 legacy Admin presentation controller에 중앙 `/v1` prefix를 적용했다. spec 기반 curation controller 2개는 prefix 대상에서 제외했고, Security permit matcher를 `/v1/auth/login`, `/v1/auth/refresh`로 갱신했다. 검증: `./gradlew :bottlenote-admin-api:compileKotlin :bottlenote-admin-api:compileTestKotlin` 성공. - 2026-05-18: Task 2 완료. spec 기반 admin curation controller를 `/v2/curations`, spec 조회 controller를 `/v2/curation-specs`로 변경하고 RestDocs/integration 테스트 URI와 snippet 경로를 v2 기준으로 갱신했다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.curation.AdminSpecBasedCurationIntegrationTest'` 성공. root aggregate `admin_integration_test --tests ...`는 `--tests` 옵션을 받지 않아 모듈 Test 태스크 명령으로 정정했다. - 2026-05-18: Task 3 완료. auth, file, user, help docs/integration 테스트 요청 URI를 `/v1/**` 기준으로 갱신해 기존 Admin v1 최종 URL 보존을 검증했다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.auth.AuthControllerDocsTest' --tests 'app.docs.file.AdminImageUploadControllerDocsTest' --tests 'app.docs.user.AdminUsersControllerDocsTest' --tests 'app.docs.help.AdminHelpControllerDocsTest'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.auth.AdminAuthIntegrationTest' --tests 'app.integration.file.AdminImageUploadIntegrationTest' --tests 'app.integration.user.AdminUsersIntegrationTest' --tests 'app.integration.help.AdminHelpIntegrationTest'` 성공. +- 2026-05-18: Task 4 완료. alcohol, distillery, region, tasting-tag docs/integration 테스트 요청 URI를 `/v1/**` 기준으로 갱신해 reference/admin alcohol API의 기존 v1 surface를 보존했다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.alcohols.*'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.alcohols.*' --tests 'app.integration.region.*'` 성공. From a8faa98c78b39bfbbaa95405cf50948a149ee1f3 Mon Sep 17 00:00:00 2001 From: hgkim Date: Mon, 18 May 2026 10:22:43 +0900 Subject: [PATCH 21/33] =?UTF-8?q?test:=20=EC=96=B4=EB=93=9C=EB=AF=BC=20v1?= =?UTF-8?q?=20=EB=B0=B0=EB=84=88=20=ED=81=90=EB=A0=88=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=20=EA=B2=80=EC=A6=9D=20=EB=B3=B4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../banner/AdminBannerControllerDocsTest.kt | 14 +++--- .../AdminCurationControllerDocsTest.kt | 18 ++++---- .../banner/AdminBannerIntegrationTest.kt | 46 +++++++++---------- .../curation/AdminCurationIntegrationTest.kt | 46 +++++++++---------- plan/admin-api-v2-curation-endpoints.md | 5 +- 5 files changed, 65 insertions(+), 64 deletions(-) diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/banner/AdminBannerControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/banner/AdminBannerControllerDocsTest.kt index b62355e80..288402730 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/banner/AdminBannerControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/banner/AdminBannerControllerDocsTest.kt @@ -66,7 +66,7 @@ class AdminBannerControllerDocsTest { // when & then assertThat( - mvc.get().uri("/banners?keyword=&isActive=true&bannerType=CURATION&page=0&size=20") + mvc.get().uri("/v1/banners?keyword=&isActive=true&bannerType=CURATION&page=0&size=20") ) .hasStatusOk() .apply( @@ -124,7 +124,7 @@ class AdminBannerControllerDocsTest { given(adminBannerService.getDetail(anyLong())).willReturn(response) // when & then - assertThat(mvc.get().uri("/banners/{bannerId}", 1L)) + assertThat(mvc.get().uri("/v1/banners/{bannerId}", 1L)) .hasStatusOk() .apply( document( @@ -184,7 +184,7 @@ class AdminBannerControllerDocsTest { // when & then assertThat( - mvc.post().uri("/banners") + mvc.post().uri("/v1/banners") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -246,7 +246,7 @@ class AdminBannerControllerDocsTest { // when & then assertThat( - mvc.put().uri("/banners/{bannerId}", 1L) + mvc.put().uri("/v1/banners/{bannerId}", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -309,7 +309,7 @@ class AdminBannerControllerDocsTest { given(adminBannerService.delete(anyLong())).willReturn(response) // when & then - assertThat(mvc.delete().uri("/banners/{bannerId}", 1L)) + assertThat(mvc.delete().uri("/v1/banners/{bannerId}", 1L)) .hasStatusOk() .apply( document( @@ -355,7 +355,7 @@ class AdminBannerControllerDocsTest { // when & then assertThat( - mvc.patch().uri("/banners/{bannerId}/status", 1L) + mvc.patch().uri("/v1/banners/{bannerId}/status", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -407,7 +407,7 @@ class AdminBannerControllerDocsTest { // when & then assertThat( - mvc.patch().uri("/banners/{bannerId}/sort-order", 1L) + mvc.patch().uri("/v1/banners/{bannerId}/sort-order", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminCurationControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminCurationControllerDocsTest.kt index 6bcc14c5d..2c6532ec9 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminCurationControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminCurationControllerDocsTest.kt @@ -62,7 +62,7 @@ class AdminCurationControllerDocsTest { // when & then assertThat( - mvc.get().uri("/curations?keyword=&isActive=true&page=0&size=20") + mvc.get().uri("/v1/curations?keyword=&isActive=true&page=0&size=20") ) .hasStatusOk() .apply( @@ -116,7 +116,7 @@ class AdminCurationControllerDocsTest { given(adminCurationService.getDetail(anyLong())).willReturn(response) // when & then - assertThat(mvc.get().uri("/curations/{curationId}", 1L)) + assertThat(mvc.get().uri("/v1/curations/{curationId}", 1L)) .hasStatusOk() .apply( document( @@ -176,7 +176,7 @@ class AdminCurationControllerDocsTest { // when & then assertThat( - mvc.post().uri("/curations") + mvc.post().uri("/v1/curations") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -229,7 +229,7 @@ class AdminCurationControllerDocsTest { // when & then assertThat( - mvc.put().uri("/curations/{curationId}", 1L) + mvc.put().uri("/v1/curations/{curationId}", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -283,7 +283,7 @@ class AdminCurationControllerDocsTest { given(adminCurationService.delete(anyLong())).willReturn(response) // when & then - assertThat(mvc.delete().uri("/curations/{curationId}", 1L)) + assertThat(mvc.delete().uri("/v1/curations/{curationId}", 1L)) .hasStatusOk() .apply( document( @@ -329,7 +329,7 @@ class AdminCurationControllerDocsTest { // when & then assertThat( - mvc.patch().uri("/curations/{curationId}/status", 1L) + mvc.patch().uri("/v1/curations/{curationId}/status", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -381,7 +381,7 @@ class AdminCurationControllerDocsTest { // when & then assertThat( - mvc.patch().uri("/curations/{curationId}/display-order", 1L) + mvc.patch().uri("/v1/curations/{curationId}/display-order", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -433,7 +433,7 @@ class AdminCurationControllerDocsTest { // when & then assertThat( - mvc.post().uri("/curations/{curationId}/alcohols", 1L) + mvc.post().uri("/v1/curations/{curationId}/alcohols", 1L) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) ) @@ -478,7 +478,7 @@ class AdminCurationControllerDocsTest { // when & then assertThat( - mvc.delete().uri("/curations/{curationId}/alcohols/{alcoholId}", 1L, 5L) + mvc.delete().uri("/v1/curations/{curationId}/alcohols/{alcoholId}", 1L, 5L) ) .hasStatusOk() .apply( diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/banner/AdminBannerIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/banner/AdminBannerIntegrationTest.kt index 968deb575..0216a39fd 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/banner/AdminBannerIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/banner/AdminBannerIntegrationTest.kt @@ -39,7 +39,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/banners") + .uri("/v1/banners") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -57,7 +57,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/banners") + .uri("/v1/banners") .param("keyword", "특별") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() @@ -76,7 +76,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/banners") + .uri("/v1/banners") .param("isActive", "true") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() @@ -95,7 +95,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/banners") + .uri("/v1/banners") .param("bannerType", "CURATION") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() @@ -108,7 +108,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { @DisplayName("인증 없이 요청하면 401을 반환한다") fun listUnauthorized() { assertThat( - mockMvcTester.get().uri("/banners") + mockMvcTester.get().uri("/v1/banners") ).hasStatus4xxClientError() } } @@ -126,7 +126,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/banners/${banner.id}") + .uri("/v1/banners/${banner.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -141,7 +141,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/banners/999999") + .uri("/v1/banners/999999") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } @@ -163,7 +163,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/banners") + .uri("/v1/banners") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -187,7 +187,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/banners") + .uri("/v1/banners") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -208,7 +208,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/banners") + .uri("/v1/banners") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -230,7 +230,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/banners") + .uri("/v1/banners") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -252,7 +252,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/banners") + .uri("/v1/banners") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -273,7 +273,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/banners") + .uri("/v1/banners") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -298,7 +298,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/banners/${banner.id}") + .uri("/v1/banners/${banner.id}") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -318,7 +318,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/banners/999999") + .uri("/v1/banners/999999") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -339,7 +339,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/banners/${banner.id}") + .uri("/v1/banners/${banner.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -354,7 +354,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/banners/999999") + .uri("/v1/banners/999999") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } @@ -374,7 +374,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .patch() - .uri("/banners/${banner.id}/status") + .uri("/v1/banners/${banner.id}/status") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -394,7 +394,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .patch() - .uri("/banners/999999/status") + .uri("/v1/banners/999999/status") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -416,7 +416,7 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .patch() - .uri("/banners/${banner.id}/sort-order") + .uri("/v1/banners/${banner.id}/sort-order") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -434,16 +434,16 @@ class AdminBannerIntegrationTest : IntegrationTestSupport() { @DisplayName("인증 없이 요청 시 실패한다") fun requestWithoutAuth() { // when & then - assertThat(mockMvcTester.get().uri("/banners")) + assertThat(mockMvcTester.get().uri("/v1/banners")) .hasStatus4xxClientError() - assertThat(mockMvcTester.get().uri("/banners/1")) + assertThat(mockMvcTester.get().uri("/v1/banners/1")) .hasStatus4xxClientError() assertThat( mockMvcTester .post() - .uri("/banners") + .uri("/v1/banners") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(BannerHelper.createBannerCreateRequest())) ).hasStatus4xxClientError() diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminCurationIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminCurationIntegrationTest.kt index 140fc1d82..26fe38cd1 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminCurationIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminCurationIntegrationTest.kt @@ -40,7 +40,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/curations") + .uri("/v1/curations") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -58,7 +58,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/curations") + .uri("/v1/curations") .param("keyword", "테스트") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() @@ -77,7 +77,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/curations") + .uri("/v1/curations") .param("isActive", "true") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() @@ -90,7 +90,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { @DisplayName("인증 없이 요청하면 401을 반환한다") fun listUnauthorized() { assertThat( - mockMvcTester.get().uri("/curations") + mockMvcTester.get().uri("/v1/curations") ).hasStatus4xxClientError() } } @@ -108,7 +108,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/curations/${curation.id}") + .uri("/v1/curations/${curation.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -123,7 +123,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .get() - .uri("/curations/999999") + .uri("/v1/curations/999999") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } @@ -145,7 +145,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/curations") + .uri("/v1/curations") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -172,7 +172,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/curations") + .uri("/v1/curations") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -196,7 +196,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/curations") + .uri("/v1/curations") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -217,7 +217,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/curations") + .uri("/v1/curations") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -243,7 +243,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/curations/${curation.id}") + .uri("/v1/curations/${curation.id}") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -263,7 +263,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .put() - .uri("/curations/999999") + .uri("/v1/curations/999999") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -284,7 +284,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/curations/${curation.id}") + .uri("/v1/curations/${curation.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -299,7 +299,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/curations/999999") + .uri("/v1/curations/999999") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } @@ -319,7 +319,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .patch() - .uri("/curations/${curation.id}/status") + .uri("/v1/curations/${curation.id}/status") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -339,7 +339,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .patch() - .uri("/curations/999999/status") + .uri("/v1/curations/999999/status") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -361,7 +361,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .patch() - .uri("/curations/${curation.id}/display-order") + .uri("/v1/curations/${curation.id}/display-order") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -391,7 +391,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .post() - .uri("/curations/${curation.id}/alcohols") + .uri("/v1/curations/${curation.id}/alcohols") .header("Authorization", "Bearer $accessToken") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(request)) @@ -412,7 +412,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/curations/${curation.id}/alcohols/${alcohol.id}") + .uri("/v1/curations/${curation.id}/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") ).hasStatusOk() .bodyJson() @@ -431,7 +431,7 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { assertThat( mockMvcTester .delete() - .uri("/curations/${curation.id}/alcohols/${alcohol.id}") + .uri("/v1/curations/${curation.id}/alcohols/${alcohol.id}") .header("Authorization", "Bearer $accessToken") ).hasStatus4xxClientError() } @@ -444,16 +444,16 @@ class AdminCurationIntegrationTest : IntegrationTestSupport() { @DisplayName("인증 없이 요청 시 실패한다") fun requestWithoutAuth() { // when & then - assertThat(mockMvcTester.get().uri("/curations")) + assertThat(mockMvcTester.get().uri("/v1/curations")) .hasStatus4xxClientError() - assertThat(mockMvcTester.get().uri("/curations/1")) + assertThat(mockMvcTester.get().uri("/v1/curations/1")) .hasStatus4xxClientError() assertThat( mockMvcTester .post() - .uri("/curations") + .uri("/v1/curations") .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(CurationHelper.createCurationCreateRequest())) ).hasStatus4xxClientError() diff --git a/plan/admin-api-v2-curation-endpoints.md b/plan/admin-api-v2-curation-endpoints.md index b72737d64..fe465cbc7 100644 --- a/plan/admin-api-v2-curation-endpoints.md +++ b/plan/admin-api-v2-curation-endpoints.md @@ -161,14 +161,14 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv - Spec 기반 curation v2와 legacy curation v1이 `/admin/api/v2/curations` vs `/admin/api/v1/curations`로 명확히 분리된다. - Verification: - `./gradlew :bottlenote-admin-api:test --tests 'app.docs.banner.AdminBannerControllerDocsTest' --tests 'app.docs.curation.AdminCurationControllerDocsTest'` - - `./gradlew admin_integration_test --tests 'app.integration.banner.AdminBannerIntegrationTest' --tests 'app.integration.curation.AdminCurationIntegrationTest'` + - `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.banner.AdminBannerIntegrationTest' --tests 'app.integration.curation.AdminCurationIntegrationTest'` - Files: - `bottlenote-admin-api/src/test/kotlin/app/docs/banner/*` - `bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminCurationControllerDocsTest.kt` - `bottlenote-admin-api/src/test/kotlin/app/integration/banner/*` - `bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminCurationIntegrationTest.kt` - Size: M -- Status: [ ] not done +- Status: [x] done ### Checkpoint: after Tasks 3-5 @@ -221,3 +221,4 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv - 2026-05-18: Task 2 완료. spec 기반 admin curation controller를 `/v2/curations`, spec 조회 controller를 `/v2/curation-specs`로 변경하고 RestDocs/integration 테스트 URI와 snippet 경로를 v2 기준으로 갱신했다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.curation.AdminSpecBasedCurationIntegrationTest'` 성공. root aggregate `admin_integration_test --tests ...`는 `--tests` 옵션을 받지 않아 모듈 Test 태스크 명령으로 정정했다. - 2026-05-18: Task 3 완료. auth, file, user, help docs/integration 테스트 요청 URI를 `/v1/**` 기준으로 갱신해 기존 Admin v1 최종 URL 보존을 검증했다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.auth.AuthControllerDocsTest' --tests 'app.docs.file.AdminImageUploadControllerDocsTest' --tests 'app.docs.user.AdminUsersControllerDocsTest' --tests 'app.docs.help.AdminHelpControllerDocsTest'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.auth.AdminAuthIntegrationTest' --tests 'app.integration.file.AdminImageUploadIntegrationTest' --tests 'app.integration.user.AdminUsersIntegrationTest' --tests 'app.integration.help.AdminHelpIntegrationTest'` 성공. - 2026-05-18: Task 4 완료. alcohol, distillery, region, tasting-tag docs/integration 테스트 요청 URI를 `/v1/**` 기준으로 갱신해 reference/admin alcohol API의 기존 v1 surface를 보존했다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.alcohols.*'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.alcohols.*' --tests 'app.integration.region.*'` 성공. +- 2026-05-18: Task 5 완료. banner docs/integration 테스트를 `/v1/banners/**`, legacy curation docs/integration 테스트를 `/v1/curations/**` 기준으로 갱신했다. spec 기반 신규 curation 테스트는 `/v2/curations`로 유지되어 legacy와 v2 surface가 분리된다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.banner.AdminBannerControllerDocsTest' --tests 'app.docs.curation.AdminCurationControllerDocsTest'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.banner.AdminBannerIntegrationTest' --tests 'app.integration.curation.AdminCurationIntegrationTest'` 성공. From 30aa68f2d5f1c400685cd29102db5f40f0dc9554 Mon Sep 17 00:00:00 2001 From: hgkim Date: Mon, 18 May 2026 10:24:42 +0900 Subject: [PATCH 22/33] =?UTF-8?q?docs:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20=EB=8D=B0=EB=AA=A8=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EA=B0=B1=EC=8B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plan/admin-api-v2-curation-endpoints.md | 9 +++++---- plan/spec-based-curation-v2-graphql-sdl.md | 10 ++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/plan/admin-api-v2-curation-endpoints.md b/plan/admin-api-v2-curation-endpoints.md index fe465cbc7..0e84961bc 100644 --- a/plan/admin-api-v2-curation-endpoints.md +++ b/plan/admin-api-v2-curation-endpoints.md @@ -172,9 +172,9 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv ### Checkpoint: after Tasks 3-5 -- [ ] Existing Admin v1 docs tests pass -- [ ] Existing Admin v1 integration tests pass -- [ ] Legacy `/admin/api/v1/curations` and new `/admin/api/v2/curations` are both represented in tests +- [x] Existing Admin v1 docs tests pass +- [x] Existing Admin v1 integration tests pass +- [x] Legacy `/admin/api/v1/curations` and new `/admin/api/v2/curations` are both represented in tests ### Task 6: Demo and planning documents update @@ -193,7 +193,7 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv - `plan/spec-based-curation-v2-graphql-sdl.md` - `plan/admin-api-v2-curation-endpoints.md` - Size: M -- Status: [ ] not done +- Status: [x] done ### Task 7: Final verification and commit @@ -222,3 +222,4 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv - 2026-05-18: Task 3 완료. auth, file, user, help docs/integration 테스트 요청 URI를 `/v1/**` 기준으로 갱신해 기존 Admin v1 최종 URL 보존을 검증했다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.auth.AuthControllerDocsTest' --tests 'app.docs.file.AdminImageUploadControllerDocsTest' --tests 'app.docs.user.AdminUsersControllerDocsTest' --tests 'app.docs.help.AdminHelpControllerDocsTest'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.auth.AdminAuthIntegrationTest' --tests 'app.integration.file.AdminImageUploadIntegrationTest' --tests 'app.integration.user.AdminUsersIntegrationTest' --tests 'app.integration.help.AdminHelpIntegrationTest'` 성공. - 2026-05-18: Task 4 완료. alcohol, distillery, region, tasting-tag docs/integration 테스트 요청 URI를 `/v1/**` 기준으로 갱신해 reference/admin alcohol API의 기존 v1 surface를 보존했다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.alcohols.*'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.alcohols.*' --tests 'app.integration.region.*'` 성공. - 2026-05-18: Task 5 완료. banner docs/integration 테스트를 `/v1/banners/**`, legacy curation docs/integration 테스트를 `/v1/curations/**` 기준으로 갱신했다. spec 기반 신규 curation 테스트는 `/v2/curations`로 유지되어 legacy와 v2 surface가 분리된다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.banner.AdminBannerControllerDocsTest' --tests 'app.docs.curation.AdminCurationControllerDocsTest'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.banner.AdminBannerIntegrationTest' --tests 'app.integration.curation.AdminCurationIntegrationTest'` 성공. +- 2026-05-18: Task 6 완료. `.example/display`의 admin base URL을 `/admin/api`로 낮추고, legacy 호출은 `/v1`, spec 기반 신규 호출은 `/v2/curation-specs`, `/v2/curations`로 분리했다. `plan/spec-based-curation-v2-graphql-sdl.md`에는 기존 `/admin/api/v1/curation-specs`, `/admin/api/v1/spec-based-curations` 결정을 취소선 + 정정으로 남겼다. 검증: `curl -s http://localhost:8098/curation-architecture.html` 성공, `rg -n "spec-based-curations|/admin/api/v1/curation-specs|/admin/api/v1/spec-based-curations" .example/display plan/spec-based-curation-v2-graphql-sdl.md` 결과는 plan 문서의 취소선/정정 이력 3건만 남고 `.example/display`에는 stale canonical reference가 없음을 확인했다. diff --git a/plan/spec-based-curation-v2-graphql-sdl.md b/plan/spec-based-curation-v2-graphql-sdl.md index 5d292be1b..a7af575b4 100644 --- a/plan/spec-based-curation-v2-graphql-sdl.md +++ b/plan/spec-based-curation-v2-graphql-sdl.md @@ -239,8 +239,10 @@ - Acceptance: - Admin spec 기반 등록/수정/상세/목록 API를 추가한다. - - Admin context-path가 이미 `/admin/api/v1`이므로 컨트롤러 path에 `/v2` prefix를 중복으로 붙이지 않는다. - - 스펙 API는 `/curation-specs`, spec 기반 큐레이션 API는 기존 `/curations`와 충돌하지 않도록 `/spec-based-curations`를 사용한다. + - ~~Admin context-path가 이미 `/admin/api/v1`이므로 컨트롤러 path에 `/v2` prefix를 중복으로 붙이지 않는다.~~ + - 정정: 2026-05-18에 admin-api context-path를 `/admin/api`로 낮추고 legacy Admin controller는 중앙 `/v1` prefix로 보존했다. spec 기반 신규 Admin API는 `/v2` controller mapping을 명시한다. + - ~~스펙 API는 `/curation-specs`, spec 기반 큐레이션 API는 기존 `/curations`와 충돌하지 않도록 `/spec-based-curations`를 사용한다.~~ + - 정정: 최종 Admin spec API는 `/admin/api/v2/curation-specs`, spec 기반 큐레이션 API는 `/admin/api/v2/curations`를 사용한다. 기존 legacy Admin curation API는 `/admin/api/v1/curations`로 유지한다. - 스펙 목록과 스펙 상세 API를 제공한다. - request payload는 저장 전 OpenAPI spec resource 기준 검증 경계로 연결한다. - admin-api 기동 시 `openapi/curation/*.json` 리소스를 읽어 `curation_spec`을 생성 또는 갱신한다. @@ -320,7 +322,7 @@ - 2026-05-15 Phase 2 Task 1 완료: `git.environment-variables/storage/mysql/changelog/schema.mysql.sql`에 `curation_spec`, `curation`, `curation_extension` changeset 3개를 추가했다. SOPS 기반 Liquibase 설정은 임시 파일로만 사용했고 secret 값은 출력하지 않았다. 개발 DB와 운영 DB 모두 `validate` 성공, pending 3건 확인 후 `update` 3건 실행, 세 테이블 생성 확인, 최종 `status --verbose` up to date를 확인했다. - 2026-05-15 Phase 2 Task 3 추가 완료: Liquibase insert seed 대신 admin-api startup resource sync를 추가했다. `CurationSpecResourceReader`가 `bottlenote-mono/src/main/resources/openapi/curation/*.json` 3종을 읽고, `CurationSpecResourceSyncService`가 `code` 기준으로 `curation_spec`을 생성 또는 갱신한다. admin-api runner는 `curation.spec-sync.enabled=${CURATION_SPEC_SYNC_ENABLED:true}`로 제어된다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-admin-api:compileKotlin :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationSpecResourceSyncServiceTest'` 성공, `./gradlew check_rule_test` 성공. - 2026-05-15 Phase 2 Task 2 완료: `bottlenote-mono`에 curation v2 Entity, domain repository interface, JPA repository, `CurationV2Service`, focused fake repository와 unit test를 추가했다. `request_spec`, `response_spec`, `payload` JSON 컬럼은 기존 의존성인 Hypersistence `JsonType`으로 매핑했다. `check_rule_test`에서 서비스 메서드 파라미터 5개 제한과 DTO 패키지/네이밍 규칙이 먼저 실패해 service 입력을 `dto.request`의 `*Request` record로 묶었다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationV2ServiceTest' check_rule_test` 성공, focused 테스트 4개 통과. -- 2026-05-15 Phase 2 Task 3 완료: 기존 Admin `/curations` endpoint는 유지하고, 신규 spec 기반 Admin surface를 `/spec-based-curations`와 `/curation-specs`로 추가했다. admin-api의 context-path가 이미 `/admin/api/v1`이므로 컨트롤러 path에 `/v2` prefix를 붙이지 않는다. 스펙 API는 목록/상세를 제공한다. 등록/수정은 `specId`로 `curation_spec`을 조회하고, `imageUrls` 1~3장을 정규화해 첫 번째 이미지를 `cover_image_url`에 저장하며, payload는 `curation_extension.payload`에 저장한다. 새 의존성 없이 requestSpec의 required field와 payload 크기를 검증하는 `CurationPayloadValidator`를 추가했다. 검증: `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.AdminSpecBasedCurationServiceTest' :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` 성공, service 테스트 5개와 RestDocs 테스트 6개 통과. `./gradlew check_rule_test` 성공. +- 2026-05-15 Phase 2 Task 3 완료: 기존 Admin `/curations` endpoint는 유지하고, 신규 spec 기반 Admin surface를 ~~`/spec-based-curations`와 `/curation-specs`~~ `/v2/curations`와 `/v2/curation-specs`로 추가했다. ~~admin-api의 context-path가 이미 `/admin/api/v1`이므로 컨트롤러 path에 `/v2` prefix를 붙이지 않는다.~~ 2026-05-18 정정: admin-api context-path는 `/admin/api`로 낮추고 legacy Admin API만 `/v1` prefix를 중앙 적용한다. 스펙 API는 목록/상세를 제공한다. 등록/수정은 `specId`로 `curation_spec`을 조회하고, `imageUrls` 1~3장을 정규화해 첫 번째 이미지를 `cover_image_url`에 저장하며, payload는 `curation_extension.payload`에 저장한다. 새 의존성 없이 requestSpec의 required field와 payload 크기를 검증하는 `CurationPayloadValidator`를 추가했다. 검증: `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.AdminSpecBasedCurationServiceTest' :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` 성공, service 테스트 5개와 RestDocs 테스트 6개 통과. `./gradlew check_rule_test` 성공. - 2026-05-15 Phase 3 Task 1 완료: Product v2 조회 API `/api/v2/curations`, `/api/v2/curations/{curationId}`를 추가하고, `responseSpec.x-graphql` 기반 materializer를 도입했다. materializer는 GraphQL query/variables를 responseSpec에서 만들고, Spring GraphQL executor를 통해 내부 실행한 뒤 payload의 `stats` 위치에 병합한다. root array와 `payloadPath = $.alcohols` object payload를 모두 지원하며, `MANUAL` 또는 `alcoholId = null` 항목은 stats를 null로 둔다. `CurationPayloadValidator`는 requestSpec/responseSpec 공통 검증기로 확장해 required, enum, type, minLength/maxLength, minItems/maxItems, minimum/maximum을 검증한다. 검증: focused 테스트 13개 통과, `./gradlew :bottlenote-product-api:compileJava` 성공, `./gradlew check_rule_test` 성공. - 2026-05-15 Phase 3 Task 2 완료: Product v2 목록/상세 RestDocs 테스트를 추가했고, `curation/v2/list`, `curation/v2/detail` 스니펫이 생성되는 것을 확인했다. `./gradlew :bottlenote-product-api:asciidoctor check_rule_test` 성공으로 `product-api.html` 생성과 rule test 통과를 확인했다. runtime smoke는 `.env` 기반 product-api를 8080에서 기동해 `GET /api/v2/curations` HTTP 200을 확인했다. 개발 DB에 active spec 기반 큐레이션이 0건이어서 `CODEX_RUNTIME_SMOKE_20260515` 임시 row를 생성한 뒤 `GET /api/v2/curations` HTTP 200, `GET /api/v2/curations/1` HTTP 200, list count=1, detail spec=`RECOMMENDED_WHISKY`, payload_count=2, BOTTLE_NOTE stats keys=`rating,reviewCount,totalPickCount,totalRatingsCount`, MANUAL stats null을 확인했다. 검증 후 임시 row는 삭제했고 삭제 확인 count=0, bootRun 프로세스도 종료했다. - 2026-05-17 Copilot review 대응 완료: GraphiQL default/local 비활성화, `/graphql`/`/graphiql`/`/graphiql/**` denyAll 차단, GraphQL stats field N+1 제거를 위한 `@BatchMapping` + `IN ... GROUP BY` 집계, Curation create/update Bean Validation enum message 수정을 반영했다. Copilot review thread 4건은 코드 확인 후 GitHub에서 resolved 처리했다. 검증: `/verify full` 범위로 compile, rule, unit, build, integration, admin integration 모두 성공. @@ -337,7 +339,7 @@ - `MANUAL` 항목처럼 `alcoholId = null`인 payload는 후속 Product hydration 단계에서 GraphQL 조회 대상으로 넘기지 않는다. - 기존 `curation_keyword`, `curation_keyword_alcohol_ids`, 기존 curation endpoint는 유지한다. - 신규 schema 변경은 Phase 2 Task 1에서 `git.environment-variables/storage/mysql/changelog/` 아래 changelog로 추가했고, 개발 DB와 운영 DB에 Liquibase CLI로 적용했다. -- Phase 2 Task 3에서 Admin spec 기반 endpoint를 추가했다. 최종 URL은 admin-api context-path를 포함해 `/admin/api/v1/curation-specs`, `/admin/api/v1/spec-based-curations`다. +- Phase 2 Task 3에서 Admin spec 기반 endpoint를 추가했다. ~~최종 URL은 admin-api context-path를 포함해 `/admin/api/v1/curation-specs`, `/admin/api/v1/spec-based-curations`다.~~ 정정: 2026-05-18 기준 최종 URL은 `/admin/api/v2/curation-specs`, `/admin/api/v2/curations`다. - Phase 3 Task 1에서 Product spec 기반 endpoint를 추가했다. 최종 URL은 `/api/v2/curations`, `/api/v2/curations/{curationId}`다. - 2026-05-17 기준 Product v2 endpoint는 노출 기간 필터를 적용한다. `isActive = true`이고 오늘 날짜가 노출 시작/종료일 사이에 있는 큐레이션만 목록/상세에서 조회된다. null 노출일은 열린 구간으로 본다. - GraphQL hydration 실패는 Product v2 상세 응답에서 부분 성공으로 처리하지 않는다. 내부 로그를 남기고 500 계열 `CURATION_GRAPHQL_EXECUTION_FAILED`로 닫는다. From ff3c0eae84d723b5c42b287026d9fff9b203f4bc Mon Sep 17 00:00:00 2001 From: hgkim Date: Mon, 18 May 2026 10:29:27 +0900 Subject: [PATCH 23/33] =?UTF-8?q?docs:=20=EC=96=B4=EB=93=9C=EB=AF=BC=20?= =?UTF-8?q?=ED=81=90=EB=A0=88=EC=9D=B4=EC=85=98=20v2=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=20=EC=99=84=EB=A3=8C=20=EA=B8=B0=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plan/admin-api-v2-curation-endpoints.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plan/admin-api-v2-curation-endpoints.md b/plan/admin-api-v2-curation-endpoints.md index 0e84961bc..a8814b072 100644 --- a/plan/admin-api-v2-curation-endpoints.md +++ b/plan/admin-api-v2-curation-endpoints.md @@ -213,7 +213,7 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv - `plan/admin-api-v2-curation-endpoints.md` - `plan/spec-based-curation-v2-graphql-sdl.md` - Size: S -- Status: [ ] not done +- Status: [x] done ## Progress Log @@ -223,3 +223,4 @@ Admin API의 versioning 경계를 정리한다. 현재 admin-api는 `server.serv - 2026-05-18: Task 4 완료. alcohol, distillery, region, tasting-tag docs/integration 테스트 요청 URI를 `/v1/**` 기준으로 갱신해 reference/admin alcohol API의 기존 v1 surface를 보존했다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.alcohols.*'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.alcohols.*' --tests 'app.integration.region.*'` 성공. - 2026-05-18: Task 5 완료. banner docs/integration 테스트를 `/v1/banners/**`, legacy curation docs/integration 테스트를 `/v1/curations/**` 기준으로 갱신했다. spec 기반 신규 curation 테스트는 `/v2/curations`로 유지되어 legacy와 v2 surface가 분리된다. 검증: `./gradlew :bottlenote-admin-api:test --tests 'app.docs.banner.AdminBannerControllerDocsTest' --tests 'app.docs.curation.AdminCurationControllerDocsTest'` 성공, `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.banner.AdminBannerIntegrationTest' --tests 'app.integration.curation.AdminCurationIntegrationTest'` 성공. - 2026-05-18: Task 6 완료. `.example/display`의 admin base URL을 `/admin/api`로 낮추고, legacy 호출은 `/v1`, spec 기반 신규 호출은 `/v2/curation-specs`, `/v2/curations`로 분리했다. `plan/spec-based-curation-v2-graphql-sdl.md`에는 기존 `/admin/api/v1/curation-specs`, `/admin/api/v1/spec-based-curations` 결정을 취소선 + 정정으로 남겼다. 검증: `curl -s http://localhost:8098/curation-architecture.html` 성공, `rg -n "spec-based-curations|/admin/api/v1/curation-specs|/admin/api/v1/spec-based-curations" .example/display plan/spec-based-curation-v2-graphql-sdl.md` 결과는 plan 문서의 취소선/정정 이력 3건만 남고 `.example/display`에는 stale canonical reference가 없음을 확인했다. +- 2026-05-18: Task 7 완료. 최종 검증으로 admin compile, admin 전체 RestDocs/test, 전체 admin integration, rule test, diff whitespace check를 수행했고 모두 성공했다. 검증: `./gradlew :bottlenote-admin-api:compileKotlin :bottlenote-admin-api:compileTestKotlin` 성공, `./gradlew :bottlenote-admin-api:test` 성공, `./gradlew admin_integration_test` 성공, `./gradlew check_rule_test` 성공, `git diff --check` 성공. From 3d7d463d07f9b5902fe3699e0738a2548a8224e4 Mon Sep 17 00:00:00 2001 From: hgkim Date: Mon, 18 May 2026 14:23:08 +0900 Subject: [PATCH 24/33] =?UTF-8?q?refactor:=20GraphQL=20=ED=81=90=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=AA=85=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...va => GraphQLCurationAlcoholResolver.java} | 34 +++++----------- .../service/CurationGraphqlExecutor.java | 8 ---- .../service/CurationResponseMaterializer.java | 24 ++++++------ ...ava => GraphQLCurationAlcoholService.java} | 39 +------------------ .../service/GraphQLCurationExecutor.java | 8 ++++ ....java => GraphQLCurationQueryBuilder.java} | 2 +- ...ava => GraphQLSpringCurationExecutor.java} | 4 +- ...> GraphQLCurationAlcoholResolverTest.java} | 14 +++---- .../CurationResponseMaterializerTest.java | 30 +++++++------- .../ProductSpecBasedCurationServiceTest.java | 8 ++-- ...st.java => GraphQLCurationSchemaTest.java} | 2 +- plan/spec-based-curation-v2-graphql-sdl.md | 10 +++-- 12 files changed, 64 insertions(+), 119 deletions(-) rename bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/{CurationAlcoholGraphqlResolver.java => GraphQLCurationAlcoholResolver.java} (73%) delete mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationGraphqlExecutor.java rename bottlenote-mono/src/main/java/app/bottlenote/curation/service/{CurationAlcoholGraphqlService.java => GraphQLCurationAlcoholService.java} (77%) create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLCurationExecutor.java rename bottlenote-mono/src/main/java/app/bottlenote/curation/service/{SpecGraphqlQueryBuilder.java => GraphQLCurationQueryBuilder.java} (99%) rename bottlenote-mono/src/main/java/app/bottlenote/curation/service/{SpringCurationGraphqlExecutor.java => GraphQLSpringCurationExecutor.java} (94%) rename bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/{CurationAlcoholGraphqlResolverTest.java => GraphQLCurationAlcoholResolverTest.java} (94%) rename bottlenote-mono/src/test/java/app/bottlenote/graphql/{CurationGraphqlSchemaTest.java => GraphQLCurationSchemaTest.java} (97%) diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolver.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/GraphQLCurationAlcoholResolver.java similarity index 73% rename from bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolver.java rename to bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/GraphQLCurationAlcoholResolver.java index 123e4da16..b882cfc4f 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolver.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/graphql/GraphQLCurationAlcoholResolver.java @@ -1,7 +1,7 @@ package app.bottlenote.curation.graphql; import app.bottlenote.alcohols.domain.Alcohol; -import app.bottlenote.curation.service.CurationAlcoholGraphqlService; +import app.bottlenote.curation.service.GraphQLCurationAlcoholService; import app.bottlenote.rating.dto.response.AlcoholRatingStatsResponse; import java.util.LinkedHashMap; import java.util.List; @@ -17,13 +17,13 @@ @Controller @RequiredArgsConstructor -public class CurationAlcoholGraphqlResolver { +public class GraphQLCurationAlcoholResolver { - private final CurationAlcoholGraphqlService curationAlcoholGraphqlService; + private final GraphQLCurationAlcoholService curationAlcoholGraphQLService; @QueryMapping public List alcohols(@Argument List ids) { - return curationAlcoholGraphqlService.findAlcohols(ids); + return curationAlcoholGraphQLService.findAlcohols(ids); } @SchemaMapping(typeName = "Alcohol", field = "alcoholId") @@ -33,51 +33,35 @@ public Long alcoholId(Alcohol alcohol) { @SchemaMapping(typeName = "Alcohol", field = "regionName") public String regionName(Alcohol alcohol) { - return curationAlcoholGraphqlService.regionName(alcohol); + return curationAlcoholGraphQLService.regionName(alcohol); } @BatchMapping(typeName = "Alcohol", field = "rating") public Map ratings(List alcohols) { Map stats = - curationAlcoholGraphqlService.ratingStats(alcohols); + curationAlcoholGraphQLService.ratingStats(alcohols); return mapByAlcohol(alcohols, alcohol -> ratingStatsOf(stats, alcohol).rating()); } @BatchMapping(typeName = "Alcohol", field = "totalRatingsCount") public Map totalRatingsCounts(List alcohols) { Map stats = - curationAlcoholGraphqlService.ratingStats(alcohols); + curationAlcoholGraphQLService.ratingStats(alcohols); return mapByAlcohol(alcohols, alcohol -> ratingStatsOf(stats, alcohol).totalRatingsCount()); } @BatchMapping(typeName = "Alcohol", field = "reviewCount") public Map reviewCounts(List alcohols) { - Map counts = curationAlcoholGraphqlService.reviewCounts(alcohols); + Map counts = curationAlcoholGraphQLService.reviewCounts(alcohols); return mapByAlcohol(alcohols, alcohol -> counts.getOrDefault(alcohol.getId(), 0L)); } @BatchMapping(typeName = "Alcohol", field = "totalPickCount") public Map totalPickCounts(List alcohols) { - Map counts = curationAlcoholGraphqlService.pickCounts(alcohols); + Map counts = curationAlcoholGraphQLService.pickCounts(alcohols); return mapByAlcohol(alcohols, alcohol -> counts.getOrDefault(alcohol.getId(), 0L)); } - public Double rating(Alcohol alcohol) { - return curationAlcoholGraphqlService.rating(alcohol); - } - - public Long totalRatingsCount(Alcohol alcohol) { - return curationAlcoholGraphqlService.totalRatingsCount(alcohol); - } - - public Long reviewCount(Alcohol alcohol) { - return curationAlcoholGraphqlService.reviewCount(alcohol); - } - - public Long totalPickCount(Alcohol alcohol) { - return curationAlcoholGraphqlService.totalPickCount(alcohol); - } - private Map mapByAlcohol(List alcohols, Function mapper) { if (alcohols == null || alcohols.isEmpty()) { return Map.of(); diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationGraphqlExecutor.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationGraphqlExecutor.java deleted file mode 100644 index b0526e343..000000000 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationGraphqlExecutor.java +++ /dev/null @@ -1,8 +0,0 @@ -package app.bottlenote.curation.service; - -import java.util.Map; - -public interface CurationGraphqlExecutor { - - Map execute(Long curationId, int index, SpecGraphqlQueryBuilder.Result query); -} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java index f490ba544..2b150f5c9 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java @@ -23,21 +23,21 @@ public class CurationResponseMaterializer { private static final String JSON_PATH_ROOT = "$"; private final ObjectMapper objectMapper; - private final SpecGraphqlQueryBuilder queryBuilder; - private final CurationGraphqlExecutor graphqlExecutor; + private final GraphQLCurationQueryBuilder queryBuilder; + private final GraphQLCurationExecutor graphqlExecutor; private final CurationPayloadValidator payloadValidator; public Object materialize( Long curationId, String specCode, Map responseSpec, Object payload) { JsonNode payloadNode = objectMapper.valueToTree(payload); JsonNode responseSpecNode = objectMapper.valueToTree(responseSpec); - List queries = + List queries = queryBuilder.build(responseSpecNode, payloadNode); JsonNode hydrated = payloadNode; for (int i = 0; i < queries.size(); i++) { Map result = graphqlExecutor.execute(curationId, i, queries.get(i)); - assertNoGraphqlErrors(curationId, specCode, queries.get(i), result); + assertNoGraphQLErrors(curationId, specCode, queries.get(i), result); hydrated = applyHydration(hydrated, queries.get(i), result); } @@ -55,10 +55,10 @@ public Object materialize( return materialized; } - private void assertNoGraphqlErrors( + private void assertNoGraphQLErrors( Long curationId, String specCode, - SpecGraphqlQueryBuilder.Result query, + GraphQLCurationQueryBuilder.Result query, Map result) { if (result == null || !(result.get("errors") instanceof List errors) || errors.isEmpty()) { return; @@ -76,7 +76,7 @@ private void assertNoGraphqlErrors( @SuppressWarnings("unchecked") private JsonNode applyHydration( - JsonNode payload, SpecGraphqlQueryBuilder.Result query, Map result) { + JsonNode payload, GraphQLCurationQueryBuilder.Result query, Map result) { if (payload == null || result == null || !(result.get("data") instanceof Map data)) { return payload; } @@ -93,7 +93,7 @@ private JsonNode applyHydration( } JsonNode rootCopy = payload.deepCopy(); - JsonNode subtree = SpecGraphqlQueryBuilder.navigate(rootCopy, query.payloadPath()); + JsonNode subtree = GraphQLCurationQueryBuilder.navigate(rootCopy, query.payloadPath()); JsonNode merged = mergeSubtree(subtree, query, byKey); if (merged != null) { setAtPath(rootCopy, query.payloadPath(), merged); @@ -127,7 +127,7 @@ private Map> indexByResultKey(List list, String r private JsonNode mergeSubtree( JsonNode subtree, - SpecGraphqlQueryBuilder.Result query, + GraphQLCurationQueryBuilder.Result query, Map> byKey) { if (subtree == null) { return null; @@ -145,13 +145,13 @@ private JsonNode mergeSubtree( private JsonNode mergeElement( JsonNode source, - SpecGraphqlQueryBuilder.Result query, + GraphQLCurationQueryBuilder.Result query, Map> byKey) { if (!source.isObject()) { return source; } ObjectNode node = ((ObjectNode) source).deepCopy(); - JsonNode joinNode = SpecGraphqlQueryBuilder.navigate(node, query.joinPath()); + JsonNode joinNode = GraphQLCurationQueryBuilder.navigate(node, query.joinPath()); if (joinNode == null || joinNode.isNull()) { if (query.writeTo() != null && !node.has(query.writeTo())) { node.set(query.writeTo(), objectMapper.nullNode()); @@ -177,7 +177,7 @@ private JsonNode pickHydration( Map> byKey, String writeMode, String resultKey) { - if (SpecGraphqlQueryBuilder.WRITE_MODE_SINGLE.equals(writeMode)) { + if (GraphQLCurationQueryBuilder.WRITE_MODE_SINGLE.equals(writeMode)) { Object key = joinNode.isArray() ? firstScalar(joinNode) : jsonScalar(joinNode); Map hit = key == null ? null : byKey.get(normalizeKey(key)); return hit == null diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationAlcoholGraphqlService.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLCurationAlcoholService.java similarity index 77% rename from bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationAlcoholGraphqlService.java rename to bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLCurationAlcoholService.java index 2df3be819..d77c7072a 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationAlcoholGraphqlService.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLCurationAlcoholService.java @@ -23,7 +23,7 @@ @Service @RequiredArgsConstructor @Transactional(readOnly = true) -public class CurationAlcoholGraphqlService { +public class GraphQLCurationAlcoholService { private final AlcoholQueryRepository alcoholQueryRepository; private final RatingRepository ratingRepository; @@ -56,43 +56,6 @@ public String regionName(Alcohol alcohol) { return alcohol.getRegion().getKorName(); } - @Transactional(readOnly = true) - public Double rating(Alcohol alcohol) { - Long alcoholId = alcoholIdOf(alcohol); - if (alcoholId == null) { - return 0.0; - } - return ratingRepository.findAverageRatingByAlcoholId(alcoholId); - } - - @Transactional(readOnly = true) - public Long totalRatingsCount(Alcohol alcohol) { - Long alcoholId = alcoholIdOf(alcohol); - if (alcoholId == null) { - return 0L; - } - return ratingRepository.countByAlcoholId(alcoholId); - } - - @Transactional(readOnly = true) - public Long reviewCount(Alcohol alcohol) { - Long alcoholId = alcoholIdOf(alcohol); - if (alcoholId == null) { - return 0L; - } - return reviewRepository.countByAlcoholIdAndActiveStatusAndStatus( - alcoholId, ReviewActiveStatus.ACTIVE, ReviewDisplayStatus.PUBLIC); - } - - @Transactional(readOnly = true) - public Long totalPickCount(Alcohol alcohol) { - Long alcoholId = alcoholIdOf(alcohol); - if (alcoholId == null) { - return 0L; - } - return picksRepository.countByAlcoholIdAndStatus(alcoholId, PicksStatus.PICK); - } - @Transactional(readOnly = true) public Map ratingStats(List alcohols) { List alcoholIds = alcoholIdsOf(alcohols); diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLCurationExecutor.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLCurationExecutor.java new file mode 100644 index 000000000..eb56d31a4 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLCurationExecutor.java @@ -0,0 +1,8 @@ +package app.bottlenote.curation.service; + +import java.util.Map; + +public interface GraphQLCurationExecutor { + + Map execute(Long curationId, int index, GraphQLCurationQueryBuilder.Result query); +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpecGraphqlQueryBuilder.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLCurationQueryBuilder.java similarity index 99% rename from bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpecGraphqlQueryBuilder.java rename to bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLCurationQueryBuilder.java index fe9555263..0807e2f8e 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpecGraphqlQueryBuilder.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLCurationQueryBuilder.java @@ -10,7 +10,7 @@ import org.springframework.stereotype.Component; @Component -public class SpecGraphqlQueryBuilder { +public class GraphQLCurationQueryBuilder { static final String WRITE_MODE_ARRAY = "array"; static final String WRITE_MODE_SINGLE = "single"; diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLSpringCurationExecutor.java similarity index 94% rename from bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java rename to bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLSpringCurationExecutor.java index d88fc2f6a..143a450b2 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpringCurationGraphqlExecutor.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLSpringCurationExecutor.java @@ -17,7 +17,7 @@ @Component @RequiredArgsConstructor @Slf4j -public class SpringCurationGraphqlExecutor implements CurationGraphqlExecutor { +public class GraphQLSpringCurationExecutor implements GraphQLCurationExecutor { private static final Duration GRAPHQL_EXECUTION_TIMEOUT = Duration.ofSeconds(3); @@ -25,7 +25,7 @@ public class SpringCurationGraphqlExecutor implements CurationGraphqlExecutor { @Override public Map execute( - Long curationId, int index, SpecGraphqlQueryBuilder.Result query) { + Long curationId, int index, GraphQLCurationQueryBuilder.Result query) { ExecutionGraphQlRequest request = new DefaultExecutionGraphQlRequest( query.query(), diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolverTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/GraphQLCurationAlcoholResolverTest.java similarity index 94% rename from bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolverTest.java rename to bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/GraphQLCurationAlcoholResolverTest.java index e1bfb73d0..30781cb85 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/CurationAlcoholGraphqlResolverTest.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/graphql/GraphQLCurationAlcoholResolverTest.java @@ -7,7 +7,7 @@ import app.bottlenote.alcohols.domain.Alcohol; import app.bottlenote.alcohols.domain.Region; import app.bottlenote.alcohols.fixture.InMemoryAlcoholQueryRepository; -import app.bottlenote.curation.service.CurationAlcoholGraphqlService; +import app.bottlenote.curation.service.GraphQLCurationAlcoholService; import app.bottlenote.global.service.cursor.PageResponse; import app.bottlenote.picks.constant.PicksStatus; import app.bottlenote.picks.domain.Picks; @@ -37,7 +37,7 @@ import org.junit.jupiter.api.Test; @Tag("unit") -class CurationAlcoholGraphqlResolverTest { +class GraphQLCurationAlcoholResolverTest { @Test @DisplayName("MANUAL 항목처럼 alcoholId가 null이면 GraphQL 조회에서 제외하고 실제 도메인 통계를 반환한다") @@ -46,9 +46,9 @@ void alcohols_whenManualItemAlcoholIdIsNull_excludesNullAndMissingIdsAndResolves FakeRatingRepository ratingRepository = new FakeRatingRepository(); InMemoryReviewRepository reviewRepository = new InMemoryReviewRepository(); FakePicksRepository picksRepository = new FakePicksRepository(); - CurationAlcoholGraphqlResolver resolver = - new CurationAlcoholGraphqlResolver( - new CurationAlcoholGraphqlService( + GraphQLCurationAlcoholResolver resolver = + new GraphQLCurationAlcoholResolver( + new GraphQLCurationAlcoholService( alcoholRepository, ratingRepository, reviewRepository, picksRepository)); Alcohol alcohol = alcohol(1L); @@ -69,10 +69,6 @@ void alcohols_whenManualItemAlcoholIdIsNull_excludesNullAndMissingIdsAndResolves assertThat(manualOnly).isEmpty(); assertThat(resolver.alcoholId(alcohol)).isEqualTo(1L); assertThat(resolver.regionName(alcohol)).isEqualTo("스코틀랜드"); - assertThat(resolver.rating(alcohol)).isEqualTo(4.0); - assertThat(resolver.totalRatingsCount(alcohol)).isEqualTo(2L); - assertThat(resolver.reviewCount(alcohol)).isEqualTo(1L); - assertThat(resolver.totalPickCount(alcohol)).isEqualTo(1L); assertThat(resolver.ratings(alcohols)).containsEntry(alcohol, 4.0); assertThat(resolver.totalRatingsCounts(alcohols)).containsEntry(alcohol, 2L); assertThat(resolver.reviewCounts(alcohols)).containsEntry(alcohol, 1L); diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java index 2bd3e4685..74dd12385 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java @@ -28,8 +28,8 @@ class CurationResponseMaterializerTest { @Test @DisplayName("root array payload는 responseSpec.x-graphql 기준으로 BOTTLE_NOTE stats만 보강한다") void materialize_whenRootArrayPayload_hydratesBottleNoteStatsOnly() throws IOException { - FakeCurationGraphqlExecutor executor = - new FakeCurationGraphqlExecutor( + FakeGraphQLCurationExecutor executor = + new FakeGraphQLCurationExecutor( List.of( map( "alcoholId", @@ -67,8 +67,8 @@ void materialize_whenRootArrayPayload_hydratesBottleNoteStatsOnly() throws IOExc @Test @DisplayName("object payload의 payloadPath=$.alcohols는 하위 alcohols 배열에만 stats를 보강한다") void materialize_whenNestedPayloadPath_hydratesOnlyAlcoholSubtree() throws IOException { - FakeCurationGraphqlExecutor executor = - new FakeCurationGraphqlExecutor( + FakeGraphQLCurationExecutor executor = + new FakeGraphQLCurationExecutor( List.of( map( "alcoholId", @@ -122,8 +122,8 @@ void materialize_whenNestedPayloadPath_hydratesOnlyAlcoholSubtree() throws IOExc @Test @DisplayName("GraphQL 실행 errors가 있으면 부분 응답을 만들지 않고 실패한다") - void materialize_whenGraphqlResultHasErrors_throwsExecutionFailed() throws IOException { - CurationResponseMaterializer materializer = materializer(new ErrorGraphqlExecutor()); + void materialize_whenGraphQLResultHasErrors_throwsExecutionFailed() throws IOException { + CurationResponseMaterializer materializer = materializer(new ErrorGraphQLCurationExecutor()); List> payload = List.of( item( @@ -142,10 +142,10 @@ void materialize_whenGraphqlResultHasErrors_throwsExecutionFailed() throws IOExc "exceptionCode", CurationExceptionCode.CURATION_GRAPHQL_EXECUTION_FAILED); } - private static CurationResponseMaterializer materializer(CurationGraphqlExecutor executor) { + private static CurationResponseMaterializer materializer(GraphQLCurationExecutor executor) { return new CurationResponseMaterializer( OBJECT_MAPPER, - new SpecGraphqlQueryBuilder(), + new GraphQLCurationQueryBuilder(), executor, new CurationPayloadValidator(OBJECT_MAPPER)); } @@ -176,32 +176,32 @@ private static Map map(Object... values) { return map; } - private static final class FakeCurationGraphqlExecutor implements CurationGraphqlExecutor { + private static final class FakeGraphQLCurationExecutor implements GraphQLCurationExecutor { private final List> alcohols; - private final List executedQueries = new ArrayList<>(); + private final List executedQueries = new ArrayList<>(); - FakeCurationGraphqlExecutor(List> alcohols) { + FakeGraphQLCurationExecutor(List> alcohols) { this.alcohols = alcohols; } @Override public Map execute( - Long curationId, int index, SpecGraphqlQueryBuilder.Result query) { + Long curationId, int index, GraphQLCurationQueryBuilder.Result query) { executedQueries.add(query); return map("data", map(query.entryField(), alcohols)); } - List executedQueries() { + List executedQueries() { return executedQueries; } } - private static final class ErrorGraphqlExecutor implements CurationGraphqlExecutor { + private static final class ErrorGraphQLCurationExecutor implements GraphQLCurationExecutor { @Override public Map execute( - Long curationId, int index, SpecGraphqlQueryBuilder.Result query) { + Long curationId, int index, GraphQLCurationQueryBuilder.Result query) { return map("errors", List.of(map("message", "forced graphql error"))); } } diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java index e46c58a60..1ace40adf 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/ProductSpecBasedCurationServiceTest.java @@ -49,8 +49,8 @@ void setUp() { CurationResponseMaterializer materializer = new CurationResponseMaterializer( OBJECT_MAPPER, - new SpecGraphqlQueryBuilder(), - new FixedGraphqlExecutor(), + new GraphQLCurationQueryBuilder(), + new FixedGraphQLCurationExecutor(), new CurationPayloadValidator(OBJECT_MAPPER)); productService = new ProductSpecBasedCurationService( @@ -194,11 +194,11 @@ private static Map map(Object... values) { return map; } - private static final class FixedGraphqlExecutor implements CurationGraphqlExecutor { + private static final class FixedGraphQLCurationExecutor implements GraphQLCurationExecutor { @Override public Map execute( - Long curationId, int index, SpecGraphqlQueryBuilder.Result query) { + Long curationId, int index, GraphQLCurationQueryBuilder.Result query) { return map( "data", map( diff --git a/bottlenote-mono/src/test/java/app/bottlenote/graphql/CurationGraphqlSchemaTest.java b/bottlenote-mono/src/test/java/app/bottlenote/graphql/GraphQLCurationSchemaTest.java similarity index 97% rename from bottlenote-mono/src/test/java/app/bottlenote/graphql/CurationGraphqlSchemaTest.java rename to bottlenote-mono/src/test/java/app/bottlenote/graphql/GraphQLCurationSchemaTest.java index a45188ff5..3eb143bd1 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/graphql/CurationGraphqlSchemaTest.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/graphql/GraphQLCurationSchemaTest.java @@ -12,7 +12,7 @@ import org.springframework.core.io.ClassPathResource; @Tag("unit") -class CurationGraphqlSchemaTest { +class GraphQLCurationSchemaTest { @Test @DisplayName("큐레이션 GraphQL SDL은 Alcohol 통계 조회 필드만 노출한다") diff --git a/plan/spec-based-curation-v2-graphql-sdl.md b/plan/spec-based-curation-v2-graphql-sdl.md index a7af575b4..7b27e2139 100644 --- a/plan/spec-based-curation-v2-graphql-sdl.md +++ b/plan/spec-based-curation-v2-graphql-sdl.md @@ -277,7 +277,7 @@ - `./gradlew check_rule_test` - Files: - `bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationPayloadValidator.java` - - `bottlenote-mono/src/main/java/app/bottlenote/curation/service/SpecGraphqlQueryBuilder.java` + - `bottlenote-mono/src/main/java/app/bottlenote/curation/service/GraphQLCurationQueryBuilder.java` - `bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java` - `bottlenote-mono/src/main/java/app/bottlenote/curation/service/ProductSpecBasedCurationService.java` - `bottlenote-product-api/src/main/java/app/bottlenote/curation/controller/ProductSpecBasedCurationController.java` @@ -309,15 +309,15 @@ ## Progress Log - 2026-05-15 Task 1 완료: Spring GraphQL starter alias를 version catalog에 추가하고, `bottlenote-mono`에 GraphQL runtime dependency를 연결했다. SDL 경로는 `bottlenote-mono/src/main/resources/graphql/schema.graphqls`로 확정했다. 검증: `./gradlew :bottlenote-mono:compileJava` 성공, `./gradlew :bottlenote-product-api:compileJava` 성공, `git diff -- git.environment-variables/storage/mysql/changelog/` 변경 없음. -- 2026-05-15 Task 2 완료: `bottlenote-mono/src/main/resources/graphql/schema.graphqls`에 `Query.alcohols(ids: [ID!]!)`와 stats hydration용 `Alcohol` SDL을 추가했다. 사용자별 `picks`, `ratings`, `reviews` 목록 field는 포함하지 않았다. 검증: `rg -n "type Alcohol|type Query|alcohols|picks\\(|ratings\\(|reviews\\(" ...` 확인, `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.graphql.CurationGraphqlSchemaTest'` 성공, changelog diff 변경 없음. -- 2026-05-15 Task 3 완료: `bottlenote-mono`에 `CurationAlcoholGraphqlResolver`와 `CurationAlcoholGraphqlService`를 추가해 `Alcohol` field resolver를 연결했다. `rating`/`totalRatingsCount`는 rating repository 집계, `reviewCount`는 `ACTIVE` + `PUBLIC` review count, `totalPickCount`는 `PICK` 상태 count로 계산한다. `alcoholId = null`인 `MANUAL` 항목과 존재하지 않는 alcohol id는 GraphQL 조회 결과에서 제외하는 정책을 resolver 테스트명과 검증에 남겼다. 검증: `./gradlew :bottlenote-mono:compileJava` 성공, `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.graphql.CurationGraphqlSchemaTest' --tests 'app.bottlenote.curation.graphql.CurationAlcoholGraphqlResolverTest'` 성공, `./gradlew :bottlenote-product-api:compileJava` 성공, `git diff -- git.environment-variables/storage/mysql/changelog/` 변경 없음. +- 2026-05-15 Task 2 완료: `bottlenote-mono/src/main/resources/graphql/schema.graphqls`에 `Query.alcohols(ids: [ID!]!)`와 stats hydration용 `Alcohol` SDL을 추가했다. 사용자별 `picks`, `ratings`, `reviews` 목록 field는 포함하지 않았다. 검증: `rg -n "type Alcohol|type Query|alcohols|picks\\(|ratings\\(|reviews\\(" ...` 확인, `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.graphql.GraphQLCurationSchemaTest'` 성공, changelog diff 변경 없음. +- 2026-05-15 Task 3 완료: `bottlenote-mono`에 `GraphQLCurationAlcoholResolver`와 `GraphQLCurationAlcoholService`를 추가해 `Alcohol` field resolver를 연결했다. `rating`/`totalRatingsCount`는 rating repository 집계, `reviewCount`는 `ACTIVE` + `PUBLIC` review count, `totalPickCount`는 `PICK` 상태 count로 계산한다. `alcoholId = null`인 `MANUAL` 항목과 존재하지 않는 alcohol id는 GraphQL 조회 결과에서 제외하는 정책을 resolver 테스트명과 검증에 남겼다. 검증: `./gradlew :bottlenote-mono:compileJava` 성공, `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.graphql.GraphQLCurationSchemaTest' --tests 'app.bottlenote.curation.graphql.GraphQLCurationAlcoholResolverTest'` 성공, `./gradlew :bottlenote-product-api:compileJava` 성공, `git diff -- git.environment-variables/storage/mysql/changelog/` 변경 없음. - 2026-05-15 추가 반영: `curation_demo/spec`의 OpenAPI 3.0 JSON 스펙 3종을 `bottlenote-mono/src/main/resources/openapi/curation/`에 그대로 추가했다. 대상은 `RECOMMENDED_WHISKY`, `WHISKY_PAIRING`, `WHISKY_TASTING_EVENT`이며 `x-curation`, `x-form-style`, `x-field-style`, `x-graphql` 메타를 포함한다. 검증: 원본 파일과 `cmp -s` 3건 일치, `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.CurationOpenApiSpecResourceTest'` 성공. - 2026-05-15 Task 4 완료: `.env`에 `SPRING_PROFILES_ACTIVE=local`을 추가하고 Redis를 로컬 `bottle-note-redis` 컨테이너(`localhost:26379`, no auth)로 연결하도록 수정했다. `set -a; source .env; set +a; ./gradlew :bottlenote-product-api:bootRun`으로 product API가 8080에서 기동했고, 로그에서 GraphQL schema 1개 로드, unmapped field 없음, `POST /graphql` 매핑, Redis connection success를 확인했다. smoke 결과: `GET /actuator/health` HTTP 200 및 Redis UP, `POST /graphql { __typename }` HTTP 200, 기존 `GET /api/v1/curations?cursor=0&pageSize=1` HTTP 200, changelog diff 변경 없음. - 2026-05-15 GraphiQL 운영 확인: `spring.graphql.graphiql.enabled=true`, `spring.graphql.graphiql.path=/graphiql`를 local/default profile에 추가해 브라우저 기반 GraphQL query console을 열 수 있게 했다. `GET /graphql`은 HTTP 405가 맞고, query 실행은 `POST /graphql` 또는 `/graphiql` UI를 사용한다. 2026-05-17 운영 하드닝에서 이 결정은 철회했다. 현재는 GraphQL을 내부 hydration boundary로만 유지하기 위해 GraphiQL을 비활성화하고 `/graphql`, `/graphiql`, `/graphiql/**` 외부 HTTP 접근을 403으로 차단한다. - 2026-05-15 GraphQL browser smoke: Chrome에서 `/graphiql?path=/graphql`로 직접 쿼리를 실행했다. `[1, 999999]`는 존재하는 `1`만 반환했고, `[1, 1, 2]`는 중복 제거 후 `1, 2`만 반환했다. `[]`는 빈 배열을 반환했다. `[3, 1, 999999, 1, 2]`는 요청 순서 기준으로 `3, 1, 2`를 반환했고 없는 id와 중복 id를 제외했다. - 2026-05-15 GraphQL boundary smoke: Chrome에서 `picks` field 요청 시 `Field 'picks' in type 'Alcohol' is undefined` validation error가 발생했다. `[1, null]` 입력은 `[ID!]!` 제약에 의해 `ids[1] ... must not be null` validation error가 발생했다. `engName`, `imageUrl`, `regionName`, `korCategory`, `cask`, `abv`, `volume`, `rating`, `totalRatingsCount`, `reviewCount`, `totalPickCount` 전체 field hydration도 정상 확인했다. - 2026-05-15 Task 5 완료: final verification 중 `check_rule_test`가 먼저 product-api 테스트 fake repository compile error로 실패했다. 원인은 `PicksRepository`, `RatingRepository`, `ReviewRepository`에 Phase 1 stats count 메서드를 추가하면서 product-api 테스트 fake 3곳이 새 인터페이스 시그니처를 구현하지 않은 것이었다. `FakePicksRepository`, `InMemoryRatingRepository`, `InMemoryReviewRepository`에 count/average 메서드를 추가했다. -- 2026-05-15 Task 5 완료: 두 번째 `check_rule_test` 실패는 GraphQL resolver의 `@Controller`가 REST controller ArchUnit 규칙에 포함된 것이 원인이었다. GraphQL handler는 HTTP mapping 기반 REST controller가 아니므로 `ControllerLayerRules`에서 `..graphql..` 패키지를 REST controller naming/mapping/method naming rule 대상에서 제외했다. 또한 `CurationAlcoholGraphqlService` public 메서드에는 프로젝트 rule에 맞춰 `@Transactional(readOnly = true)`를 메서드 레벨로 명시했다. +- 2026-05-15 Task 5 완료: 두 번째 `check_rule_test` 실패는 GraphQL resolver의 `@Controller`가 REST controller ArchUnit 규칙에 포함된 것이 원인이었다. GraphQL handler는 HTTP mapping 기반 REST controller가 아니므로 `ControllerLayerRules`에서 `..graphql..` 패키지를 REST controller naming/mapping/method naming rule 대상에서 제외했다. 또한 `GraphQLCurationAlcoholService` public 메서드에는 프로젝트 rule에 맞춰 `@Transactional(readOnly = true)`를 메서드 레벨로 명시했다. - 2026-05-15 Task 5 검증 결과: `./gradlew :bottlenote-mono:compileJava` 성공, `./gradlew :bottlenote-product-api:compileJava` 성공, focused tests 3종 성공, `./gradlew check_rule_test` 성공, `git diff -- git.environment-variables/storage/mysql/changelog/` 변경 없음. Phase 1은 종료 가능한 상태로 확인했다. - 2026-05-15 Phase 2 Task 1 완료: `git.environment-variables/storage/mysql/changelog/schema.mysql.sql`에 `curation_spec`, `curation`, `curation_extension` changeset 3개를 추가했다. SOPS 기반 Liquibase 설정은 임시 파일로만 사용했고 secret 값은 출력하지 않았다. 개발 DB와 운영 DB 모두 `validate` 성공, pending 3건 확인 후 `update` 3건 실행, 세 테이블 생성 확인, 최종 `status --verbose` up to date를 확인했다. - 2026-05-15 Phase 2 Task 3 추가 완료: Liquibase insert seed 대신 admin-api startup resource sync를 추가했다. `CurationSpecResourceReader`가 `bottlenote-mono/src/main/resources/openapi/curation/*.json` 3종을 읽고, `CurationSpecResourceSyncService`가 `code` 기준으로 `curation_spec`을 생성 또는 갱신한다. admin-api runner는 `curation.spec-sync.enabled=${CURATION_SPEC_SYNC_ENABLED:true}`로 제어된다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-admin-api:compileKotlin :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationSpecResourceSyncServiceTest'` 성공, `./gradlew check_rule_test` 성공. @@ -328,11 +328,13 @@ - 2026-05-17 Copilot review 대응 완료: GraphiQL default/local 비활성화, `/graphql`/`/graphiql`/`/graphiql/**` denyAll 차단, GraphQL stats field N+1 제거를 위한 `@BatchMapping` + `IN ... GROUP BY` 집계, Curation create/update Bean Validation enum message 수정을 반영했다. Copilot review thread 4건은 코드 확인 후 GitHub에서 resolved 처리했다. 검증: `/verify full` 범위로 compile, rule, unit, build, integration, admin integration 모두 성공. - 2026-05-17 Product V2 Runtime Hardening 완료: Product v2 목록/상세에 `isActive = true`와 `exposureStartDate <= today <= exposureEndDate` 정책을 적용했다. `exposureStartDate` 또는 `exposureEndDate`가 null이면 열린 구간으로 처리한다. GraphQL executor가 null response 또는 execution errors를 반환하면 부분 응답을 만들지 않고 `CURATION_GRAPHQL_EXECUTION_FAILED`로 fail-closed 처리한다. responseSpec 검증 실패 시 내부 로그에 `curationId`, `specCode`, validator error path를 남긴다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-product-api:compileJava :bottlenote-mono:compileTestJava :bottlenote-product-api:compileTestJava` 성공, focused unit/integration + `check_rule_test` 성공. - 2026-05-18 리팩토링 완료: `CurationV2Service`와 `CurationSpecCreateRequest`를 제거해 검증 없는 운영 저장 경로를 닫았다. 단위 테스트의 spec/curation 생성은 `CurationFixtureFactory`로 이동했고, 실제 Admin 저장 경로는 `AdminSpecBasedCurationService`로 단일화했다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-mono:compileTestJava` 성공, focused curation unit 13개 성공, `./gradlew check_rule_test` 성공, `./gradlew unit_test` 성공. +- 2026-05-18 GraphQL prefix 리팩토링 완료: GraphQL 관련 클래스명을 `GraphQL*` prefix로 통일하고, annotation 없는 단건 Alcohol field resolver/service 메서드 4개를 제거해 batch mapping 경로만 남겼다. 검증: `./gradlew :bottlenote-mono:compileJava :bottlenote-mono:compileTestJava` 성공, focused GraphQL/curation unit 9개 성공, `./gradlew check_rule_test` 성공. ## Current Decision Summary - Phase 1의 GraphQL boundary는 외부 공개 curation endpoint가 아니라 서버 내부 hydration 기반으로 둔다. - 현재 SDL은 `Query.alcohols(ids: [ID!]!)`와 `Alcohol` 표시/stats field만 노출한다. +- GraphQL 관련 구현 클래스명은 화면 정렬과 검색 일관성을 위해 `GraphQL*` prefix를 사용한다. - 사용자별 원본 목록 field(`picks`, `reviews`, `ratings`)는 SDL에 노출하지 않는다. - 없는 alcohol id는 전체 요청 실패가 아니라 결과에서 제외한다. - 중복 alcohol id는 resolver service에서 제거하며, 반환 순서는 최초 요청 순서를 따른다. From e48385c4e4160a80637a9ccdbd2dc0ff676645fc Mon Sep 17 00:00:00 2001 From: hgkim Date: Mon, 18 May 2026 15:05:20 +0900 Subject: [PATCH 25/33] =?UTF-8?q?docs:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20HTTP=20=EC=98=88=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...53\240\210\354\235\264\354\205\230v2.http" | 268 ++++++++++++++++++ http/admin/http-client.env.json | 2 + ...53\240\210\354\235\264\354\205\230v2.http" | 39 +++ 3 files changed, 309 insertions(+) create mode 100644 "http/admin/05_\355\201\220\353\240\210\354\235\264\354\205\230\352\264\200\353\246\254/\354\212\244\355\216\231\352\270\260\353\260\230\355\201\220\353\240\210\354\235\264\354\205\230v2.http" create mode 100644 "http/product/02_\354\234\204\354\212\244\355\202\244\355\203\220\354\203\211/\354\234\204\354\212\244\355\202\244\354\260\276\352\270\260/\355\201\220\353\240\210\354\235\264\354\205\230v2.http" diff --git "a/http/admin/05_\355\201\220\353\240\210\354\235\264\354\205\230\352\264\200\353\246\254/\354\212\244\355\216\231\352\270\260\353\260\230\355\201\220\353\240\210\354\235\264\354\205\230v2.http" "b/http/admin/05_\355\201\220\353\240\210\354\235\264\354\205\230\352\264\200\353\246\254/\354\212\244\355\216\231\352\270\260\353\260\230\355\201\220\353\240\210\354\235\264\354\205\230v2.http" new file mode 100644 index 000000000..ac52e8ba2 --- /dev/null +++ "b/http/admin/05_\355\201\220\353\240\210\354\235\264\354\205\230\352\264\200\353\246\254/\354\212\244\355\216\231\352\270\260\353\260\230\355\201\220\353\240\210\354\235\264\354\205\230v2.http" @@ -0,0 +1,268 @@ +### 로그인 +# v1 인증 API로 토큰을 받은 뒤 v2 큐레이션 관리 API를 호출한다. +POST {{host}}/auth/login +Content-Type: application/json + +{ + "email": "{{email}}", + "password": "{{password}}" +} + +> {% + client.global.set("accessToken", response.body.data.accessToken); + client.global.set("refreshToken", response.body.data.refreshToken); +%} + +### 1. 큐레이션 스펙 목록 조회 +# @no-cookie-jar +GET {{adminApiHost}}/v2/curation-specs +Authorization: Bearer {{accessToken}} + +> {% + const specs = response.body.data || []; + const recommended = specs.find((spec) => spec.code === "RECOMMENDED_WHISKY"); + const pairing = specs.find((spec) => spec.code === "WHISKY_PAIRING"); + const tasting = specs.find((spec) => spec.code === "WHISKY_TASTING_EVENT"); + + if (recommended) client.global.set("recommendedWhiskySpecId", recommended.id); + if (pairing) client.global.set("whiskyPairingSpecId", pairing.id); + if (tasting) client.global.set("whiskyTastingEventSpecId", tasting.id); +%} + +### 2. 큐레이션 스펙 상세 조회 +# @no-cookie-jar +@specId = {{recommendedWhiskySpecId}} +GET {{adminApiHost}}/v2/curation-specs/{{specId}} +Authorization: Bearer {{accessToken}} + +### 3. spec 기반 큐레이션 목록 조회 +# @no-cookie-jar +GET {{adminApiHost}}/v2/curations?keyword=&isActive=true&page=0&size=20 +Authorization: Bearer {{accessToken}} + +> {% + const page = response.body.data || {}; + const content = page.content || page.items || []; + if (content.length > 0) { + client.global.set("curationV2Id", content[0].id); + } +%} + +### 4. spec 기반 큐레이션 상세 조회 +# @no-cookie-jar +@curationId = {{curationV2Id}} +GET {{adminApiHost}}/v2/curations/{{curationId}} +Authorization: Bearer {{accessToken}} + +### 5. 추천 위스키 큐레이션 생성 +# @no-cookie-jar +POST {{adminApiHost}}/v2/curations +Content-Type: application/json +Authorization: Bearer {{accessToken}} + +{ + "specId": {{recommendedWhiskySpecId}}, + "name": "비 오는 날 위스키", + "description": "스모키 위스키 추천", + "imageUrls": [ + "https://cdn.example.com/curation/rainy-whisky-cover.jpg" + ], + "exposureStartDate": "2026-06-01", + "exposureEndDate": "2026-06-30", + "displayOrder": 1, + "isActive": true, + "payload": [ + { + "source": "BOTTLE_NOTE", + "alcohol": { + "alcoholId": 1, + "korName": "검증 위스키", + "selectedTags": ["셰리", "오크"] + }, + "comment": "비 오는 날 천천히 마시기 좋은 위스키" + }, + { + "source": "MANUAL", + "alcohol": { + "alcoholId": null, + "korName": "수동 입력 위스키", + "selectedTags": ["스모키"] + }, + "comment": "외부 데이터 없이 직접 노출하는 항목" + } + ] +} + +> {% + if (response.body.data && response.body.data.targetId) { + client.global.set("curationV2Id", response.body.data.targetId); + } +%} + +### 6. 추천 위스키 큐레이션 수정 +# @no-cookie-jar +PUT {{adminApiHost}}/v2/curations/{{curationV2Id}} +Content-Type: application/json +Authorization: Bearer {{accessToken}} + +{ + "specId": {{recommendedWhiskySpecId}}, + "name": "수정된 비 오는 날 위스키", + "description": "request spec 검증을 통과하는 수정 요청", + "imageUrls": [ + "https://cdn.example.com/curation/rainy-whisky-cover.jpg", + "https://cdn.example.com/curation/rainy-whisky-second.jpg" + ], + "exposureStartDate": "2026-06-01", + "exposureEndDate": "2026-06-30", + "displayOrder": 2, + "isActive": true, + "payload": [ + { + "source": "BOTTLE_NOTE", + "alcohol": { + "alcoholId": 1, + "korName": "검증 위스키", + "selectedTags": ["셰리", "오크", "스모키"] + }, + "comment": "수정된 추천 코멘트" + } + ] +} + +### 7. 위스키 페어링 큐레이션 생성 +# @no-cookie-jar +POST {{adminApiHost}}/v2/curations +Content-Type: application/json +Authorization: Bearer {{accessToken}} + +{ + "specId": {{whiskyPairingSpecId}}, + "name": "디저트 페어링 위스키", + "description": "위스키와 어울리는 디저트 페어링", + "imageUrls": [ + "https://cdn.example.com/curation/pairing-cover.jpg" + ], + "exposureStartDate": "2026-06-01", + "exposureEndDate": "2026-06-30", + "displayOrder": 3, + "isActive": true, + "payload": [ + { + "source": "BOTTLE_NOTE", + "alcohol": { + "alcoholId": 1, + "korName": "글렌드로낙 오리지널 12년", + "selectedTags": ["셰리", "건포도", "오크"] + }, + "comment": "셰리 캐스크 입문용으로 추천", + "pairings": [ + { + "itemName": "부드러운 티라미수 초콜릿", + "itemImageUrl": "https://images.example.com/pairing/tiramisu.jpg", + "pairingNote": "진한 초콜릿 향이 위스키의 단맛과 이어진다." + } + ] + } + ] +} + +### 8. 위스키 시음회 큐레이션 생성 +# @no-cookie-jar +POST {{adminApiHost}}/v2/curations +Content-Type: application/json +Authorization: Bearer {{accessToken}} + +{ + "specId": {{whiskyTastingEventSpecId}}, + "name": "6월 싱글몰트 시음회", + "description": "소규모 위스키 테이스팅 이벤트", + "imageUrls": [ + "https://cdn.example.com/curation/tasting-event-cover.jpg" + ], + "exposureStartDate": "2026-06-01", + "exposureEndDate": "2026-06-30", + "displayOrder": 4, + "isActive": true, + "payload": { + "eventDate": "2026-06-15", + "eventTime": "19:30", + "barAddress": "서울 강남구 테헤란로 123", + "detailAddress": "2층 도시남 바", + "isRecruiting": true, + "entryFee": 0, + "capacity": 12, + "applicationLink": "https://forms.example.com/tasting", + "guideText": "시작 10분 전 입장해 주세요.", + "alcohols": [ + { + "source": "BOTTLE_NOTE", + "alcohol": { + "alcoholId": 1, + "korName": "검증 위스키", + "selectedTags": ["셰리", "오크"] + }, + "comment": "시음회 대표 위스키" + } + ] + } +} + +### 9. 검증 실패 예시 - request spec required 누락 +# @no-cookie-jar +POST {{adminApiHost}}/v2/curations +Content-Type: application/json +Authorization: Bearer {{accessToken}} + +{ + "specId": {{recommendedWhiskySpecId}}, + "name": "필수 필드 누락 테스트", + "description": "payload.source 누락으로 400 기대", + "imageUrls": [ + "https://cdn.example.com/curation/invalid-cover.jpg" + ], + "exposureStartDate": "2026-06-01", + "exposureEndDate": "2026-06-30", + "displayOrder": 99, + "isActive": true, + "payload": [ + { + "alcohol": { + "alcoholId": 1, + "korName": "검증 위스키", + "selectedTags": ["오크"] + }, + "comment": "source가 없어서 실패해야 한다." + } + ] +} + +### 10. 검증 실패 예시 - enum 값 불일치 +# @no-cookie-jar +POST {{adminApiHost}}/v2/curations +Content-Type: application/json +Authorization: Bearer {{accessToken}} + +{ + "specId": {{recommendedWhiskySpecId}}, + "name": "enum 실패 테스트", + "description": "source enum 불일치로 400 기대", + "imageUrls": [ + "https://cdn.example.com/curation/invalid-cover.jpg" + ], + "exposureStartDate": "2026-06-01", + "exposureEndDate": "2026-06-30", + "displayOrder": 100, + "isActive": true, + "payload": [ + { + "source": "UNKNOWN_SOURCE", + "alcohol": { + "alcoholId": 1, + "korName": "검증 위스키", + "selectedTags": ["오크"] + }, + "comment": "source enum이 아니어서 실패해야 한다." + } + ] +} diff --git a/http/admin/http-client.env.json b/http/admin/http-client.env.json index d55a9180e..f2936f938 100644 --- a/http/admin/http-client.env.json +++ b/http/admin/http-client.env.json @@ -1,6 +1,7 @@ { "local": { "host": "http://localhost:8080/admin/api/v1", + "adminApiHost": "http://localhost:8080/admin/api", "email": "admin@bottlenote.com", "password": "password123", "accessToken": "", @@ -8,6 +9,7 @@ }, "dev": { "host": "https://admin-api.development.bottle-note.com/admin/api/v1", + "adminApiHost": "https://admin-api.development.bottle-note.com/admin/api", "email": "bottlenote.official@email.com", "password": "password1234", "accessToken": "", diff --git "a/http/product/02_\354\234\204\354\212\244\355\202\244\355\203\220\354\203\211/\354\234\204\354\212\244\355\202\244\354\260\276\352\270\260/\355\201\220\353\240\210\354\235\264\354\205\230v2.http" "b/http/product/02_\354\234\204\354\212\244\355\202\244\355\203\220\354\203\211/\354\234\204\354\212\244\355\202\244\354\260\276\352\270\260/\355\201\220\353\240\210\354\235\264\354\205\230v2.http" new file mode 100644 index 000000000..86f82a0bf --- /dev/null +++ "b/http/product/02_\354\234\204\354\212\244\355\202\244\355\203\220\354\203\211/\354\234\204\354\212\244\355\202\244\354\260\276\352\270\260/\355\201\220\353\240\210\354\235\264\354\205\230v2.http" @@ -0,0 +1,39 @@ +### 토큰 발급 (일반) +# @no-cookie-jar +POST {{host}}/api/v1/oauth/login +Content-Type: application/json + +{ + "email": "dev.bottle-note@gmail.com", + "socialType": "GOOGLE", + "gender": "MALE", + "age": 25 +} + +> {% + client.global.set("accessToken", response.body.data.accessToken); +%} + +### 1. spec 기반 큐레이션 v2 목록 조회 +# @no-cookie-jar +GET {{host}}/api/v2/curations +Authorization: Bearer {{accessToken}} + +> {% + const curations = response.body.data || []; + if (curations.length > 0) { + client.global.set("curationV2Id", curations[0].id); + } +%} + +### 2. spec 기반 큐레이션 v2 상세 조회 +# @no-cookie-jar +@curationId = {{curationV2Id}} +GET {{host}}/api/v2/curations/{{curationId}} +Authorization: Bearer {{accessToken}} + +### 3. spec 기반 큐레이션 v2 상세 조회 - 직접 ID 지정 +# @no-cookie-jar +@manualCurationId = 1 +GET {{host}}/api/v2/curations/{{manualCurationId}} +Authorization: Bearer {{accessToken}} From 2d9955d258100da4be833637745196ebe1ecb5f0 Mon Sep 17 00:00:00 2001 From: hgkim Date: Mon, 18 May 2026 16:55:23 +0900 Subject: [PATCH 26/33] =?UTF-8?q?test:=20=ED=81=90=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20v2=20=EC=A0=95=EC=B1=85=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin-curations/spec-based-curations.adoc | 52 ++--- .../AdminSpecBasedCurationIntegrationTest.kt | 73 +++++++ .../service/CurationResponseMaterializer.java | 31 ++- .../service/CurationPayloadValidatorTest.java | 120 +++++++++++ .../CurationResponseMaterializerTest.java | 89 ++++++++- ...oductSpecBasedCurationIntegrationTest.java | 59 ++++++ git.environment-variables | 2 +- .../admin-api-v2-curation-endpoints.md | 0 .../curation-v2-display-demo-runbook.md | 29 ++- .../curation-v2-display-demo.md | 13 +- plan/complete/curation-v2-test-hardening.md | 187 ++++++++++++++++++ .../spec-based-curation-v2-graphql-sdl.md | 2 +- 12 files changed, 610 insertions(+), 47 deletions(-) rename plan/{ => complete}/admin-api-v2-curation-endpoints.md (100%) rename plan/{ => complete}/curation-v2-display-demo-runbook.md (67%) rename plan/{ => complete}/curation-v2-display-demo.md (93%) create mode 100644 plan/complete/curation-v2-test-hardening.md rename plan/{ => complete}/spec-based-curation-v2-graphql-sdl.md (99%) diff --git a/bottlenote-admin-api/src/docs/asciidoc/api/admin-curations/spec-based-curations.adoc b/bottlenote-admin-api/src/docs/asciidoc/api/admin-curations/spec-based-curations.adoc index 941a8a1ce..518c10d49 100644 --- a/bottlenote-admin-api/src/docs/asciidoc/api/admin-curations/spec-based-curations.adoc +++ b/bottlenote-admin-api/src/docs/asciidoc/api/admin-curations/spec-based-curations.adoc @@ -5,19 +5,19 @@ [source] ---- -GET /admin/api/v1/curation-specs +GET /admin/api/v2/curation-specs ---- [discrete] ==== 요청 예시 ==== -include::{snippets}/admin/curation-specs/list/curl-request.adoc[] -include::{snippets}/admin/curation-specs/list/http-request.adoc[] +include::{snippets}/admin/v2/curation-specs/list/curl-request.adoc[] +include::{snippets}/admin/v2/curation-specs/list/http-request.adoc[] [discrete] ==== 응답 예시 ==== -include::{snippets}/admin/curation-specs/list/response-body.adoc[] +include::{snippets}/admin/v2/curation-specs/list/response-body.adoc[] ''' @@ -27,19 +27,19 @@ include::{snippets}/admin/curation-specs/list/response-body.adoc[] [source] ---- -GET /admin/api/v1/curation-specs/{specId} +GET /admin/api/v2/curation-specs/{specId} ---- [discrete] ==== 요청 예시 ==== -include::{snippets}/admin/curation-specs/detail/curl-request.adoc[] -include::{snippets}/admin/curation-specs/detail/http-request.adoc[] +include::{snippets}/admin/v2/curation-specs/detail/curl-request.adoc[] +include::{snippets}/admin/v2/curation-specs/detail/http-request.adoc[] [discrete] ==== 응답 예시 ==== -include::{snippets}/admin/curation-specs/detail/response-body.adoc[] +include::{snippets}/admin/v2/curation-specs/detail/response-body.adoc[] ''' @@ -50,19 +50,19 @@ include::{snippets}/admin/curation-specs/detail/response-body.adoc[] [source] ---- -GET /admin/api/v1/spec-based-curations +GET /admin/api/v2/curations ---- [discrete] ==== 요청 예시 ==== -include::{snippets}/admin/spec-based-curations/list/curl-request.adoc[] -include::{snippets}/admin/spec-based-curations/list/http-request.adoc[] +include::{snippets}/admin/v2/curations/list/curl-request.adoc[] +include::{snippets}/admin/v2/curations/list/http-request.adoc[] [discrete] ==== 응답 예시 ==== -include::{snippets}/admin/spec-based-curations/list/response-body.adoc[] +include::{snippets}/admin/v2/curations/list/response-body.adoc[] ''' @@ -72,19 +72,19 @@ include::{snippets}/admin/spec-based-curations/list/response-body.adoc[] [source] ---- -GET /admin/api/v1/spec-based-curations/{curationId} +GET /admin/api/v2/curations/{curationId} ---- [discrete] ==== 요청 예시 ==== -include::{snippets}/admin/spec-based-curations/detail/curl-request.adoc[] -include::{snippets}/admin/spec-based-curations/detail/http-request.adoc[] +include::{snippets}/admin/v2/curations/detail/curl-request.adoc[] +include::{snippets}/admin/v2/curations/detail/http-request.adoc[] [discrete] ==== 응답 예시 ==== -include::{snippets}/admin/spec-based-curations/detail/response-body.adoc[] +include::{snippets}/admin/v2/curations/detail/response-body.adoc[] ''' @@ -94,20 +94,20 @@ include::{snippets}/admin/spec-based-curations/detail/response-body.adoc[] [source] ---- -POST /admin/api/v1/spec-based-curations +POST /admin/api/v2/curations ---- [discrete] ==== 요청 예시 ==== -include::{snippets}/admin/spec-based-curations/create/curl-request.adoc[] -include::{snippets}/admin/spec-based-curations/create/http-request.adoc[] -include::{snippets}/admin/spec-based-curations/create/request-body.adoc[] +include::{snippets}/admin/v2/curations/create/curl-request.adoc[] +include::{snippets}/admin/v2/curations/create/http-request.adoc[] +include::{snippets}/admin/v2/curations/create/request-body.adoc[] [discrete] ==== 응답 예시 ==== -include::{snippets}/admin/spec-based-curations/create/response-body.adoc[] +include::{snippets}/admin/v2/curations/create/response-body.adoc[] ''' @@ -118,17 +118,17 @@ include::{snippets}/admin/spec-based-curations/create/response-body.adoc[] [source] ---- -PUT /admin/api/v1/spec-based-curations/{curationId} +PUT /admin/api/v2/curations/{curationId} ---- [discrete] ==== 요청 예시 ==== -include::{snippets}/admin/spec-based-curations/update/curl-request.adoc[] -include::{snippets}/admin/spec-based-curations/update/http-request.adoc[] -include::{snippets}/admin/spec-based-curations/update/request-body.adoc[] +include::{snippets}/admin/v2/curations/update/curl-request.adoc[] +include::{snippets}/admin/v2/curations/update/http-request.adoc[] +include::{snippets}/admin/v2/curations/update/request-body.adoc[] [discrete] ==== 응답 예시 ==== -include::{snippets}/admin/spec-based-curations/update/response-body.adoc[] +include::{snippets}/admin/v2/curations/update/response-body.adoc[] diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt index 6a516ca11..50a8dc2a7 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt @@ -47,6 +47,16 @@ class AdminSpecBasedCurationIntegrationTest : IntegrationTestSupport() { .contains("RECOMMENDED_WHISKY") } + @Test + @DisplayName("Admin v2에서 인증 없이 /v2/curation-specs를 요청할 경우 4xx를 반환한다") + fun listSpecs_whenUnauthenticated_returnsUnauthorized() { + assertThat( + mockMvcTester + .get() + .uri("/v2/curation-specs") + ).hasStatus4xxClientError() + } + @Test @DisplayName("큐레이션 스펙 상세에서 requestSpec과 responseSpec을 조회할 수 있다") fun getSpecDetailSuccess() { @@ -85,6 +95,32 @@ class AdminSpecBasedCurationIntegrationTest : IntegrationTestSupport() { .isEqualTo("CURATION_CREATED") } + @Test + @DisplayName("Admin v2에서 존재하지 않는 specId로 생성할 경우 404를 반환한다") + fun create_whenSpecIdDoesNotExist_returnsNotFound() { + val request = createRequest(validPayload()) + ("specId" to 999999L) + + assertNotFound( + mockMvcTester + .post() + .uri("/v2/curations") + .header("Authorization", "Bearer $accessToken") + .contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(request)) + .exchange() + ) + } + + @Test + @DisplayName("Admin v2에서 인증 없이 /v2/curations를 요청할 경우 4xx를 반환한다") + fun listCurations_whenUnauthenticated_returnsUnauthorized() { + assertThat( + mockMvcTester + .get() + .uri("/v2/curations") + ).hasStatus4xxClientError() + } + @Test @DisplayName("request spec의 required 필드가 없으면 400을 반환한다") fun create_whenRequiredFieldMissing_returnsBadRequest() { @@ -131,6 +167,24 @@ class AdminSpecBasedCurationIntegrationTest : IntegrationTestSupport() { } } + @Nested + @DisplayName("spec 기반 큐레이션 수정 API") + inner class UpdateSpecBasedCuration { + @Test + @DisplayName("Admin v2에서 존재하지 않는 curationId로 수정할 경우 404를 반환한다") + fun update_whenCurationIdDoesNotExist_returnsNotFound() { + assertNotFound( + mockMvcTester + .put() + .uri("/v2/curations/{curationId}", 999999L) + .header("Authorization", "Bearer $accessToken") + .contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(updateRequest(validPayload()))) + .exchange() + ) + } + } + private fun assertBadRequest(request: Map) { assertThat( mockMvcTester @@ -145,6 +199,13 @@ class AdminSpecBasedCurationIntegrationTest : IntegrationTestSupport() { .isEqualTo(400) } + private fun assertNotFound(result: org.springframework.test.web.servlet.assertj.MvcTestResult) { + assertThat(result).hasStatus(404) + .bodyJson() + .extractingPath("$.code") + .isEqualTo(404) + } + private fun createRequest(payload: Any): Map = mapOf( "specId" to recommendedSpecId(), "name" to "통합 테스트 큐레이션", @@ -157,6 +218,18 @@ class AdminSpecBasedCurationIntegrationTest : IntegrationTestSupport() { "payload" to listOf(payload) ) + private fun updateRequest(payload: Any): Map = mapOf( + "specId" to recommendedSpecId(), + "name" to "수정 테스트 큐레이션", + "description" to "존재하지 않는 큐레이션 수정 테스트", + "imageUrls" to listOf("https://cdn.example.com/cover.jpg"), + "exposureStartDate" to "2026-06-01", + "exposureEndDate" to "2026-06-30", + "displayOrder" to 1, + "isActive" to true, + "payload" to listOf(payload) + ) + private fun validPayload( source: String = "BOTTLE_NOTE", selectedTags: List = listOf("셰리", "오크") diff --git a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java index 2b150f5c9..76f59a156 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/curation/service/CurationResponseMaterializer.java @@ -36,9 +36,15 @@ public Object materialize( JsonNode hydrated = payloadNode; for (int i = 0; i < queries.size(); i++) { - Map result = graphqlExecutor.execute(curationId, i, queries.get(i)); - assertNoGraphQLErrors(curationId, specCode, queries.get(i), result); - hydrated = applyHydration(hydrated, queries.get(i), result); + GraphQLCurationQueryBuilder.Result query = queries.get(i); + if (hasNoArgumentValues(query)) { + hydrated = applyHydration(hydrated, query, emptyHydrationResult(query)); + continue; + } + + Map result = graphqlExecutor.execute(curationId, i, query); + assertNoGraphQLErrors(curationId, specCode, query, result); + hydrated = applyHydration(hydrated, query, result); } Object materialized = objectMapper.convertValue(hydrated, Object.class); @@ -55,6 +61,21 @@ public Object materialize( return materialized; } + private boolean hasNoArgumentValues(GraphQLCurationQueryBuilder.Result query) { + return query.variables().values().stream().allMatch(this::isEmptyArgumentValue); + } + + private boolean isEmptyArgumentValue(Object value) { + if (value == null) { + return true; + } + return value instanceof List list && list.isEmpty(); + } + + private Map emptyHydrationResult(GraphQLCurationQueryBuilder.Result query) { + return Map.of("data", Map.of(query.entryField(), List.of())); + } + private void assertNoGraphQLErrors( Long curationId, String specCode, @@ -83,10 +104,6 @@ private JsonNode applyHydration( Object raw = data.get(query.entryField()); List hydrationList = normalizeHydration(raw); - if (hydrationList.isEmpty()) { - return payload; - } - Map> byKey = indexByResultKey(hydrationList, query.resultKey()); if (JSON_PATH_ROOT.equals(query.payloadPath())) { return mergeSubtree(payload, query, byKey); diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java index 1a2659a4c..f9a543bb6 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java @@ -10,9 +10,13 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.core.io.ClassPathResource; @Tag("unit") @@ -37,6 +41,43 @@ void validate_whenRecommendedWhiskyBottleNotePayloadIsValid_returnsEmptyErrors() assertThat(errors).isEmpty(); } + @ParameterizedTest(name = "{0}") + @MethodSource("validRequestPayloadsBySpec") + @DisplayName("큐레이션 스펙별 유효한 request payload일 경우 requestSpec 검증을 통과한다") + void validate_whenPayloadMatchesEachRequestSpec_returnsEmptyErrors( + String specCode, String resourceName, Object payload) throws IOException { + Map requestSpec = schema(resourceName, "Request"); + + List errors = validator.validate(new MapBackedSchema(requestSpec), payload); + + assertThat(errors).as(specCode).isEmpty(); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("validResponsePayloadsBySpec") + @DisplayName("큐레이션 스펙별 대표 materialized payload일 경우 responseSpec 검증을 통과한다") + void validate_whenMaterializedPayloadMatchesEachResponseSpec_returnsEmptyErrors( + String specCode, String resourceName, Object payload) throws IOException { + Map responseSpec = schema(resourceName, "Response"); + + List errors = validator.validate(new MapBackedSchema(responseSpec), payload); + + assertThat(errors).as(specCode).isEmpty(); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("invalidRequestPayloadsBySpec") + @DisplayName("큐레이션 스펙별 필수 payload가 누락될 경우 requestSpec 검증 오류를 반환한다") + void validate_whenRequiredPayloadBySpecIsMissing_returnsErrors( + String specCode, String resourceName, Object payload, String expectedError) + throws IOException { + Map requestSpec = schema(resourceName, "Request"); + + List errors = validator.validate(new MapBackedSchema(requestSpec), payload); + + assertThat(errors).as(specCode).contains(expectedError); + } + @Test @DisplayName("requestSpec의 x-container가 array이면 root payload는 비어 있거나 object일 수 없다") void validate_whenArrayContainerIsEmptyOrObject_returnsContainerErrors() throws IOException { @@ -213,6 +254,35 @@ private static Map recommendedItem(String source, Map pairingItem(String source) { + Map item = recommendedItem(source); + item.put( + "pairings", + List.of( + map( + "itemName", + "다크 초콜릿", + "itemImageUrl", + "https://cdn.example.com/pairing/chocolate.jpg", + "pairingNote", + "셰리 향과 단맛을 이어준다."))); + return item; + } + + private static Map itemWithStats(Map item) { + Map itemWithStats = new LinkedHashMap<>(item); + itemWithStats.put( + "stats", + map("rating", 4.2, "totalRatingsCount", 10, "reviewCount", 3, "totalPickCount", 8)); + return itemWithStats; + } + + private static Map withoutField(Map source, String field) { + Map copy = new LinkedHashMap<>(source); + copy.remove(field); + return copy; + } + private static Map tastingEventPayload( int entryFee, int capacity, List> alcohols) { return map( @@ -238,6 +308,56 @@ private static Map tastingEventPayload( alcohols); } + private static Stream validRequestPayloadsBySpec() { + return Stream.of( + Arguments.of( + "RECOMMENDED_WHISKY", + "recommended_whisky.json", + List.of(recommendedItem("BOTTLE_NOTE"))), + Arguments.of("WHISKY_PAIRING", "whisky_pairing.json", List.of(pairingItem("BOTTLE_NOTE"))), + Arguments.of( + "WHISKY_TASTING_EVENT", + "whisky_tasting_event.json", + tastingEventPayload(0, 1, List.of(recommendedItem("BOTTLE_NOTE"))))); + } + + private static Stream validResponsePayloadsBySpec() { + return Stream.of( + Arguments.of( + "RECOMMENDED_WHISKY", + "recommended_whisky.json", + List.of(itemWithStats(recommendedItem("BOTTLE_NOTE")))), + Arguments.of( + "WHISKY_PAIRING", + "whisky_pairing.json", + List.of(itemWithStats(pairingItem("BOTTLE_NOTE")))), + Arguments.of( + "WHISKY_TASTING_EVENT", + "whisky_tasting_event.json", + tastingEventPayload(0, 1, List.of(itemWithStats(recommendedItem("BOTTLE_NOTE")))))); + } + + private static Stream invalidRequestPayloadsBySpec() { + return Stream.of( + Arguments.of( + "RECOMMENDED_WHISKY", + "recommended_whisky.json", + List.of(withoutField(recommendedItem("BOTTLE_NOTE"), "alcohol")), + "$[0].alcohol 필드는 필수입니다."), + Arguments.of( + "WHISKY_PAIRING", + "whisky_pairing.json", + List.of(recommendedItem("BOTTLE_NOTE")), + "$[0].pairings 필드는 필수입니다."), + Arguments.of( + "WHISKY_TASTING_EVENT", + "whisky_tasting_event.json", + withoutField( + tastingEventPayload(0, 1, List.of(recommendedItem("BOTTLE_NOTE"))), + "applicationLink"), + "$.applicationLink 필드는 필수입니다.")); + } + private static Map map(Object... values) { Map map = new LinkedHashMap<>(); for (int i = 0; i < values.length; i += 2) { diff --git a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java index 74dd12385..ed0253b1b 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java @@ -26,7 +26,7 @@ class CurationResponseMaterializerTest { private static final TypeReference> MAP_TYPE = new TypeReference<>() {}; @Test - @DisplayName("root array payload는 responseSpec.x-graphql 기준으로 BOTTLE_NOTE stats만 보강한다") + @DisplayName("source: BOTTLE_NOTE(내부 알코올 참조)는 저장된 메타 정보를 유지하고 stats만 GraphQL 결과로 보강한다") void materialize_whenRootArrayPayload_hydratesBottleNoteStatsOnly() throws IOException { FakeGraphQLCurationExecutor executor = new FakeGraphQLCurationExecutor( @@ -41,7 +41,11 @@ void materialize_whenRootArrayPayload_hydratesBottleNoteStatsOnly() throws IOExc "reviewCount", 3, "totalPickCount", - 8))); + 8, + "korName", + "GraphQL 원본명", + "selectedTags", + List.of("GraphQL 태그")))); CurationResponseMaterializer materializer = materializer(executor); List> payload = List.of( @@ -58,12 +62,93 @@ void materialize_whenRootArrayPayload_hydratesBottleNoteStatsOnly() throws IOExc assertThat(executor.executedQueries()).hasSize(1); assertThat(executor.executedQueries().get(0).query()).contains("alcohols(ids: $ids)"); assertThat(executor.executedQueries().get(0).variables().get("ids")).isEqualTo(List.of(1L)); + assertThat(resultNode.get(0).path("alcohol").path("korName").asText()).isEqualTo("테스트"); + assertThat(resultNode.get(0).path("alcohol").path("korName").asText()) + .isNotEqualTo("GraphQL 원본명"); + assertThat(resultNode.get(0).path("alcohol").path("selectedTags").get(0).asText()) + .isEqualTo("셰리"); + assertThat(resultNode.get(0).path("alcohol").path("selectedTags").get(0).asText()) + .isNotEqualTo("GraphQL 태그"); assertThat(resultNode.get(0).path("stats").path("rating").asDouble()).isEqualTo(4.2); + assertThat(resultNode.get(0).path("stats").path("totalRatingsCount").asInt()).isEqualTo(10); assertThat(resultNode.get(0).path("stats").has("alcoholId")).isFalse(); assertThat(resultNode.get(1).path("stats").isNull()).isTrue(); assertThat(resultNode.get(1).path("alcohol").path("korName").asText()).isEqualTo("수동"); } + @Test + @DisplayName( + "source: BOTTLE_NOTE(내부 알코올 참조)가 중복 alcoholId를 가질 경우 GraphQL 변수는 중복 제거하고 각 항목에 stats를 보강한다") + void materialize_whenDuplicateBottleNoteAlcoholId_deduplicatesQueryVariablesAndHydratesEachItem() + throws IOException { + FakeGraphQLCurationExecutor executor = + new FakeGraphQLCurationExecutor( + List.of( + map( + "alcoholId", + 11, + "rating", + 4.7, + "totalRatingsCount", + 5, + "reviewCount", + 2, + "totalPickCount", + 9))); + CurationResponseMaterializer materializer = materializer(executor); + List> payload = + List.of( + item( + "BOTTLE_NOTE", + map("alcoholId", 11, "korName", "첫 번째 스냅샷", "selectedTags", List.of("셰리"))), + item( + "BOTTLE_NOTE", + map("alcoholId", 11, "korName", "두 번째 스냅샷", "selectedTags", List.of("피트"))), + item( + "MANUAL", + map("alcoholId", null, "korName", "직접 입력", "selectedTags", List.of("오크")))); + + Object result = + materializer.materialize( + 1L, "RECOMMENDED_WHISKY", schema("recommended_whisky.json", "Response"), payload); + + JsonNode resultNode = OBJECT_MAPPER.valueToTree(result); + assertThat(executor.executedQueries()).hasSize(1); + assertThat(executor.executedQueries().get(0).variables().get("ids")).isEqualTo(List.of(11L)); + assertThat(resultNode.get(0).path("alcohol").path("korName").asText()).isEqualTo("첫 번째 스냅샷"); + assertThat(resultNode.get(1).path("alcohol").path("korName").asText()).isEqualTo("두 번째 스냅샷"); + assertThat(resultNode.get(0).path("stats").path("rating").asDouble()).isEqualTo(4.7); + assertThat(resultNode.get(1).path("stats").path("rating").asDouble()).isEqualTo(4.7); + assertThat(resultNode.get(0).path("stats").path("totalPickCount").asInt()).isEqualTo(9); + assertThat(resultNode.get(1).path("stats").path("totalPickCount").asInt()).isEqualTo(9); + assertThat(resultNode.get(2).path("stats").isNull()).isTrue(); + } + + @Test + @DisplayName("source: MANUAL(직접 입력)만 있을 경우 GraphQL을 실행하지 않고 저장된 payload 그대로 응답한다") + void materialize_whenOnlyManualItems_doesNotExecuteGraphQLAndKeepsSnapshotPayload() + throws IOException { + FakeGraphQLCurationExecutor executor = new FakeGraphQLCurationExecutor(List.of()); + CurationResponseMaterializer materializer = materializer(executor); + List> payload = + List.of( + item( + "MANUAL", + map("alcoholId", null, "korName", "직접 입력 위스키", "selectedTags", List.of("오크")))); + + Object result = + materializer.materialize( + 1L, "RECOMMENDED_WHISKY", schema("recommended_whisky.json", "Response"), payload); + + JsonNode resultNode = OBJECT_MAPPER.valueToTree(result); + assertThat(executor.executedQueries()).isEmpty(); + assertThat(resultNode.get(0).path("source").asText()).isEqualTo("MANUAL"); + assertThat(resultNode.get(0).path("alcohol").path("korName").asText()).isEqualTo("직접 입력 위스키"); + assertThat(resultNode.get(0).path("alcohol").path("selectedTags").get(0).asText()) + .isEqualTo("오크"); + assertThat(resultNode.get(0).path("stats").isNull()).isTrue(); + } + @Test @DisplayName("object payload의 payloadPath=$.alcohols는 하위 alcohols 배열에만 stats를 보강한다") void materialize_whenNestedPayloadPath_hydratesOnlyAlcoholSubtree() throws IOException { diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java b/bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java index 5b53d0e3b..eacddd52c 100644 --- a/bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java +++ b/bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java @@ -5,6 +5,7 @@ import app.bottlenote.IntegrationTestSupport; import app.bottlenote.alcohols.domain.Alcohol; +import app.bottlenote.alcohols.domain.AlcoholQueryRepository; import app.bottlenote.alcohols.fixture.AlcoholTestFactory; import app.bottlenote.curation.domain.CurationSpec; import app.bottlenote.curation.domain.CurationSpecRepository; @@ -38,6 +39,7 @@ class ProductSpecBasedCurationIntegrationTest extends IntegrationTestSupport { @Autowired private CurationSpecRepository curationSpecRepository; @Autowired private AdminSpecBasedCurationService adminSpecBasedCurationService; @Autowired private AlcoholTestFactory alcoholTestFactory; + @Autowired private AlcoholQueryRepository alcoholRepository; @Autowired private UserTestFactory userTestFactory; @Autowired private RatingTestFactory ratingTestFactory; @Autowired private ReviewTestFactory reviewTestFactory; @@ -148,6 +150,43 @@ void getDetail_whenBottleNoteAndManualItems_returnsPayloadMatchingResponseSpec() assertThat(payload.get(1).path("stats").isNull()).isTrue(); } + @Test + @DisplayName("Product v2에서 알코올 원본 정보가 변경된 후 조회할 경우 큐레이션 payload의 저장 시점 메타 정보로 응답하고 현재 통계를 보강한다") + void getDetail_whenSourceAlcoholMetadataChanged_returnsSnapshotMetadataAndCurrentStats() + throws Exception { + // given + Alcohol alcohol = alcoholTestFactory.persistAlcoholWithName("저장 시점 위스키", "Snapshot Whisky"); + Long curationId = createCuration("스냅샷 큐레이션", 1, true, List.of(bottleNoteItem(alcohol))); + changeSourceAlcoholMetadata(alcohol); + assertThat(alcoholRepository.findById(alcohol.getId()).orElseThrow().getKorName()) + .isEqualTo("변경된 원본 위스키"); + User userA = userTestFactory.persistUser(); + User userB = userTestFactory.persistUser(); + ratingTestFactory.persistRating(userA, alcohol, 3); + ratingTestFactory.persistRating(userB, alcohol, 5); + reviewTestFactory.persistReview(userA, alcohol); + picksTestFactory.persistPicks(alcohol.getId(), userA.getId()); + + // when + MvcTestResult result = + mockMvcTester + .get() + .uri("/api/v2/curations/{curationId}", curationId) + .contentType(APPLICATION_JSON) + .exchange(); + + // then + JsonNode payloadItem = dataNode(result).path("payload").get(0); + assertThat(payloadItem.path("alcohol").path("korName").asText()).isEqualTo("저장 시점 위스키"); + assertThat(payloadItem.path("alcohol").path("korName").asText()).isNotEqualTo("변경된 원본 위스키"); + assertThat(payloadItem.path("alcohol").path("selectedTags").get(0).asText()).isEqualTo("셰리"); + assertThat(payloadItem.path("stats").path("rating").asDouble()).isEqualTo(4.0); + assertThat(payloadItem.path("stats").path("totalRatingsCount").asLong()).isEqualTo(2L); + assertThat(payloadItem.path("stats").path("reviewCount").asLong()).isEqualTo(1L); + assertThat(payloadItem.path("stats").path("totalPickCount").asLong()).isEqualTo(1L); + assertThat(payloadItem.path("stats").has("alcoholId")).isFalse(); + } + @Test @DisplayName("비활성 큐레이션 상세 조회는 404를 반환한다") void getDetail_whenInactiveCuration_returnsNotFound() { @@ -246,6 +285,26 @@ private Map bottleNoteItem(Alcohol alcohol) { List.of("셰리", "오크"))); } + private void changeSourceAlcoholMetadata(Alcohol alcohol) { + Alcohol sourceAlcohol = alcoholRepository.findById(alcohol.getId()).orElseThrow(); + sourceAlcohol.update( + "변경된 원본 위스키", + "Changed Source Whisky", + null, + null, + null, + null, + null, + null, + null, + null, + null, + "https://cdn.example.com/changed-source.jpg", + null, + null); + alcoholRepository.save(sourceAlcohol); + } + private Map manualItem(String name) { return item("MANUAL", map("alcoholId", null, "korName", name, "selectedTags", List.of("오크"))); } diff --git a/git.environment-variables b/git.environment-variables index 8dd662e15..95160c970 160000 --- a/git.environment-variables +++ b/git.environment-variables @@ -1 +1 @@ -Subproject commit 8dd662e15c098c2e57c36a2604a1ba42fceed9f1 +Subproject commit 95160c9709dacb1275d55a310d87f7d799fa1191 diff --git a/plan/admin-api-v2-curation-endpoints.md b/plan/complete/admin-api-v2-curation-endpoints.md similarity index 100% rename from plan/admin-api-v2-curation-endpoints.md rename to plan/complete/admin-api-v2-curation-endpoints.md diff --git a/plan/curation-v2-display-demo-runbook.md b/plan/complete/curation-v2-display-demo-runbook.md similarity index 67% rename from plan/curation-v2-display-demo-runbook.md rename to plan/complete/curation-v2-display-demo-runbook.md index 74836a61f..9b235c89e 100644 --- a/plan/curation-v2-display-demo-runbook.md +++ b/plan/complete/curation-v2-display-demo-runbook.md @@ -35,6 +35,17 @@ export const displayConfig = { - token은 파일에 쓰지 않는다. - 401 응답을 받으면 저장된 token을 지우고 한 번 재로그인한다. +## Current API Contract + +현재 코드베이스 기준 데모가 호출해야 하는 canonical endpoint는 다음과 같다. + +- Admin login: `/admin/api/v1/auth/login` +- Admin specs: `/admin/api/v2/curation-specs`, `/admin/api/v2/curation-specs/{specId}` +- Admin spec-based curation: `/admin/api/v2/curations`, `/admin/api/v2/curations/{curationId}` +- Product curation v2: `/api/v2/curations`, `/api/v2/curations/{curationId}` + +기존 `/admin/api/v1/curation-specs`, `/admin/api/v1/spec-based-curations`는 2026-05-18 Admin API versioning 변경 이후 canonical endpoint가 아니며 alias도 제공하지 않는다. + ## Local Static Server ```bash @@ -53,6 +64,8 @@ python3 -m http.server 8097 --directory .example/display Executed at: 2026-05-17 +이 결과는 2026-05-18 Admin API v2 path remap 이전 실행 기록이다. 현재 코드베이스로 재검증할 때는 위 Current API Contract의 `/admin/api/v2/**` 경로를 사용한다. + - Static pages: - `index.html`: HTTP 200 - `specs.html`: HTTP 200 @@ -62,23 +75,31 @@ Executed at: 2026-05-17 - `/admin/api/v1/auth/login`: HTTP 200 - access token present: yes - Admin specs: - - `/admin/api/v1/curation-specs`: HTTP 200 + - historical path: `/admin/api/v1/curation-specs` + - current path: `/admin/api/v2/curation-specs` + - historical result: HTTP 200 - count: 3 - first spec keys: `id`, `code`, `name`, `description`, `hydratorKey`, `version`, `isActive`, `requestSpec`, `responseSpec` - Admin curation list before demo create: - - `/admin/api/v1/spec-based-curations?keyword=&isActive=&page=0&size=50`: HTTP 200 + - historical path: `/admin/api/v1/spec-based-curations?keyword=&isActive=&page=0&size=50` + - current path: `/admin/api/v2/curations?keyword=&isActive=&page=0&size=50` + - historical result: HTTP 200 - count: 0 - Product curation list before demo create: - `/api/v2/curations`: HTTP 200 - count: 0 - Invalid create smoke: - - `/admin/api/v1/spec-based-curations`: HTTP 400 + - historical path: `/admin/api/v1/spec-based-curations` + - current path: `/admin/api/v2/curations` + - historical result: HTTP 400 - error code: `CURATION_PAYLOAD_REQUIRED` - Valid create smoke: - created name: `CODEX_DISPLAY_SMOKE_20260517` - targetId: 2 - Admin detail: - - `/admin/api/v1/spec-based-curations/2`: HTTP 200 + - historical path: `/admin/api/v1/spec-based-curations/2` + - current path: `/admin/api/v2/curations/2` + - historical result: HTTP 200 - spec: `RECOMMENDED_WHISKY` - payload type: array - payload count: 1 diff --git a/plan/curation-v2-display-demo.md b/plan/complete/curation-v2-display-demo.md similarity index 93% rename from plan/curation-v2-display-demo.md rename to plan/complete/curation-v2-display-demo.md index cd1d286cb..85902b7ce 100644 --- a/plan/curation-v2-display-demo.md +++ b/plan/complete/curation-v2-display-demo.md @@ -25,9 +25,9 @@ Bottlenote repository 안에 curation demo 프로젝트의 `display` 정적 데 - `.example/display` 아래에서 정적 데모 페이지가 열리고 원본 display의 주요 화면을 제공한다. - config 파일에서 `active` 환경을 `local` 또는 `development`로 바꾸면 같은 화면이 해당 API base URL을 사용한다. - development 환경에서 admin login이 자동 수행되고 access token이 이후 Admin API 요청의 `Authorization: Bearer` 헤더에 자동 반영된다. -- 스펙 목록 화면에서 `GET /admin/api/v1/curation-specs` 응답의 3개 spec이 표시된다. +- 스펙 목록 화면에서 `GET /admin/api/v2/curation-specs` 응답의 3개 spec이 표시된다. - 스펙 상세 또는 카드 확장 영역에서 `requestSpec`, `responseSpec`, `hydratorKey`, `version`, `isActive`가 확인 가능하다. -- 큐레이션 목록 화면에서 Admin `GET /admin/api/v1/spec-based-curations`와 Product `GET /api/v2/curations`의 결과 차이를 구분해 확인할 수 있다. +- 큐레이션 목록 화면에서 Admin `GET /admin/api/v2/curations`와 Product `GET /api/v2/curations`의 결과 차이를 구분해 확인할 수 있다. - 큐레이션 생성 화면은 현재 Bottlenote Admin create contract에 맞는 payload를 생성한다. - 생성 요청 실패 시 HTTP status, 서버 error code/message, validation 실패 위치를 화면에 표시한다. - 생성 성공 후 상세 화면에서 Admin detail payload와 Product detail materialized payload를 비교해 볼 수 있다. @@ -48,8 +48,8 @@ Bottlenote repository 안에 curation demo 프로젝트의 `display` 정적 데 - API surfaces: - Admin login: `/admin/api/v1/auth/login` - - Admin specs: `/admin/api/v1/curation-specs`, `/admin/api/v1/curation-specs/{specId}` - - Admin spec-based curation: `/admin/api/v1/spec-based-curations`, `/admin/api/v1/spec-based-curations/{curationId}` + - Admin specs: `/admin/api/v2/curation-specs`, `/admin/api/v2/curation-specs/{specId}` + - Admin spec-based curation: `/admin/api/v2/curations`, `/admin/api/v2/curations/{curationId}` - Product curation v2: `/api/v2/curations`, `/api/v2/curations/{curationId}` - Security: @@ -97,7 +97,7 @@ Bottlenote repository 안에 curation demo 프로젝트의 `display` 정적 데 ### Task 3: Spec browsing screens - Acceptance: 원본 display의 navigation, common style, specs/curations 목록 화면이 Bottlenote API 응답 구조에 맞게 동작한다. -- Acceptance: development 환경에서 자동 로그인 후 `GET /admin/api/v1/curation-specs`가 3개 spec을 표시한다. +- Acceptance: development 환경에서 자동 로그인 후 `GET /admin/api/v2/curation-specs`가 3개 spec을 표시한다. - Acceptance: spec 카드에서 `requestSpec`, `responseSpec`, `hydratorKey`, `version`, `isActive`를 확인할 수 있다. - Verification: static server + development config로 specs 화면 조회, browser console error 없음 - Files: `.example/display/specs.html`, `.example/display/curations.html`, `.example/display/css/**`, `.example/display/js/nav.js`, `.example/display/js/specs.js`, `.example/display/js/curations.js` ignored @@ -111,7 +111,7 @@ Bottlenote repository 안에 curation demo 프로젝트의 `display` 정적 데 - [x] no credential or token is tracked by git ### Task 4: Curation creation flow -- Acceptance: 원본 `curation-new.html`의 동적 form UX를 가능한 유지하면서 Bottlenote Admin `POST /admin/api/v1/spec-based-curations` request body를 생성한다. +- Acceptance: 원본 `curation-new.html`의 동적 form UX를 가능한 유지하면서 Bottlenote Admin `POST /admin/api/v2/curations` request body를 생성한다. - Acceptance: request payload는 선택된 spec의 `requestSpec` 기준으로 구성되고, 기본 정보와 payload가 현재 `CurationCreateRequest` 계약에 맞게 전송된다. - Acceptance: 실패 시 HTTP status, server error code/message, validation 실패 위치를 화면에 표시한다. - Verification: development config에서 intentionally invalid payload 요청 후 validation error 표시 확인, valid payload 요청은 사용자 승인 데이터로 smoke 가능 @@ -148,6 +148,7 @@ Bottlenote repository 안에 curation demo 프로젝트의 `display` 정적 데 - 2026-05-17 Task 1 완료: `main`으로 전환 후 `git pull`로 `dc9cc851`까지 fast-forward했고, `git.environment-variables` submodule은 `8dd662e15c098c2e57c36a2604a1ba42fceed9f1` 상태임을 확인했다. 최신 main 기준 작업 브랜치 `codex/curation-v2-display-demo`를 생성했다. 검증: `git status --short --branch`, `git rev-parse --short HEAD`, `git submodule status --recursive`. - 2026-05-17 Task 2 완료: `.gitignore`에 `.example/`를 추가했고 원본 curation demo display를 `.example/display`로 복사했다. `js/config.js`는 `active` 기반 local/development 전환을 제공하고, `js/api.js`는 Bottlenote Admin/Product base URL, admin 자동 로그인, sessionStorage token 저장, GlobalResponse unwrap을 담당한다. 검증: `git status --short --ignored .example .gitignore plan/curation-v2-display-demo.md`, `node --check .example/display/js/api.js`, `node --check .example/display/js/config.js`, `node --check .example/display/js/nav.js`. - 2026-05-17 Task 3 완료: specs 화면은 Admin `/curation-specs` 응답의 `requestSpec`, `responseSpec`, `hydratorKey`, `version`, `isActive`를 표시하고, curations 화면은 Admin `/spec-based-curations`와 Product `/api/v2/curations`를 나란히 조회하도록 조정했다. 정적 서버 `localhost:8097`에서 `index.html`, `specs.html`, `curations.html` HTTP 200을 확인했다. development API smoke는 specs=200 count=3, admin_curations=200 count=0, product_curations=200 count=0. +- 2026-05-18 정정: admin-api context-path를 `/admin/api`로 낮추고 spec 기반 curation surface를 `/v2`로 이동했다. 현재 코드베이스 기준 Admin specs는 `/admin/api/v2/curation-specs`, Admin spec-based curation은 `/admin/api/v2/curations`가 canonical endpoint다. 기존 `/admin/api/v1/curation-specs`, `/admin/api/v1/spec-based-curations` alias는 제공하지 않는다. - 2026-05-17 Task 4 완료: `curation-new.html` 기본 노출 기간을 현재 dev smoke에 맞게 2026-05-17~2026-12-31로 바꾸고, submit body에서 DTO에 없는 `coverImageUrl`을 제거했다. 오류 표시는 `HTTP status`, server `code/status/message`를 노출하도록 조정했다. development Admin create invalid smoke는 HTTP 400, `CURATION_PAYLOAD_REQUIRED`를 확인했다. - 2026-05-17 Task 5 완료: 상세 화면을 Admin raw detail과 Product materialized detail 비교 화면으로 단순화했다. development에 `CODEX_DISPLAY_SMOKE_20260517` 큐레이션을 생성했고 `targetId=2`를 받았다. Admin detail HTTP 200, Product detail HTTP 200, Admin payload array count=1, Product payload array count=1, MANUAL 항목 `stats=null`을 확인했다. 정적 상세 페이지 `curation-detail.html?id=2`도 HTTP 200으로 서빙됐다. - 2026-05-17 Task 6 완료: `plan/curation-v2-display-demo-runbook.md`에 ignored demo 실행 방법, config 전환, 자동 로그인, development smoke 결과, git tracking policy를 기록했다. `.example/`는 `!! .example/`로 ignored 상태이고, tracked diff에는 `.example/display/**`가 포함되지 않는다. diff --git a/plan/complete/curation-v2-test-hardening.md b/plan/complete/curation-v2-test-hardening.md new file mode 100644 index 000000000..1454f382f --- /dev/null +++ b/plan/complete/curation-v2-test-hardening.md @@ -0,0 +1,187 @@ +# Plan: Curation V2 Test Hardening + +## Overview + +큐레이션 v2의 현재 코드베이스 로직을 테스트로 더 명확하게 고정한다. + +이번 작업은 신규 기능 구현이 아니라 테스트 보강이다. 특히 사용자가 설계한 핵심 정책인 "큐레이션 아이템은 저장 시점의 메타 정보를 payload로 스냅샷 저장하고, 현재성이 필요한 통계만 GraphQL로 보강한다"는 동작을 테스트명과 assertion으로 직접 표현한다. + +테스트 보강은 에이전트 역할을 분리해서 진행한다. 구현 에이전트가 테스트를 추가하고, 목적 검증 에이전트가 테스트가 실제 의도를 검증하는지 반례까지 확인하며, 컨벤션 검토 에이전트가 기존 테스트 방식과 프로젝트 규칙을 점검한다. 마지막으로 회귀 검증 에이전트가 focused Gradle suite를 실행해 실제 통과 여부를 확인한다. + +### Assumptions + +- 대상은 spec 기반 큐레이션 v2만이다. legacy `curation_keyword` 테스트는 이번 범위가 아니다. +- 현재 canonical endpoint는 Admin `/admin/api/v2/curation-specs`, `/admin/api/v2/curations`, Product `/api/v2/curations`다. +- `source: BOTTLE_NOTE(내부 알코올 참조)`는 `alcoholId`를 통해 현재 통계를 GraphQL로 보강할 수 있는 아이템이다. +- `source: MANUAL(직접 입력)`은 내부 알코올 조회 대상이 아니며 저장된 payload 그대로 응답하고 `stats`는 `null`이다. +- 이름, 이미지, 태그, 코멘트 같은 노출용 메타 정보는 저장 시점 payload의 스냅샷을 사용한다. +- 별점, 평가 수, 리뷰 수, 찜 수 같은 현재성 있는 통계만 Product 상세 조회 시 GraphQL hydration으로 보강한다. +- Unit test는 fake, in-memory repository, fake GraphQL executor를 우선 사용한다. +- E2E/Integration test는 실제 Spring context, JPA, TestContainers가 필요한 검증에만 사용한다. +- 기존 미커밋 변경인 Admin Asciidoc, display demo plan/runbook, `git.environment-variables` gitlink 변경은 보존한다. + +### Success Criteria + +- `source: BOTTLE_NOTE(내부 알코올 참조)` 항목은 저장된 메타 정보를 유지하고 현재 통계만 GraphQL로 보강한다는 테스트가 추가된다. +- `source: MANUAL(직접 입력)` 항목은 GraphQL 조회 대상에서 제외되고 `stats=null`로 응답한다는 테스트가 명확히 유지되거나 보강된다. +- 알코올 원본 정보가 변경된 뒤 Product v2 상세를 조회해도 큐레이션 payload의 저장 시점 메타 정보가 응답된다는 E2E/Integration 테스트가 추가된다. +- 3개 스펙 `RECOMMENDED_WHISKY`, `WHISKY_PAIRING`, `WHISKY_TASTING_EVENT`에 대해 유효 payload 저장 또는 materialized response 검증이 보강된다. +- Admin v2 무인증 접근 또는 존재하지 않는 spec/curation 같은 API 경계 오류가 필요한 범위에서 보강된다. +- 테스트 이름은 가능한 한 `~할 경우 ~한다` 형태를 사용하고, source 타입은 `source: BOTTLE_NOTE(내부 알코올 참조)`, `source: MANUAL(직접 입력)`처럼 괄호 설명을 포함한다. +- Parameterized test가 중복을 줄일 수 있는 스펙별 검증에는 `@ParameterizedTest`를 우선 고려한다. +- 추가 테스트는 기존 tag 규칙을 따른다: unit은 `@Tag("unit")`, product integration은 `@Tag("integration")`, admin integration은 `@Tag("admin_integration")`. +- focused verification이 성공한다: + - `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.*' --tests 'app.bottlenote.graphql.GraphQLCurationSchemaTest'` + - `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.curation.AdminSpecBasedCurationIntegrationTest'` + - `./gradlew :bottlenote-product-api:integration_test --tests 'app.bottlenote.curation.integration.ProductSpecBasedCurationIntegrationTest'` + - 필요 시 관련 RestDocs 테스트와 `git diff --check` + +### Impact Scope + +- `bottlenote-mono` + - `CurationResponseMaterializerTest` + - `CurationPayloadValidatorTest` + - `ProductSpecBasedCurationServiceTest` + - `AdminSpecBasedCurationServiceTest` + - `GraphQLCurationAlcoholResolverTest` + - curation fixture/fake repository +- `bottlenote-product-api` + - `ProductSpecBasedCurationIntegrationTest` + - 필요 시 Product curation RestDocs test +- `bottlenote-admin-api` + - `AdminSpecBasedCurationIntegrationTest` + - 필요 시 Admin spec-based curation RestDocs test +- Persistence + - schema 변경 없음. + - 테스트 데이터만 추가한다. +- API Contract + - endpoint 변경 없음. + - 응답 형태 변경 없음. +- Docs + - 테스트 보강 자체에는 API 문서 변경이 필수는 아니다. + - 기존 문서 diff는 보존한다. + +### Agent Roles + +- Implementation Agent + - 테스트 코드를 추가한다. + - 기존 fixture, fake, TestFactory를 우선 재사용한다. + - production code 변경은 테스트 불가능성이 확인된 경우에만 별도 보고한다. + +- Test Intent Review Agent + - 각 테스트가 이름 그대로의 목적을 검증하는지 확인한다. + - `A일 때 X다`뿐 아니라 `B일 때 X가 아니다`에 해당하는 반례 assertion이 필요한지 점검한다. + - 스냅샷 메타 정보와 GraphQL 통계 보강이 같은 assertion에 섞여 흐려지지 않았는지 확인한다. + +- Test Convention Review Agent + - 기존 테스트 패턴, tag, DisplayName, fake/in-memory 우선 원칙, TestContainers 사용 기준을 검토한다. + - 불필요한 mock, 과도한 통합 테스트, 기존 fixture 중복 생성을 반려한다. + +- Regression Verification Agent + - focused Gradle suite를 실행한다. + - 실패 시 compile/test/docs/integration/TestContainers 문제를 분리해 보고한다. + - 성공 주장 전 실제 `BUILD SUCCESSFUL` 또는 실패 원인을 확인한다. + +### Out of Scope + +- 큐레이션 v2 production 로직 변경 +- DB schema 변경 +- legacy `curation_keyword` 동작 변경 +- 신규 큐레이션 스펙 추가 +- Admin/Product endpoint 변경 +- display demo UI 구현 변경 + +## Runtime Boundary + +이 문서는 `/define` 산출물이다. 다음 단계는 `/plan`에서 테스트 보강 task를 쪼개는 것이다. + +## Dependency Analysis + +1. Unit 테스트는 production context 없이 빠르게 정책을 고정한다. 특히 `CurationResponseMaterializer`와 `CurationPayloadValidator`가 Product 상세 응답의 payload 형태를 결정하므로 먼저 보강한다. +2. Product integration 테스트는 Admin 저장 경로, JPA persistence, Product 조회, 내부 GraphQL hydration까지 연결되는 핵심 E2E 경로다. 저장 시점 스냅샷 정책은 이 레이어에서 가장 명확하게 검증한다. +3. Admin integration 테스트는 v2 endpoint의 인증/오류 경계를 고정한다. Product integration과 독립적으로 구현 가능하다. +4. 리뷰 에이전트는 구현 후 병렬로 목적/컨벤션을 검토한다. 회귀 검증은 리뷰 반영 뒤 수행한다. + +## Tasks + +### Task 1: Unit materializer source policy hardening + +- Acceptance: `source: BOTTLE_NOTE(내부 알코올 참조)`는 저장된 메타 정보를 유지하고 stats만 GraphQL 결과로 보강한다. +- Acceptance: `source: MANUAL(직접 입력)`은 GraphQL 변수에서 제외되고 stats를 null로 유지한다. +- Acceptance: 중복 `alcoholId`는 GraphQL 변수에서 중복 제거된다. +- Verification: `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationResponseMaterializerTest'` +- Files: `bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationResponseMaterializerTest.java` +- Size: S +- Status: [x] done + +### Task 2: Spec parameterized validation coverage + +- Acceptance: `RECOMMENDED_WHISKY`, `WHISKY_PAIRING`, `WHISKY_TASTING_EVENT` 유효 request payload가 모두 requestSpec 검증을 통과한다. +- Acceptance: 세 스펙의 대표 materialized payload가 responseSpec 검증을 통과한다. +- Verification: `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.service.CurationPayloadValidatorTest'` +- Files: `bottlenote-mono/src/test/java/app/bottlenote/curation/service/CurationPayloadValidatorTest.java` +- Size: S +- Status: [x] done + +### Task 3: Product integration snapshot semantics + +- Acceptance: Product v2에서 알코올 원본 정보가 변경된 뒤 조회할 경우 큐레이션 payload의 저장 시점 메타 정보로 응답한다. +- Acceptance: 같은 응답에서 현재 통계는 GraphQL hydration 결과로 보강된다. +- Verification: `./gradlew :bottlenote-product-api:integration_test --tests 'app.bottlenote.curation.integration.ProductSpecBasedCurationIntegrationTest'` +- Files: `bottlenote-product-api/src/test/java/app/bottlenote/curation/integration/ProductSpecBasedCurationIntegrationTest.java` +- Size: S +- Status: [x] done + +### Checkpoint: after Tasks 1-3 + +- [x] Mono curation unit tests pass +- [x] Product curation integration tests pass +- [x] Snapshot semantics are asserted by both unit or integration coverage + +### Task 4: Admin integration boundary coverage + +- Acceptance: Admin v2에서 존재하지 않는 specId로 생성할 경우 404를 반환한다. +- Acceptance: Admin v2에서 존재하지 않는 curationId로 수정할 경우 404를 반환한다. +- Acceptance: Admin v2에서 인증 없이 `/v2/curation-specs` 또는 `/v2/curations`를 요청할 경우 현재 보안 설정에 맞는 4xx를 반환한다. +- Verification: `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.curation.AdminSpecBasedCurationIntegrationTest'` +- Files: `bottlenote-admin-api/src/test/kotlin/app/integration/curation/AdminSpecBasedCurationIntegrationTest.kt` +- Size: S +- Status: [x] done + +### Task 5: Agent review and focused verification + +- Acceptance: Test Intent Review Agent가 테스트 목적과 반례 assertion을 검토한다. +- Acceptance: Test Convention Review Agent가 tag, fixture, fake/TestContainers 사용 기준을 검토한다. +- Acceptance: Focused Gradle suite와 `git diff --check`가 성공한다. +- Verification: + - `./gradlew :bottlenote-mono:test --tests 'app.bottlenote.curation.*' --tests 'app.bottlenote.graphql.GraphQLCurationSchemaTest'` + - `./gradlew :bottlenote-admin-api:test --tests 'app.docs.curation.AdminSpecBasedCurationControllerDocsTest'` + - `./gradlew :bottlenote-admin-api:admin_integration_test --tests 'app.integration.curation.AdminSpecBasedCurationIntegrationTest'` + - `./gradlew :bottlenote-product-api:test --tests 'app.docs.curation.RestProductSpecBasedCurationControllerTest'` + - `./gradlew :bottlenote-product-api:integration_test --tests 'app.bottlenote.curation.integration.ProductSpecBasedCurationIntegrationTest'` + - `git diff --check` +- Files: no expected source files beyond test updates and plan progress log +- Size: S +- Status: [x] done + +### Task 6: Full verification + +- Acceptance: `/verify full` 상당 범위의 compile, rule, unit, build, integration, admin integration 검증이 성공한다. +- Acceptance: 실패 시 실패 레이어와 원인을 Progress Log에 기록한다. +- Verification: + - `./gradlew compileJava compileKotlin compileTestJava compileTestKotlin` + - `./gradlew check_rule_test` + - `./gradlew unit_test` + - `./gradlew build` + - `./gradlew integration_test` + - `./gradlew admin_integration_test` +- Files: `plan/curation-v2-test-hardening.md` +- Size: S +- Status: [x] done + +## Progress Log + +- 2026-05-18: `/plan` 완료. 테스트 보강을 unit materializer, spec parameterized validation, Product integration snapshot semantics, Admin integration boundary, agent review/focused verification, full verification 6개 task로 분리했다. +- 2026-05-18: Task 1-4 구현 및 리뷰 피드백 반영. `source: MANUAL(직접 입력)` 단독 payload에서 GraphQL 실행을 생략하고 `stats=null`을 유지하도록 materializer를 보강했다. Admin 무인증 경계는 현재 보안 설정의 실제 응답인 403을 포함하는 4xx 기준으로 문서화했다. +- 2026-05-18: Test Intent Review Agent와 Test Convention Review Agent 검토 완료. 반영 사항: 원본 알코올 변경 전제 assertion 추가, 스펙별 required 누락 parameterized 반례 추가, Admin 무인증 테스트 복구, helper mutation 제거, DisplayName 문장형 보정. +- 2026-05-18: Task 5 focused suite와 `git diff --check` 성공. `/verify full` 수행 결과 `compileJava compileTestJava`, `:bottlenote-admin-api:compileKotlin :bottlenote-admin-api:compileTestKotlin`, `check_rule_test`, `unit_test`, `build -x test -x asciidoctor --build-cache --parallel`, `integration_test`, `admin_integration_test`, optional `asciidoctor` 모두 `BUILD SUCCESSFUL`. diff --git a/plan/spec-based-curation-v2-graphql-sdl.md b/plan/complete/spec-based-curation-v2-graphql-sdl.md similarity index 99% rename from plan/spec-based-curation-v2-graphql-sdl.md rename to plan/complete/spec-based-curation-v2-graphql-sdl.md index 7b27e2139..f0af2a0c0 100644 --- a/plan/spec-based-curation-v2-graphql-sdl.md +++ b/plan/complete/spec-based-curation-v2-graphql-sdl.md @@ -10,7 +10,7 @@ ### Flow Diagram -![Spec-Based Curation V2 Flow](assets/spec-based-curation-v2-flow.png) +![Spec-Based Curation V2 Flow](../assets/spec-based-curation-v2-flow.png) ### Phase Roadmap From 0abab2824d38c150028b6d3098ff9097c9ba0117 Mon Sep 17 00:00:00 2001 From: Living whale Date: Tue, 19 May 2026 17:31:03 +0900 Subject: [PATCH 27/33] =?UTF-8?q?feat:=20=EC=96=B4=EB=93=9C=EB=AF=BC=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?API=20(#594)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: hgkim --- .../src/docs/asciidoc/admin-api.adoc | 6 + .../src/docs/asciidoc/admin-review.adoc | 28 ++ .../common/enums/admin-review-sort-type.adoc | 10 + .../asciidoc/api/common/enums/sort-order.adoc | 9 + .../presentation/AdminReviewController.kt | 22 ++ .../review/AdminReviewControllerDocsTest.kt | 149 +++++++++++ .../review/AdminReviewIntegrationTest.kt | 242 ++++++++++++++++++ .../review/constant/AdminReviewSortType.java | 14 + .../review/domain/ReviewRepository.java | 5 + .../dto/request/AdminReviewSearchRequest.java | 32 +++ .../dto/response/AdminReviewListResponse.java | 19 ++ .../repository/CustomReviewRepository.java | 5 + .../CustomReviewRepositoryImpl.java | 68 +++++ .../repository/ReviewQuerySupporter.java | 70 +++++ .../service/AdminReviewQueryService.java | 20 ++ .../fixture/InMemoryReviewRepository.java | 10 + .../review/fixture/ReviewTestFactory.java | 43 ++++ .../fixture/InMemoryReviewRepository.java | 10 + plan/complete/admin-review-list.md | 171 +++++++++++++ 19 files changed, 933 insertions(+) create mode 100644 bottlenote-admin-api/src/docs/asciidoc/admin-review.adoc create mode 100644 bottlenote-admin-api/src/docs/asciidoc/api/common/enums/admin-review-sort-type.adoc create mode 100644 bottlenote-admin-api/src/docs/asciidoc/api/common/enums/sort-order.adoc create mode 100644 bottlenote-admin-api/src/main/kotlin/app/bottlenote/review/presentation/AdminReviewController.kt create mode 100644 bottlenote-admin-api/src/test/kotlin/app/docs/review/AdminReviewControllerDocsTest.kt create mode 100644 bottlenote-admin-api/src/test/kotlin/app/integration/review/AdminReviewIntegrationTest.kt create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/review/constant/AdminReviewSortType.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/review/dto/request/AdminReviewSearchRequest.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/review/dto/response/AdminReviewListResponse.java create mode 100644 bottlenote-mono/src/main/java/app/bottlenote/review/service/AdminReviewQueryService.java create mode 100644 plan/complete/admin-review-list.md diff --git a/bottlenote-admin-api/src/docs/asciidoc/admin-api.adoc b/bottlenote-admin-api/src/docs/asciidoc/admin-api.adoc index f76f521dd..8ab95a103 100644 --- a/bottlenote-admin-api/src/docs/asciidoc/admin-api.adoc +++ b/bottlenote-admin-api/src/docs/asciidoc/admin-api.adoc @@ -80,6 +80,12 @@ include::api/admin-users/users.adoc[] ''' +== Review API + +include::admin-review.adoc[] + +''' + == Banner API include::api/admin-banners/banners.adoc[] diff --git a/bottlenote-admin-api/src/docs/asciidoc/admin-review.adoc b/bottlenote-admin-api/src/docs/asciidoc/admin-review.adoc new file mode 100644 index 000000000..174f82809 --- /dev/null +++ b/bottlenote-admin-api/src/docs/asciidoc/admin-review.adoc @@ -0,0 +1,28 @@ +=== 리뷰 목록 조회 === + +- 리뷰 목록을 페이지네이션으로 조회합니다. +- 술, 작성자, 활성 상태, 노출 상태, 키워드, 작성일시 범위로 필터링할 수 있습니다. +- `sortType`은 정렬 기준을, `sortOrder`는 선택한 기준의 정렬 방향을 의미합니다. +- 기본 정렬은 작성일시 기준 내림차순입니다. + +[source] +---- +GET /admin/api/v1/reviews +---- + +[discrete] +==== 요청 파라미터 ==== + +[discrete] +include::{snippets}/admin/reviews/list/query-parameters.adoc[] +include::api/common/enums/admin-review-sort-type.adoc[] +include::api/common/enums/sort-order.adoc[] +include::{snippets}/admin/reviews/list/curl-request.adoc[] +include::{snippets}/admin/reviews/list/http-request.adoc[] + +[discrete] +==== 응답 파라미터 ==== + +[discrete] +include::{snippets}/admin/reviews/list/response-fields.adoc[] +include::{snippets}/admin/reviews/list/http-response.adoc[] diff --git a/bottlenote-admin-api/src/docs/asciidoc/api/common/enums/admin-review-sort-type.adoc b/bottlenote-admin-api/src/docs/asciidoc/api/common/enums/admin-review-sort-type.adoc new file mode 100644 index 000000000..4306714b0 --- /dev/null +++ b/bottlenote-admin-api/src/docs/asciidoc/api/common/enums/admin-review-sort-type.adoc @@ -0,0 +1,10 @@ +[discrete] +==== AdminReviewSortType (관리자 리뷰 정렬 기준) ==== + +[cols="2,3", options="header"] +|=== +|값 |설명 +|`CREATED_AT` |리뷰 작성일시 기준 정렬 +|`REPLY_COUNT` |리뷰 댓글 수 기준 정렬 +|`UPDATED_AT` |리뷰 최종 수정일시 기준 정렬 +|=== diff --git a/bottlenote-admin-api/src/docs/asciidoc/api/common/enums/sort-order.adoc b/bottlenote-admin-api/src/docs/asciidoc/api/common/enums/sort-order.adoc new file mode 100644 index 000000000..56cefe8e9 --- /dev/null +++ b/bottlenote-admin-api/src/docs/asciidoc/api/common/enums/sort-order.adoc @@ -0,0 +1,9 @@ +[discrete] +==== SortOrder (정렬 방향) ==== + +[cols="2,3", options="header"] +|=== +|값 |설명 +|`DESC` |내림차순 정렬 +|`ASC` |오름차순 정렬 +|=== diff --git a/bottlenote-admin-api/src/main/kotlin/app/bottlenote/review/presentation/AdminReviewController.kt b/bottlenote-admin-api/src/main/kotlin/app/bottlenote/review/presentation/AdminReviewController.kt new file mode 100644 index 000000000..5627481e6 --- /dev/null +++ b/bottlenote-admin-api/src/main/kotlin/app/bottlenote/review/presentation/AdminReviewController.kt @@ -0,0 +1,22 @@ +package app.bottlenote.review.presentation + +import app.bottlenote.global.data.response.GlobalResponse +import app.bottlenote.review.dto.request.AdminReviewSearchRequest +import app.bottlenote.review.service.AdminReviewQueryService +import jakarta.validation.Valid +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.ModelAttribute +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/reviews") +class AdminReviewController( + private val adminReviewQueryService: AdminReviewQueryService +) { + @GetMapping + fun list( + @Valid @ModelAttribute request: AdminReviewSearchRequest + ): ResponseEntity = ResponseEntity.ok(adminReviewQueryService.searchReviews(request)) +} diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/review/AdminReviewControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/review/AdminReviewControllerDocsTest.kt new file mode 100644 index 000000000..595095ce1 --- /dev/null +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/review/AdminReviewControllerDocsTest.kt @@ -0,0 +1,149 @@ +package app.docs.review + +import app.bottlenote.global.data.response.GlobalResponse +import app.bottlenote.global.service.cursor.SortOrder +import app.bottlenote.review.constant.AdminReviewSortType +import app.bottlenote.review.constant.ReviewActiveStatus +import app.bottlenote.review.constant.ReviewDisplayStatus +import app.bottlenote.review.dto.request.AdminReviewSearchRequest +import app.bottlenote.review.dto.response.AdminReviewListResponse +import app.bottlenote.review.presentation.AdminReviewController +import app.bottlenote.review.service.AdminReviewQueryService +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.mockito.ArgumentMatchers.any +import org.mockito.BDDMockito.given +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.data.domain.PageImpl +import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document +import org.springframework.restdocs.operation.preprocess.Preprocessors.* +import org.springframework.restdocs.payload.JsonFieldType +import org.springframework.restdocs.payload.PayloadDocumentation.* +import org.springframework.restdocs.request.RequestDocumentation.* +import org.springframework.test.context.bean.override.mockito.MockitoBean +import org.springframework.test.web.servlet.assertj.MockMvcTester +import java.time.LocalDateTime + +@WebMvcTest( + controllers = [AdminReviewController::class], + excludeAutoConfiguration = [SecurityAutoConfiguration::class] +) +@AutoConfigureRestDocs +@DisplayName("Admin Review 컨트롤러 RestDocs 테스트") +class AdminReviewControllerDocsTest { + + @Autowired + private lateinit var mvc: MockMvcTester + + @MockitoBean + private lateinit var adminReviewQueryService: AdminReviewQueryService + + @Test + @DisplayName("관리자용 리뷰 목록을 조회할 수 있다") + fun listReviews() { + // given + val items = listOf( + AdminReviewListResponse( + 1L, + 101L, + "글렌피딕 12년", + 1001L, + "reviewer1", + "향이 풍부하고 균형감이 좋습니다.", + 4.5, + ReviewActiveStatus.ACTIVE, + ReviewDisplayStatus.PUBLIC, + 3L, + LocalDateTime.of(2026, 1, 10, 10, 30), + LocalDateTime.of(2026, 1, 12, 9, 15) + ), + AdminReviewListResponse( + 2L, + 102L, + "맥켈란 12년", + 1002L, + "reviewer2", + "비공개 처리된 운영 확인 대상 리뷰입니다.", + 3.0, + ReviewActiveStatus.DISABLED, + ReviewDisplayStatus.PRIVATE, + 0L, + LocalDateTime.of(2026, 1, 9, 18, 0), + LocalDateTime.of(2026, 1, 9, 18, 0) + ) + ) + val response = GlobalResponse.fromPage(PageImpl(items)) + + given(adminReviewQueryService.searchReviews(any(AdminReviewSearchRequest::class.java))) + .willReturn(response) + + // when & then + assertThat( + mvc.get().uri("/v1/reviews") + .param("alcoholId", "101") + .param("userId", "1001") + .param("activeStatus", ReviewActiveStatus.ACTIVE.name) + .param("displayStatus", ReviewDisplayStatus.PUBLIC.name) + .param("keyword", "글렌") + .param("createdFrom", "2026-01-01T00:00:00") + .param("createdTo", "2026-01-31T23:59:59") + .param("sortType", AdminReviewSortType.CREATED_AT.name) + .param("sortOrder", SortOrder.DESC.name) + .param("page", "0") + .param("size", "20") + ) + .hasStatusOk() + .apply( + document( + "admin/reviews/list", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + queryParameters( + parameterWithName("alcoholId").description("술 ID 필터").optional(), + parameterWithName("userId").description("작성자 유저 ID 필터").optional(), + parameterWithName("activeStatus").description("리뷰 활성 상태 필터 (ACTIVE/DELETED/DISABLED)").optional(), + parameterWithName("displayStatus").description("리뷰 노출 상태 필터 (PUBLIC/PRIVATE)").optional(), + parameterWithName("keyword").description("검색어 (리뷰 본문/작성자 닉네임/작성자 이메일/술 한글명/술 영문명)").optional(), + parameterWithName("createdFrom").description("작성일시 시작 범위 (ISO-8601 LocalDateTime)").optional(), + parameterWithName("createdTo").description("작성일시 종료 범위 (ISO-8601 LocalDateTime)").optional(), + parameterWithName("sortType").description("정렬 기준 (기본값: CREATED_AT, 상세 값은 AdminReviewSortType 표 참조)").optional(), + parameterWithName("sortOrder").description("정렬 방향 (기본값: DESC, 상세 값은 SortOrder 표 참조)").optional(), + parameterWithName("page").description("페이지 번호 (0 이상, 기본값: 0)").optional(), + parameterWithName("size").description("페이지 크기 (1~100, 기본값: 20)").optional() + ), + responseFields( + fieldWithPath("success").type(JsonFieldType.BOOLEAN).description("응답 성공 여부"), + fieldWithPath("code").type(JsonFieldType.NUMBER).description("응답 코드"), + fieldWithPath("data[]").type(JsonFieldType.ARRAY).description("리뷰 목록"), + fieldWithPath("data[].reviewId").type(JsonFieldType.NUMBER).description("리뷰 ID"), + fieldWithPath("data[].alcoholId").type(JsonFieldType.NUMBER).description("술 ID"), + fieldWithPath("data[].alcoholName").type(JsonFieldType.STRING).description("술 이름"), + fieldWithPath("data[].userId").type(JsonFieldType.NUMBER).description("작성자 유저 ID"), + fieldWithPath("data[].userNickname").type(JsonFieldType.STRING).description("작성자 닉네임"), + fieldWithPath("data[].content").type(JsonFieldType.STRING).description("리뷰 본문"), + fieldWithPath("data[].reviewRating").type(JsonFieldType.NUMBER).description("리뷰 평점"), + fieldWithPath("data[].activeStatus").type(JsonFieldType.STRING).description("리뷰 활성 상태 (ACTIVE/DELETED/DISABLED)"), + fieldWithPath("data[].displayStatus").type(JsonFieldType.STRING).description("리뷰 노출 상태 (PUBLIC/PRIVATE)"), + fieldWithPath("data[].replyCount").type(JsonFieldType.NUMBER).description("댓글 수"), + fieldWithPath("data[].createAt").type(JsonFieldType.STRING).description("리뷰 작성일시"), + fieldWithPath("data[].lastModifyAt").type(JsonFieldType.STRING).description("리뷰 최종 수정일시"), + fieldWithPath("errors").type(JsonFieldType.ARRAY).description("에러 목록"), + fieldWithPath("meta").type(JsonFieldType.OBJECT).description("메타 정보"), + fieldWithPath("meta.page").type(JsonFieldType.NUMBER).description("현재 페이지 번호"), + fieldWithPath("meta.size").type(JsonFieldType.NUMBER).description("페이지 크기"), + fieldWithPath("meta.totalElements").type(JsonFieldType.NUMBER).description("전체 요소 수"), + fieldWithPath("meta.totalPages").type(JsonFieldType.NUMBER).description("전체 페이지 수"), + fieldWithPath("meta.hasNext").type(JsonFieldType.BOOLEAN).description("다음 페이지 존재 여부"), + fieldWithPath("meta.serverVersion").type(JsonFieldType.STRING).ignored(), + fieldWithPath("meta.serverEncoding").type(JsonFieldType.STRING).ignored(), + fieldWithPath("meta.serverResponseTime").type(JsonFieldType.STRING).ignored(), + fieldWithPath("meta.serverPathVersion").type(JsonFieldType.STRING).ignored() + ) + ) + ) + } +} diff --git a/bottlenote-admin-api/src/test/kotlin/app/integration/review/AdminReviewIntegrationTest.kt b/bottlenote-admin-api/src/test/kotlin/app/integration/review/AdminReviewIntegrationTest.kt new file mode 100644 index 000000000..d4226f91d --- /dev/null +++ b/bottlenote-admin-api/src/test/kotlin/app/integration/review/AdminReviewIntegrationTest.kt @@ -0,0 +1,242 @@ +package app.integration.review + +import app.IntegrationTestSupport +import app.bottlenote.alcohols.domain.Alcohol +import app.bottlenote.alcohols.fixture.AlcoholTestFactory +import app.bottlenote.global.service.cursor.SortOrder +import app.bottlenote.review.constant.AdminReviewSortType +import app.bottlenote.review.constant.ReviewActiveStatus +import app.bottlenote.review.constant.ReviewDisplayStatus +import app.bottlenote.review.domain.Review +import app.bottlenote.review.fixture.ReviewTestFactory +import app.bottlenote.user.domain.User +import app.bottlenote.user.fixture.UserTestFactory +import com.fasterxml.jackson.databind.JsonNode +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Tag +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import java.time.LocalDateTime + +@Tag("admin_integration") +@DisplayName("[integration] Admin Review API 통합 테스트") +class AdminReviewIntegrationTest : IntegrationTestSupport() { + @Autowired + private lateinit var alcoholTestFactory: AlcoholTestFactory + + @Autowired + private lateinit var userTestFactory: UserTestFactory + + @Autowired + private lateinit var reviewTestFactory: ReviewTestFactory + + private lateinit var accessToken: String + + @BeforeEach + fun setUp() { + val admin = adminUserTestFactory.persistRootAdmin() + accessToken = getAccessToken(admin) + } + + @Test + @DisplayName("기본 목록을 조회할 때 응답 필드와 전체 상태를 노출한다") + fun searchAdminReviews_returnsFieldsAndAllStatuses() { + // given + seedReviews() + + // when + val response = getReviews() + + // then + assertThat(response.get("success").asBoolean()).isTrue() + assertThat(response.get("data")).hasSize(3) + assertThat(response.get("data").flatMap { it.fieldNames().asSequence().toList() }) + .contains( + "reviewId", + "alcoholId", + "alcoholName", + "userId", + "userNickname", + "content", + "reviewRating", + "activeStatus", + "displayStatus", + "replyCount", + "createAt", + "lastModifyAt" + ) + assertThat(values(response, "activeStatus")) + .containsExactlyInAnyOrder("ACTIVE", "DELETED", "DISABLED") + assertThat(values(response, "displayStatus")) + .containsExactlyInAnyOrder("PUBLIC", "PRIVATE", "PUBLIC") + } + + @Test + @DisplayName("필터 7종을 단독 적용할 때 결과를 좁힌다") + fun searchAdminReviews_filtersBySingleCondition() { + // given + val fixture = seedReviews() + + // when & then + assertReviewIds(getReviews("alcoholId" to fixture.alcoholA.id.toString()), fixture.activePublic.id, fixture.disabledPublic.id) + assertReviewIds(getReviews("userId" to fixture.userB.id.toString()), fixture.deletedPrivate.id) + assertReviewIds(getReviews("activeStatus" to "DELETED"), fixture.deletedPrivate.id) + assertReviewIds(getReviews("displayStatus" to "PRIVATE"), fixture.deletedPrivate.id) + assertReviewIds(getReviews("keyword" to "AlphaReviewer"), fixture.activePublic.id) + assertReviewIds(getReviews("createdFrom" to "2026-01-02T00:00:00"), fixture.activePublic.id, fixture.deletedPrivate.id) + assertReviewIds(getReviews("createdTo" to "2026-01-02T23:59:59"), fixture.deletedPrivate.id, fixture.disabledPublic.id) + } + + @Test + @DisplayName("키워드를 리뷰 본문, 작성자 이메일, 주류명에 적용한다") + fun searchAdminReviews_filtersByKeywordTargets() { + // given + val fixture = seedReviews() + + // when & then + assertReviewIds(getReviews("keyword" to "smoky keyword"), fixture.activePublic.id) + assertReviewIds(getReviews("keyword" to "beta-admin"), fixture.deletedPrivate.id) + assertReviewIds(getReviews("keyword" to "Admin Macallan"), fixture.deletedPrivate.id) + assertReviewIds(getReviews("keyword" to "Admin Ardbeg"), fixture.activePublic.id, fixture.disabledPublic.id) + } + + @Test + @DisplayName("정렬 조건과 방향을 적용한다") + fun searchAdminReviews_sortsByTypeAndOrder() { + // given + val fixture = seedReviews() + + // when & then + assertReviewIds(sorted(AdminReviewSortType.CREATED_AT, SortOrder.DESC), fixture.activePublic.id, fixture.deletedPrivate.id, fixture.disabledPublic.id) + assertReviewIds(sorted(AdminReviewSortType.CREATED_AT, SortOrder.ASC), fixture.disabledPublic.id, fixture.deletedPrivate.id, fixture.activePublic.id) + assertReviewIds(sorted(AdminReviewSortType.REPLY_COUNT, SortOrder.DESC), fixture.activePublic.id, fixture.disabledPublic.id, fixture.deletedPrivate.id) + assertReviewIds(sorted(AdminReviewSortType.REPLY_COUNT, SortOrder.ASC), fixture.deletedPrivate.id, fixture.disabledPublic.id, fixture.activePublic.id) + assertReviewIds(sorted(AdminReviewSortType.UPDATED_AT, SortOrder.DESC), fixture.deletedPrivate.id, fixture.activePublic.id, fixture.disabledPublic.id) + assertReviewIds(sorted(AdminReviewSortType.UPDATED_AT, SortOrder.ASC), fixture.disabledPublic.id, fixture.activePublic.id, fixture.deletedPrivate.id) + } + + @Test + @DisplayName("페이지 메타 정보를 반환한다") + fun searchAdminReviews_returnsPageMeta() { + // given + seedReviews() + + // when + val response = getReviews("page" to "0", "size" to "2") + + // then + assertThat(response.get("data")).hasSize(2) + assertThat(response.at("/meta/page").asInt()).isEqualTo(0) + assertThat(response.at("/meta/size").asInt()).isEqualTo(2) + assertThat(response.at("/meta/totalElements").asLong()).isEqualTo(3) + assertThat(response.at("/meta/totalPages").asInt()).isEqualTo(2) + assertThat(response.at("/meta/hasNext").asBoolean()).isTrue() + } + + @Test + @DisplayName("페이지 요청 값이 범위를 벗어나면 400을 반환한다") + fun searchAdminReviews_whenPageRequestOutOfRange_returnsBadRequest() { + // when & then + assertInvalidReviewSearch("page" to "-1") + assertInvalidReviewSearch("size" to "0") + assertInvalidReviewSearch("size" to "101") + } + + private fun sorted( + sortType: AdminReviewSortType, + sortOrder: SortOrder + ): JsonNode = getReviews("sortType" to sortType.name, "sortOrder" to sortOrder.name) + + private fun getReviews(vararg params: Pair): JsonNode { + val request = mockMvcTester + .get() + .uri("/v1/reviews") + .header("Authorization", "Bearer $accessToken") + params.forEach { request.param(it.first, it.second) } + + val result = request.exchange() + assertThat(result).hasStatusOk() + return mapper.readTree(result.response.contentAsString) + } + + private fun assertInvalidReviewSearch(vararg params: Pair) { + val request = mockMvcTester + .get() + .uri("/v1/reviews") + .header("Authorization", "Bearer $accessToken") + params.forEach { request.param(it.first, it.second) } + + assertThat(request.exchange()).hasStatus(400) + } + + private fun assertReviewIds( + response: JsonNode, + vararg expected: Long + ) { + assertThat(reviewIds(response)).containsExactly(*expected.toTypedArray()) + } + + private fun reviewIds(response: JsonNode): List = response.get("data").map { it.get("reviewId").asLong() } + + private fun values( + response: JsonNode, + fieldName: String + ): List = response.get("data").map { it.get(fieldName).asText() } + + private fun seedReviews(): SeededReviews { + val userA = userTestFactory.persistUser("alpha-admin", "AlphaReviewer") + val userB = userTestFactory.persistUser("beta-admin", "BetaReviewer") + val userC = userTestFactory.persistUser("gamma-admin", "GammaReviewer") + val alcoholA = alcoholTestFactory.persistAlcoholWithName("어드민 아드벡", "Admin Ardbeg") + val alcoholB = alcoholTestFactory.persistAlcoholWithName("어드민 맥캘란", "Admin Macallan") + + val disabledPublic = reviewTestFactory.persistAdminReview( + userC, + alcoholA, + "disabled oak note", + ReviewActiveStatus.DISABLED, + ReviewDisplayStatus.PUBLIC, + 3.0, + LocalDateTime.of(2026, 1, 1, 10, 0), + LocalDateTime.of(2026, 1, 4, 10, 0) + ) + val deletedPrivate = reviewTestFactory.persistAdminReview( + userB, + alcoholB, + "deleted private peat note", + ReviewActiveStatus.DELETED, + ReviewDisplayStatus.PRIVATE, + 4.0, + LocalDateTime.of(2026, 1, 2, 10, 0), + LocalDateTime.of(2026, 1, 6, 10, 0) + ) + val activePublic = reviewTestFactory.persistAdminReview( + userA, + alcoholA, + "active smoky keyword note", + ReviewActiveStatus.ACTIVE, + ReviewDisplayStatus.PUBLIC, + 4.5, + LocalDateTime.of(2026, 1, 3, 10, 0), + LocalDateTime.of(2026, 1, 5, 10, 0) + ) + reviewTestFactory.persistReviewReply(activePublic, userB) + reviewTestFactory.persistReviewReply(activePublic, userC) + reviewTestFactory.persistReviewReply(disabledPublic, userA) + + return SeededReviews(userA, userB, userC, alcoholA, alcoholB, activePublic, deletedPrivate, disabledPublic) + } + + private data class SeededReviews( + val userA: User, + val userB: User, + val userC: User, + val alcoholA: Alcohol, + val alcoholB: Alcohol, + val activePublic: Review, + val deletedPrivate: Review, + val disabledPublic: Review + ) +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/review/constant/AdminReviewSortType.java b/bottlenote-mono/src/main/java/app/bottlenote/review/constant/AdminReviewSortType.java new file mode 100644 index 000000000..cb4b3adc1 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/review/constant/AdminReviewSortType.java @@ -0,0 +1,14 @@ +package app.bottlenote.review.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum AdminReviewSortType { + CREATED_AT("작성일"), + REPLY_COUNT("댓글 수"), + UPDATED_AT("수정일"); + + private final String description; +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java index c996debe1..c9c0e422e 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java @@ -4,7 +4,9 @@ import app.bottlenote.global.service.cursor.PageResponse; import app.bottlenote.review.constant.ReviewActiveStatus; import app.bottlenote.review.constant.ReviewDisplayStatus; +import app.bottlenote.review.dto.request.AdminReviewSearchRequest; import app.bottlenote.review.dto.request.ReviewPageableRequest; +import app.bottlenote.review.dto.response.AdminReviewListResponse; import app.bottlenote.review.dto.response.AlcoholReviewCountResponse; import app.bottlenote.review.dto.response.ReviewExploreItem; import app.bottlenote.review.dto.response.ReviewListResponse; @@ -12,6 +14,7 @@ import java.util.List; import java.util.Optional; import org.apache.commons.lang3.tuple.Pair; +import org.springframework.data.domain.Page; public interface ReviewRepository { @@ -29,6 +32,8 @@ PageResponse getReviews( PageResponse getReviewsByMe( Long alcoholId, ReviewPageableRequest reviewPageableRequest, Long userId); + Page searchAdminReviews(AdminReviewSearchRequest request); + Optional findByIdAndUserId(Long reviewId, Long userId); List findByUserId(Long userId); diff --git a/bottlenote-mono/src/main/java/app/bottlenote/review/dto/request/AdminReviewSearchRequest.java b/bottlenote-mono/src/main/java/app/bottlenote/review/dto/request/AdminReviewSearchRequest.java new file mode 100644 index 000000000..5d09628c0 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/review/dto/request/AdminReviewSearchRequest.java @@ -0,0 +1,32 @@ +package app.bottlenote.review.dto.request; + +import app.bottlenote.global.service.cursor.SortOrder; +import app.bottlenote.review.constant.AdminReviewSortType; +import app.bottlenote.review.constant.ReviewActiveStatus; +import app.bottlenote.review.constant.ReviewDisplayStatus; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import java.time.LocalDateTime; + +public record AdminReviewSearchRequest( + Long alcoholId, + Long userId, + ReviewActiveStatus activeStatus, + ReviewDisplayStatus displayStatus, + String keyword, + LocalDateTime createdFrom, + LocalDateTime createdTo, + AdminReviewSortType sortType, + SortOrder sortOrder, + @Min(value = 0, message = "ADMIN_REVIEW_PAGE_MINIMUM") Integer page, + @Min(value = 1, message = "ADMIN_REVIEW_SIZE_MINIMUM") + @Max(value = 100, message = "ADMIN_REVIEW_SIZE_MAXIMUM") + Integer size) { + + public AdminReviewSearchRequest { + sortType = sortType != null ? sortType : AdminReviewSortType.CREATED_AT; + sortOrder = sortOrder != null ? sortOrder : SortOrder.DESC; + page = page != null ? page : 0; + size = size != null ? size : 20; + } +} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/review/dto/response/AdminReviewListResponse.java b/bottlenote-mono/src/main/java/app/bottlenote/review/dto/response/AdminReviewListResponse.java new file mode 100644 index 000000000..65e7b8da3 --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/review/dto/response/AdminReviewListResponse.java @@ -0,0 +1,19 @@ +package app.bottlenote.review.dto.response; + +import app.bottlenote.review.constant.ReviewActiveStatus; +import app.bottlenote.review.constant.ReviewDisplayStatus; +import java.time.LocalDateTime; + +public record AdminReviewListResponse( + Long reviewId, + Long alcoholId, + String alcoholName, + Long userId, + String userNickname, + String content, + Double reviewRating, + ReviewActiveStatus activeStatus, + ReviewDisplayStatus displayStatus, + Long replyCount, + LocalDateTime createAt, + LocalDateTime lastModifyAt) {} diff --git a/bottlenote-mono/src/main/java/app/bottlenote/review/repository/CustomReviewRepository.java b/bottlenote-mono/src/main/java/app/bottlenote/review/repository/CustomReviewRepository.java index ba1dd866d..2497db0a5 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/review/repository/CustomReviewRepository.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/review/repository/CustomReviewRepository.java @@ -2,12 +2,15 @@ import app.bottlenote.global.service.cursor.CursorResponse; import app.bottlenote.global.service.cursor.PageResponse; +import app.bottlenote.review.dto.request.AdminReviewSearchRequest; import app.bottlenote.review.dto.request.ReviewPageableRequest; +import app.bottlenote.review.dto.response.AdminReviewListResponse; import app.bottlenote.review.dto.response.ReviewExploreItem; import app.bottlenote.review.dto.response.ReviewListResponse; import app.bottlenote.review.facade.payload.ReviewInfo; import java.util.List; import org.apache.commons.lang3.tuple.Pair; +import org.springframework.data.domain.Page; public interface CustomReviewRepository { @@ -42,6 +45,8 @@ PageResponse getReviews( PageResponse getReviewsByMe( Long alcoholId, ReviewPageableRequest reviewPageableRequest, Long userId); + Page searchAdminReviews(AdminReviewSearchRequest request); + Pair> getStandardExplore( Long userId, List keywords, Long cursor, Integer size); } diff --git a/bottlenote-mono/src/main/java/app/bottlenote/review/repository/CustomReviewRepositoryImpl.java b/bottlenote-mono/src/main/java/app/bottlenote/review/repository/CustomReviewRepositoryImpl.java index 9ce329991..864276f8e 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/review/repository/CustomReviewRepositoryImpl.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/review/repository/CustomReviewRepositoryImpl.java @@ -8,6 +8,8 @@ import static app.bottlenote.review.domain.QReviewImage.reviewImage; import static app.bottlenote.review.domain.QReviewReply.reviewReply; import static app.bottlenote.review.domain.QReviewTastingTag.reviewTastingTag; +import static app.bottlenote.review.repository.ReviewQuerySupporter.adminReviewFilters; +import static app.bottlenote.review.repository.ReviewQuerySupporter.adminReviewSortBy; import static app.bottlenote.review.repository.ReviewQuerySupporter.containsKeywordInAll; import static app.bottlenote.review.repository.ReviewQuerySupporter.getCursorPageable; import static app.bottlenote.review.repository.ReviewQuerySupporter.getTastingTag; @@ -22,7 +24,9 @@ import app.bottlenote.global.service.cursor.CursorResponse; import app.bottlenote.global.service.cursor.PageResponse; import app.bottlenote.like.constant.LikeStatus; +import app.bottlenote.review.dto.request.AdminReviewSearchRequest; import app.bottlenote.review.dto.request.ReviewPageableRequest; +import app.bottlenote.review.dto.response.AdminReviewListResponse; import app.bottlenote.review.dto.response.ReviewExploreItem; import app.bottlenote.review.dto.response.ReviewListResponse; import app.bottlenote.review.facade.payload.ReviewInfo; @@ -40,6 +44,9 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.Pair; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; @Slf4j @RequiredArgsConstructor @@ -207,6 +214,67 @@ public PageResponse getReviewsByMe( return PageResponse.of(ReviewListResponse.of(totalCount, fetch), cursorPageable); } + @Override + public Page searchAdminReviews(AdminReviewSearchRequest request) { + List content = + queryFactory + .select( + Projections.constructor( + AdminReviewListResponse.class, + review.id, + alcohol.id, + alcohol.korName, + user.id, + user.nickName, + review.content, + review.reviewRating, + review.activeStatus, + review.status, + reviewReply.id.countDistinct(), + review.createAt, + review.lastModifyAt)) + .from(review) + .join(user) + .on(review.userId.eq(user.id)) + .leftJoin(alcohol) + .on(alcohol.id.eq(review.alcoholId)) + .leftJoin(reviewReply) + .on(review.id.eq(reviewReply.reviewId)) + .where(adminReviewFilters(request)) + .groupBy( + review.id, + alcohol.id, + alcohol.korName, + user.id, + user.nickName, + review.content, + review.reviewRating, + review.activeStatus, + review.status, + review.createAt, + review.lastModifyAt) + .orderBy( + adminReviewSortBy(request.sortType(), request.sortOrder()) + .toArray(new OrderSpecifier[0])) + .offset((long) request.page() * request.size()) + .limit(request.size()) + .fetch(); + + Long total = + queryFactory + .select(review.id.countDistinct()) + .from(review) + .join(user) + .on(review.userId.eq(user.id)) + .leftJoin(alcohol) + .on(alcohol.id.eq(review.alcoholId)) + .where(adminReviewFilters(request)) + .fetchOne(); + + return new PageImpl<>( + content, PageRequest.of(request.page(), request.size()), total != null ? total : 0L); + } + @Override public Pair> getStandardExplore( Long userId, List keywords, Long cursor, Integer size) { diff --git a/bottlenote-mono/src/main/java/app/bottlenote/review/repository/ReviewQuerySupporter.java b/bottlenote-mono/src/main/java/app/bottlenote/review/repository/ReviewQuerySupporter.java index cd86fd4f3..58497213b 100644 --- a/bottlenote-mono/src/main/java/app/bottlenote/review/repository/ReviewQuerySupporter.java +++ b/bottlenote-mono/src/main/java/app/bottlenote/review/repository/ReviewQuerySupporter.java @@ -14,8 +14,11 @@ import app.bottlenote.global.service.cursor.CursorPageable; import app.bottlenote.global.service.cursor.SortOrder; +import app.bottlenote.review.constant.AdminReviewSortType; import app.bottlenote.review.constant.ReviewActiveStatus; +import app.bottlenote.review.constant.ReviewDisplayStatus; import app.bottlenote.review.constant.ReviewSortType; +import app.bottlenote.review.dto.request.AdminReviewSearchRequest; import app.bottlenote.review.dto.request.ReviewPageableRequest; import app.bottlenote.review.facade.payload.ReviewInfo; import app.bottlenote.review.facade.payload.UserInfo; @@ -173,6 +176,73 @@ public static List> sortBy(ReviewSortType reviewSortType, Sort }; } + public static BooleanExpression[] adminReviewFilters(AdminReviewSearchRequest request) { + return new BooleanExpression[] { + alcoholIdEq(request.alcoholId()), + userIdEq(request.userId()), + activeStatusEq(request.activeStatus()), + displayStatusEq(request.displayStatus()), + adminKeywordContains(request.keyword()), + createdFromGoe(request.createdFrom()), + createdToLoe(request.createdTo()) + }; + } + + public static List> adminReviewSortBy( + AdminReviewSortType sortType, SortOrder sortOrder) { + Order order = sortOrder == SortOrder.ASC ? Order.ASC : Order.DESC; + NumberExpression replyCount = reviewReply.id.countDistinct(); + OrderSpecifier latestReview = review.createAt.desc(); + OrderSpecifier latestReviewId = review.id.desc(); + + OrderSpecifier primary = + switch (sortType) { + case CREATED_AT -> new OrderSpecifier<>(order, review.createAt); + case REPLY_COUNT -> new OrderSpecifier<>(order, replyCount); + case UPDATED_AT -> new OrderSpecifier<>(order, review.lastModifyAt); + }; + + return Arrays.asList(primary, latestReview, latestReviewId); + } + + private static BooleanExpression alcoholIdEq(Long alcoholId) { + return alcoholId != null ? review.alcoholId.eq(alcoholId) : null; + } + + private static BooleanExpression userIdEq(Long userId) { + return userId != null ? review.userId.eq(userId) : null; + } + + private static BooleanExpression activeStatusEq(ReviewActiveStatus activeStatus) { + return activeStatus != null ? review.activeStatus.eq(activeStatus) : null; + } + + private static BooleanExpression displayStatusEq(ReviewDisplayStatus displayStatus) { + return displayStatus != null ? review.status.eq(displayStatus) : null; + } + + private static BooleanExpression adminKeywordContains(String keyword) { + if (keyword == null || keyword.isBlank()) { + return null; + } + String value = "%" + keyword.trim() + "%"; + return review + .content + .likeIgnoreCase(value) + .or(user.nickName.likeIgnoreCase(value)) + .or(user.email.likeIgnoreCase(value)) + .or(alcohol.korName.likeIgnoreCase(value)) + .or(alcohol.engName.likeIgnoreCase(value)); + } + + private static BooleanExpression createdFromGoe(java.time.LocalDateTime createdFrom) { + return createdFrom != null ? review.createAt.goe(createdFrom) : null; + } + + private static BooleanExpression createdToLoe(java.time.LocalDateTime createdTo) { + return createdTo != null ? review.createAt.loe(createdTo) : null; + } + /** 키워드를 이용해 작성자, 주류 정보, 리뷰 콘텐츠, 테이스팅 태그를 모두 검색하는 조건 생성 */ public static BooleanExpression containsKeywordInAll(List keywords) { if (keywords == null || keywords.isEmpty()) { diff --git a/bottlenote-mono/src/main/java/app/bottlenote/review/service/AdminReviewQueryService.java b/bottlenote-mono/src/main/java/app/bottlenote/review/service/AdminReviewQueryService.java new file mode 100644 index 000000000..1daac6ead --- /dev/null +++ b/bottlenote-mono/src/main/java/app/bottlenote/review/service/AdminReviewQueryService.java @@ -0,0 +1,20 @@ +package app.bottlenote.review.service; + +import app.bottlenote.global.data.response.GlobalResponse; +import app.bottlenote.review.domain.ReviewRepository; +import app.bottlenote.review.dto.request.AdminReviewSearchRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class AdminReviewQueryService { + + private final ReviewRepository reviewRepository; + + @Transactional(readOnly = true) + public GlobalResponse searchReviews(AdminReviewSearchRequest request) { + return GlobalResponse.fromPage(reviewRepository.searchAdminReviews(request)); + } +} diff --git a/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java b/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java index 4a6484cf3..3c4c79d11 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java @@ -6,7 +6,9 @@ import app.bottlenote.review.constant.ReviewDisplayStatus; import app.bottlenote.review.domain.Review; import app.bottlenote.review.domain.ReviewRepository; +import app.bottlenote.review.dto.request.AdminReviewSearchRequest; import app.bottlenote.review.dto.request.ReviewPageableRequest; +import app.bottlenote.review.dto.response.AdminReviewListResponse; import app.bottlenote.review.dto.response.AlcoholReviewCountResponse; import app.bottlenote.review.dto.response.ReviewExploreItem; import app.bottlenote.review.dto.response.ReviewListResponse; @@ -19,6 +21,9 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; import org.springframework.test.util.ReflectionTestUtils; public class InMemoryReviewRepository implements ReviewRepository { @@ -67,6 +72,11 @@ public PageResponse getReviewsByMe( return null; } + @Override + public Page searchAdminReviews(AdminReviewSearchRequest request) { + return new PageImpl<>(List.of(), PageRequest.of(request.page(), request.size()), 0); + } + @Override public Optional findByIdAndUserId(Long reviewId, Long userId) { return Optional.empty(); diff --git a/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/ReviewTestFactory.java b/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/ReviewTestFactory.java index 3121442f4..262f6fb7e 100644 --- a/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/ReviewTestFactory.java +++ b/bottlenote-mono/src/test/java/app/bottlenote/review/fixture/ReviewTestFactory.java @@ -12,6 +12,7 @@ import app.bottlenote.user.domain.User; import jakarta.persistence.EntityManager; import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import lombok.RequiredArgsConstructor; @@ -104,6 +105,35 @@ public Review persistReview(@NotNull Review.ReviewBuilder builder) { return review; } + /** 어드민 리뷰 목록 테스트용 Review 생성 */ + @Transactional + @NotNull + public Review persistAdminReview( + @NotNull User user, + @NotNull Alcohol alcohol, + @NotNull String content, + @NotNull ReviewActiveStatus activeStatus, + @NotNull ReviewDisplayStatus displayStatus, + double reviewRating, + @NotNull LocalDateTime createAt, + @NotNull LocalDateTime lastModifyAt) { + Review review = + Review.builder() + .userId(user.getId()) + .alcoholId(alcohol.getId()) + .content(content) + .sizeType(SizeType.BOTTLE) + .price(BigDecimal.valueOf(50000)) + .reviewRating(reviewRating) + .activeStatus(activeStatus) + .status(displayStatus) + .build(); + em.persist(review); + em.flush(); + updateReviewTimestamps(review.getId(), createAt, lastModifyAt); + return review; + } + /** 여러 Review 일괄 생성 */ @Transactional @NotNull @@ -256,6 +286,19 @@ private String generateRandomSuffix() { return String.valueOf(counter.incrementAndGet()); } + private void updateReviewTimestamps( + @NotNull Long reviewId, + @NotNull LocalDateTime createAt, + @NotNull LocalDateTime lastModifyAt) { + em.createNativeQuery( + "UPDATE reviews SET create_at = :createAt, last_modify_at = :lastModifyAt WHERE id = :id") + .setParameter("createAt", createAt) + .setParameter("lastModifyAt", lastModifyAt) + .setParameter("id", reviewId) + .executeUpdate(); + em.flush(); + } + /** Review 빌더의 누락 필드 채우기 */ private Review.ReviewBuilder fillMissingReviewFields(Review.ReviewBuilder builder) { // 빌더를 임시로 빌드해서 필드 체크 diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java b/bottlenote-product-api/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java index 82721334c..eb02d8afb 100644 --- a/bottlenote-product-api/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java +++ b/bottlenote-product-api/src/test/java/app/bottlenote/review/fixture/InMemoryReviewRepository.java @@ -6,7 +6,9 @@ import app.bottlenote.review.constant.ReviewDisplayStatus; import app.bottlenote.review.domain.Review; import app.bottlenote.review.domain.ReviewRepository; +import app.bottlenote.review.dto.request.AdminReviewSearchRequest; import app.bottlenote.review.dto.request.ReviewPageableRequest; +import app.bottlenote.review.dto.response.AdminReviewListResponse; import app.bottlenote.review.dto.response.AlcoholReviewCountResponse; import app.bottlenote.review.dto.response.ReviewExploreItem; import app.bottlenote.review.dto.response.ReviewListResponse; @@ -19,6 +21,9 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; import org.springframework.test.util.ReflectionTestUtils; public class InMemoryReviewRepository implements ReviewRepository { @@ -67,6 +72,11 @@ public PageResponse getReviewsByMe( return null; } + @Override + public Page searchAdminReviews(AdminReviewSearchRequest request) { + return new PageImpl<>(List.of(), PageRequest.of(request.page(), request.size()), 0); + } + @Override public Optional findByIdAndUserId(Long reviewId, Long userId) { return database.values().stream() diff --git a/plan/complete/admin-review-list.md b/plan/complete/admin-review-list.md new file mode 100644 index 000000000..8e7b98564 --- /dev/null +++ b/plan/complete/admin-review-list.md @@ -0,0 +1,171 @@ +``` +================================================================================ + PROJECT COMPLETION STAMP +================================================================================ +Status: **COMPLETED** +Completion Date: 2026-05-14 + +** Core Achievements ** +- 어드민 리뷰 목록 조회 GET API 추가 (bottlenote-admin-api): `GET /admin/api/v1/reviews` — 필터 7종(alcoholId / userId / activeStatus / displayStatus / keyword / createdFrom / createdTo) + 정렬 3종(CREATED_AT / REPLY_COUNT / UPDATED_AT) + 전체 상태(ACTIVE/DELETED/DISABLED, PUBLIC/PRIVATE) 노출 +- Task 4개 전부 커밋: 50caf5ae(기본 조회) / 669a038d(필터·정렬) / d4137a56(통합 테스트) / a0428009(RestDocs) +- /verify full L3 8단계 전부 PASS (compile / lint / arch / unit / build / integration / admin-integration / asciidoctor, 11m 28s) +- DB 스키마 변경 0건, 기존 product 리뷰 조회 정책 무변 + +** Key Components ** +- AdminReviewController.kt (bottlenote-admin-api, presentation) — GET /reviews 엔드포인트 +- AdminReviewQueryService (bottlenote-mono) — 어드민 전용 read-only 조회 서비스 +- CustomReviewRepository / CustomReviewRepositoryImpl + ReviewQuerySupporter — QueryDSL 동적 필터·정렬 +- AdminReviewSearchRequest / AdminReviewListResponse / AdminReviewSortType +- AdminReviewIntegrationTest (@Tag("admin_integration")) + AdminReviewControllerDocsTest (RestDocs) +- InMemoryReviewRepository 2곳(mono / product) 갱신 — domain interface 변경 동기화 + +** Deferred Items ** +- [Important] AdminReviewIntegrationTest 의 keyword 검색 커버리지에 한글 주류명(alcohol.korName) 케이스 누락 — 구현은 포함돼 있으나 회귀 방지 테스트 부재. /test 로 보강 권장 +- [Nit] AdminReviewControllerDocsTest 의 PageImpl 예시를 PageRequest 명시 형태로 정리하면 문서 일관성 향상 + +** GSL 검증 메모 ** +- 본 작업은 GSL 강화본(B1'~B5)이 codex 런타임에서 게이트를 지키는지 실전 검증을 겸함 +- /define → /plan → /implement Task 1~4 → /verify full → /self-review → /next-flow 전 단계에서 codex 가 "Runtime Boundary — HARD STOP" 을 준수, 모호한 "진행하자" 에도 Task 단위로만 진행 (news-admin 구버전 폭주 대비 단계별 정지 확인) +================================================================================ +``` + +# Plan: 어드민 리뷰 목록 조회 API + +## Overview + +어드민이 리뷰 운영 상태를 한 화면에서 확인할 수 있도록 `bottlenote-admin-api`에 리뷰 목록 조회 `GET` API를 추가한다. API 표면은 Kotlin `presentation` 패키지에 두고, 조회 조건 조합과 목록 응답 생성은 `bottlenote-mono`의 어드민 전용 리뷰 조회 서비스와 QueryDSL 기반 repository 확장으로 처리한다. + +범위는 목록 조회만 포함한다. 단건 상세 조회, 리뷰 상태 변경, DB 스키마 변경, 기존 product 리뷰 조회 정책 변경은 포함하지 않는다. + +### Assumptions + +- endpoint는 admin context path `/admin/api/v1` 아래 `GET /reviews`로 둔다. +- 컨트롤러는 `bottlenote-admin-api/src/main/kotlin/app/bottlenote/review/presentation/AdminReviewController.kt`에 신설한다. +- 요청 DTO, 응답 DTO, sort enum, 어드민 전용 조회 서비스는 `bottlenote-mono`의 `app.bottlenote.review` 하위에 둔다. +- 어드민 목록 조회는 인증된 admin API surface로 동작하며, 현재 `bottlenote-admin-api`의 SecurityConfig 정책을 그대로 따른다. +- 페이징은 기존 어드민 검색 API와 맞춰 `page`, `size` 기반 offset pagination과 `GlobalResponse.fromPage(Page)` 응답을 사용한다. +- 필터는 `alcoholId`, `userId`, `activeStatus`, `displayStatus`, `keyword`, `createdFrom`, `createdTo`를 지원한다. +- `keyword`는 리뷰 본문과 작성자 식별 정보 중 기존 join으로 안정적으로 제공 가능한 값에 적용한다. 정확한 대상 컬럼은 `/plan`에서 기존 user/alcohol join 비용을 보고 확정한다. +- 정렬은 `CREATED_AT`, `REPLY_COUNT`, `UPDATED_AT` 3종과 `sortOrder`를 지원하며 기본값은 `CREATED_AT DESC`다. +- 모든 상태 노출 요구사항에 따라 기본 조회는 `ReviewActiveStatus.ACTIVE/DELETED/DISABLED`와 `ReviewDisplayStatus.PUBLIC/PRIVATE`를 모두 포함하고, 상태 파라미터가 있을 때만 좁힌다. +- 응답 항목에는 운영 목록에서 식별과 판단에 필요한 최소 필드인 `reviewId`, `alcoholId`, `alcoholName`, `userId`, `userNickname`, `content`, `reviewRating`, `activeStatus`, `displayStatus`, `replyCount`, `createAt`, `lastModifyAt`를 포함한다. +- 댓글 수 정렬은 기존 `ReviewReply` 데이터를 집계해서 산출하며, 별도 counter column이나 schema migration은 추가하지 않는다. + +### Success Criteria + +- `GET /admin/api/v1/reviews`가 `GlobalResponse` 형식으로 리뷰 목록과 page meta를 반환한다. +- 필터 7종 중 각각을 단독 적용했을 때 결과가 해당 조건으로 좁혀진다: `alcoholId`, `userId`, `activeStatus`, `displayStatus`, `keyword`, `createdFrom`, `createdTo`. +- `activeStatus` 미지정 시 `ACTIVE`, `DELETED`, `DISABLED` 리뷰가 모두 조회 대상에 포함된다. +- `displayStatus` 미지정 시 `PUBLIC`, `PRIVATE` 리뷰가 모두 조회 대상에 포함된다. +- 정렬 `CREATED_AT`, `REPLY_COUNT`, `UPDATED_AT`가 각각 `ASC`/`DESC` 방향으로 동작한다. +- 단건 상세 API나 상태 변경 API가 추가되지 않는다. +- DB migration 파일이 추가되지 않는다. +- 기존 product 리뷰 목록/상세 조회는 계속 `ACTIVE`와 공개 정책을 유지한다. +- admin controller docs 또는 admin integration 테스트에서 필터, 전체 상태 노출, 정렬, page meta를 검증한다. +- `./gradlew :bottlenote-admin-api:test` 또는 관련 admin integration/docs 테스트 태스크로 변경 범위를 검증할 수 있다. + +### Impact Scope + +- `bottlenote-admin-api` + - 새 admin review presentation controller 추가 + - admin docs/integration 테스트 추가 가능 +- `bottlenote-mono` + - admin review search request/response DTO 추가 + - admin review sort enum 추가 + - admin 전용 read-only service 추가 + - `ReviewRepository` 또는 `CustomReviewRepository` 계열에 admin 목록 조회 query 추가 + - `Review`, `ReviewReply`, `User`, `Alcohol` join 및 댓글 수 집계 사용 +- Persistence + - DB 스키마 변경 없음 + - 기존 `reviews.active_status`, `reviews.status`, `reviews.create_at`, `reviews.last_modify_at` 필드 사용 +- Async / Events + - 새 이벤트 발행 또는 소비 없음 +- Cache + - 신규 캐시와 invalidation 정책 없음 +- API Contract / Docs + - admin API 계약 추가 + - product API 계약 변경 없음 +- Tests + - QueryDSL 조건 조합 검증 + - admin controller 문서 또는 통합 테스트 + - 상태 미지정 시 전체 상태 노출 회귀 방지 + +## Tasks + +의존성 순서는 `bottlenote-mono` 조회 경로를 먼저 만들고, `bottlenote-admin-api` HTTP surface를 같은 기본 목록 slice에 연결한 뒤, 필터/정렬과 검증 범위를 확장한다. 모든 Task는 L 사이즈(8개 이상 파일)를 피하고, 한 번에 커밋 가능한 수직 slice로 유지한다. + +### Task 1: 기본 어드민 리뷰 목록 조회 slice +- Acceptance: `GET /admin/api/v1/reviews`가 인증된 admin 요청에서 기본 `page=0`, `size=20`, `CREATED_AT DESC` 목록을 `GlobalResponse.fromPage(Page)` 형태로 반환한다. +- Acceptance: 응답 항목에 `reviewId`, `alcoholId`, `alcoholName`, `userId`, `userNickname`, `content`, `reviewRating`, `activeStatus`, `displayStatus`, `replyCount`, `createAt`, `lastModifyAt`가 포함된다. +- Acceptance: 상태 파라미터가 없을 때 `ACTIVE`, `DELETED`, `DISABLED` 및 `PUBLIC`, `PRIVATE` 리뷰가 조회 대상에서 제외되지 않는다. +- Verification: `./gradlew :bottlenote-mono:compileJava :bottlenote-admin-api:compileKotlin` +- Files: `bottlenote-mono/src/main/java/app/bottlenote/review/dto/request/AdminReviewSearchRequest.java`, `bottlenote-mono/src/main/java/app/bottlenote/review/dto/response/AdminReviewListResponse.java`, `bottlenote-mono/src/main/java/app/bottlenote/review/service/AdminReviewQueryService.java`, `bottlenote-mono/src/main/java/app/bottlenote/review/domain/ReviewRepository.java`, `bottlenote-mono/src/main/java/app/bottlenote/review/repository/CustomReviewRepository.java`, `bottlenote-mono/src/main/java/app/bottlenote/review/repository/CustomReviewRepositoryImpl.java`, `bottlenote-admin-api/src/main/kotlin/app/bottlenote/review/presentation/AdminReviewController.kt` +- Size: M +- Status: [x] done + +### Task 2: 필터와 정렬 query slice +- Acceptance: `alcoholId`, `userId`, `activeStatus`, `displayStatus`, `keyword`, `createdFrom`, `createdTo`가 단독 적용될 때 QueryDSL where 조건으로 결과를 좁힌다. +- Acceptance: `keyword`는 리뷰 본문, 작성자 닉네임, 작성자 이메일, 주류 한글명, 주류 영문명에 적용한다. +- Acceptance: `CREATED_AT`, `REPLY_COUNT`, `UPDATED_AT` 정렬이 `ASC`/`DESC`로 동작하고 동일 정렬값에서는 최신 리뷰가 보조 정렬된다. +- Verification: `./gradlew :bottlenote-mono:compileJava :bottlenote-admin-api:compileKotlin` +- Files: `bottlenote-mono/src/main/java/app/bottlenote/review/constant/AdminReviewSortType.java`, `bottlenote-mono/src/main/java/app/bottlenote/review/dto/request/AdminReviewSearchRequest.java`, `bottlenote-mono/src/main/java/app/bottlenote/review/repository/CustomReviewRepositoryImpl.java`, `bottlenote-mono/src/main/java/app/bottlenote/review/repository/ReviewQuerySupporter.java` +- Size: M +- Status: [x] done + +### Checkpoint: after Tasks 1-2 +- [x] `bottlenote-mono` Java compile passes +- [x] `bottlenote-admin-api` Kotlin compile passes +- [x] No DB migration file is added +- [x] Product review query policy remains unchanged + +### Task 3: 어드민 리뷰 목록 통합 테스트 slice +- Acceptance: admin integration 테스트가 기본 목록, 전체 active/display 상태 노출, 7종 필터 단독 적용을 검증한다. +- Acceptance: admin integration 테스트가 `CREATED_AT`, `REPLY_COUNT`, `UPDATED_AT` 정렬과 `ASC`/`DESC` 방향, page meta를 검증한다. +- Acceptance: 테스트 데이터는 기존 Testcontainers 기반 factory를 사용하고 Mock 기반 repository 대체를 추가하지 않는다. +- Verification: `./gradlew admin_integration_test --tests '*AdminReviewIntegrationTest'` +- Files: `bottlenote-admin-api/src/test/kotlin/app/integration/review/AdminReviewIntegrationTest.kt`, `bottlenote-mono/src/test/java/app/bottlenote/review/fixture/ReviewTestFactory.java` +- Size: S +- Status: [x] done + +### Task 4: 어드민 리뷰 목록 RestDocs 계약 slice +- Acceptance: RestDocs 테스트가 `GET /reviews` query parameters와 응답 필드, page meta를 문서화한다. +- Acceptance: 문서에는 목록 조회만 포함하고 단건 상세 조회, 상태 변경 API, DB migration 내용은 추가하지 않는다. +- Acceptance: admin default test에서 새 DocsTest가 함께 통과한다. +- Verification: `./gradlew :bottlenote-admin-api:test --tests '*AdminReviewControllerDocsTest'` +- Files: `bottlenote-admin-api/src/test/kotlin/app/docs/review/AdminReviewControllerDocsTest.kt`, `bottlenote-admin-api/src/docs/asciidoc/admin-review.adoc` +- Size: S +- Status: [x] done + +### Checkpoint: after Tasks 3-4 +- [ ] `./gradlew admin_integration_test --tests '*AdminReviewIntegrationTest'` passes +- [x] `./gradlew :bottlenote-admin-api:test --tests '*AdminReviewControllerDocsTest'` passes +- [x] `./gradlew :bottlenote-admin-api:test` passes or any unrelated failure is recorded with evidence +- [x] API contract still exposes only `GET /admin/api/v1/reviews` + +## Progress Log + +### 2026-05-14 — Task 1 +- Implemented admin review basic list slice for `GET /admin/api/v1/reviews`. +- Added mono request/response DTOs, read-only admin query service, `ReviewRepository.searchAdminReviews`, QueryDSL projection, and admin Kotlin controller. +- Updated `InMemoryReviewRepository` implementations in mono/product test fixtures because the domain repository interface changed. +- Verification: `./gradlew :bottlenote-mono:compileJava :bottlenote-admin-api:compileKotlin` passed. + +### 2026-05-14 — Task 2 +- Added admin review sort type and request defaults for `CREATED_AT DESC`. +- Added QueryDSL filters for `alcoholId`, `userId`, `activeStatus`, `displayStatus`, `keyword`, `createdFrom`, and `createdTo`. +- Added admin review ordering for `CREATED_AT`, `REPLY_COUNT`, and `UPDATED_AT` with latest-review tie breakers. +- Verification: `./gradlew :bottlenote-mono:compileJava :bottlenote-admin-api:compileKotlin` passed. + +### 2026-05-14 — Task 3 +- Added `AdminReviewIntegrationTest` with `@Tag("admin_integration")` for default list response fields, all active/display state exposure, 7 standalone filters, keyword targets, 3 sort types with both directions, and page meta. +- Extended `ReviewTestFactory` with a Testcontainers-backed admin review fixture method that persists real `Review` rows and fixes `create_at` / `last_modify_at` via the test database. +- Verification note: root aggregate command `./gradlew admin_integration_test --tests '*AdminReviewIntegrationTest'` failed because the aggregate task does not accept `--tests`. +- Verification: `git submodule update --init --recursive` completed for missing `git.environment-variables`; `./gradlew :bottlenote-admin-api:admin_integration_test --tests '*AdminReviewIntegrationTest'` passed. + +### 2026-05-14 — Task 4 +- Added `AdminReviewControllerDocsTest` for `GET /admin/api/v1/reviews` query parameters, response fields, and page meta. +- Added `admin-review.adoc` and linked it from `admin-api.adoc`; the document includes only the admin review list API. +- Verification: `./gradlew :bottlenote-admin-api:test --tests '*AdminReviewControllerDocsTest'` passed. +- Verification: `./gradlew :bottlenote-admin-api:test` passed, confirming the new admin DocsTest runs in the default admin test task. +- Verification: `./gradlew :bottlenote-admin-api:asciidoctor` passed. +- Contract check: `rg -n "@(?:Get|Post|Put|Patch|Delete)Mapping|/reviews|admin/reviews|Review API|admin-review" ...` found only `@GetMapping` on `/reviews`, the list DocsTest, and the list document include. From 3530206bdc1f74bc2bcd1f601db74289180e588c Mon Sep 17 00:00:00 2001 From: Whale0928 Date: Mon, 18 May 2026 17:43:42 +0900 Subject: [PATCH 28/33] =?UTF-8?q?test:=20RestDocs=20=ED=83=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=A0=95=EC=B1=85=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/github-pages.yml | 7 +- bottlenote-admin-api/build.gradle.kts | 2 +- .../AdminAlcoholsControllerDocsTest.kt | 2 + .../AdminDistilleryControllerDocsTest.kt | 2 + .../alcohols/AdminRegionControllerDocsTest.kt | 2 + .../AdminTastingTagControllerDocsTest.kt | 2 + .../app/docs/auth/AuthControllerDocsTest.kt | 2 + .../banner/AdminBannerControllerDocsTest.kt | 2 + .../AdminCurationControllerDocsTest.kt | 2 + ...dminSpecBasedCurationControllerDocsTest.kt | 2 + .../AdminImageUploadControllerDocsTest.kt | 2 + .../docs/help/AdminHelpControllerDocsTest.kt | 2 + .../docs/user/AdminUsersControllerDocsTest.kt | 2 + .../user/service/AdminAuthServiceTest.java | 5 - bottlenote-product-api/build.gradle | 2 +- .../asciidoc/api/review/review-modify.adoc | 9 +- ...stomJpaAlcoholQueryRepositoryImplTest.java | 183 ------------------ .../upload/MinioContainerLoadingTest.java | 2 + .../event/UserHistoryListenerTest.java | 2 + .../CustomRatingQueryRepositoryImplTest.java | 44 ----- .../user/service/OauthServiceTest.java | 157 --------------- .../RestAlcoholExploreControllerTest.java | 2 + .../RestAlcoholQueryControllerTest.java | 2 + .../RestAlcoholReferenceControllerTest.java | 2 +- .../alcohols/RestPopularControllerTest.java | 2 + .../alcohols/RestReferenceControllerTest.java | 2 + .../RestTastingTagControllerTest.java | 2 +- .../banner/RestBannerQueryControllerTest.java | 2 + ...roductSpecBasedCurationControllerTest.java | 2 + .../follow/RestDocsFollowControllerTest.java | 2 + .../docs/history/RestDocsUserHistoryTest.java | 2 + .../likes/RestLikesControllerDocsTest.java | 2 + .../picks/RestPicksCommandControllerTest.java | 2 + .../docs/rating/RestRatingControllerTest.java | 2 + .../review/RestReviewControllerDocsTest.java | 2 + .../RestReviewExploreControllerTest.java | 2 + .../review/RestReviewReplyControllerTest.java | 2 +- .../block/RestDocsBlockControllerTest.java | 2 + .../RestDocsHelpCommandControllerTest.java | 2 + .../RestDocsReportCommandControllerTest.java | 2 + .../upload/RestImageUploadControllerTest.java | 2 + .../user/OpenApiAuthV2ControllerTest.java | 2 +- .../docs/user/RestAuthV2ControllerTest.java | 2 +- .../user/RestDocsUserChangeContollerTest.java | 2 + .../user/RestDocsUserQueryControllerTest.java | 2 +- .../docs/user/RestOauthControllerTest.java | 2 +- .../user/RestUserBasicControllerTest.java | 2 + .../test/java/app/rule/test/TestTagRules.java | 86 ++++++++ build.gradle | 52 ++++- 49 files changed, 215 insertions(+), 410 deletions(-) delete mode 100644 bottlenote-mono/src/test/java/app/bottlenote/user/service/AdminAuthServiceTest.java delete mode 100644 bottlenote-product-api/src/test/java/app/bottlenote/alcohols/repository/CustomJpaAlcoholQueryRepositoryImplTest.java delete mode 100644 bottlenote-product-api/src/test/java/app/bottlenote/rating/repository/CustomRatingQueryRepositoryImplTest.java create mode 100644 bottlenote-product-api/src/test/java/app/rule/test/TestTagRules.java diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index ea3b36186..5c9b4245f 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -8,6 +8,7 @@ on: - 'bottlenote-*/src/test/java/**/docs/**' - 'bottlenote-*/src/test/kotlin/**/docs/**' - 'bottlenote-*/build.gradle*' + - 'build.gradle' - 'gradle/libs.versions.toml' - 'docs/**' - '.github/workflows/github-pages.yml' @@ -38,8 +39,8 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 - - name: Generate REST Docs snippets - run: ./gradlew restDocsTest + - name: Generate and assemble REST Docs + run: ./gradlew docs_test - name: Setup Node.js uses: actions/setup-node@v4 @@ -89,4 +90,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 \ No newline at end of file + uses: actions/deploy-pages@v4 diff --git a/bottlenote-admin-api/build.gradle.kts b/bottlenote-admin-api/build.gradle.kts index b04d1bcb6..714624624 100644 --- a/bottlenote-admin-api/build.gradle.kts +++ b/bottlenote-admin-api/build.gradle.kts @@ -79,7 +79,7 @@ tasks.jar { tasks.asciidoctor { inputs.dir(snippetsDir) configurations(asciidoctorExt.name) - dependsOn(tasks.test) + dependsOn(tasks.named("restDocsTest")) sources { include("**/admin-api.adoc") } diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminAlcoholsControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminAlcoholsControllerDocsTest.kt index 92f87e92a..31d1f0338 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminAlcoholsControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminAlcoholsControllerDocsTest.kt @@ -14,6 +14,7 @@ import app.helper.alcohols.AlcoholsHelper import com.fasterxml.jackson.databind.ObjectMapper import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.mockito.BDDMockito.given import org.mockito.Mockito.any @@ -36,6 +37,7 @@ import org.springframework.test.web.servlet.assertj.MockMvcTester excludeAutoConfiguration = [SecurityAutoConfiguration::class] ) @AutoConfigureRestDocs +@Tag("restdocs") @DisplayName("Admin Alcohol 컨트롤러 RestDocs 테스트") class AdminAlcoholsControllerDocsTest { diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminDistilleryControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminDistilleryControllerDocsTest.kt index 854fd2952..8c17cbe5e 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminDistilleryControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminDistilleryControllerDocsTest.kt @@ -14,6 +14,7 @@ import app.helper.alcohols.AlcoholsHelper import com.fasterxml.jackson.databind.ObjectMapper import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyLong @@ -42,6 +43,7 @@ import java.time.LocalDateTime excludeAutoConfiguration = [SecurityAutoConfiguration::class] ) @AutoConfigureRestDocs +@Tag("restdocs") @DisplayName("Admin Distillery 컨트롤러 RestDocs 테스트") class AdminDistilleryControllerDocsTest { diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminRegionControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminRegionControllerDocsTest.kt index e42c357d6..918b8d395 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminRegionControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminRegionControllerDocsTest.kt @@ -8,6 +8,7 @@ import app.bottlenote.global.data.response.GlobalResponse import app.helper.alcohols.AlcoholsHelper import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.any import org.mockito.BDDMockito.given @@ -31,6 +32,7 @@ import org.springframework.test.web.servlet.assertj.MockMvcTester excludeAutoConfiguration = [SecurityAutoConfiguration::class] ) @AutoConfigureRestDocs +@Tag("restdocs") @DisplayName("Admin Region 컨트롤러 RestDocs 테스트") class AdminRegionControllerDocsTest { diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminTastingTagControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminTastingTagControllerDocsTest.kt index c28a15a4d..15a237d72 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminTastingTagControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/alcohols/AdminTastingTagControllerDocsTest.kt @@ -15,6 +15,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyLong @@ -39,6 +40,7 @@ import java.time.LocalDateTime excludeAutoConfiguration = [SecurityAutoConfiguration::class] ) @AutoConfigureRestDocs +@Tag("restdocs") @DisplayName("Admin TastingTag 컨트롤러 RestDocs 테스트") class AdminTastingTagControllerDocsTest { diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/auth/AuthControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/auth/AuthControllerDocsTest.kt index 358cf6074..a25104b65 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/auth/AuthControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/auth/AuthControllerDocsTest.kt @@ -11,6 +11,7 @@ import app.helper.auth.AuthHelper import com.fasterxml.jackson.databind.ObjectMapper import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyLong import org.mockito.BDDMockito.given @@ -38,6 +39,7 @@ import java.util.* excludeAutoConfiguration = [SecurityAutoConfiguration::class] ) @AutoConfigureRestDocs +@Tag("restdocs") @DisplayName("Admin Auth 컨트롤러 RestDocs 테스트") class AuthControllerDocsTest { diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/banner/AdminBannerControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/banner/AdminBannerControllerDocsTest.kt index 288402730..a204bbf5f 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/banner/AdminBannerControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/banner/AdminBannerControllerDocsTest.kt @@ -14,6 +14,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyLong @@ -37,6 +38,7 @@ import org.springframework.test.web.servlet.assertj.MockMvcTester excludeAutoConfiguration = [SecurityAutoConfiguration::class] ) @AutoConfigureRestDocs +@Tag("restdocs") @DisplayName("Admin Banner 컨트롤러 RestDocs 테스트") class AdminBannerControllerDocsTest { diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminCurationControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminCurationControllerDocsTest.kt index 2c6532ec9..3c0d8662a 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminCurationControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminCurationControllerDocsTest.kt @@ -10,6 +10,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyLong @@ -33,6 +34,7 @@ import org.springframework.test.web.servlet.assertj.MockMvcTester excludeAutoConfiguration = [SecurityAutoConfiguration::class] ) @AutoConfigureRestDocs +@Tag("restdocs") @DisplayName("Admin Curation 컨트롤러 RestDocs 테스트") class AdminCurationControllerDocsTest { diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt index 56c3ef593..52e42422e 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/curation/AdminSpecBasedCurationControllerDocsTest.kt @@ -14,6 +14,7 @@ import app.bottlenote.global.dto.response.AdminResultResponse import com.fasterxml.jackson.databind.ObjectMapper import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyLong @@ -41,6 +42,7 @@ import java.time.LocalDateTime excludeAutoConfiguration = [SecurityAutoConfiguration::class] ) @AutoConfigureRestDocs +@Tag("restdocs") @DisplayName("Admin Spec Based Curation 컨트롤러 RestDocs 테스트") class AdminSpecBasedCurationControllerDocsTest { diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/file/AdminImageUploadControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/file/AdminImageUploadControllerDocsTest.kt index 74f3d50ef..4b3d8bcec 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/file/AdminImageUploadControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/file/AdminImageUploadControllerDocsTest.kt @@ -8,6 +8,7 @@ import app.bottlenote.common.file.service.ImageUploadService import app.bottlenote.global.security.SecurityContextUtil import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyLong @@ -34,6 +35,7 @@ import java.util.* excludeAutoConfiguration = [SecurityAutoConfiguration::class] ) @AutoConfigureRestDocs +@Tag("restdocs") @DisplayName("Admin 이미지 업로드 컨트롤러 RestDocs 테스트") class AdminImageUploadControllerDocsTest { diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/help/AdminHelpControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/help/AdminHelpControllerDocsTest.kt index b4d3f42d8..ec74e3e42 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/help/AdminHelpControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/help/AdminHelpControllerDocsTest.kt @@ -14,6 +14,7 @@ import app.bottlenote.support.help.service.AdminHelpService import com.fasterxml.jackson.databind.ObjectMapper import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyLong @@ -42,6 +43,7 @@ import java.util.* excludeAutoConfiguration = [SecurityAutoConfiguration::class] ) @AutoConfigureRestDocs +@Tag("restdocs") @DisplayName("Admin Help 컨트롤러 RestDocs 테스트") class AdminHelpControllerDocsTest { diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/user/AdminUsersControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/user/AdminUsersControllerDocsTest.kt index 05bf87d95..d3ab12e4b 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/user/AdminUsersControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/user/AdminUsersControllerDocsTest.kt @@ -10,6 +10,7 @@ import app.bottlenote.user.presentation.AdminUsersController import app.bottlenote.user.service.AdminUserService import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.any import org.mockito.BDDMockito.given @@ -32,6 +33,7 @@ import java.time.LocalDateTime excludeAutoConfiguration = [SecurityAutoConfiguration::class] ) @AutoConfigureRestDocs +@Tag("restdocs") @DisplayName("Admin Users 컨트롤러 RestDocs 테스트") class AdminUsersControllerDocsTest { diff --git a/bottlenote-mono/src/test/java/app/bottlenote/user/service/AdminAuthServiceTest.java b/bottlenote-mono/src/test/java/app/bottlenote/user/service/AdminAuthServiceTest.java deleted file mode 100644 index f5ba5d1bb..000000000 --- a/bottlenote-mono/src/test/java/app/bottlenote/user/service/AdminAuthServiceTest.java +++ /dev/null @@ -1,5 +0,0 @@ -package app.bottlenote.user.service; - -import static org.junit.jupiter.api.Assertions.*; - -class AdminAuthServiceTest {} diff --git a/bottlenote-product-api/build.gradle b/bottlenote-product-api/build.gradle index ea655f9e0..82732a76d 100644 --- a/bottlenote-product-api/build.gradle +++ b/bottlenote-product-api/build.gradle @@ -97,7 +97,7 @@ tasks.register("prepareKotlinBuildScriptModel") {} asciidoctor { inputs.dir snippetsDir configurations 'asciidoctorExt' - dependsOn test + dependsOn restDocsTest sources { include("**/product-api.adoc") } diff --git a/bottlenote-product-api/src/docs/asciidoc/api/review/review-modify.adoc b/bottlenote-product-api/src/docs/asciidoc/api/review/review-modify.adoc index e34d200a8..c54e5251d 100644 --- a/bottlenote-product-api/src/docs/asciidoc/api/review/review-modify.adoc +++ b/bottlenote-product-api/src/docs/asciidoc/api/review/review-modify.adoc @@ -15,14 +15,15 @@ ReviewStatus와 SizeType은 아래 ENUM을 참고해주세요. [source] ---- -PATCH /api/v1/reviews +PATCH /api/v1/reviews/{reviewId} ---- [discrete] ==== 요청 파라미터 ==== [discrete] -//include::{snippets}/review/review-modify/request-fields.adoc[] +include::{snippets}/review/review-update/request-fields.adoc[] +include::{snippets}/review/review-update/request-body.adoc[] - Request Body 예시 @@ -33,8 +34,8 @@ PATCH /api/v1/reviews ==== 응답 파라미터 ==== [discrete] -//include::{snippets}/review/review-modify/response-fields.adoc[] -//include::{snippets}/review/review-modify/http-response.adoc[] +include::{snippets}/review/review-update/response-fields.adoc[] +include::{snippets}/review/review-update/http-response.adoc[] [discrete] ==== ReviewStatus ==== diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/alcohols/repository/CustomJpaAlcoholQueryRepositoryImplTest.java b/bottlenote-product-api/src/test/java/app/bottlenote/alcohols/repository/CustomJpaAlcoholQueryRepositoryImplTest.java deleted file mode 100644 index 6eb6097f7..000000000 --- a/bottlenote-product-api/src/test/java/app/bottlenote/alcohols/repository/CustomJpaAlcoholQueryRepositoryImplTest.java +++ /dev/null @@ -1,183 +0,0 @@ -package app.bottlenote.alcohols.repository; - -import static app.bottlenote.alcohols.constant.SearchSortType.REVIEW; -import static app.bottlenote.global.service.cursor.SortOrder.DESC; -import static app.bottlenote.user.constant.SocialType.GOOGLE; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import app.bottlenote.alcohols.constant.AlcoholCategoryGroup; -import app.bottlenote.alcohols.domain.Alcohol; -import app.bottlenote.alcohols.domain.AlcoholQueryRepository; -import app.bottlenote.alcohols.dto.dsl.AlcoholSearchCriteria; -import app.bottlenote.alcohols.dto.request.AlcoholSearchRequest; -import app.bottlenote.alcohols.dto.response.AlcoholSearchResponse; -import app.bottlenote.alcohols.dto.response.AlcoholsSearchItem; -import app.bottlenote.config.ModuleConfig; -import app.bottlenote.config.TestConfig; -import app.bottlenote.global.service.cursor.CursorPageable; -import app.bottlenote.global.service.cursor.PageResponse; -import app.bottlenote.rating.domain.Rating; -import app.bottlenote.rating.domain.Rating.RatingId; -import app.bottlenote.rating.domain.RatingPoint; -import app.bottlenote.review.domain.Review; -import app.bottlenote.user.constant.UserType; -import app.bottlenote.user.domain.User; -import app.bottlenote.user.domain.UserRepository; -import jakarta.persistence.EntityManager; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Stream; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.transaction.annotation.Transactional; - -@Disabled("테스트 컨테이너 도입으로 인한 추후 수정 대상 ") -@Tag(value = "data-jpa-test") -@DisplayName("[database] [repository] AlcoholQuery") -@DataJpaTest -@ActiveProfiles("test") -@Import({TestConfig.class, ModuleConfig.class}) -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -class CustomJpaAlcoholQueryRepositoryImplTest { - - private EntityManager em; - @Autowired private TestEntityManager testEntityManager; - @Autowired private AlcoholQueryRepository alcoholQueryRepository; - @Autowired private UserRepository userRepository; - - static Stream testCase1Provider() { - return Stream.of( - Arguments.of("검색조건이 없어도 조회 된다.", AlcoholSearchRequest.builder().build(), "none"), - Arguments.of( - "키워드를 통해 검색 할 수 있다.", - AlcoholSearchRequest.builder().keyword("아벨라워").build(), - "keyword"), - Arguments.of( - "카테고리를 통해 검색 할 수 있다.", - AlcoholSearchRequest.builder().category(AlcoholCategoryGroup.BLEND).build(), - "category"), - Arguments.of( - "지역을 통해 검색 할 수 있다.", - AlcoholSearchRequest.builder().regionId(5L).pageSize(1L).build(), - "region"), - Arguments.of( - "정렬 조건을 지정할 수 있다.", - AlcoholSearchRequest.builder().sortType(REVIEW).sortOrder(DESC).pageSize(2L).build(), - "sort"), - Arguments.of( - "페이지 조건을 지정할 수 있다.", - AlcoholSearchRequest.builder().cursor(5L).pageSize(8L).build(), - "page")); - } - - @BeforeEach - void init() { - em = testEntityManager.getEntityManager(); - - Alcohol alcohol = alcoholQueryRepository.findById(1L).orElseThrow(); - User user = - userRepository.save( - User.builder() - .email("test@emai.com") - .nickName("test") - .role(UserType.ROLE_USER) - .socialType(new ArrayList<>(List.of(GOOGLE))) - .build()); - - Review review = - Review.builder().alcoholId(alcohol.getId()).userId(user.getId()).content("맛있어요").build(); - RatingId ratingId = RatingId.is(alcohol.getId(), user.getId()); - Rating rating_1 = Rating.builder().id(ratingId).ratingPoint(RatingPoint.of(4.5)).build(); - - em.persist(review); - em.persist(rating_1); - } - - @AfterEach - void tearDown() { - em.clear(); - } - - @Transactional(readOnly = true) - @ParameterizedTest(name = "[{index}]{0}") - @DisplayName("검색조건에 따라 술을 조회 할 수 있다.") - @MethodSource("testCase1Provider") - void test_case_1(String description, AlcoholSearchRequest request, String testType) { - - System.out.println(description); - - AlcoholSearchCriteria criteria = AlcoholSearchCriteria.of(request, null); - - // when - PageResponse response = alcoholQueryRepository.searchAlcohols(criteria); - - // then - AlcoholSearchResponse content = response.content(); - List alcohols = content.getAlcohols(); - Long totalCount = content.getTotalCount(); - - assertNotNull(response); - assertTrue(totalCount > 0); - - edgeTest(request, testType, alcohols, response); - } - - private void edgeTest( - AlcoholSearchRequest request, - String testType, - List alcohols, - PageResponse response) { - switch (testType) { - case "keyword": - assertTrue( - alcohols.stream() - .allMatch( - detail -> - detail.getKorName().contains(request.keyword()) - || detail.getEngName().contains(request.keyword()))); - break; - case "category": - assertTrue( - alcohols.stream() - .allMatch( - detail -> request.category().containsCategory(detail.getEngCategoryName()))); - break; - case "region": - String regionAlcohol = "아란"; // 리전ID 5는 아란이 포함된 술이 있음 - assertTrue( - alcohols.stream() - .allMatch( - detail -> - detail.getKorName().contains(regionAlcohol) - || detail.getEngName().contains(regionAlcohol))); - break; - case "sort": - System.out.println("test case sort"); - AlcoholsSearchItem detail_1 = alcohols.get(0); - AlcoholsSearchItem detail_2 = alcohols.get(1); - assertTrue(detail_1.getReviewCount() > detail_2.getReviewCount()); - break; - case "page": - System.out.println("test case page"); - CursorPageable pageable = response.cursorPageable(); - assertEquals(request.cursor(), pageable.getCurrentCursor()); - assertEquals(request.pageSize(), pageable.getPageSize()); - System.out.println(pageable); - break; - } - } -} diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/common/file/upload/MinioContainerLoadingTest.java b/bottlenote-product-api/src/test/java/app/bottlenote/common/file/upload/MinioContainerLoadingTest.java index 58d29f7ee..bf38c482a 100644 --- a/bottlenote-product-api/src/test/java/app/bottlenote/common/file/upload/MinioContainerLoadingTest.java +++ b/bottlenote-product-api/src/test/java/app/bottlenote/common/file/upload/MinioContainerLoadingTest.java @@ -7,10 +7,12 @@ import app.bottlenote.operation.utils.TestContainersConfig; import com.amazonaws.services.s3.AmazonS3; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.testcontainers.containers.MinIOContainer; +@Tag("integration") @DisplayName("[integration] MinIO 컨테이너 로딩 테스트") class MinioContainerLoadingTest extends IntegrationTestSupport { diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/history/event/UserHistoryListenerTest.java b/bottlenote-product-api/src/test/java/app/bottlenote/history/event/UserHistoryListenerTest.java index 829a067c9..c111a3642 100644 --- a/bottlenote-product-api/src/test/java/app/bottlenote/history/event/UserHistoryListenerTest.java +++ b/bottlenote-product-api/src/test/java/app/bottlenote/history/event/UserHistoryListenerTest.java @@ -8,8 +8,10 @@ import app.bottlenote.history.fixture.InMemoryUserHistoryRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +@Tag("unit") class UserHistoryListenerTest { private HistoryListener historyListener; diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/rating/repository/CustomRatingQueryRepositoryImplTest.java b/bottlenote-product-api/src/test/java/app/bottlenote/rating/repository/CustomRatingQueryRepositoryImplTest.java deleted file mode 100644 index fa8970a43..000000000 --- a/bottlenote-product-api/src/test/java/app/bottlenote/rating/repository/CustomRatingQueryRepositoryImplTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package app.bottlenote.rating.repository; - -import app.bottlenote.global.service.cursor.SortOrder; -import app.bottlenote.rating.constant.SearchSortType; -import app.bottlenote.rating.domain.RatingRepository; -import app.bottlenote.rating.dto.dsl.RatingListFetchCriteria; -import app.bottlenote.rating.dto.response.RatingListFetchResponse; - -/** 해당 테스트는 실제로 어플리케이션을 띄워 실행 결과를 볼수 있는 예시라고 생각하고 참조하세요. 테스트를 실행하려면 해당 테스트를 실행할 수 있는 환경이 필요합니다. */ -// @SpringBootTest -// @ActiveProfiles("dev") -class CustomRatingQueryRepositoryImplTest { - - // @Autowired - private RatingRepository ratingRepository; - - // @Test - void test() { - var criteria = - new RatingListFetchCriteria( - "Yam", null, null, SearchSortType.REVIEW, SortOrder.DESC, 0L, 10L, 33L); - - var response = ratingRepository.fetchRatingList(criteria); - - RatingListFetchResponse content = response.content(); - - content - .ratings() - .forEach( - info -> - System.out.printf( - "ID: %d\nImage URL: %s\nKorean Name: %s\nEnglish Name: %s\nKorean Category Name: %s\nEnglish Category Name: %s\nIs Picked: %b\n\n", - info.alcoholId(), - info.imageUrl(), - info.korName(), - info.engName(), - info.korCategoryName(), - info.engCategoryName(), - info.isPicked())); - - // when - // then - } -} diff --git a/bottlenote-product-api/src/test/java/app/bottlenote/user/service/OauthServiceTest.java b/bottlenote-product-api/src/test/java/app/bottlenote/user/service/OauthServiceTest.java index 311ba6b0d..08a77e498 100644 --- a/bottlenote-product-api/src/test/java/app/bottlenote/user/service/OauthServiceTest.java +++ b/bottlenote-product-api/src/test/java/app/bottlenote/user/service/OauthServiceTest.java @@ -183,161 +183,4 @@ void reissue_token_fail() { // when & then assertThrows(UserException.class, () -> oauthService.refresh(invalidRefreshToken)); } - - // @Test - // @DisplayName("Apple 로그인 시 Nonce 검증에 실패하면 예외를 발생시킨다.") - // void loginWithApple_invalidNonce_throwsException() { - // // Given - // String idToken = "mockIdToken"; - // String invalidNonce = "invalidNonce"; - - // // When & Then - // assertThrows(UserException.class, () -> oauthService.loginWithApple(idToken, invalidNonce)); - // } - - // @Test - // @DisplayName("Apple 로그인이 성공할 수 있다.") - // void loginWithApple_success() { - // // Given - // String idToken = "validIdToken"; - // String validNonce = nonceService.generateNonce(); - - // // When - // TokenItem result = oauthService.loginWithApple(idToken, validNonce); - - // // Then - // assertNotNull(result); - // assertThat(result.accessToken()).isNotNull().isNotEmpty(); - // assertThat(result.refreshToken()).isNotNull().isNotEmpty(); - - // // 사용자가 저장되었는지 확인 - // assertThat(oauthRepository.findByEmail("apple.user@example.com")).isPresent(); - // } - - // @Test - // @DisplayName("카카오 로그인 - 신규 회원가입이 성공할 수 있다") - // void loginWithKakao_신규회원가입_성공() { - // // Given - // String accessToken = "valid_token_with_email"; - - // // When - // TokenItem result = oauthService.loginWithKakao(accessToken); - - // // Then - // assertNotNull(result); - // assertThat(result.accessToken()).isNotNull().isNotEmpty(); - // assertThat(result.refreshToken()).isNotNull().isNotEmpty(); - - // // 카카오 ID로 사용자가 저장되었는지 확인 - // assertThat(oauthRepository.findBySocialUniqueId("123456789")).isPresent(); - - // // 이메일로도 조회 가능한지 확인 - // assertThat(oauthRepository.findByEmail("test@kakao.com")).isPresent(); - - // User savedUser = oauthRepository.findBySocialUniqueId("123456789").get(); - // assertThat(savedUser.getSocialType()).contains(SocialType.KAKAO); - // assertThat(savedUser.getGender()).isEqualTo(GenderType.FEMALE); - // assertThat(savedUser.getAge()).isEqualTo(24); // 20~29 -> 24 - // } - - // @Test - // @DisplayName("카카오 로그인 - 이메일 없는 사용자도 회원가입할 수 있다") - // void loginWithKakao_이메일없는사용자_회원가입_성공() { - // // Given - // String accessToken = "valid_token_without_email"; - - // // When - // TokenItem result = oauthService.loginWithKakao(accessToken); - - // // Then - // assertNotNull(result); - // assertThat(result.accessToken()).isNotNull().isNotEmpty(); - // assertThat(result.refreshToken()).isNotNull().isNotEmpty(); - - // // 카카오 ID로 사용자가 저장되었는지 확인 - // User savedUser = oauthRepository.findBySocialUniqueId("987654321").orElseThrow(); - // assertThat(savedUser.getEmail()).startsWith("kakao").endsWith("@bottlenote.com"); - // assertThat(savedUser.getSocialType()).contains(SocialType.KAKAO); - // assertThat(savedUser.getGender()).isEqualTo(GenderType.MALE); - // assertThat(savedUser.getAge()).isEqualTo(34); // 30~39 -> 34 - // } - - // @Test - // @DisplayName("카카오 로그인 - 기존 회원은 로그인할 수 있다") - // void loginWithKakao_기존회원_로그인_성공() { - // // Given - // // 기존 사용자를 DB에 미리 저장 - // User existingUser = - // User.builder() - // .email("existing@test.com") - // .socialUniqueId("555555555") - // .socialType(List.of(SocialType.KAKAO)) - // .role(UserType.ROLE_USER) - // .nickName("기존회원") - // .build(); - // oauthRepository.save(existingUser); - - // String accessToken = "existing_user_token"; - - // // When - // TokenItem result = oauthService.loginWithKakao(accessToken); - - // // Then - // assertNotNull(result); - // assertThat(result.accessToken()).isNotNull().isNotEmpty(); - // assertThat(result.refreshToken()).isNotNull().isNotEmpty(); - - // // 기존 사용자가 조회되는지 확인 - // User loginUser = oauthRepository.findBySocialUniqueId("555555555").orElseThrow(); - // assertThat(loginUser.getNickName()).isEqualTo("기존회원"); - // } - - // @Test - // @DisplayName("카카오 로그인 - 잘못된 토큰으로 요청하면 예외가 발생한다") - // void loginWithKakao_잘못된토큰_예외발생() { - // // Given - // String invalidToken = "invalid_token"; - - // // When & Then - // assertThrows(UserException.class, () -> oauthService.loginWithKakao(invalidToken)); - // } - - // @Test - // @DisplayName("카카오 로그인 - 카카오 서버 에러시 예외가 발생한다") - // void loginWithKakao_서버에러_예외발생() { - // // Given - // kakaoFeignClient.simulateServerError(); - // String accessToken = "valid_token_with_email"; - - // // When & Then - // assertThrows(UserException.class, () -> oauthService.loginWithKakao(accessToken)); - // } - - // @Test - // @DisplayName("카카오 로그인 - 이메일로 기존 회원 연동이 가능하다") - // void loginWithKakao_이메일기반_기존회원연동_성공() { - // // Given - // // 기존 사용자를 이메일로만 저장 (카카오 연동 안된 상태) - // User existingUser = - // User.builder() - // .email("test@kakao.com") - // .socialType(new ArrayList<>(List.of(SocialType.BASIC))) - // .role(UserType.ROLE_USER) - // .nickName("기존회원") - // .build(); - // oauthRepository.save(existingUser); - - // String accessToken = "valid_token_with_email"; - - // // When - // TokenItem result = oauthService.loginWithKakao(accessToken); - - // // Then - // assertNotNull(result); - - // // 기존 회원에 카카오 ID가 업데이트되었는지 확인 - // User updatedUser = oauthRepository.findByEmail("test@kakao.com").orElseThrow(); - // assertThat(updatedUser.getSocialUniqueId()).isEqualTo("123456789"); - // assertThat(updatedUser.getNickName()).isEqualTo("기존회원"); // 기존 정보 유지 - // } } diff --git a/bottlenote-product-api/src/test/java/app/docs/alcohols/RestAlcoholExploreControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/alcohols/RestAlcoholExploreControllerTest.java index b398064f4..910e98934 100644 --- a/bottlenote-product-api/src/test/java/app/docs/alcohols/RestAlcoholExploreControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/alcohols/RestAlcoholExploreControllerTest.java @@ -21,8 +21,10 @@ import app.docs.AbstractRestDocs; import java.util.List; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +@Tag("restdocs") @DisplayName("alcohol 컨트롤러 RestDocs용 테스트") public class RestAlcoholExploreControllerTest extends AbstractRestDocs { private final AlcoholQueryService alcoholQueryService = mock(AlcoholQueryService.class); diff --git a/bottlenote-product-api/src/test/java/app/docs/alcohols/RestAlcoholQueryControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/alcohols/RestAlcoholQueryControllerTest.java index 99cde0583..553c42723 100644 --- a/bottlenote-product-api/src/test/java/app/docs/alcohols/RestAlcoholQueryControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/alcohols/RestAlcoholQueryControllerTest.java @@ -23,8 +23,10 @@ import app.bottlenote.global.service.cursor.PageResponse; import app.docs.AbstractRestDocs; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +@Tag("restdocs") @DisplayName("alcohol 컨트롤러 RestDocs용 테스트") class RestAlcoholQueryControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/alcohols/RestAlcoholReferenceControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/alcohols/RestAlcoholReferenceControllerTest.java index a311b4459..6f7eaf33b 100644 --- a/bottlenote-product-api/src/test/java/app/docs/alcohols/RestAlcoholReferenceControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/alcohols/RestAlcoholReferenceControllerTest.java @@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test; import org.springframework.test.web.servlet.ResultActions; -@Tag("rest-docs") +@Tag("restdocs") @DisplayName("큐레이션 키워드 API 문서화 테스트") class RestAlcoholReferenceControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/alcohols/RestPopularControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/alcohols/RestPopularControllerTest.java index 4152492f4..805c38fc0 100644 --- a/bottlenote-product-api/src/test/java/app/docs/alcohols/RestPopularControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/alcohols/RestPopularControllerTest.java @@ -21,9 +21,11 @@ import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +@Tag("restdocs") @DisplayName("Popular API RestDocs") class RestPopularControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/alcohols/RestReferenceControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/alcohols/RestReferenceControllerTest.java index 48a0c44f5..257187ed7 100644 --- a/bottlenote-product-api/src/test/java/app/docs/alcohols/RestReferenceControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/alcohols/RestReferenceControllerTest.java @@ -20,10 +20,12 @@ import app.docs.AbstractRestDocs; import java.util.List; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.restdocs.payload.JsonFieldType; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +@Tag("restdocs") @DisplayName("알코올 참조 컨트롤러 RestDocs용 테스트") class RestReferenceControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/alcohols/RestTastingTagControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/alcohols/RestTastingTagControllerTest.java index 02fcf52a9..a5c2b6886 100644 --- a/bottlenote-product-api/src/test/java/app/docs/alcohols/RestTastingTagControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/alcohols/RestTastingTagControllerTest.java @@ -25,7 +25,7 @@ import org.junit.jupiter.api.Test; import org.springframework.test.web.servlet.ResultActions; -@Tag("rest-docs") +@Tag("restdocs") @DisplayName("TastingTag API 문서화 테스트") class RestTastingTagControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/banner/RestBannerQueryControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/banner/RestBannerQueryControllerTest.java index b823f5194..2461348b5 100644 --- a/bottlenote-product-api/src/test/java/app/docs/banner/RestBannerQueryControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/banner/RestBannerQueryControllerTest.java @@ -20,9 +20,11 @@ import java.time.LocalDateTime; import java.util.List; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.restdocs.payload.JsonFieldType; +@Tag("restdocs") @DisplayName("배너 조회 컨트롤러 Rest API 문서화 테스트") class RestBannerQueryControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/curation/RestProductSpecBasedCurationControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/curation/RestProductSpecBasedCurationControllerTest.java index 719fa230a..5bfc6afa4 100644 --- a/bottlenote-product-api/src/test/java/app/docs/curation/RestProductSpecBasedCurationControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/curation/RestProductSpecBasedCurationControllerTest.java @@ -26,8 +26,10 @@ import java.util.List; import java.util.Map; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +@Tag("restdocs") @DisplayName("Product spec 기반 큐레이션 v2 API 문서화 테스트") class RestProductSpecBasedCurationControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/follow/RestDocsFollowControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/follow/RestDocsFollowControllerTest.java index d573a0165..07aaf116c 100644 --- a/bottlenote-product-api/src/test/java/app/docs/follow/RestDocsFollowControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/follow/RestDocsFollowControllerTest.java @@ -31,11 +31,13 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.springframework.http.MediaType; import org.springframework.restdocs.payload.JsonFieldType; +@Tag("restdocs") @DisplayName("FollowController RestDocs 테스트") class RestDocsFollowControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/history/RestDocsUserHistoryTest.java b/bottlenote-product-api/src/test/java/app/docs/history/RestDocsUserHistoryTest.java index d1be7e5fd..f59c23226 100644 --- a/bottlenote-product-api/src/test/java/app/docs/history/RestDocsUserHistoryTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/history/RestDocsUserHistoryTest.java @@ -30,11 +30,13 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.springframework.http.MediaType; import org.springframework.restdocs.payload.JsonFieldType; +@Tag("restdocs") @DisplayName("UserHistory RestDocs 테스트") class RestDocsUserHistoryTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/likes/RestLikesControllerDocsTest.java b/bottlenote-product-api/src/test/java/app/docs/likes/RestLikesControllerDocsTest.java index 62316cb48..2e8193b45 100644 --- a/bottlenote-product-api/src/test/java/app/docs/likes/RestLikesControllerDocsTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/likes/RestLikesControllerDocsTest.java @@ -24,10 +24,12 @@ import java.util.Optional; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.springframework.http.MediaType; +@Tag("restdocs") @DisplayName("RestLikesController API 문서화 테스트") public class RestLikesControllerDocsTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/picks/RestPicksCommandControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/picks/RestPicksCommandControllerTest.java index 45c5ce51f..644b7376a 100644 --- a/bottlenote-product-api/src/test/java/app/docs/picks/RestPicksCommandControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/picks/RestPicksCommandControllerTest.java @@ -21,11 +21,13 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.springframework.http.MediaType; import org.springframework.restdocs.payload.JsonFieldType; +@Tag("restdocs") @DisplayName("Pick 컨트롤러 Rest API 문서화 테스트") class RestPicksCommandControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/rating/RestRatingControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/rating/RestRatingControllerTest.java index 4102c3772..3cdf0f822 100644 --- a/bottlenote-product-api/src/test/java/app/docs/rating/RestRatingControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/rating/RestRatingControllerTest.java @@ -41,11 +41,13 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.springframework.http.MediaType; import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +@Tag("restdocs") @DisplayName("별점 RestDocs용 테스트") public class RestRatingControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/review/RestReviewControllerDocsTest.java b/bottlenote-product-api/src/test/java/app/docs/review/RestReviewControllerDocsTest.java index 01444738e..120d14d4d 100644 --- a/bottlenote-product-api/src/test/java/app/docs/review/RestReviewControllerDocsTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/review/RestReviewControllerDocsTest.java @@ -37,12 +37,14 @@ import java.util.Optional; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.springframework.http.MediaType; import org.springframework.restdocs.payload.JsonFieldType; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +@Tag("restdocs") @DisplayName("[restdocs] 리뷰 컨트롤러 RestDocs용 테스트") class RestReviewControllerDocsTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/review/RestReviewExploreControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/review/RestReviewExploreControllerTest.java index 16b0d4314..e0a7de7f2 100644 --- a/bottlenote-product-api/src/test/java/app/docs/review/RestReviewExploreControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/review/RestReviewExploreControllerTest.java @@ -23,8 +23,10 @@ import java.util.List; import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +@Tag("restdocs") @DisplayName("[restdocs] 리뷰 둘러보기 계열 컨트롤러 RestDocs용 테스트") public class RestReviewExploreControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/review/RestReviewReplyControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/review/RestReviewReplyControllerTest.java index 67179f9a1..896de1ea2 100644 --- a/bottlenote-product-api/src/test/java/app/docs/review/RestReviewReplyControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/review/RestReviewReplyControllerTest.java @@ -41,7 +41,7 @@ import org.mockito.MockedStatic; import org.springframework.http.MediaType; -@Tag("rest-docs") +@Tag("restdocs") @DisplayName("리뷰 댓글 컨트롤러 RestDocs용 테스트") class RestReviewReplyControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/support/block/RestDocsBlockControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/support/block/RestDocsBlockControllerTest.java index bb2ad4144..32775bd74 100644 --- a/bottlenote-product-api/src/test/java/app/docs/support/block/RestDocsBlockControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/support/block/RestDocsBlockControllerTest.java @@ -29,11 +29,13 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.springframework.http.MediaType; import org.springframework.restdocs.payload.JsonFieldType; +@Tag("restdocs") @DisplayName("BlockController RestDocs 테스트") class RestDocsBlockControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/support/help/RestDocsHelpCommandControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/support/help/RestDocsHelpCommandControllerTest.java index 69d02a76b..45b881ef5 100644 --- a/bottlenote-product-api/src/test/java/app/docs/support/help/RestDocsHelpCommandControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/support/help/RestDocsHelpCommandControllerTest.java @@ -36,11 +36,13 @@ import java.util.Optional; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.springframework.http.MediaType; import org.springframework.restdocs.payload.JsonFieldType; +@Tag("restdocs") @DisplayName("문의글 커맨드 컨트롤러 RestDocs용 테스트") class RestDocsHelpCommandControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/support/report/RestDocsReportCommandControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/support/report/RestDocsReportCommandControllerTest.java index 8bc0da993..0644b5b1b 100644 --- a/bottlenote-product-api/src/test/java/app/docs/support/report/RestDocsReportCommandControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/support/report/RestDocsReportCommandControllerTest.java @@ -22,11 +22,13 @@ import java.util.Optional; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.springframework.http.MediaType; import org.springframework.restdocs.payload.JsonFieldType; +@Tag("restdocs") @DisplayName("유저 신고 커맨드 컨트롤러 RestDocs용 테스트") class RestDocsReportCommandControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/upload/RestImageUploadControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/upload/RestImageUploadControllerTest.java index f570e15b3..0b3802c03 100644 --- a/bottlenote-product-api/src/test/java/app/docs/upload/RestImageUploadControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/upload/RestImageUploadControllerTest.java @@ -18,9 +18,11 @@ import app.docs.AbstractRestDocs; import java.util.List; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.security.test.context.support.WithMockUser; +@Tag("restdocs") @DisplayName("이미지 업로드 RestDocs용 테스트") class RestImageUploadControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/user/OpenApiAuthV2ControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/user/OpenApiAuthV2ControllerTest.java index 8ac68f8eb..968f5de10 100644 --- a/bottlenote-product-api/src/test/java/app/docs/user/OpenApiAuthV2ControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/user/OpenApiAuthV2ControllerTest.java @@ -23,7 +23,7 @@ import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; -@Tag("document") +@Tag("restdocs") @DisplayName("유저 Auth 컨트롤러 V2x OpenAPI 테스트") class OpenApiAuthV2ControllerTest extends AbstractRestDocs { private final AuthService authService = Mockito.mock(AuthService.class); diff --git a/bottlenote-product-api/src/test/java/app/docs/user/RestAuthV2ControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/user/RestAuthV2ControllerTest.java index 8618c82b6..686c95f34 100644 --- a/bottlenote-product-api/src/test/java/app/docs/user/RestAuthV2ControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/user/RestAuthV2ControllerTest.java @@ -33,7 +33,7 @@ import org.mockito.MockedStatic; import org.springframework.http.MediaType; -@Tag("document") +@Tag("restdocs") @DisplayName("유저 Auth 컨트롤러 V2x RestDocs 테스트") class RestAuthV2ControllerTest extends AbstractRestDocs { private final AuthService authService = mock(AuthService.class); diff --git a/bottlenote-product-api/src/test/java/app/docs/user/RestDocsUserChangeContollerTest.java b/bottlenote-product-api/src/test/java/app/docs/user/RestDocsUserChangeContollerTest.java index 97ab897b6..7aaef3fe6 100644 --- a/bottlenote-product-api/src/test/java/app/docs/user/RestDocsUserChangeContollerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/user/RestDocsUserChangeContollerTest.java @@ -28,11 +28,13 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.springframework.http.MediaType; import org.springframework.restdocs.payload.JsonFieldType; +@Tag("restdocs") @DisplayName("닉네임 변경 RestDocs용 테스트") class RestDocsUserChangeContollerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/user/RestDocsUserQueryControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/user/RestDocsUserQueryControllerTest.java index 492b8b077..0f80daa4a 100644 --- a/bottlenote-product-api/src/test/java/app/docs/user/RestDocsUserQueryControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/user/RestDocsUserQueryControllerTest.java @@ -31,7 +31,7 @@ import org.mockito.Mockito; import org.springframework.http.MediaType; -@Tag("rest-docs") +@Tag("restdocs") @DisplayName("[restdocs] 마이페이지 컨트롤러 RestDocs용 테스트") class RestDocsUserQueryControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/docs/user/RestOauthControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/user/RestOauthControllerTest.java index 8a0cf9037..d80bf93b3 100644 --- a/bottlenote-product-api/src/test/java/app/docs/user/RestOauthControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/user/RestOauthControllerTest.java @@ -35,7 +35,7 @@ import org.springframework.http.MediaType; import org.springframework.restdocs.payload.JsonFieldType; -@Tag("document") +@Tag("restdocs") @DisplayName("유저 Auth 컨트롤러 RestDocs 테스트") class RestOauthControllerTest extends AbstractRestDocs { private final OauthService oauthService = mock(OauthService.class); diff --git a/bottlenote-product-api/src/test/java/app/docs/user/RestUserBasicControllerTest.java b/bottlenote-product-api/src/test/java/app/docs/user/RestUserBasicControllerTest.java index 0a29b09dd..ed37708e1 100644 --- a/bottlenote-product-api/src/test/java/app/docs/user/RestUserBasicControllerTest.java +++ b/bottlenote-product-api/src/test/java/app/docs/user/RestUserBasicControllerTest.java @@ -21,11 +21,13 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +@Tag("restdocs") @DisplayName("유저 Command 컨트롤러 RestDocs용 테스트") class RestUserBasicControllerTest extends AbstractRestDocs { diff --git a/bottlenote-product-api/src/test/java/app/rule/test/TestTagRules.java b/bottlenote-product-api/src/test/java/app/rule/test/TestTagRules.java new file mode 100644 index 000000000..9fd1b8488 --- /dev/null +++ b/bottlenote-product-api/src/test/java/app/rule/test/TestTagRules.java @@ -0,0 +1,86 @@ +package app.rule.test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +@Tag("rule") +@DisplayName("테스트 태그 정책") +@SuppressWarnings({"NonAsciiCharacters", "JUnitTestClassNamingConvention"}) +class TestTagRules { + + private static final Set ALLOWED_TAGS = + Set.of("unit", "integration", "admin_integration", "restdocs", "rule", "batch"); + private static final Pattern TAG_PATTERN = + Pattern.compile("@Tag\\(\\s*(?:value\\s*=\\s*)?\"([^\"]+)\"\\s*\\)"); + + @Test + void 모든_테스트_파일은_허용된_태그를_가져야_한다() throws IOException { + Path root = findRepositoryRoot(Path.of("").toAbsolutePath()); + List violations = new ArrayList<>(); + + try (Stream files = Files.walk(root)) { + files + .filter(Files::isRegularFile) + .filter(TestTagRules::isTestSource) + .forEach(path -> collectViolations(root, path, violations)); + } + + assertTrue(violations.isEmpty(), () -> "테스트 태그 정책 위반:\n- " + String.join("\n- ", violations)); + } + + private static Path findRepositoryRoot(Path start) { + Path current = start; + while (current != null) { + if (Files.exists(current.resolve("settings.gradle"))) { + return current; + } + current = current.getParent(); + } + return start; + } + + private static boolean isTestSource(Path path) { + String normalized = path.toString().replace('\\', '/'); + String fileName = path.getFileName().toString(); + return normalized.contains("/src/test/") + && (fileName.endsWith("Test.java") || fileName.endsWith("Test.kt")); + } + + private static void collectViolations(Path root, Path path, List violations) { + String content; + try { + content = Files.readString(path, StandardCharsets.UTF_8); + } catch (IOException e) { + throw new IllegalStateException("테스트 파일을 읽을 수 없습니다: " + path, e); + } + + List tags = new ArrayList<>(); + Matcher matcher = TAG_PATTERN.matcher(content); + while (matcher.find()) { + tags.add(matcher.group(1)); + } + + Path relative = root.relativize(path); + if (tags.isEmpty()) { + violations.add(relative + " - @Tag 누락"); + return; + } + + tags.stream() + .filter(tag -> !ALLOWED_TAGS.contains(tag)) + .forEach(tag -> violations.add(relative + " - 허용되지 않은 @Tag(\"" + tag + "\")")); + } +} diff --git a/build.gradle b/build.gradle index f884faabb..c9c2d64fa 100644 --- a/build.gradle +++ b/build.gradle @@ -110,7 +110,7 @@ subprojects { test { outputs.upToDateWhen { false } useJUnitPlatform { - excludeTags 'data-jpa-test', 'integration', 'admin_integration' + excludeTags 'integration', 'admin_integration' } testLogging { events "passed", "skipped", "failed" @@ -154,10 +154,8 @@ subprojects { tasks.register('restDocsTest', Test) { description = 'REST Docs snippets 생성을 위한 테스트' group = 'documentation' - useJUnitPlatform() - filter { - includeTestsMatching 'app.docs.*' - includeTestsMatching 'app.external.docs.*' + useJUnitPlatform { + includeTags 'restdocs' } } } @@ -207,6 +205,50 @@ tasks.register('restDocsTest') { dependsOn subprojects.findAll { it.tasks.findByName('restDocsTest') }.collect { it.tasks.restDocsTest } } +tasks.register('verifyRestDocsIncludes') { + description = 'AsciiDoc include 대상과 REST Docs snippet 존재 여부 검증' + group = 'documentation' + dependsOn tasks.named('restDocsTest') + + doLast { + def missing = [] + ['bottlenote-product-api', 'bottlenote-admin-api'].each { moduleName -> + def docsDir = file("${moduleName}/src/docs/asciidoc") + def snippetsDir = file("${moduleName}/build/generated-snippets") + fileTree(docsDir) { + include '**/*.adoc' + }.each { adoc -> + def matcher = adoc.text =~ /include::(.+?)\[\]/ + matcher.each { match -> + def includePath = match[1] + def includeFile = includePath.startsWith('{snippets}/') + ? new File(snippetsDir, includePath - '{snippets}/') + : new File(adoc.parentFile, includePath) + if (!includeFile.isFile()) { + missing << "${moduleName}:${docsDir.toPath().relativize(adoc.toPath())} -> ${includePath}" + } + } + } + } + if (!missing.isEmpty()) { + throw new GradleException("Missing AsciiDoc includes:\\n- ${missing.join('\\n- ')}") + } + } +} + +tasks.register('docs_test') { + description = 'REST Docs snippets 생성과 AsciiDoc 조립 검증' + group = 'documentation' + dependsOn tasks.named('restDocsTest') + dependsOn tasks.named('verifyRestDocsIncludes') +} + +gradle.projectsEvaluated { + tasks.named('docs_test') { + dependsOn subprojects.findAll { it.tasks.findByName('asciidoctor') }.collect { it.tasks.asciidoctor } + } +} + tasks.register('batch_test') { description = '배치 모듈 테스트 실행 (@Tag("batch"))' group = 'verification' From 2398c28e95b2af714248414ea94cde4e0e451ca4 Mon Sep 17 00:00:00 2001 From: Whale0928 Date: Tue, 19 May 2026 18:00:51 +0900 Subject: [PATCH 29/33] =?UTF-8?q?test:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20RestDocs=20=ED=83=9C=EA=B7=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/app/docs/review/AdminReviewControllerDocsTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bottlenote-admin-api/src/test/kotlin/app/docs/review/AdminReviewControllerDocsTest.kt b/bottlenote-admin-api/src/test/kotlin/app/docs/review/AdminReviewControllerDocsTest.kt index 595095ce1..a04fd7f21 100644 --- a/bottlenote-admin-api/src/test/kotlin/app/docs/review/AdminReviewControllerDocsTest.kt +++ b/bottlenote-admin-api/src/test/kotlin/app/docs/review/AdminReviewControllerDocsTest.kt @@ -11,6 +11,7 @@ import app.bottlenote.review.presentation.AdminReviewController import app.bottlenote.review.service.AdminReviewQueryService import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.any import org.mockito.BDDMockito.given @@ -34,6 +35,7 @@ import java.time.LocalDateTime ) @AutoConfigureRestDocs @DisplayName("Admin Review 컨트롤러 RestDocs 테스트") +@Tag("restdocs") class AdminReviewControllerDocsTest { @Autowired From 87abe40bacbfb2d367e9260ea4fbc05d42d8dae3 Mon Sep 17 00:00:00 2001 From: Living whale Date: Wed, 20 May 2026 15:13:25 +0900 Subject: [PATCH 30/33] =?UTF-8?q?chore:=20product=20VERSION=201.1.5=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bottlenote-product-api/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bottlenote-product-api/VERSION b/bottlenote-product-api/VERSION index 65087b4f5..e25d8d9f3 100644 --- a/bottlenote-product-api/VERSION +++ b/bottlenote-product-api/VERSION @@ -1 +1 @@ -1.1.4 +1.1.5 From bc64777aacd73ed10ce6556d7e60f229de5a0f44 Mon Sep 17 00:00:00 2001 From: Living whale Date: Wed, 20 May 2026 15:13:37 +0900 Subject: [PATCH 31/33] =?UTF-8?q?chore:=20admin=20VERSION=201.1.5=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bottlenote-admin-api/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bottlenote-admin-api/VERSION b/bottlenote-admin-api/VERSION index 65087b4f5..e25d8d9f3 100644 --- a/bottlenote-admin-api/VERSION +++ b/bottlenote-admin-api/VERSION @@ -1 +1 @@ -1.1.4 +1.1.5 From 683d6e7fb49c48f47cf657d05624d851d89f0ce3 Mon Sep 17 00:00:00 2001 From: Living whale Date: Wed, 20 May 2026 16:41:45 +0900 Subject: [PATCH 32/33] =?UTF-8?q?chore:=20product=20VERSION=201.1.6=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bottlenote-product-api/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bottlenote-product-api/VERSION b/bottlenote-product-api/VERSION index e25d8d9f3..0664a8fd2 100644 --- a/bottlenote-product-api/VERSION +++ b/bottlenote-product-api/VERSION @@ -1 +1 @@ -1.1.5 +1.1.6 From 23a7b1e7ec1ed94dc0cde490ce158baa13782428 Mon Sep 17 00:00:00 2001 From: Living whale Date: Wed, 20 May 2026 16:41:58 +0900 Subject: [PATCH 33/33] =?UTF-8?q?chore:=20admin=20VERSION=201.1.6=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bottlenote-admin-api/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bottlenote-admin-api/VERSION b/bottlenote-admin-api/VERSION index e25d8d9f3..0664a8fd2 100644 --- a/bottlenote-admin-api/VERSION +++ b/bottlenote-admin-api/VERSION @@ -1 +1 @@ -1.1.5 +1.1.6