-
Notifications
You must be signed in to change notification settings - Fork 1
[feat] 홈 화면 '내 산책 정보' 조회 API 구현 및 성능 최적화 #225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
|
@CodeRabbit review |
✅ Actions performedReview triggered.
|
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the
Walkthrough날씨 도메인을 홈화면 전용 homeWeather 도메인으로 리팩토링하고, 사용자의 월간 누적 산책 정보(거리, 시간, 횟수)를 반환하는 GET /api/v1/home/info 엔드포인트를 추가합니다. QueryDSL 기반 쿼리 최적화, Redis 캐싱, 그리고 데이터베이스 복합 인덱스를 도입합니다. Changes
Sequence DiagramsequenceDiagram
participant Client
participant HomeController
participant HomeFacade
participant HomeService
participant RouteRepository
participant RouteQueryRepositoryImpl
participant Database
participant Cache as Redis Cache
Client->>HomeController: GET /api/v1/home/info
HomeController->>Cache: GET homeInfo::{userId}
alt Cache Hit
Cache-->>HomeController: HomeInfoResponseDto
else Cache Miss
HomeController->>HomeFacade: getHomeInfo(userId)
HomeFacade->>HomeService: getHomeInfo(userId)
HomeService->>RouteRepository: getMonthlyWalkSummary(userId)
RouteRepository->>RouteQueryRepositoryImpl: getMonthlyWalkSummary(userId)
RouteQueryRepositoryImpl->>Database: QueryDSL Query<br/>(user_id + created_at >= 1st of month)
Database-->>RouteQueryRepositoryImpl: distance, duration, count
RouteQueryRepositoryImpl-->>RouteRepository: HomeInfoResponseDto
RouteRepository-->>HomeService: HomeInfoResponseDto
HomeService-->>HomeFacade: HomeInfoResponseDto
HomeFacade-->>HomeController: HomeInfoResponseDto
HomeController->>Cache: SET homeInfo::{userId}
Cache-->>HomeController: OK
end
HomeController-->>Client: ApiResponse<HomeInfoResponseDto>
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In
`@src/main/java/org/sopt/pawkey/backendapi/domain/homeWeather/api/dto/HomeInfoResponseDto.java`:
- Around line 3-15: Remove the unnecessary Jackson polymorphic annotation from
the HomeInfoResponseDto: delete the import
com.fasterxml.jackson.annotation.JsonTypeInfo; and remove the `@JsonTypeInfo`(use
= JsonTypeInfo.Id.CLASS, property = "@class") annotation placed above the public
record HomeInfoResponseDto(...); keep the record and its compact constructor
that defaults null distance/totalTime/count to 0.0/0/0 unchanged so behavior
remains the same while preventing internal class name exposure in JSON
responses.
In
`@src/main/java/org/sopt/pawkey/backendapi/domain/routes/infra/persistence/RouteQueryRepositoryImpl.java`:
- Around line 3-34: getMonthlyWalkSummary uses LocalDate.now() which relies on
JVM default timezone and can miscalculate month boundaries; replace that with an
explicit timezone-aware computation (e.g., ZoneId.of("Asia/Seoul")). In the
getMonthlyWalkSummary method, compute the month start using
ZonedDateTime.now(ZoneId.of("Asia/Seoul")).withDayOfMonth(1).truncatedTo(ChronoUnit.DAYS).toLocalDateTime()
(or equivalent) and use that value in the route.createdAt.goe(startOfMonth)
predicate so the createdAt filter and startOfMonth use the same, explicit
timezone; update the startOfMonth variable and imports accordingly in
RouteQueryRepositoryImpl and ensure references to startOfMonth remain unchanged.
🧹 Nitpick comments (3)
src/main/java/org/sopt/pawkey/backendapi/global/config/RedisConfig.java (1)
54-66: 월간 집계 캐시의 만료/키 설계를 확인해 주세요.현재 기본 CacheConfig에 TTL이 없어서
@Cacheable키에 연-월이 포함되지 않으면 월 변경 후에도 이전 월 데이터가 유지될 수 있습니다. 홈 화면 월간 집계 캐시가 월 경계에서 갱신되도록 키에 YearMonth를 포함하거나 TTL을 설정했는지 확인 부탁드립니다.src/main/java/org/sopt/pawkey/backendapi/domain/routes/domain/repository/RouteRepository.java (1)
5-13: 레포지토리가 API DTO에 직접 의존합니다.도메인 레포지토리가
HomeInfoResponseDto를 반환하면 계층 결합이 생깁니다. 도메인/애플리케이션 레벨의 요약 모델(예:MonthlyWalkSummary)을 반환하고, 응답 DTO로의 매핑은 서비스/파사드에서 처리하는 구조를 권장합니다.src/test/java/org/sopt/pawkey/backendapi/global/cache/CacheIntegrationTest.java (1)
1-55: Redis 상태 정리로 테스트 플래키 방지
Redis 키가 테스트 간 남으면 간헐 실패 가능성이 있어, 종료 시 키 정리(또는 테스트 전 flush)를 넣는 게 안전합니다.🧹 예시 수정안
-import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; @@ class CacheIntegrationTest { @@ `@Autowired` private RedisTemplate<String, Object> redisTemplate; + private String cacheKey; @@ - String cacheKey = "homeInfo::" + userId; + cacheKey = "homeInfo::" + userId; assertThat(redisTemplate.hasKey(cacheKey)).isTrue(); @@ assertThat(redisTemplate.hasKey(cacheKey)).isFalse(); } + + `@AfterEach` + void clearCache() { + if (cacheKey != null) { + redisTemplate.delete(cacheKey); + } + } }
📌 PR 제목
[feat] 홈 화면 '내 산책 정보' 조회 API 구현 및 성능 최적화
✨ 요약 설명
사용자가 홈 화면에 진입 할 때 마주하는 '이번 달 누적 산책 거리, 시간, 횟수'를 확인할 수 있는 API를 구현했습니다. 데이터 조회 성능을 위해 Redis 캐싱을 적용했으며, 데이터 정합성을 보장하기 위한 로직 개선과 성능 테스트를 완료했습니다.
🧾 변경 사항
📂 PR 타입
🧪 테스트
데이터가 적어 인덱스 없이
전체를 읽는 것이 빠르다고 판단함
(Execution Time: 0.044ms)
가상 데이터 주입 시 설계한
복합 인덱스가 정상 작동함을 확인
(Execution Time: 4.751ms)
✅ 체크리스트
💬 리뷰어에게 전달할 말
🔗 관련 이슈
Summary by CodeRabbit
릴리스 노트
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.