From fa5e65b4322aa3886990451ec7b56b383bb86f6b Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 23 Feb 2026 16:51:53 +0900 Subject: [PATCH] =?UTF-8?q?fix(explorer):=20=EB=AF=B8=EB=9E=98=20=EB=9D=BC?= =?UTF-8?q?=EC=9D=B4=EB=B8=8C=20=ED=8F=AC=ED=95=A8=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=8C=EC=88=98=20D+=20=EB=85=B8=EC=B6=9C=EC=9D=84=20?= =?UTF-8?q?=EB=B0=A9=EC=A7=80=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/20260223_크리에이터상세정보조회api추가.md | 4 ++++ .../vividnext/sodalive/explorer/ExplorerQueryRepository.kt | 2 ++ .../kr/co/vividnext/sodalive/explorer/ExplorerService.kt | 5 +++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/20260223_크리에이터상세정보조회api추가.md b/docs/20260223_크리에이터상세정보조회api추가.md index 77be446e..30dccfc8 100644 --- a/docs/20260223_크리에이터상세정보조회api추가.md +++ b/docs/20260223_크리에이터상세정보조회api추가.md @@ -4,15 +4,19 @@ - [x] `ExplorerService`에 상세정보 조회 비즈니스 로직 추가 - [x] `ExplorerQueryRepository`에 데뷔일/활동요약 조회 쿼리 추가 - [x] 응답 DTO 추가 및 `Member` SNS URL 매핑 연결 +- [x] 3차 수정: 미래 라이브만 있는 크리에이터의 음수 `D+` 노출 방지 - [x] 정적 진단/테스트/빌드 검증 및 결과 기록 ## 검증 기록 - 무엇을: - 1차 구현: 크리에이터 상세정보 조회 API(`/explorer/profile/{id}/detail`)와 응답 DTO를 추가하고, 데뷔일(라이브 `beginDateTime`/콘텐츠 `releaseDate` 최솟값), `D+N`, 활동요약, SNS URL 반환을 구현했다. - 2차 수정: 상세 조회에 차단 관계 검사를 추가하고, 활동요약의 `contentCount`를 오픈된 콘텐츠(`releaseDate <= now`) 기준으로 집계하도록 기존 쿼리를 보정했다. + - 3차 수정: 라이브 데뷔 후보 조회에서 미래 `beginDateTime`을 제외하고, `D+` 계산 결과가 음수인 경우 `""`을 반환하도록 상세 조회 로직을 보정했다. - 왜: - 1차 구현: 탐색 화면에서 크리에이터 기본 정보·활동 통계·데뷔 정보·SNS를 한 번에 조회할 수 있어야 했다. - 2차 수정: 차단 관계에서도 상세정보가 노출되는 우회가 있었고, 예약 공개 콘텐츠가 포함되어 요구사항의 “오픈한 콘텐츠 수”와 불일치할 수 있었다. + - 3차 수정: 오픈된 콘텐츠 없이 미래 예약 라이브만 있을 때 `D+-N`이 내려가 요구사항의 “오늘 기준 데뷔일로부터 며칠째(D+N)” 표현과 불일치했다. - 어떻게: - 1차 구현/2차 수정 모두 Kotlin LSP 부재로 `lsp_diagnostics`는 불가를 확인했다. - 1차 구현 시점과 2차 수정 시점에 각각 `./gradlew ktlintCheck test build`를 실행해 정적검사/테스트/빌드 성공(Exit code 0)을 확인했다. + - 3차 수정 시점에도 Kotlin LSP 부재로 `lsp_diagnostics`는 불가를 확인했고, `./gradlew ktlintCheck test build`를 실행해 정적검사/테스트/빌드 성공(Exit code 0)을 확인했다. diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt index e776dce8..bd0a9a1f 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt @@ -572,6 +572,8 @@ class ExplorerQueryRepository( .where( liveRoom.member.id.eq(creatorId) .and(liveRoom.channelName.isNotNull) + .and(liveRoom.beginDateTime.isNotNull) + .and(liveRoom.beginDateTime.loe(LocalDateTime.now())) ) .fetchFirst() } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt index bd99454d..49205a9f 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt @@ -225,8 +225,9 @@ class ExplorerService( ).minOrNull() val debutDate = debutDateTime?.toLocalDate() - val dDay = if (debutDate != null) { - "D+${ChronoUnit.DAYS.between(debutDate, LocalDate.now())}" + val elapsedDebutDays = debutDate?.let { ChronoUnit.DAYS.between(it, LocalDate.now()) } + val dDay = if (elapsedDebutDays != null && elapsedDebutDays >= 0) { + "D+$elapsedDebutDays" } else { "" }