Skip to content

Refactor/#99 reject#100

Merged
dev-domo merged 25 commits intodevfrom
refactor/#99-reject
Jan 16, 2026
Merged

Refactor/#99 reject#100
dev-domo merged 25 commits intodevfrom
refactor/#99-reject

Conversation

@dev-domo
Copy link
Collaborator

✅ PR 타입

  • feat: 새로운 기능 추가
  • refactor: 코드 리펙토링

🪾 반영 브랜치

refactor/#99-reject -> dev

✨ 변경 사항

  • 유저 이름 조회 API 연동
  • 약관 동의 조회 API 에러 처리를 통한 회원가입 여부 판단
  • 백그라운드 모드 제거
  • WetherKit 로고 및 법적 고지 링크 삽입
  • 애플 로그인 시 이름 입력 뷰 건너뛰기
  • 위치 권한 팝업 문구 수정

📂 관련 이슈

#99

@dev-domo dev-domo self-assigned this Jan 16, 2026
@dev-domo dev-domo added enhancement New feature or request refactor labels Jan 16, 2026
@gemini-code-assist
Copy link

Summary of Changes

Hello @dev-domo, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 사용자 인증 및 온보딩 경험을 개선하고, WeatherKit 통합을 통해 위치 기반 기능을 강화하는 데 중점을 둡니다. UserDefaults에 의존하던 사용자 상태 관리를 API 기반으로 전환하여 데이터 처리의 견고함을 높였으며, UITableView 상호작용 로직을 추상화하여 코드의 유지보수성을 향상시켰습니다. 전반적으로 사용자 경험과 코드 품질을 동시에 개선하는 리팩토링 작업입니다.

Highlights

  • API 연동 및 인증 흐름 개선: 사용자 이름 조회 API를 연동하고, 약관 동의 조회 API의 에러 처리를 통해 회원가입 여부를 판단하도록 개선했습니다. 특히 Apple 로그인 시 사용자의 이름을 자동으로 가져와 이름 입력 단계를 건너뛸 수 있도록 변경되었습니다.
  • 위치 권한 및 WeatherKit 통합: 위치 권한 팝업 문구를 사용자에게 더 명확하게 수정하고, WeatherKit 로고 및 법적 고지 링크를 앱 내 여러 뷰에 삽입하여 날씨 정보 출처를 명시했습니다. 백그라운드 위치 모드는 제거되었습니다.
  • 데이터 관리 및 리팩토링: 사용자 온보딩 완료 여부, 약관 동의 상태, 멤버 이름 등 UserDefaults에 저장되던 여러 사용자 상태를 API 호출을 통해 관리하도록 변경하여 데이터 일관성을 높였습니다. 또한, UITableView의 드래그, 드롭, 스와이프 액션에 대한 공통 로직을 확장 및 프로토콜로 분리하여 코드 재사용성을 향상시켰습니다.
  • UI/UX 개선: 앱의 전반적인 UI 스타일을 라이트 모드로 고정하고, 여러 설정 관련 뷰의 배경색을 흰색으로 통일하는 등 시각적인 일관성을 확보했습니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이번 PR은 로그인 및 사용자 데이터 처리 로직을 대대적으로 리팩토링하는 내용을 담고 있습니다. 전반적으로 서버 API를 통해 상태를 관리하도록 변경하고, UserDefaults 의존성을 줄인 점이 인상적입니다. 특히 Apple 로그인 시 사용자 이름을 가져와 닉네임 설정 단계를 건너뛰는 기능과, UITableView의 드래그 앤 드롭 및 스와이프 액션 로직을 프로토콜과 익스텐션으로 분리하여 코드 중복을 줄인 점은 매우 훌륭한 개선입니다. 몇 가지 추가 개선 제안 사항을 리뷰 코멘트로 남겼습니다. 오류 처리 방식과 코드 중복 제거에 관한 내용이니 확인 부탁드립니다.

Comment on lines +38 to 45
func getMemberName() async throws -> MemberNameEntity {
do {
let memberName = try await fetchMemberName()
return memberName
} catch {
return .stub()
}
}

Choose a reason for hiding this comment

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

high

getMemberName() 함수가 오류 발생 시 .stub()을 반환하도록 구현되어 있습니다. 이 방식은 API 호출 실패나 다른 오류가 발생했을 때 실제 원인을 파악하기 어렵게 만들고, 사용자에게는 기본값("워리")이 보여 혼란을 줄 수 있습니다. throws 키워드를 사용하는 함수인 만큼, catch 블록에서 오류를 처리하기보다는 상위 호출 지점으로 오류를 다시 던져(rethrow) UI/ViewModel 레벨에서 적절한 오류 처리(예: 에러 메시지 표시)를 할 수 있도록 하는 것이 더 견고한 설계입니다.

    func getMemberName() async throws -> MemberNameEntity {
        let memberName = try await fetchMemberName()
        return memberName
    }

Comment on lines +77 to 80
guard let accessToken = keyChainService.load(key: .accessToken) else {
BeforeGoingLogger.error(BeforeGoingError.accessTokenMissing)
return .stub()
}

Choose a reason for hiding this comment

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

high

accessToken이 없을 경우, 오류를 던지는 대신 .stub()을 반환하고 있습니다. 토큰이 없는 것은 인증이 필요한 요청에서 명백한 오류 상황이므로, BeforeGoingError.accessTokenMissing 오류를 던져서 호출자가 이 상황을 명확히 인지하고 처리하도록 하는 것이 좋습니다. 현재 구현은 오류를 숨기고 기본값을 반환하여 잠재적인 버그를 유발할 수 있습니다.

        guard let accessToken = keyChainService.load(key: .accessToken) else {
            BeforeGoingLogger.error(BeforeGoingError.accessTokenMissing)
            throw BeforeGoingError.accessTokenMissing
        }

Comment on lines +170 to 180
private func isAgreedTerms(accessToken: String) async throws -> Bool {
do {
let _ = try await networkService.request(
endPoint: TermsAPI.getTerms(accessToken: accessToken),
responseType: TermsResponseDTO.self
)
return true
} catch {
return false
}
return isCompleted
}

Choose a reason for hiding this comment

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

medium

isAgreedTerms(accessToken:) 함수가 TermsRepository에도 동일하게 구현되어 있어 코드 중복이 발생했습니다. 약관 관련 로직은 TermsRepository에서 관리하는 것이 역할 분리 측면에서 더 적절해 보입니다. TermsRepositoryisAgreedTerms 함수를 public으로 변경하고, AuthRepository에서는 TermsInterface를 통해 해당 함수를 호출하여 사용하는 방식으로 리팩토링하면 중복을 제거하고 코드 유지보수성을 높일 수 있습니다.

Comment on lines +130 to 140
try await withThrowingTaskGroup(of: Void.self) { group in
group.addTask { [weak self] in
try await self?.requestDate()
}

group.addTask { [weak self] in
try await self?.updateWeatherInformation(date: DateUtil.getCurrentDate())
}

try await group.waitForAll()
}

Choose a reason for hiding this comment

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

medium

withThrowingTaskGroupelse 블록에서 try await group.waitForAll()을 호출하고 있습니다. withThrowingTaskGroup은 클로저의 실행이 끝나면 모든 자식 작업(child task)이 완료될 때까지 암시적으로 기다리므로, 이 코드는 불필요합니다. 해당 라인을 제거하여 코드를 더 간결하게 만들 수 있습니다.

                try await withThrowingTaskGroup(of: Void.self) { group in
                    group.addTask { [weak self] in
                        try await self?.requestDate()
                    }
                    
                    group.addTask { [weak self] in
                        try await self?.updateWeatherInformation(date: DateUtil.getCurrentDate())
                    }
                }

Comment on lines 702 to 709
private func createSwipeAction(deleteAction: UIContextualAction) -> UISwipeActionsConfiguration {
let config = UISwipeActionsConfiguration(actions: [deleteAction])
config.performsFirstActionWithFullSwipe = false
return config
let swipeActionsConfig: UISwipeActionsConfiguration = {
let config = UISwipeActionsConfiguration(actions: [deleteAction])
config.performsFirstActionWithFullSwipe = false
return config
}()
return swipeActionsConfig
}

Choose a reason for hiding this comment

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

medium

createSwipeAction 함수가 즉시 실행 클로저(immediately-executed closure)를 사용하도록 변경되었는데, 이로 인해 코드가 이전보다 더 길어지고 가독성이 다소 저하되었습니다. 특별한 이유가 없다면, 이전처럼 상수를 선언하고 프로퍼티를 설정한 뒤 반환하는 간결한 형태로 되돌리는 것이 좋겠습니다.

    private func createSwipeAction(deleteAction: UIContextualAction) -> UISwipeActionsConfiguration {
        let config = UISwipeActionsConfiguration(actions: [deleteAction])
        config.performsFirstActionWithFullSwipe = false
        return config
    }

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@dev-domo dev-domo merged commit e073107 into dev Jan 16, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant