Flt 22 컬렉션 신고 UI 제작#215
Hidden character warning
Conversation
…to FLT-22-컬렉션-신고-UI-제작
|
Warning Review limit reached
More reviews will be available in 44 minutes and 16 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?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 credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. 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, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthrough컬렉션 신고(Report) 기능을 전체 스택으로 추가한다. 데이터 레이어에 신고 요청 DTO·모델·매퍼·API 엔드포인트·레포지토리 메서드를 신설하고, 프레젠테이션 레이어에 신고 화면 Compose UI·ViewModel·네비게이션을 추가하며, Changes컬렉션 신고 기능 전체 스택
Sequence Diagram(s)sequenceDiagram
actor 사용자
participant CollectionDetailScreen
participant CollectionReportScreen
participant CollectionReportViewModel
participant CollectionRepository
participant CollectionApi
사용자->>CollectionDetailScreen: 신고 버튼 클릭
CollectionDetailScreen->>CollectionReportScreen: navigateToCollectionReport(collectionId)
사용자->>CollectionReportScreen: 신고 사유 선택 및 제출
CollectionReportScreen->>CollectionReportViewModel: submitReport()
CollectionReportViewModel->>CollectionRepository: postCollectionReport(collectionId, model)
CollectionRepository->>CollectionApi: POST /collections/{collectionId}/reports
CollectionApi-->>CollectionRepository: BaseEmptyResponse
CollectionRepository-->>CollectionReportViewModel: Result.success(Unit)
CollectionReportViewModel-->>CollectionReportScreen: SideEffect: ReportSuccess
CollectionReportScreen->>CollectionDetailScreen: navigateUpWithSuccess()
CollectionDetailScreen->>CollectionDetailScreen: 신고 접수 토스트 표시
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 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 |
jongwoo2003-sidewalk
left a comment
There was a problem hiding this comment.
코드 리뷰 — 컬렉션 신고 UI 제작
전반적인 구조와 플로우는 기존 컨벤션을 잘 따르고 있습니다. 아래 몇 가지 사항을 확인해 주세요.
🔴 필수 수정
1. isLoading 상태가 UI에 연결되어 있지 않음
CollectionReportUiState에 isLoading 필드가 있고 ViewModel에서 업데이트하지만, CollectionReportScreen으로 전달되지 않아 제출 버튼이 API 호출 중에도 활성화된 상태로 남습니다. 빠르게 두 번 탭하면 중복 요청이 발생할 수 있습니다.
// isEnabled 계산 시 isLoading도 반영해야 함
val isEnabled = !uiState.isLoading && when (selectedReportReason) { ... }2. Repository가 DTO를 직접 받음
다른 메서드들과 달리 postCollectionReport는 도메인 모델 대신 DTO를 파라미터로 받고 있습니다. ViewModel에서 .toDto() 변환 후 Repository에 전달하고 있는데, 이 변환은 Repository 내부에서 이루어져야 합니다.
// 현재 (ViewModel에서 변환)
collectionRepository.postCollectionReport(collectionId, requestModel.toDto())
// 올바른 방향 (Repository에서 변환)
collectionRepository.postCollectionReport(collectionId, requestModel)
// Repository 내부에서 requestModel.toDto() 호출🟡 권장 수정
3. 신고 사유 문자열이 여러 곳에 분산
ReportCheck.kt의 하드코딩된 한국어 문자열과 CollectionReportViewModel의 REASON_CODE_MAP 키가 동일한 문자열을 중복 사용합니다. 문자열 하나라도 수정되면 두 파일 모두 수정해야 합니다.
enum으로 통합하는 것을 권장합니다.
enum class ReportReason(val displayText: String, val code: String) {
ABUSE("욕설·혐오 표현이 포함된 콘텐츠", "ABUSE"),
OBSCENE("음란하거나 선정적인 콘텐츠", "OBSCENE"),
SPAM("광고·홍보 또는 스팸성 콘텐츠", "SPAM"),
COPYRIGHT("저작권을 침해한 콘텐츠", "COPYRIGHT"),
OTHER("기타", "OTHER"),
}4. 텍스트 필드 포커스 시 자동으로 "기타" 선택
다른 항목이 선택된 상태에서 텍스트 필드를 탭하면 선택이 "기타"로 바뀌는 동작이 의도한 것인지 확인 부탁드립니다. 일반적으로는 선택 항목이 입력 필드 포커스에 의해 바뀌지 않는 방식이 더 자연스럽습니다.
🔵 선택 사항
- 클릭 영역:
ReportCheckItem의 클릭 영역이 아이콘 48dp로만 한정되어 있어 텍스트를 탭해도 선택되지 않습니다. Row 전체를 클릭 가능하게 하면 UX가 개선됩니다. - 신고 실패 처리 TODO: 의도적으로 미구현인 경우 PR 설명의 미구현 체크리스트에 명시해 주세요.
reasons타입: 항상 단일 아이템으로만 전송된다면 API 스펙과 맞추어List<String>vsString재검토를 고려해 보세요.- PR 템플릿: 이슈 번호와 스크린샷이 기본 템플릿 그대로 남아 있습니다.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
app/src/main/java/com/flint/domain/model/collection/CollectionReportModel.kt (1)
3-5: 🏗️ Heavy lift신고 사유 계약을 도메인 타입으로 승격해 문자열 의존을 줄여주세요.
reasons: List<String>는 코드값 오타/변경을 컴파일 타임에 막지 못합니다. 현재는 코드값 정의가 프레젠테이션(ReportReason.code)에 있고 도메인은 raw string을 받아서, API 계약 변경 시 영향 추적이 어려워집니다. 도메인에 전용 reason 타입(예: enum/value class)을 두고 DTO 매퍼에서만 문자열로 변환하는 구조가 더 안전합니다.🤖 Prompt for 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. In `@app/src/main/java/com/flint/domain/model/collection/CollectionReportModel.kt` around lines 3 - 5, The `reasons` field in CollectionReportRequestModel is using `List<String>` which lacks type safety and allows any string value, making it impossible to catch invalid reason codes at compile time and difficult to track API contract changes. Create a dedicated domain type for report reasons (such as an enum or value class) and replace `List<String>` with `List<YourReasonType>` in the CollectionReportRequestModel. Handle the conversion from string values (coming from the API/presentation layer) to the domain reason type only in the DTO mapper layer, keeping the domain model decoupled from raw string dependencies and ensuring compile-time validation of valid reason codes.
🤖 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
`@app/src/main/java/com/flint/presentation/collectiondetail/report/CollectionReportScreen.kt`:
- Around line 42-44: The ReportFailure side effect handler in the
CollectionReportScreen is empty with only a TODO comment, providing no user
feedback when report submission fails. Implement the ReportFailure case in the
side effect handling block to display a toast or dialog message to inform users
that the report submission has failed. Replace the empty TODO comment with
appropriate UI feedback mechanism (such as showToast or showDialog) that conveys
the failure to the user.
In
`@app/src/main/java/com/flint/presentation/collectiondetail/report/component/ReportCheck.kt`:
- Around line 72-80: The clickable area for the report reason selection is
currently restricted to only the Icon component because the noRippleClickable
modifier with the onCheckClick callback is applied to the Icon. To expand the
touch target and improve user experience, move the noRippleClickable(onClick =
onCheckClick) modifier from the Icon to the Row container. This will make the
entire row clickable, allowing users to select the option by clicking either the
icon or the text.
In
`@app/src/main/java/com/flint/presentation/collectiondetail/report/component/ReportTopAppBar.kt`:
- Around line 44-48: The Icon composable used for the cancel button in
ReportTopAppBar has contentDescription set to null, which prevents accessibility
tools like TalkBack from describing the button's action to users. Replace the
null value with an appropriate string resource that describes the cancel action
(such as a localized string like "Close" or "Cancel") so that screen reader
users can understand the button's purpose.
---
Nitpick comments:
In
`@app/src/main/java/com/flint/domain/model/collection/CollectionReportModel.kt`:
- Around line 3-5: The `reasons` field in CollectionReportRequestModel is using
`List<String>` which lacks type safety and allows any string value, making it
impossible to catch invalid reason codes at compile time and difficult to track
API contract changes. Create a dedicated domain type for report reasons (such as
an enum or value class) and replace `List<String>` with `List<YourReasonType>`
in the CollectionReportRequestModel. Handle the conversion from string values
(coming from the API/presentation layer) to the domain reason type only in the
DTO mapper layer, keeping the domain model decoupled from raw string
dependencies and ensuring compile-time validation of valid reason codes.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d4a2d6de-21be-4e7b-81f6-12617276aac7
📒 Files selected for processing (17)
app/src/main/java/com/flint/data/api/CollectionApi.ktapp/src/main/java/com/flint/data/dto/collection/request/CollectionReportRequestDto.ktapp/src/main/java/com/flint/domain/mapper/collection/CollectionReportMapper.ktapp/src/main/java/com/flint/domain/model/collection/CollectionReportModel.ktapp/src/main/java/com/flint/domain/repository/CollectionRepository.ktapp/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailScreen.ktapp/src/main/java/com/flint/presentation/collectiondetail/navigation/CollectionDetailNavigation.ktapp/src/main/java/com/flint/presentation/collectiondetail/report/CollectionReportScreen.ktapp/src/main/java/com/flint/presentation/collectiondetail/report/CollectionReportUiState.ktapp/src/main/java/com/flint/presentation/collectiondetail/report/CollectionReportViewModel.ktapp/src/main/java/com/flint/presentation/collectiondetail/report/ReportReason.ktapp/src/main/java/com/flint/presentation/collectiondetail/report/component/ReportBottomSection.ktapp/src/main/java/com/flint/presentation/collectiondetail/report/component/ReportCheck.ktapp/src/main/java/com/flint/presentation/collectiondetail/report/component/ReportTopAppBar.ktapp/src/main/java/com/flint/presentation/collectiondetail/report/navigation/CollectionReportNavigation.ktapp/src/main/java/com/flint/presentation/main/MainNavHost.ktapp/src/main/java/com/flint/presentation/main/MainNavigator.kt
📮 관련 이슈
📌 작업 내용
📸 스크린샷
😅 미구현
🫛 To. 리뷰어
Summary by CodeRabbit
릴리스 노트