Repository navigation
feat: AtchaV2 소셜 로그인 + 계정 수직 슬라이스 완결 (가입·로그아웃·탈퇴·유저정보) - #361
Merged
Merged
Conversation
- 홈: 브랜드 워드마크 강등 + 큰 컨텍스트 타이틀("어디로 가세요?") + 출발/도착
그룹 필드 카드(DSGroupedCard + HomeFieldRow) + "최근 경로" 섹션 헤더 +
하단 고정 알람 CTA(스크롤 밖, safeArea 위) + 통과형 토스트 호스트(CTA 위 앵커)
- 검색: 필드 2개를 홈과 같은 그룹 카드로 수납(전폭 구분선 제거),
aboveKeyboardArea 앵커만 이동(키보드 위 빈 상태 중앙 배치 유지)
- 모션(핵심만): DSPressEffect 프레스 스케일(버튼·칩·행·경로 카드 셀) +
첫 진입 페이드인(검색 왕복 시 무재생, reduce motion 존중)
- DS 신규 2종(DSGroupedCard·DSPressEffect)은 양 화면 공용 — 테스트+갤러리 데모
포함, 기존 컴포넌트·토큰은 무수정
- ViewModel/UseCase/Coordinator 계약 불변 — render()는 기계적 치환 3곳뿐
- 자동 검수: XCUITest 하니스 8케이스 통과, 증적 docs/verification/ui-redesign-toss
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 잠금화면: 3행 나열 → 타이머 히어로 4단 위계(헤더/오버라인/대형 카운트다운 38pt/메타). 타이머 아이콘 제거 — 긴급도는 숫자 색이 전달, 아이콘 앵커는 헤더 수단 심벌. stale·final은 heroMessage 공용 헬퍼로 히어로 자리 차지 - ⚠ 당겨짐 배지: solid red400 → 홈 배너 caution 티어(danger 글자 + dangerContainer 채움) — 강한 긴급색은 히어로 숫자 몫 - DI: expanded bottom 미니 히어로(오버라인+28pt), leading/trailing/compact Pretendard 통일, compactTrailing maxWidth 56 등 기존 수정자 세트 보존, expanded .center 미사용 사유 주석화. keylineTint·배경 틴트 불변 - Pretendard 브리지(DSFont+SwiftUI) 신규 — DSFont.pretendard 기반이라 once-가드 등록+가중치 보존 폴백 내장, WidgetBundle init에서 이른 등록 - #Preview 픽스처 9종(활성 3단계·배지·final 3종·DI expanded/compact/minimal· stale 직접 렌더) — 빌드에서 컴파일 검증 - 계약(LastTrainActivityAttributes)·어댑터·카피·파생 헬퍼 무수정 - 시뮬 검수: 잠금화면 활성/배지/운행종료 + 컴팩트 DI 증적 docs/verification/la-redesign (DI 실물·실기기 타이머 폰트는 실기기 잔여) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- AnonymousSessionIssuing/UnconfiguredAnonymousSessionIssuer 삭제 (TokenPair는 TokenPair.swift로 이동) - AuthSessionManager: bootstrapState()(동기 판정) + adopt(토큰 채택) + clearSession + sessionExpired 스트림 - performRecovery: refresh 확정 거절(비-SUCCESS/401)만 세션 사망 — 토큰 클리어 + loginRequired throw + sessionExpired yield, 일시 장애는 토큰 보존·propagate - AuthError: issuerNotConfigured → loginRequired - AppCoordinator: bootstrapState 분기(loginRequired는 임시 재시도 문구 — AuthFeature 통합 커밋에서 교체) - 테스트 30케이스 재정렬: bootstrapState/adopt/clearSession/확정거절·일시장애 케이스 신규, issuer 폴백 케이스 제거 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- SocialCredential/SocialLoginProvider/SocialLoginError, LoginSession 엔티티 - 포트 4종: SocialLoginService(@mainactor authorize), AuthRepository(check/login), SessionStoring, PushTokenProviding - DefaultSignInUseCase: authorize → check → (기존 회원) login → 세션 채택 / 미가입은 needsSignUp (소셜 자격 증명 미보관) - DefaultSignInUseCaseTests 5케이스(호출 순서·미가입 단락·취소 전파·store 실패 전파·fcm nil) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- AuthEndpoint: GET /auth/check·/auth/login, 소셜 자격 증명 Bearer + provider(kakao=0/apple=1), fcmToken nil→"" (레거시 실측 계약) - LoginResponseDTO(전 필드 옵셔널, lat/lon 디코딩만) + toEntity(토큰 부재 throw) - AuthRepositoryImpl: plain client 주입 규약(소셜 Bearer 보존·401 복구 미촉발) - 계약 핀 테스트 8케이스 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Project.feature(name: "Auth") 4타겟 + Workspace 등록, 에셋(kakao/apple imageset) 레거시에서 복사 - LoginViewController: 레거시 시트 비주얼(dim 0.9·컨테이너 198·핸들·슬라이드업) 이식, 강제 로그인이라 dismiss 제스처 제거 - LoginViewModel: State(idle/loading) + 원샷 Event(미가입 안내/실패 토스트), 취소는 무표출 idle 복귀, 로딩 중 중복 탭 가드 - SocialLoginButton(레거시 스펙 52·radius8·아이콘 leading16) + AuthPalette(카카오 브랜드 상수 — DSPalette 미오염) - LoginCoordinator(overFullScreen present, 성공 시 하강 연출 후 onAuthenticated→finish) + AuthDIContainer - #if DEV 건너뛰기 버튼(시뮬 자동 검수용, DevDemoFallbacks와 함께 제거 예정) - LoginViewModelTests 6케이스 + Example(미가입→실패→성공 순환 스텁) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- AppCoordinator: bootstrapState 분기(loginRequired→스플래시 위 로그인 시트), sessionExpired 구독(만료 시 홈 접고 재로그인, 재로그인 후 syncNow 1회) - SocialLoginAdapter: 카카오(톡/계정 분기, 취소 매핑) + Apple(continuation take() 패턴, 활성 씬 anchor — 레거시 force unwrap 제거) - AuthSessionStoreAdapter(SessionStoring→adopt), FCMPushTokenAdapter(Firebase 미구성 시 nil) - AppDIContainer: plainNetworkClient 승격, AuthRepositoryImpl(plain) + makeAuthDIContainer - Project.swift: Kakao SDK 3종 링크(앱 타겟 전용), applesignin entitlement, TUIST_KAKAO_APP_KEY env→Info.plist(키 없으면 URL 스킴 미등록), LSApplicationQueriesSchemes - AppDelegate KakaoSDK.initSDK(키 존재 시) / SceneDelegate openURLContexts 카카오 복귀 처리 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- SignInUseCase: needsSignUp 데드엔드 제거 — 미가입이면 현재 위치(8초 타임아웃 레이스)+역지오코딩 주소로 자동 sign-up까지 수행하고 Void 반환 - SignUpForm: 레거시 실측 기본값(userName ""·address ""·(0,0)·알림빈도 [1,10]) - UserProfile 엔티티 + UserRepository 포트(/members/me 계열 4메서드) - SessionEnding 포트 + Logout/Withdraw/GetUserProfile/UpdateHomeAddress/ UpdateAlertFrequency UseCase — 탈퇴는 서버 성공 후에만 로컬 세션 무효화 - AuthRepository에 signUp 추가, 테스트 갱신·신설 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VEZMsiwwexokUxJBEk2C1A
…idateSession - LogoutEndpoint: POST /auth/logout, refresh 토큰을 Bearer로(레거시 TokenInterceptor 특례 실측) — 토큰이 CoreAuth 밖으로 새지 않도록 여기 배치 - AuthSessionManager.signOut(): 서버 호출은 베스트 에포트(실패 무시), 로컬 정리+sessionExpired yield는 항상 — 기존 만료 라우팅이 로그인 복귀 처리 - invalidateSession(): 탈퇴 후 경로 — 네트워크 호출 없이 로컬 만료만 - 계약 핀·베스트 에포트·무토큰 스킵 테스트 4건 추가 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VEZMsiwwexokUxJBEk2C1A
- AuthEndpoint.signUp: POST /auth/sign-up, 소셜 토큰 Bearer + JSON body (레거시 실측), 응답은 LoginResponseDTO 재사용(로그인과 계약 동일) - UserEndpoint: GET /members/me(X-Platform: iOS)·PATCH home-address· PATCH alert-frequency·DELETE /members/me(사유 body) - DTO 6종(SignUpRequest·UserInfoResponse·UserInfoPatchResponse· HomePatch·AlertFrequencyPatch·Withdraw) — 레거시 필드 실측 그대로 - UserRepositoryImpl(authorized client)·AuthRepositoryImpl.signUp(plain 규약 유지) - 계약 핀 테스트: signUp body·X-Platform·PATCH/DELETE body·lat/lon 키·좌표 nil 규칙 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VEZMsiwwexokUxJBEk2C1A
- LoginViewModel: 미가입 분기·showSignUpNotice 이벤트·안내 문구 제거 — 가입은 UseCase가 자동 수행하므로 성공은 곧 세션 채택 완료 - devSkipTapped 제거 — 데모 폴백 제거 후엔 토큰 없는 홈 진입이 401 → 로그인 시트 복귀 루프의 함정만 남음(시뮬레이터 검수는 Apple 로그인으로) - LoginViewController: 가입 안내 알럿·DEV 건너뛰기 버튼 제거 - Example 스텁·LoginViewModelTests Void 시그니처 반영 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VEZMsiwwexokUxJBEk2C1A
- AppDIContainer: SignInUseCase에 위치·역지오코딩 주입(최소 가입 재료), publicPathSuffixes에 /auth/* 5경로 명시(소셜/refresh Bearer가 access 토큰으로 덮이지 않는 이중 방어), UserRepository + Logout/Withdraw UseCase 팩토리 - AuthSessionEndingAdapter: SessionEnding → AuthSessionManager 배선 - DevDemoFallbacks 제거: 실패 은폐 폴백 3종·DEV 3초 타임아웃 삭제 — DEV에서도 실서버 실패가 그대로 표면화된다(전 구성 10s/30s 통일) - DevChangeSimulator 분리 존치: refresh 주입 가로채기 전용 슬림 데코레이터 (register/cancel 에러 은폐 없음) — 막차 변경 검수의 유일 수단 - SceneDelegate DEV 메뉴에 "로그아웃 (DEV)" — 설정 화면 前 유일한 검수 진입점 - CLAUDE.md 미완 상태 절 갱신(가입 완결·로그아웃/탈퇴·폴백 제거 반영) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VEZMsiwwexokUxJBEk2C1A
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
요약
레거시 소셜 로그인(카카오·애플)을 V2 구조로 전면 리팩토링해 이식하고, 로그인 이후 토큰 기반 서비스 제공에 필요한 계정 API(가입·로그아웃·탈퇴·유저정보)까지 레거시 실측 계약대로 완결. 화면 비주얼은 레거시 바텀시트 유지, 내부는 uFeatures+클린아키텍처 규약 준수. 신규 유저의 check → sign-up → 세션 채택 전 경로가 이 PR에서 닫힌다.
확정 제품 결정
SignInUseCase가POST /auth/sign-up까지 자동 수행: 현재 위치(8초 타임아웃 레이스)+역지오코딩 주소, 실패 시 레거시 실측 폴백(""·(0,0)), 알림 빈도 [1,10]. 홈주소·알림빈도는 가입 후 PATCH로 변경 가능loginRequired표면화구조
bootstrapState()/adopt()/sessionExpired스트림 +signOut()(POST /auth/logout — refresh 토큰을 Bearer로 싣는 레거시 특례를LogoutEndpoint로 CoreAuth 내부 처리, 서버 실패에도 로컬 정리·만료 라우팅은 항상)·invalidateSession()(탈퇴 후 로컬만). 확정 거절(비-SUCCESS/401)만 세션 사망 — 일시 장애는 토큰 보존SignInUseCase(인가→가입확인→교환/자동가입→채택, Void 반환) +UserProfile·SignUpForm엔티티 +UserRepository·SessionEnding포트 + Logout/Withdraw/GetUserProfile/UpdateHomeAddress/UpdateAlertFrequency UseCase. 탈퇴는 서버 성공 후에만 로컬 세션 무효화. 소셜 토큰 미보관(레거시 UserDefaults 평문 저장 미계승)AuthEndpoint(check/login/signUp — 소셜 Bearer + provider 0/1, plain client 전용) +UserEndpoint(GET /members/meX-Platform: iOS·홈주소/알림빈도 PATCH·DELETE /members/me 사유 body) + DTO 6종·UserRepositoryImplTUIST_KAKAO_APP_KEYenv 주입, sessionExpired 구독.publicPathSuffixes에/auth/*5경로 명시 — 소셜/refresh Bearer가 access 토큰으로 덮이는 사고의 이중 방어DevChangeSimulator만 refresh 가로채기 전용 슬림 데코레이터로 축소 존치(register/cancel 에러 은폐 없음). 자동 검수 예약 키워드("결과없음"/"경로없음")는 무효화 — 이후 빈 상태 검수는 실서버 응답 의존검증
잔여 (코드 밖 액션)
com.atcha.iOS.v2등록 +TUIST_KAKAO_APP_KEY주입(레포에 키 없음)GET /members/me의appVersion비옵셔널 핀 확인(서버가 생략하면 완화 필요)🤖 Generated with Claude Code
https://claude.ai/code/session_01VEZMsiwwexokUxJBEk2C1A