-
Notifications
You must be signed in to change notification settings - Fork 0
[Feature/#182] 전체 리뷰 조회 API 수정 #183
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
Conversation
|
Caution Review failedThe pull request is closed. 📝 WalkthroughSummary by CodeRabbit
Walkthrough리뷰 셀에 onToggle 콜백과 라인 기반 잘림 판정(int)이 추가되고 레이아웃 제약이 완화되었습니다. ReviewView에 더보기 버튼 가시성 제어 API가 추가되었으며, EntireReviewViewController는 vintage를 모든 API 경로로 전달하도록 변경되었습니다. WineDetailViewController는 리뷰 UI 업데이트를 updateReviewView()로 일원화했습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant U as 사용자
participant Cell as ReviewCollectionViewCell
participant VC as 부모 ViewController
U->>Cell: 토글 버튼 탭
Cell->>Cell: toggleButtonTapped()
alt onToggle 존재
Cell-->>VC: onToggle?()
end
VC->>VC: 레이아웃/데이터 갱신 처리
sequenceDiagram
participant U as 사용자
participant ER as EntireReviewViewController
participant DD as Dropdown
participant API as NetworkService
U->>ER: 화면 진입
ER->>API: fetchWineReviews(wineId, sortType, page=1, vintageYear?)
API-->>ER: 리뷰 목록 응답
U->>DD: 옵션 선택(정렬)
DD-->>ER: onOptionSelected(option)
ER->>API: fetchWineReviews(wineId, mappedSortType, page=1, vintageYear?)
API-->>ER: 응답
U->>ER: 스크롤 하단(페이징)
ER->>API: fetchWineReviews(..., page+1, vintageYear?)
sequenceDiagram
participant WDV as WineDetailViewController
participant RV as ReviewView
WDV->>WDV: 리뷰 데이터 준비
WDV->>RV: configureButton(isHidden: reviewCount != 3)
WDV->>WDV: updateReviewView()
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. 📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
✨ Finishing touches
🧪 Generate unit tests
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: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
DE/DE/Sources/Features/Search/ViewControllers/EntireReviewViewController.swift (1)
201-213: 셀 토글 클로저: 강한 순환 참조 + 재사용 시 인덱스 오류 + 2초 딜레이로 인한 UI 글리치
- VC → CollectionView → Cell → onToggle(클로저) → VC로 강한 순환 가능.
- indexPath 캡처는 재사용 후 잘못된 아이템 토글 가능.
- 2초 지연은 스크롤/재사용 시 엉뚱한 셀에 라인 변경 적용 위험.
즉시 수정 권장.
- cell.onToggle = { - self.expandedCells[indexPath.item].toggle() - - UIView.animate(withDuration: 0, animations: { - collectionView.performBatchUpdates(nil, completion: nil) - }) { _ in - // 텍스트를 약간 늦춰서 줄이기 - DispatchQueue.main.asyncAfter(deadline: .now() + 2) { - cell.review.numberOfLines = self.expandedCells[indexPath.item] ? 0 : 2 - } - } - } + cell.onToggle = { [weak self, weak collectionView, weak cell] in + guard + let self = self, + let collectionView = collectionView, + let cell = cell, + let currentIndexPath = collectionView.indexPath(for: cell) + else { return } + self.expandedCells[currentIndexPath.item].toggle() + collectionView.performBatchUpdates(nil) { _ in + cell.review.numberOfLines = self.expandedCells[currentIndexPath.item] ? 0 : 2 + } + }추가로, numberOfLines 토글은 셀 내부에서 처리하도록 일원화하면 VC 단 로직이 더 간결해집니다.
DE/DE/Sources/Features/Search/ViewControllers/WineDetailViewController.swift (1)
490-497: 셀 토글 클로저의 강한 캡처VC ↔ 셀 간 순환 참조 및 재사용 시 indexPath 불일치 위험. 약한 캡처와 현재 indexPath 조회로 보완하세요.
- cell.onToggle = { - self.expandedCells[indexPath.item].toggle() - - UIView.animate(withDuration: 0, animations: { - collectionView.performBatchUpdates(nil, completion: nil) - self.updateScrollViewHeight() - }) - } + cell.onToggle = { [weak self, weak collectionView, weak cell] in + guard + let self = self, + let collectionView = collectionView, + let cell = cell, + let currentIndexPath = collectionView.indexPath(for: cell) + else { return } + self.expandedCells[currentIndexPath.item].toggle() + collectionView.performBatchUpdates(nil) { _ in + self.updateScrollViewHeight() + } + }DE/DE/Sources/Core/CommonUI/Cells/ReviewCollectionViewCell.swift (1)
89-95: toggleButton에 bottom 제약이 2개 설정되어 충돌합니다
- Line 92: bottom = -10
- Line 93-94: bottom = -12 (toggleBottomConstraint로 보관)
두 개의 동일 anchor(equal) 제약이 상충합니다. 하나만 남기세요. -12로 관리되는 보관 제약만 유지하는 수정을 제안합니다.
toggleButton.snp.makeConstraints { - $0.top.greaterThanOrEqualTo(review.snp.bottom).offset(2) + $0.top.greaterThanOrEqualTo(review.snp.bottom).offset(2) $0.leading.equalTo(review.snp.leading) - $0.bottom.equalToSuperview().offset(-10) - self.toggleBottomConstraint = $0.bottom.equalToSuperview().offset(-12).constraint + self.toggleBottomConstraint = $0.bottom.equalToSuperview().offset(-12).constraint }
🧹 Nitpick comments (10)
DE/DE/Sources/Features/Search/ViewControllers/EntireReviewViewController.swift (4)
111-118: 드롭다운 클릭 로깅이 셋업 시점에 찍히는 문제현재 setupDropdownAction() 진입 시점에 클릭 이벤트가 로깅됩니다. 실제 선택 시점으로 이동하세요.
적용 예시:
- logButtonClick(screenName: screenName, buttonName: Tracking.ButtonEvent.dropdownBtnTapped, fileName: #file) entireReviewView.dropdownView.onOptionSelected = { [weak self] selectedOption in guard let self = self else { return } + self.logButtonClick(screenName: self.screenName, + buttonName: Tracking.ButtonEvent.dropdownBtnTapped, + fileName: #file)
117-125: 정렬 타입 하드코딩/공백 불일치 가능성"최신 순" ↔ "최신순"처럼 UI 라벨과 API 파라미터가 혼재되어 있습니다. 맵으로 단일화하세요. 디폴트도 명시해 예외를 방지하세요.
- if selectedOption == "최신 순" { - currentType = "최신순" - } else if selectedOption == "오래된 순" { - currentType = "오래된 순" - } else if selectedOption == "별점 높은 순" { - currentType = "별점 높은 순" - } else if selectedOption == "별점 낮은 순" { - currentType = "별점 낮은 순" - } + let sortMap: [String: String] = [ + "최신 순": "최신순", + "오래된 순": "오래된 순", + "별점 높은 순": "별점 높은 순", + "별점 낮은 순": "별점 낮은 순" + ] + currentType = sortMap[selectedOption, default: "최신순"]
275-277: 중복 reloadData 호출callEntireReviewAPI() 내부에서 이미 reloadData를 수행합니다. 아래 호출은 불필요합니다.
- DispatchQueue.main.async { - self.entireReviewView.reviewCollectionView.reloadData() - } + // 중복 호출 제거
261-270: 무한 스크롤에서 전체 화면 블로킹은 UX 저하페이지네이션에는 테일 로더(footer spinner)나 셀 플래스홀더가 적합합니다. overlay는 입력을 막아 스크롤 흐름을 끊습니다.
DE/DE/Sources/Core/CommonUI/View/ReviewView.swift (1)
138-140: 버튼 가시성 제어 API 추가 OK간단·명확합니다.
메서드 의도가 더 드러나도록 주석을 권장합니다.
- public func configureButton(_ isHidden: Bool) { + /// "더보기" 버튼 노출 제어 (true = 숨김) + public func configureButton(_ isHidden: Bool) { moreBtn.isHidden = isHidden }DE/DE/Sources/Core/CommonUI/Cells/ReviewCollectionViewCell.swift (5)
20-21: vertical hugging을 required로 올린 부분, 제약 충돌 가능성 점검닉네임 라벨을 세로 방향 required로 고정하면, 동적 폰트/멀티라인 조합에서 score/date와의 제약 우선순위에 따라 경고가 날 수 있습니다. 증상이 있으면 .defaultHigh로 낮추거나, 인접 라벨의 compressionResistance를 조정하는 쪽을 고려해 주세요.
32-38: 토글 버튼 접근성/현지화 보완
- 텍스트(“더보기/접기”) 하드코딩 → Localizable로 분리 권장.
- 터치 타겟 44pt 확보 및 VoiceOver 레이블/힌트 지정 추천.
아래와 같이 최소 보완을 제안합니다.
private let toggleButton = UIButton().then { - $0.setTitle("더보기", for: .normal) + $0.setTitle(NSLocalizedString("common.more", comment: "더보기"), for: .normal) $0.titleLabel?.font = UIFont.pretendard(.medium, size: 13) $0.setTitleColor(AppColor.gray70, for: .normal) $0.contentHorizontalAlignment = .left $0.isHidden = true + $0.contentEdgeInsets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0) // 터치 타겟 확보 + $0.accessibilityTraits = .button }
51-56: 토글 후 레이아웃 갱신 책임 범위 확인셀 내부에서 numberOfLines만 바꾸면 셀 높이 변경이 컬렉션뷰에 반영되지 않을 수 있습니다. 외부(onToggle)에서 performBatchUpdates/reloadItems로 레이아웃을 갱신하고 있는지 확인해 주세요. 필요시 isExpanded 상태도 함께 전달하면 추적이 쉬워집니다.
112-122: 가독성/의도 명확화: lineCount 기반으로 분기하세요변수명이 shouldShowToggle이지만 실제론 라인 수(Int)입니다. 가독성을 위해 lineCount와 showMore로 분리하면 조건이 즉시 읽힙니다. 동작은 동일합니다.
- let shouldShowToggle = isReviewTextTruncated() - toggleButton.isHidden = !(shouldShowToggle > 2) + let lineCount = isReviewTextTruncated() + let showMore = lineCount > 2 + toggleButton.isHidden = !showMore @@ - if shouldShowToggle > 2 { + if showMore { toggleBottomConstraint?.activate() reviewBottomConstraint?.deactivate() } else { toggleBottomConstraint?.deactivate() reviewBottomConstraint?.activate() }
124-127: 1줄일 때 개행 추가하는 “텍스트 조작”은 제거 권장실제 리뷰 내용을 임의로 변형하면 접근성/복사/분석 로직에서 부작용을 만들 수 있습니다. 레이아웃 문제라면 제약/인셋으로 해결하는 게 안전합니다. 아래처럼 해당 블록을 제거해도 의도한 레이아웃은 윗부분 분기(showMore=false일 때 reviewBottomConstraint 활성화)로 충족됩니다.
- if shouldShowToggle == 1 { - let reviewString = "\(model.contents)\n" - AppTextStyle.KR.body3.apply(to: review, text: reviewString, color: AppColor.gray90) - } + // 1줄 케이스에서도 텍스트는 원본 그대로 표시합니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
DE/DE/Sources/Core/CommonUI/Cells/ReviewCollectionViewCell.swift(6 hunks)DE/DE/Sources/Core/CommonUI/View/ReviewView.swift(1 hunks)DE/DE/Sources/Features/Search/ViewControllers/EntireReviewViewController.swift(6 hunks)DE/DE/Sources/Features/Search/ViewControllers/WineDetailViewController.swift(2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: doyeonk429
PR: Drink-Easy/DE_iOS#0
File: :0-0
Timestamp: 2025-08-30T13:14:55.618Z
Learning: 사용자 doyeonk429는 한국어로 코드 리뷰를 받기를 선호합니다.
📚 Learning: 2025-09-02T12:53:54.084Z
Learnt from: doyeonk429
PR: Drink-Easy/DE_iOS#180
File: DE/DE/Sources/Features/TastingNote/ViewControllers/CreateVCs/RecordGraphViewController.swift:44-46
Timestamp: 2025-09-02T12:53:54.084Z
Learning: 사용자 doyeonk429는 와인 상세에서 테이스팅노트로 이동하는 플로우에서 빈티지가 무조건 설정되어 넘어간다고 설명했습니다. WineDetailViewController에서 goToTastingNote 메서드에서 vintage 가드 조건이 있어 빈티지 선택이 필수입니다.
Applied to files:
DE/DE/Sources/Features/Search/ViewControllers/WineDetailViewController.swiftDE/DE/Sources/Features/Search/ViewControllers/EntireReviewViewController.swift
🔇 Additional comments (11)
DE/DE/Sources/Features/Search/ViewControllers/EntireReviewViewController.swift (5)
47-52: 초기 로드에서 빈티지 파라미터 전파 OK초기 API 호출에 vintage 반영이 일관적입니다.
61-64: 화면 로깅 위치 이전 OKviewDidAppear로 이동해 정확한 노출 시점에 로깅됩니다.
130-136: 정렬 변경 시 빈티지 포함 재호출 OK옵션 변경 시 vintage 동반 전파가 잘 되어 있습니다.
151-156: 네트워크 계층에 vintageYear 전달 OK파라미터 체인이 명확합니다.
41-57: showColorBlockingView/hideBlockingView 페어 불일치 가능성 점검 필요색상 블로킹 뷰와 일반 블로킹 뷰의 hide API가 동일 엔티티를 가리키는지 확인 부탁드립니다. 아니면 잔존 오버레이가 생길 수 있습니다.
다음 스크립트로 표시/해제 API 사용처를 점검해 주세요:
#!/bin/bash rg -n --stats -C1 -S '\bshow(Color)?BlockingView\(' echo '----' rg -n --stats -C1 -S '\bhide(Color)?BlockingView\('DE/DE/Sources/Features/Search/ViewControllers/WineDetailViewController.swift (4)
223-231: 전체 리뷰 화면으로 빈티지 전달 OK넘겨받은 vintage를 그대로 연결해 일관성 확보되었습니다.
310-311: '더보기' 노출 조건 재확인 필요현재 count == 3일 때만 노출(그 외는 숨김)입니다. 사양이 “미리보기 개수(최대 3)만큼 내려오고, 3개면 더보기 노출”이라면 OK입니다. 전체 개수를 모르면 3 == hasMore의 휴리스틱이 맞는지 PM/백엔드와 재확인해 주세요.
409-413: 상세 API 호출에 vintageYear 전달 OK빈티지 필터링 목표와 일치합니다.
406-423: 블로킹 뷰 API 페어 확인여기도 showColorBlockingView → hideBlockingView 조합입니다. 앞선 코멘트와 함께 통일성/정상 해제 여부를 확인해 주세요.
DE/DE/Sources/Core/CommonUI/Cells/ReviewCollectionViewCell.swift (2)
15-16: onToggle 콜백 추가 적절합니다셀 내부 토글 상태 변화에 대해 외부로 신호를 주는 방식이 간단하고 재사용성도 좋습니다. 현 시점에선 문제 없어 보입니다.
130-138: 레이블의 좌우 인셋이 실제로 어떻게 설정되어 있는지 확인하기 위해 아래 스크립트를 실행해주세요.#!/bin/bash FILE=$(fd ReviewCollectionViewCell.swift -t f) echo "ReviewCollectionViewCell.swift 경로: $FILE" rg -nC3 "review.snp.makeConstraints" "$FILE"
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
1 similar comment
✅ Actions performedFull review triggered. |
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: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
DE/DE/Sources/Core/CommonUI/Cells/ReviewCollectionViewCell.swift (1)
89-95: toggleButton에 bottom 제약 2개 설정됨(충돌 위험)동일 뷰에 서로 다른 bottom 제약 두 개가 동시에 활성화됩니다. 하나만 유지하세요.
toggleButton.snp.makeConstraints { $0.top.greaterThanOrEqualTo(review.snp.bottom).offset(2) $0.leading.equalTo(review.snp.leading) - $0.bottom.equalToSuperview().offset(-10) self.toggleBottomConstraint = $0.bottom.equalToSuperview().offset(-12).constraint }
🧹 Nitpick comments (9)
DE/DE/Sources/Core/CommonUI/View/ReviewView.swift (1)
137-140: 공개 API 네이밍 명확화 + 메인 스레드 보장 제안뷰 외부에서 호출되는 공개 API는 의도가 드러나게 네이밍하고, UI 업데이트는 메인 스레드 보장이 안전합니다.
아래처럼 메서드명을 명확히 하고 MainActor로 보장하는 것을 제안합니다.
- public func configureButton(_ isHidden: Bool) { - moreBtn.isHidden = isHidden - } + @MainActor + public func setMoreButtonHidden(_ hidden: Bool) { + moreBtn.isHidden = hidden + }추가로 호출부 교체(동일 PR 내):
- WineDetailViewController.updateReviewView():
- reviewView.configureButton(reviewData.count != 3) + reviewView.setMoreButtonHidden(reviewData.count != 3)DE/DE/Sources/Features/Search/ViewControllers/EntireReviewViewController.swift (4)
49-52: 초기 호출도 상태값(currentType) 사용초기 로드 시에도 하드코딩 대신 currentType을 사용하면 소스 일관성이 좋아집니다.
- sortType: "최신순", + sortType: currentType,
275-277: 중복 reloadData 제거callEntireReviewAPI() 내부에서 이미 reload를 수행합니다. 여기서 한 번 더 호출하면 불필요한 레이아웃 패스가 발생합니다.
- DispatchQueue.main.async { - self.entireReviewView.reviewCollectionView.reloadData() - } + // 중복 reload 제거
45-59: Blocking View 토글의 메인 스레드 보장 확인show/hideBlockingView가 UI 변경을 동반한다면 메인 스레드에서 호출되도록 보장하세요(내부에서 보장하지 않는 경우).
// 예: 보장이 없다면 await MainActor.run { self.view.hideBlockingView() }Also applies to: 262-271
117-125: 정렬 문자열 분기 간소화 — 딕셔너리 매핑으로 교체하고 기본값을 '최신순'으로 통일if-else 하드코딩은 오타 취약이므로 딕셔너리 매핑으로 단순화하세요. 레포에 이미 DE/DE/Sources/Features/Search/ViewControllers/EntireReviewViewController.swift 에서 sortType: "최신순"으로 호출되고 있으니 기본값도 "최신순"으로 맞춥니다 (WineService.fetchWineReviews 정의: DE/DE/Sources/Network/Wine/Service/WineService.swift).
- if selectedOption == "최신 순" { - currentType = "최신순" - } else if selectedOption == "오래된 순" { - currentType = "오래된 순" - } else if selectedOption == "별점 높은 순" { - currentType = "별점 높은 순" - } else if selectedOption == "별점 낮은 순" { - currentType = "별점 낮은 순" - } + let map: [String: String] = [ + "최신 순": "최신순", + "오래된 순": "오래된 순", + "별점 높은 순": "별점 높은 순", + "별점 낮은 순": "별점 낮은 순" + ] + currentType = map[selectedOption, default: "최신순"]DE/DE/Sources/Features/Search/ViewControllers/WineDetailViewController.swift (2)
310-311: ‘더보기’ 노출 정책(count == 3) 적용 👍 + 메서드명 정합성정책대로 count == 3 일 때만 노출되는 로직은 타당합니다. 상응하는 API 명도 위 제안(setMoreButtonHidden)으로 맞추면 가독성이 올라갑니다.
- reviewView.configureButton(reviewData.count != 3) + reviewView.setMoreButtonHidden(reviewData.count != 3)
325-327: 고정 높이 계산 대신 실제 콘텐츠 높이 기반으로 전환 고려현재 32 + count*100은 내용 줄수/토글에 따라 오차가 큽니다. 초기 바인딩 시점에 한 번 layoutIfNeeded 후 collectionViewContentSize.height로 세팅하는 접근을 권장합니다.
reviewView.reviewCollectionView.layoutIfNeeded() let contentHeight = reviewView.reviewCollectionView.collectionViewLayout.collectionViewContentSize.height reviewView.reviewCollectionView.snp.updateConstraints { $0.height.equalTo(max(contentHeight, 100)) }DE/DE/Sources/Core/CommonUI/Cells/ReviewCollectionViewCell.swift (2)
97-114: 레이아웃 확정 전 폭 0 문제 방지numberOfLines 계산 전에 layoutIfNeeded로 레이아웃을 확정하면 계산 안정성이 높아집니다. 또한 isHidden 표현을 단순화하세요.
toggleButton.setTitle(isExpanded ? "접기" : "더보기", for: .normal) - let shouldShowToggle = isReviewTextTruncated() - toggleButton.isHidden = !(shouldShowToggle > 2) + contentView.layoutIfNeeded() + let shouldShowToggle = isReviewTextTruncated() + toggleButton.isHidden = (shouldShowToggle <= 2)
130-138: 라벨 너비 상수 정합성(인셋 17+17 = 34)labelWidth는 좌우 인셋(17, 17)을 반영해 34를 사용하는 것이 수치 일관성에 맞습니다.
- let labelWidth = contentView.frame.width - 30 + let labelWidth = contentView.frame.width - 34
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
DE/DE/Sources/Core/CommonUI/Cells/ReviewCollectionViewCell.swift(6 hunks)DE/DE/Sources/Core/CommonUI/View/ReviewView.swift(1 hunks)DE/DE/Sources/Features/Search/ViewControllers/EntireReviewViewController.swift(6 hunks)DE/DE/Sources/Features/Search/ViewControllers/WineDetailViewController.swift(2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: doyeonk429
PR: Drink-Easy/DE_iOS#0
File: :0-0
Timestamp: 2025-08-30T13:14:55.618Z
Learning: 사용자 doyeonk429는 한국어로 코드 리뷰를 받기를 선호합니다.
📚 Learning: 2025-09-02T12:53:54.129Z
Learnt from: doyeonk429
PR: Drink-Easy/DE_iOS#180
File: DE/DE/Sources/Features/TastingNote/ViewControllers/CreateVCs/RecordGraphViewController.swift:44-46
Timestamp: 2025-09-02T12:53:54.129Z
Learning: 사용자 doyeonk429는 와인 상세에서 테이스팅노트로 이동하는 플로우에서 빈티지가 무조건 설정되어 넘어간다고 설명했습니다. WineDetailViewController에서 goToTastingNote 메서드에서 vintage 가드 조건이 있어 빈티지 선택이 필수입니다.
Applied to files:
DE/DE/Sources/Features/Search/ViewControllers/EntireReviewViewController.swiftDE/DE/Sources/Features/Search/ViewControllers/WineDetailViewController.swift
🔇 Additional comments (1)
DE/DE/Sources/Core/CommonUI/Cells/ReviewCollectionViewCell.swift (1)
17-21: 닉네임 라벨 hugging 우선순위 상향 👍줄바꿈/압축 충돌 줄이는 데 도움 됩니다.
🚀 PR 개요
💡 PR 유형
✏️ 변경 사항 요약
더보기버튼 노출 정책에 따라 UI 분기 처리🔗 관련 이슈
🧪 테스트 내역
🎨 스크린샷 또는 시연 영상 (선택)
Simulator.Screen.Recording.-.iPhone.16.Pro.-.2025-09-07.at.18.49.43.mp4
✅ PR 체크리스트
develop입니다💬 추가 설명 or 리뷰 포인트 (선택)