Skip to content

feat: 탐색(Hifi) 모듈 + 배틀 검색 API + 약관 동의 바텀시트/WebView #4#37

Merged
Roy-wonji merged 13 commits into
developfrom
feature/hifi
Jun 4, 2026
Merged

feat: 탐색(Hifi) 모듈 + 배틀 검색 API + 약관 동의 바텀시트/WebView #4#37
Roy-wonji merged 13 commits into
developfrom
feature/hifi

Conversation

@Roy-wonji

Copy link
Copy Markdown
Contributor

개요

탐색(Hi-Fi) 모듈 신설 + 배틀 검색 API, Apple/Google 약관 동의 바텀시트 + 약관 WebView, 공통 유틸 정리 등.

주요 변경

탐색(Hifi) 모듈 (신규)

  • GET /api/v1/search/battles 검색 API 전 계층(API/Service/DTO/Mapper/Entity/Repository/UseCase + DI)
  • 탭바 "탐색" 연결, 카테고리/정렬, 무한 스크롤, 좌우 스와이프 카테고리 전환(순환), 스켈레톤/빈 상태
  • 컨텐츠 탭 → ChatCoordinator(PreVote) 진입, 큐레이팅 X → 부모 루트 복귀(popToRoot)

약관 동의 (Apple/Google 신규가입)

  • TermsAgreementFeature + 커스텀 바텀시트 pickeModal(DesignSystem) — .customAlert/Attendance 패턴
  • isNewUser && (apple|google) 일 때만 노출, 동의 → 온보딩
  • 약관 상세 > → delegate → AuthCoordinator 가 WebView 화면 push (노션 약관 링크)
  • WebView 로딩 인디케이터 GIF → ProgressView, PickeNavigationBar 적용

공통화 / 정리

  • 숫자 포맷 Int.decimalFormatted 를 Utill 모듈로 공통화 (Chat 중복 제거)
  • basicBlack/errorStrong/noDataLogo 등 DesignSystem 토큰·에셋 추가
  • Fastfile platform 블록 end 누락 문법 에러 수정

Refs

Refs #4

@Roy-wonji Roy-wonji added ♻️ 리팩토링 기존 코드 리팩토링 ✨ 기능추가 새로운 기능 추가 🎨 디자인 UI 디자인 작업 labels Jun 4, 2026

@github-actions github-actions 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.

탐색(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)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 [P1] Critical

AVPlayerseek(to:)는 비동기 메서드이므로 await를 붙여 호출해야 합니다. 이 변경은 잠재적인 동시성 문제와 오디오 재생 흐름의 정확성을 확보하는 데 필수적입니다. 이전 코드에서는 비동기 메서드 호출이 완료되기 전에 다음 작업이 진행되어 예기치 않은 동작을 유발할 수 있었습니다. 이 변경으로 인해 올바른 동기화가 이루어집니다.

}

public enum AsyncAction: Equatable {
case search(reset: Bool)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 [P3] Minor

TCA Action은 '발생한 이벤트'를 설명하는 것이 권장됩니다. search는 '의도하는 효과'를 나타내므로, searchRequested와 같이 이벤트성을 강조하는 이름으로 변경하는 것이 TCA 컨벤션에 더 부합합니다.

Suggested change
case search(reset: Bool)
public enum AsyncAction: Equatable {
case searchRequested(reset: Bool)
}

} else {
await send(.delegate(.presentAuth))
}
// if hasStoredCredential {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [P4] Readability

스플래시 화면에서 로그인 자격 증명 여부에 따른 분기 로직이 주석 처리된 채로 추가되었습니다. AppReducer에서 스플래시 화면의 onAppear 시점에 presentAuth 액션을 직접 보내기 때문에 현재 이 코드는 실행되지 않습니다. 실행되지 않는 큰 코드 블록은 혼란을 줄 수 있으므로 제거하거나, 향후 다시 활성화될 예정이라면 명확한 주석으로 의도를 설명하는 것이 좋습니다.

Suggested change
// if hasStoredCredential {
// (이 줄과 다음 4줄은 삭제하거나, 재사용 시점에 주석을 해제하고 명확히 설명하는 것이 좋습니다.)
// if hasStoredCredential {
// await send(.delegate(.presentMainTab))
// // } else {
// await send(.delegate(.presentAuth))
// // }

await send(.delegate(.presentAuth))
}
// if hasStoredCredential {
// await send(.delegate(.presentMainTab))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [P4] Readability

스플래시 화면에서 로그인 자격 증명 여부에 따른 분기 로직이 주석 처리된 채로 추가되었습니다. AppReducer에서 스플래시 화면의 onAppear 시점에 presentAuth 액션을 직접 보내기 때문에 현재 이 코드는 실행되지 않습니다. 실행되지 않는 큰 코드 블록은 혼란을 줄 수 있으므로 제거하거나, 향후 다시 활성화될 예정이라면 명확한 주석으로 의도를 설명하는 것이 좋습니다.

Suggested change
// await send(.delegate(.presentMainTab))
// (이 줄은 삭제하거나, 재사용 시점에 주석을 해제하고 명확히 설명하는 것이 좋습니다.)
// await send(.delegate(.presentMainTab))

}
// if hasStoredCredential {
// await send(.delegate(.presentMainTab))
// } else {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [P4] Readability

스플래시 화면에서 로그인 자격 증명 여부에 따른 분기 로직이 주석 처리된 채로 추가되었습니다. AppReducer에서 스플래시 화면의 onAppear 시점에 presentAuth 액션을 직접 보내기 때문에 현재 이 코드는 실행되지 않습니다. 실행되지 않는 큰 코드 블록은 혼란을 줄 수 있으므로 제거하거나, 향후 다시 활성화될 예정이라면 명확한 주석으로 의도를 설명하는 것이 좋습니다.

Suggested change
// } else {
// (이 줄은 삭제하거나, 재사용 시점에 주석을 해제하고 명확히 설명하는 것이 좋습니다.)
// // } else {

// if hasStoredCredential {
// await send(.delegate(.presentMainTab))
// } else {
// await send(.delegate(.presentAuth))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [P4] Readability

스플래시 화면에서 로그인 자격 증명 여부에 따른 분기 로직이 주석 처리된 채로 추가되었습니다. AppReducer에서 스플래시 화면의 onAppear 시점에 presentAuth 액션을 직접 보내기 때문에 현재 이 코드는 실행되지 않습니다. 실행되지 않는 큰 코드 블록은 혼란을 줄 수 있으므로 제거하거나, 향후 다시 활성화될 예정이라면 명확한 주석으로 의도를 설명하는 것이 좋습니다.

Suggested change
// await send(.delegate(.presentAuth))
// (이 줄은 삭제하거나, 재사용 시점에 주석을 해제하고 명확히 설명하는 것이 좋습니다.)
// await send(.delegate(.presentAuth))

// await send(.delegate(.presentMainTab))
// } else {
// await send(.delegate(.presentAuth))
// }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [P4] Readability

스플래시 화면에서 로그인 자격 증명 여부에 따른 분기 로직이 주석 처리된 채로 추가되었습니다. AppReducer에서 스플래시 화면의 onAppear 시점에 presentAuth 액션을 직접 보내기 때문에 현재 이 코드는 실행되지 않습니다. 실행되지 않는 큰 코드 블록은 혼란을 줄 수 있으므로 제거하거나, 향후 다시 활성화될 예정이라면 명확한 주석으로 의도를 설명하는 것이 좋습니다.

Suggested change
// }
// (이 줄은 삭제하거나, 재사용 시점에 주석을 해제하고 명확히 설명하는 것이 좋습니다.)
// // }

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 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".

Comment on lines 238 to +239
case .splash(.view(.onAppear)):
return .none
return .send(.view(.presentAuth))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge 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 👍 / 👎.

Comment on lines +20 to +22
Color.black.opacity(0.4)
.ignoresSafeArea()
.onTapGesture { store.send(.view(.dismissTapped)) }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge 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 👍 / 👎.

Roy-wonji added 5 commits June 5, 2026 00:05
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
@Roy-wonji Roy-wonji merged commit 80d7cbc into develop Jun 4, 2026
2 of 3 checks passed
@Roy-wonji Roy-wonji deleted the feature/hifi branch June 4, 2026 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

♻️ 리팩토링 기존 코드 리팩토링 ✨ 기능추가 새로운 기능 추가 🎨 디자인 UI 디자인 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant