feat: 탐색(Hifi) 모듈 + 배틀 검색 API + 약관 동의 바텀시트/WebView #4#37
Conversation
There was a problem hiding this comment.
탐색(Hifi) 모듈, 배틀 검색 API, 약관 동의 바텀시트/WebView 기능이 성공적으로 추가되었습니다. TCA 아키텍처, 모듈 의존성 및 SwiftUI 컨벤션은 전반적으로 잘 지켜졌습니다. Utill 모듈을 통한 숫자 포맷 공통화 및 DesignSystem 토큰 추가 등 공통화 및 정리 작업도 좋은 개선입니다.
주요 개선점으로는 TCA Action 명명법 준수, WKWebView 구현 시 하드코딩된 UI 요소(색상)를 DesignSystem 토큰으로 교체, 그리고 불필요한 주석 코드 제거를 통한 가독성 향상이 있습니다.
| let item = AVPlayerItem(url: url) | ||
| player.replaceCurrentItem(with: item) | ||
| player.seek(to: .zero) | ||
| await player.seek(to: .zero) |
There was a problem hiding this comment.
🔴 [P1] Critical
AVPlayer의 seek(to:)는 비동기 메서드이므로 await를 붙여 호출해야 합니다. 이 변경은 잠재적인 동시성 문제와 오디오 재생 흐름의 정확성을 확보하는 데 필수적입니다. 이전 코드에서는 비동기 메서드 호출이 완료되기 전에 다음 작업이 진행되어 예기치 않은 동작을 유발할 수 있었습니다. 이 변경으로 인해 올바른 동기화가 이루어집니다.
| } | ||
|
|
||
| public enum AsyncAction: Equatable { | ||
| case search(reset: Bool) |
There was a problem hiding this comment.
🟡 [P3] Minor
TCA Action은 '발생한 이벤트'를 설명하는 것이 권장됩니다. search는 '의도하는 효과'를 나타내므로, searchRequested와 같이 이벤트성을 강조하는 이름으로 변경하는 것이 TCA 컨벤션에 더 부합합니다.
| case search(reset: Bool) | |
| public enum AsyncAction: Equatable { | |
| case searchRequested(reset: Bool) | |
| } |
| } else { | ||
| await send(.delegate(.presentAuth)) | ||
| } | ||
| // if hasStoredCredential { |
There was a problem hiding this comment.
🔵 [P4] Readability
스플래시 화면에서 로그인 자격 증명 여부에 따른 분기 로직이 주석 처리된 채로 추가되었습니다. AppReducer에서 스플래시 화면의 onAppear 시점에 presentAuth 액션을 직접 보내기 때문에 현재 이 코드는 실행되지 않습니다. 실행되지 않는 큰 코드 블록은 혼란을 줄 수 있으므로 제거하거나, 향후 다시 활성화될 예정이라면 명확한 주석으로 의도를 설명하는 것이 좋습니다.
| // if hasStoredCredential { | |
| // (이 줄과 다음 4줄은 삭제하거나, 재사용 시점에 주석을 해제하고 명확히 설명하는 것이 좋습니다.) | |
| // if hasStoredCredential { | |
| // await send(.delegate(.presentMainTab)) | |
| // // } else { | |
| // await send(.delegate(.presentAuth)) | |
| // // } |
| await send(.delegate(.presentAuth)) | ||
| } | ||
| // if hasStoredCredential { | ||
| // await send(.delegate(.presentMainTab)) |
There was a problem hiding this comment.
🔵 [P4] Readability
스플래시 화면에서 로그인 자격 증명 여부에 따른 분기 로직이 주석 처리된 채로 추가되었습니다. AppReducer에서 스플래시 화면의 onAppear 시점에 presentAuth 액션을 직접 보내기 때문에 현재 이 코드는 실행되지 않습니다. 실행되지 않는 큰 코드 블록은 혼란을 줄 수 있으므로 제거하거나, 향후 다시 활성화될 예정이라면 명확한 주석으로 의도를 설명하는 것이 좋습니다.
| // await send(.delegate(.presentMainTab)) | |
| // (이 줄은 삭제하거나, 재사용 시점에 주석을 해제하고 명확히 설명하는 것이 좋습니다.) | |
| // await send(.delegate(.presentMainTab)) |
| } | ||
| // if hasStoredCredential { | ||
| // await send(.delegate(.presentMainTab)) | ||
| // } else { |
There was a problem hiding this comment.
🔵 [P4] Readability
스플래시 화면에서 로그인 자격 증명 여부에 따른 분기 로직이 주석 처리된 채로 추가되었습니다. AppReducer에서 스플래시 화면의 onAppear 시점에 presentAuth 액션을 직접 보내기 때문에 현재 이 코드는 실행되지 않습니다. 실행되지 않는 큰 코드 블록은 혼란을 줄 수 있으므로 제거하거나, 향후 다시 활성화될 예정이라면 명확한 주석으로 의도를 설명하는 것이 좋습니다.
| // } else { | |
| // (이 줄은 삭제하거나, 재사용 시점에 주석을 해제하고 명확히 설명하는 것이 좋습니다.) | |
| // // } else { |
| // if hasStoredCredential { | ||
| // await send(.delegate(.presentMainTab)) | ||
| // } else { | ||
| // await send(.delegate(.presentAuth)) |
There was a problem hiding this comment.
🔵 [P4] Readability
스플래시 화면에서 로그인 자격 증명 여부에 따른 분기 로직이 주석 처리된 채로 추가되었습니다. AppReducer에서 스플래시 화면의 onAppear 시점에 presentAuth 액션을 직접 보내기 때문에 현재 이 코드는 실행되지 않습니다. 실행되지 않는 큰 코드 블록은 혼란을 줄 수 있으므로 제거하거나, 향후 다시 활성화될 예정이라면 명확한 주석으로 의도를 설명하는 것이 좋습니다.
| // await send(.delegate(.presentAuth)) | |
| // (이 줄은 삭제하거나, 재사용 시점에 주석을 해제하고 명확히 설명하는 것이 좋습니다.) | |
| // await send(.delegate(.presentAuth)) |
| // await send(.delegate(.presentMainTab)) | ||
| // } else { | ||
| // await send(.delegate(.presentAuth)) | ||
| // } |
There was a problem hiding this comment.
🔵 [P4] Readability
스플래시 화면에서 로그인 자격 증명 여부에 따른 분기 로직이 주석 처리된 채로 추가되었습니다. AppReducer에서 스플래시 화면의 onAppear 시점에 presentAuth 액션을 직접 보내기 때문에 현재 이 코드는 실행되지 않습니다. 실행되지 않는 큰 코드 블록은 혼란을 줄 수 있으므로 제거하거나, 향후 다시 활성화될 예정이라면 명확한 주석으로 의도를 설명하는 것이 좋습니다.
| // } | |
| // (이 줄은 삭제하거나, 재사용 시점에 주석을 해제하고 명확히 설명하는 것이 좋습니다.) | |
| // // } |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d97aba0f1c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| case .splash(.view(.onAppear)): | ||
| return .none | ||
| return .send(.view(.presentAuth)) |
There was a problem hiding this comment.
Preserve credential-based splash routing
When any user launches the app, this handler now immediately transitions to Auth before SplashFeature can choose a destination, and the same commit comments out Splash's hasStoredCredential branch. Consequently, users with valid access and refresh tokens are always sent back to the login screen instead of MainTab; restore the credential-based routing rather than unconditionally presenting Auth.
Useful? React with 👍 / 👎.
| Color.black.opacity(0.4) | ||
| .ignoresSafeArea() | ||
| .onTapGesture { store.send(.view(.dismissTapped)) } |
There was a problem hiding this comment.
Prevent dismissing required terms without rolling back login
For a newly created Apple or Google account, tapping the backdrop dismisses the required-agreement sheet without invalidating the authenticated session or deleting the tokens already saved by UnifiedOAuthUseCase. On the next login the account can be returned as an existing user and LoginFeature routes it directly to MainTab, bypassing the required terms entirely; either make this sheet non-dismissible or explicitly roll back/logout on dismissal.
Useful? React with 👍 / 👎.
Fastlane should run through the project Gemfile on Ruby 3.3.9 so local automation avoids the Ruby 3.2 support warning and stays reproducible. Rejected: Continue using globally installed fastlane | it bypasses Gemfile locking and preserves the setup warning.
QA and release archives should reuse local package state and incremental Swift compilation while exposing build progress and timing data. Rejected: Skip archive or use a debug configuration | those outputs cannot be uploaded as the requested App Store build.
Splash completion should decide between the main tab and authentication from stored credentials, while generated fastlane lane documentation remains available in the repository. Rejected: Keep the unconditional auth presentation on splash appearance | it bypasses the credential-aware delegate routing.
…ature/hifi # Conflicts: # Projects/Presentation/Hifi/Sources/Reducer/HifiFeature.swift # fastlane/Fastfile
개요
탐색(Hi-Fi) 모듈 신설 + 배틀 검색 API, Apple/Google 약관 동의 바텀시트 + 약관 WebView, 공통 유틸 정리 등.
주요 변경
탐색(Hifi) 모듈 (신규)
GET /api/v1/search/battles검색 API 전 계층(API/Service/DTO/Mapper/Entity/Repository/UseCase + DI)약관 동의 (Apple/Google 신규가입)
TermsAgreementFeature+ 커스텀 바텀시트pickeModal(DesignSystem) —.customAlert/Attendance 패턴>→ delegate → AuthCoordinator 가 WebView 화면 push (노션 약관 링크)PickeNavigationBar적용공통화 / 정리
Int.decimalFormatted를 Utill 모듈로 공통화 (Chat 중복 제거)basicBlack/errorStrong/noDataLogo등 DesignSystem 토큰·에셋 추가end누락 문법 에러 수정Refs
Refs #4