[FEAT] 구글 플레이스 이미지 연동 - #301
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Next review available in: 28 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (14)
📝 WalkthroughWalkthroughGoogle Places 사진 조회 API와 클라이언트 훅을 추가했습니다. 장소 선택 화면은 조회 사진을 표시하고, 사진이 없으면 카테고리별 아이콘을 사용합니다. 원격 사진은 코스 이미지 업로드 대상으로 변환합니다. ChangesGoogle Places 사진 기능
기존 API 동작 정리
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant PlaceSelection
participant usePlacePhotos
participant PhotoApi
participant GooglePlaces
PlaceSelection->>usePlacePhotos: 장소 목록과 위치 정보 전달
usePlacePhotos->>PhotoApi: 장소별 사진 조회 요청
PhotoApi->>GooglePlaces: 텍스트 검색 및 사진 조회
GooglePlaces-->>PhotoApi: 사진 URI 또는 null
PhotoApi-->>usePlacePhotos: 사진 결과 반환
usePlacePhotos-->>PlaceSelection: 사진 상태 맵 반환
PlaceSelection-->>PlaceSelection: 사진 또는 카테고리 아이콘 렌더링
Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 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.
Actionable comments posted: 6
🤖 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 `@api/google-places/photo.ts`:
- Around line 13-20: Update the photo lookup caching and rate-limiting flow
around responseCache and rateLimitEntries to key requests only by normalized
name, address, latitude, and longitude, excluding unused request-body fields.
Add TTL-based removal of expired entries and enforce a maximum entry count with
eviction for responseCache; apply the same expired-entry cleanup to
rateLimitEntries.
In `@api/google-places/placePhoto.ts`:
- Around line 33-43: Update lookupPlacePhoto to accept unknown input and
validate that requestBody is a non-null object before accessing its properties;
throw InvalidPlacePhotoRequestError for invalid values such as JSON null so both
photo.ts and vite.config.ts return 400 instead of 502.
- Around line 60-111: Apply a shared timeout-enabled fetchGooglePlaces helper to
fetchTextSearch, fetchPlaceDetails, and fetchMedia in placePhoto.ts, using
AbortSignal.timeout for every upstream request. Handle DOMException errors with
name AbortError separately from other failures, preserving existing error
behavior for non-timeout failures. Apply the same pattern to the corresponding
Google Places calls in placeHours.ts.
In `@src/pages/admin/course-registration/place-selection/index.tsx`:
- Around line 36-79: Update getCategoryFallbackIcon to accept a scale parameter
and set every fallback icon’s width and height to 28 * scale, removing the fixed
h-7 w-7 sizing while preserving the shared styling. Update every call site of
getCategoryFallbackIcon to pass the active scale value, with no artificial
minimum bound.
In `@src/pages/admin/course-registration/visit-order/uploadAdminCourseImages.ts`:
- Around line 33-45: Remove the cross-origin fetch logic from fetchImageAsFile
and stop converting the Google Places photoUri into a browser-side File. Pass
photoUri only as an <img> src, or route downloading through a same-origin
backend proxy before creating the upload File, while keeping API keys out of the
client.
In `@src/pages/local-recommendation/components/SelectionResultCard.tsx`:
- Around line 61-64: Update the imageSize calculation in SelectionResultCard so
the add-action thumbnail also multiplies ADD_IMAGE_SIZE by scale, matching the
scaled remove-action thumbnail and other UI dimensions.
🪄 Autofix
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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 2f172a1a-a582-4f9d-9151-8fbd86ce4ef5
📒 Files selected for processing (24)
api/google-places/parseRequest.tsapi/google-places/photo.tsapi/google-places/placeHours.tsapi/google-places/placePhoto.tssrc/apis/courses.tssrc/apis/googlePlacesPhoto.tssrc/apis/localRecommendations.tssrc/hooks/usePlaceOpeningHours.tssrc/hooks/usePlacePhotos.tssrc/hooks/utils/createRequestQueue.tssrc/pages/admin/course-registration/place-selection/index.tsxsrc/pages/admin/course-registration/visit-order/uploadAdminCourseImages.tssrc/pages/admin/course-registration/visit-order/useAdminCourseVisitOrder.tssrc/pages/local-recommendation/components/PlaceMarkerIcon.tsxsrc/pages/local-recommendation/components/SelectionResultCard.tsxsrc/pages/local-recommendation/place-selection/components/PlacePhotoModal.tsxsrc/pages/local-recommendation/place-selection/components/PlacePhotoModalFooter.tsxsrc/pages/local-recommendation/place-selection/components/PlaceSearchSection.tsxsrc/pages/local-recommendation/place-selection/components/SelectedPlaceSection.tsxsrc/pages/local-recommendation/place-selection/hooks/useSelectedPlaces.tssrc/pages/local-recommendation/place-selection/index.tsxsrc/store/localRecommendation.store.tsvercel.jsonvite.config.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2026-07-26T17:09:23.387Z
Learnt from: KJun-2
Repo: yeogido/frontend PR: 125
File: src/pages/local-recommendation/course-basic-info/components/CompanionSelector.tsx:82-90
Timestamp: 2026-07-26T17:09:23.387Z
Learning: 이 프로젝트의 반응형 스케일 정책에서는 텍스트(폰트) 크기를 설계 기준 값에 전역 `scale`을 곱해 비율대로 스케일하세요. `12px`, `14px`처럼 특정 최소 하한을 강제로 적용하거나(클램프/바닥값) 임의의 픽셀 값으로 제한하지 마세요. 즉, 기준값(디자인 스펙) × `scale` 방식으로 계산해 비율이 유지되도록 구현합니다.
Applied to files:
src/pages/local-recommendation/place-selection/components/SelectedPlaceSection.tsxsrc/pages/local-recommendation/place-selection/components/PlaceSearchSection.tsxsrc/pages/local-recommendation/place-selection/components/PlacePhotoModalFooter.tsxsrc/pages/local-recommendation/place-selection/index.tsxsrc/pages/local-recommendation/components/PlaceMarkerIcon.tsxsrc/pages/local-recommendation/place-selection/components/PlacePhotoModal.tsxsrc/pages/local-recommendation/components/SelectionResultCard.tsxsrc/pages/admin/course-registration/place-selection/index.tsx
📚 Learning: 2026-08-03T09:41:11.931Z
Learnt from: KJun-2
Repo: yeogido/frontend PR: 188
File: src/pages/detail/components/CourseDetailLayout.tsx:202-205
Timestamp: 2026-08-03T09:41:11.931Z
Learning: When implementing the shared back-navigation UI component in yeogido/frontend, manage all UI dimensions, including positional offsets, according to the project’s global `scale` policy so the component remains visually consistent across screens.
Applied to files:
src/pages/local-recommendation/place-selection/components/SelectedPlaceSection.tsxsrc/pages/local-recommendation/place-selection/components/PlaceSearchSection.tsxsrc/pages/local-recommendation/place-selection/components/PlacePhotoModalFooter.tsxsrc/pages/local-recommendation/place-selection/index.tsxsrc/pages/local-recommendation/components/PlaceMarkerIcon.tsxsrc/pages/local-recommendation/place-selection/components/PlacePhotoModal.tsxsrc/pages/local-recommendation/components/SelectionResultCard.tsxsrc/pages/admin/course-registration/place-selection/index.tsx
📚 Learning: 2026-07-26T17:09:27.685Z
Learnt from: KJun-2
Repo: yeogido/frontend PR: 125
File: src/pages/local-recommendation/course-basic-info/components/TransportSelector.tsx:84-91
Timestamp: 2026-07-26T17:09:27.685Z
Learning: In this project’s 390px-based continuous responsive scaling, do not apply an artificial minimum lower bound to text sizes (e.g., avoid clamping via Math.max/min-font-size patterns). Instead, compute typography using proportional ratio scaling: render font sizes as `VALUE * scale` (for example, `DESCRIPTION_FONT_SIZE * scale`). During review, flag any code that enforces a hard minimum text size that breaks the intended proportional scaling.
Applied to files:
src/pages/local-recommendation/place-selection/components/SelectedPlaceSection.tsxsrc/pages/local-recommendation/place-selection/components/PlaceSearchSection.tsxsrc/pages/local-recommendation/place-selection/components/PlacePhotoModalFooter.tsxsrc/pages/local-recommendation/place-selection/index.tsxsrc/pages/local-recommendation/components/PlaceMarkerIcon.tsxsrc/pages/local-recommendation/place-selection/components/PlacePhotoModal.tsxsrc/pages/local-recommendation/components/SelectionResultCard.tsxsrc/pages/admin/course-registration/place-selection/index.tsx
📚 Learning: 2026-07-26T17:09:32.991Z
Learnt from: KJun-2
Repo: yeogido/frontend PR: 125
File: src/pages/local-recommendation/tag-selection/components/KeywordSelectionSection.tsx:51-56
Timestamp: 2026-07-26T17:09:32.991Z
Learning: When implementing responsive scaling in this project, prefer direct proportional calculations (e.g., using `VALUE * scale`) without applying artificial minimum lower bounds (clamps) to text sizes or other visual dimensions. Only introduce a lower bound when there is an explicitly documented exception; the primary allowed example is enforcing a 44px minimum touch target for interactive elements. In review, flag new/minimum clamps for text/visual dimensions unless they match an explicitly documented exception.
Applied to files:
src/pages/local-recommendation/place-selection/components/SelectedPlaceSection.tsxsrc/pages/local-recommendation/place-selection/components/PlaceSearchSection.tsxsrc/pages/local-recommendation/place-selection/components/PlacePhotoModalFooter.tsxsrc/pages/local-recommendation/place-selection/index.tsxsrc/pages/local-recommendation/components/PlaceMarkerIcon.tsxsrc/pages/local-recommendation/place-selection/components/PlacePhotoModal.tsxsrc/pages/local-recommendation/components/SelectionResultCard.tsxsrc/pages/admin/course-registration/place-selection/index.tsx
📚 Learning: 2026-07-26T17:09:40.303Z
Learnt from: KJun-2
Repo: yeogido/frontend PR: 125
File: src/pages/local-recommendation/tag-selection/components/RepresentativePhotoSection.tsx:107-122
Timestamp: 2026-07-26T17:09:40.303Z
Learning: yeogido/frontend의 반응형 스케일 정책에 맞춰, 텍스트를 포함한 UI 치수는 (디자인 기준값) × 전역 `scale`로 “연속적으로” 계산하고, 12px·14px 같은 최소 폰트/사이즈 하한(floor) 클램프를 적용하지 않는다. `scaleValue`를 쓰더라도 텍스트에 임의의 minimum floor를 추가하거나 `Math.max(value, 12/14)` 같은 보정을 넣지 말 것.
Applied to files:
src/pages/local-recommendation/place-selection/components/SelectedPlaceSection.tsxsrc/pages/local-recommendation/place-selection/components/PlaceSearchSection.tsxsrc/pages/local-recommendation/place-selection/components/PlacePhotoModalFooter.tsxsrc/pages/local-recommendation/place-selection/index.tsxsrc/pages/local-recommendation/components/PlaceMarkerIcon.tsxsrc/pages/local-recommendation/place-selection/components/PlacePhotoModal.tsxsrc/pages/local-recommendation/components/SelectionResultCard.tsxsrc/pages/admin/course-registration/place-selection/index.tsx
🔇 Additional comments (22)
src/apis/courses.ts (1)
79-79: LGTM!Also applies to: 102-102
src/apis/localRecommendations.ts (1)
1-2: LGTM!Also applies to: 62-62
src/pages/admin/course-registration/place-selection/index.tsx (2)
3-22: LGTM!Also applies to: 95-111, 184-184
262-262: LGTM!src/pages/admin/course-registration/visit-order/useAdminCourseVisitOrder.ts (1)
29-32: LGTM!Also applies to: 115-144
src/pages/local-recommendation/components/PlaceMarkerIcon.tsx (1)
1-21: LGTM!src/pages/local-recommendation/place-selection/components/PlacePhotoModal.tsx (1)
19-20: LGTM!Also applies to: 29-29, 63-74
src/pages/local-recommendation/place-selection/components/PlacePhotoModalFooter.tsx (1)
10-24: LGTM!src/pages/local-recommendation/place-selection/components/PlaceSearchSection.tsx (1)
46-48: LGTM!src/pages/local-recommendation/place-selection/components/SelectedPlaceSection.tsx (1)
38-38: LGTM!src/pages/local-recommendation/place-selection/index.tsx (1)
42-42: LGTM!src/store/localRecommendation.store.ts (1)
32-32: LGTM!Also applies to: 180-181
src/pages/local-recommendation/place-selection/hooks/useSelectedPlaces.ts (1)
38-40: LGTM!Also applies to: 76-87
api/google-places/parseRequest.ts (1)
1-9: LGTM!api/google-places/photo.ts (1)
22-68: LGTM!vite.config.ts (1)
10-20: LGTM!Also applies to: 30-75, 132-136
vercel.json (1)
11-14: LGTM!api/google-places/placeHours.ts (1)
1-1: LGTM!src/hooks/utils/createRequestQueue.ts (1)
1-24: LGTM!src/hooks/usePlacePhotos.ts (1)
1-57: LGTM!src/hooks/usePlaceOpeningHours.ts (1)
8-8: LGTM!Also applies to: 17-17, 89-89
src/apis/googlePlacesPhoto.ts (1)
1-27: LGTM!
…ature/google-places-images # Conflicts: # src/apis/courses.ts # src/pages/admin/course-registration/visit-order/useAdminCourseVisitOrder.ts
구글 플레이스 이미지 연동(#301)이 develop에 먼저 머지되면서 겹친 useSelectedPlaces.ts 충돌만 해결 — addSelectedPlace의 imageKey/imageUrl null 초기화(우리동네 코스 수정 기능)는 유지. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

작업 내용
변경 화면
확인 방법
체크리스트
스크린샷
참고 사항
관련 이슈
Closes #300
Summary by CodeRabbit
새 기능
버그 수정