Skip to content

[feat] #44 home 구현#50

Merged
JangInho merged 12 commits into
developfrom
feat/#44-home
May 19, 2026
Merged

[feat] #44 home 구현#50
JangInho merged 12 commits into
developfrom
feat/#44-home

Conversation

@JangInho

@JangInho JangInho commented May 19, 2026

Copy link
Copy Markdown
Contributor

🧾 요약

  • 홈 화면 진입 시 지도/추천/등산 기록 표시에 필요한 백엔드 API 3개를 추가합니다. 사용자 위치에서 가까운 산을 거리순으로 추천하고, 지도 BBox 내 산의 사용자 방문 정보(visited/visitCount)와 함께 '다녀온 산이 있는지' 여부 플래그를 같이 내려줍니다.

🔗 이슈

✨ 변경 내용

신규 API

  • GET /api/mountains/map?swLat=&swLng=&neLat=&neLng=
    • 지도 BBox 내 산 목록 + 사용자별 visited / visitCount / imageUrl 채워서 반환
    • 응답에 hasHikingRecord(유저 전체 등산 기록 유무) 플래그 포함 → 프론트 빈 상태 분기용
    • BBox 4개 모두 누락 시 서울 기본 영역 적용 (TODO: 서비스 영역 확장 시 재조정 추후에 할 예정임)
  • GET /api/mountains/recommendations?lat=&lng=&page=&size=
    • 사용자 등산 레벨(HikingLevel) → 산 난이도(Difficulty) 매핑으로 후보 필터
    • 사용자 위치(lat, lng)에서 가까운 순(squared distance ASC) 정렬
    • lat/lng 필수: 누락 시 400
    • 보조 정렬 id ASC 로 페이지 간 일관성 보장
    • Pageable.sort 무시됨 (서버 정책상 "거리 가까운 순" 고정)
  • GET /api/hiking-records/me/mountains/{mountainId}
    • 특정 산에 대한 본인의 등산 기록 목록 페이징

응답 DTO 변경 (중요!)

  • GetUserHikingRecordResponse.imageUrl: StringimageUrls: List<String>
    • 영향 API: GET /api/hiking-records/me, GET /api/hiking-records/me/mountains/{mountainId}
    • 순서: photoReportImageUrl 우선 → cliveImageUrl (null 필드는 제외)
    • 프론트 측 매핑 변경 필요

신규 파일

  • domain/mountain/dto/response/MountainMapResponse, MountainMapListResponse,
    MountainRecommendationResponse
  • domain/mountain/repository/projection/MountainMapProjection

홈 관련 더 해야할 것들

  • 온보딩 정보 받아와서 레벨 별 로직 적용하기

✅ 확인

  • 빌드 OK
  • 테스트 OK

Summary by CodeRabbit

  • New Features

    • Map-based mountain discovery using bounding-box coordinates, showing visit counts and visited status
    • Personalized mountain recommendations near your location based on hiking level
    • View your hiking history filtered by a specific mountain (paged)
    • Hiking records now include multiple images per session
  • Bug Fixes / Validation

    • Validation/error when bounding-box coordinates are partially provided (all four required or omit)

Review Change Stack

@JangInho JangInho self-assigned this May 19, 2026
@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4564c862-ea60-4c09-9c1d-f2c835e86577

📥 Commits

Reviewing files that changed from the base of the PR and between 849f80a and 1f99795.

📒 Files selected for processing (1)
  • src/main/java/com/semosan/api/domain/hiking/service/HikingRecordService.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/com/semosan/api/domain/hiking/service/HikingRecordService.java

📝 Walkthrough

Walkthrough

Adds home-screen mountain features: map-bounds mountain lookup, level-based recommendations, and per-mountain paged user hiking-records; includes DTOs/projections, native repository queries, service logic, controller endpoints, OpenAPI docs, and status/error codes.

Changes

Home feature implementation

Layer / File(s) Summary
Success status codes for new endpoints
src/main/java/com/semosan/api/common/status/SuccessStatus.java
Three new enum constants added: MOUNTAIN_MAP_SUCCESS, MOUNTAIN_RECOMMENDATION_SUCCESS, and GET_HIKING_RECORD_LIST_BY_MOUNTAIN_SUCCESS with corresponding HTTP status, codes, and Korean messages.
Hiking records by mountain endpoint
src/main/java/com/semosan/api/domain/hiking/controller/HikingRecordController.java, src/main/java/com/semosan/api/domain/hiking/controller/docs/HikingRecordControllerDocs.java, src/main/java/com/semosan/api/domain/hiking/dto/response/GetUserHikingRecordResponse.java, src/main/java/com/semosan/api/domain/hiking/repository/HikingRecordRepository.java, src/main/java/com/semosan/api/domain/hiking/repository/projection/UserHikingRecordProjection.java, src/main/java/com/semosan/api/domain/hiking/service/HikingRecordService.java, src/main/java/com/semosan/api/domain/hiking/repository/HikingMemberRepository.java
New GET /api/hiking-records/me/mountains/{mountainId} endpoint fetches paginated user hiking records for a specific mountain. Response DTO updated to expose multiple image URLs (photoReportImageUrl and cliveImageUrl) via buildImageUrls(). Projection updated with separate image URL getters. Repository adds findUserHikingRecordsByUserIdAndMountainId native query. Service validates mountain existence and maps results.
Mountain map and recommendation DTOs and projection
src/main/java/com/semosan/api/domain/mountain/dto/response/MountainMapListResponse.java, src/main/java/com/semosan/api/domain/mountain/dto/response/MountainMapResponse.java, src/main/java/com/semosan/api/domain/mountain/dto/response/MountainRecommendationResponse.java, src/main/java/com/semosan/api/domain/mountain/repository/projection/MountainMapProjection.java
Response contract types for mountain features. MountainMapListResponse wraps hasHikingRecord and mountains. MountainMapResponse includes visit status derived from visitCount. MountainRecommendationResponse exposes mountain attributes. MountainMapProjection defines data shape including visitCount and imageUrl.
Mountain repository queries for map and recommendations
src/main/java/com/semosan/api/domain/mountain/repository/MountainRepository.java
Two complex native SQL queries. findInBBoxWithUserHikingStats selects mountains within a bounding box and includes correlated subqueries for per-user visitCount and latest image URL. findRecommendationsByDifficulties returns paginated mountains filtered by difficulty set, ordered by squared distance from provided coordinates with deterministic id tiebreaker.
Mountain service for map and recommendations
src/main/java/com/semosan/api/domain/mountain/service/MountainService.java
getMountainsForMap validates bbox completeness (Seoul defaults when omitted), queries mountains with per-user stats, checks user's overall hiking-record existence via HikingMemberRepository, and returns MountainMapListResponse. getRecommendedMountains derives Difficulty set from onboarding level (fallback to all difficulties), queries by difficulty names, and maps to MountainRecommendationResponse. Includes mapHikingLevelToDifficulties utility.
Mountain controller endpoints and documentation
src/main/java/com/semosan/api/domain/mountain/controller/MountainController.java, src/main/java/com/semosan/api/domain/mountain/controller/docs/MountainControllerDocs.java
Two new @GetMapping endpoints with Swagger docs: GET /api/mountains/map (optional bbox params) returning MountainMapListResponse; and GET /api/mountains/recommendations (required lat/lng) returning paged MountainRecommendationResponse. Both document success and error responses.
Error status for partial BBox
src/main/java/com/semosan/api/common/status/ErrorStatus.java
Added MOUNTAIN_BBOX_PARTIAL to represent bad requests when BBox coordinates are partially provided.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant MountainController
  participant MountainService
  participant MountainRepository
  participant UserOnboardingRepository
  participant HikingMemberRepository
  participant Database
  Client->>MountainController: GET /api/mountains/map or /api/mountains/recommendations
  MountainController->>MountainService: getMountainsForMap(...) / getRecommendedMountains(...)
  MountainService->>MountainRepository: findInBBoxWithUserHikingStats(...) / findRecommendationsByDifficulties(...)
  MountainService->>UserOnboardingRepository: findByUserId(userId)
  MountainService->>HikingMemberRepository: existsByUser_Id(userId)
  MountainRepository->>Database: native SELECT queries
  MountainService-->>MountainController: MountainMapListResponse / Page<MountainRecommendationResponse>
  MountainController-->>Client: ApiResponse.success(...)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I nibble trails on mapped-out ground,
From bbox bounds to peaks I found,
Records grouped by mountain, images aligned,
Recommendations fit each hiker's mind,
Home screen hops with trails profound!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '[feat] #44 home 구현' clearly and concisely describes the main feature implementation (home screen), with the issue reference (#44) providing additional context.
Linked Issues check ✅ Passed All coding requirements from issue #44 are implemented: three new API endpoints (map BBox query, level-based recommendations, mountain-specific hiking records), hasHikingRecord flag, image URL list handling, repository queries, and Swagger documentation.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #44 objectives. No unrelated refactoring, dependency upgrades, or out-of-scope modifications are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#44-home

Comment @coderabbitai help to get the list of available commands and usage tips.

@JangInho JangInho changed the title feat: #44 home 구현 [feat] #44 home 구현 May 19, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/com/semosan/api/domain/mountain/service/MountainService.java`:
- Around line 63-67: The current logic in MountainService that computes
hasFullBBox and then sets
resolvedSwLat/resolvedSwLng/resolvedNeLat/resolvedNeLng silently falls back to
Seoul defaults whenever any of swLat, swLng, neLat, neLng are not all present;
change it so defaults are applied only when all four coordinates are null (i.e.,
the entire bbox is missing), and if some but not all bbox fields are provided
return a BAD_REQUEST (throw a suitable exception such as
IllegalArgumentException or ResponseStatusException) indicating incomplete bbox
input; update the code that currently uses hasFullBBox and the resolved*
variables (swLat, swLng, neLat, neLng, hasFullBBox, resolvedSwLat,
resolvedSwLng, resolvedNeLat, resolvedNeLng) to implement this validation and
error path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 73dffa98-1e87-4312-9545-aa1413eba17b

📥 Commits

Reviewing files that changed from the base of the PR and between 86d586d and 2983ca6.

📒 Files selected for processing (16)
  • src/main/java/com/semosan/api/common/status/SuccessStatus.java
  • src/main/java/com/semosan/api/domain/hiking/controller/HikingRecordController.java
  • src/main/java/com/semosan/api/domain/hiking/controller/docs/HikingRecordControllerDocs.java
  • src/main/java/com/semosan/api/domain/hiking/dto/response/GetUserHikingRecordResponse.java
  • src/main/java/com/semosan/api/domain/hiking/repository/HikingMemberRepository.java
  • src/main/java/com/semosan/api/domain/hiking/repository/HikingRecordRepository.java
  • src/main/java/com/semosan/api/domain/hiking/repository/projection/UserHikingRecordProjection.java
  • src/main/java/com/semosan/api/domain/hiking/service/HikingRecordService.java
  • src/main/java/com/semosan/api/domain/mountain/controller/MountainController.java
  • src/main/java/com/semosan/api/domain/mountain/controller/docs/MountainControllerDocs.java
  • src/main/java/com/semosan/api/domain/mountain/dto/response/MountainMapListResponse.java
  • src/main/java/com/semosan/api/domain/mountain/dto/response/MountainMapResponse.java
  • src/main/java/com/semosan/api/domain/mountain/dto/response/MountainRecommendationResponse.java
  • src/main/java/com/semosan/api/domain/mountain/repository/MountainRepository.java
  • src/main/java/com/semosan/api/domain/mountain/repository/projection/MountainMapProjection.java
  • src/main/java/com/semosan/api/domain/mountain/service/MountainService.java

Comment thread src/main/java/com/semosan/api/domain/mountain/service/MountainService.java Outdated
JangInho added 3 commits May 19, 2026 22:32
# Conflicts:
#	src/main/java/com/semosan/api/domain/hiking/repository/HikingMemberRepository.java
#	src/main/java/com/semosan/api/domain/mountain/service/MountainService.java
@howooyeon
howooyeon self-requested a review May 19, 2026 14:21

@howooyeon howooyeon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니당~ 몇가지 코멘트 남겼습니다!

Comment thread src/main/java/com/semosan/api/domain/mountain/repository/MountainRepository.java Outdated
JangInho added 2 commits May 19, 2026 23:47
- BBox 지도 조회: visitCount 상관 서브쿼리를 LEFT JOIN + GROUP BY로 치환 (COUNT(hm.user_id))
- 레벨추천 정렬: 경도항에 COS(RADIANS(lat)) 보정 추가
- MountainMapResponse.visitCount 타입을 Long으로 통일
같은 서비스 내 다른 내 등산기록 API와 정책 일관성 맞춤
@JangInho
JangInho merged commit a1866f7 into develop May 19, 2026
1 check passed
@howooyeon howooyeon added the enhancement New feature or request label May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 홈 구현

2 participants