Skip to content

refactor(navigation): 탭별 NavigationStack + Router/Coordinator 전환 - #112

Merged
gomminjae merged 1 commit into
developfrom
refactor/navigation-per-tab-router
Jul 12, 2026
Merged

gomminjae merged 1 commit into
developfrom
refactor/navigation-per-tab-router

Conversation

@gomminjae

Copy link
Copy Markdown
Collaborator
  • 전역 단일 스택 + AppRoute god-enum 제거, 탭별 독립 Route/Router 도입
  • feature View에서 커스텀 @Environment(AppRouter/TabSelection/AppState/ToastCenter) 제거; 네비게이션은 클로저 주입, 세션상태/토스트는 .shared 직접 접근으로 전환
  • AppCoordinator(탭 선택·크로스탭·둘러보기 pending·auth present) + AuthFlow(contextual fullScreenCover)
  • AppRouter/AppRoute/TabSelection 삭제, NewDokTab enum 분리
  • Interface/Builder 8쌍 시그니처 + AppContainer + 셸(NewdokApp/AppRootView/NewDokTabView) 재작성

- 전역 단일 스택 + AppRoute god-enum 제거, 탭별 독립 Route/Router 도입
- feature View에서 커스텀 @Environment(AppRouter/TabSelection/AppState/ToastCenter) 제거;
  네비게이션은 클로저 주입, 세션상태/토스트는 .shared 직접 접근으로 전환
- AppCoordinator(탭 선택·크로스탭·둘러보기 pending·auth present) + AuthFlow(contextual fullScreenCover)
- AppRouter/AppRoute/TabSelection 삭제, NewDokTab enum 분리
- Interface/Builder 8쌍 시그니처 + AppContainer + 셸(NewdokApp/AppRootView/NewDokTabView) 재작성

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the application's navigation architecture by replacing the global AppRouter and TabSelection with a centralized AppCoordinator and generic Router system utilizing the Observation framework. It introduces dedicated stack views for each tab, manages authentication flows via AuthFlow presented as a full-screen cover, and refactors feature views to use closure-based callbacks for navigation instead of environment objects. Feedback on these changes highlights a critical issue in AppCoordinator where tab routers' paths are not cleared upon logout, potentially exposing previous user states to newly logged-in accounts. Additionally, a minor cleanup is requested to remove a leftover crash log message from a comment in ToastCenter.swift.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +67 to +71
func logout(to route: AuthRoute) {
mypageRouter.popToRoot()
selectedTab = .home
authRoute = route
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

현재 AppCoordinator는 NewdokApp에서 @State로 관리되어 앱의 생명주기 동안 단 한 번만 생성되고 유지됩니다. 따라서 NewDokTabView가 .id(...) 변경으로 인해 재생성되더라도, AppCoordinator 내부의 각 탭 라우터(homeRouter, exploreRouter 등)의 path 상태는 초기화되지 않고 그대로 유지됩니다.

이로 인해 로그아웃 후 다른 계정으로 로그인했을 때 이전 사용자가 보던 상세 화면 스택이 그대로 노출되는 심각한 UX 및 보안 문제가 발생할 수 있습니다.

따라서 logout 메서드에서 모든 라우터의 path를 비워주도록(popToRoot()) 명시적으로 처리해야 합니다.

    func logout(to route: AuthRoute) {
        homeRouter.popToRoot()
        exploreRouter.popToRoot()
        subscribeRouter.popToRoot()
        bookmarkRouter.popToRoot()
        mypageRouter.popToRoot()
        exploreDay = nil
        exploreTab = 0
        hasPendingExplore = false
        selectedTab = .home
        authRoute = route
    }

if toast.isShown {
if ToastCenter.shared.isShown {
// DesignSystem의 ToastView는 상위 모듈에 존재하므로, 여기서는 텍스트만 렌더합니다.
// 실제 디자인 토스트를 쓰려면 이 ToastHost를 App 레이어로 옮겨 DesignSystem을 import 하세요.Thread 1: Fatal error: No ObservableObject

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

주석 끝에 디버깅 중 발생한 것으로 보이는 크래시 로그(Thread 1: Fatal error: No ObservableObject)가 실수로 남겨져 있습니다. 불필요한 텍스트를 제거하여 코드를 깔끔하게 정리해주세요.

Suggested change
// 실제 디자인 토스트를 쓰려면 이 ToastHost를 App 레이어로 옮겨 DesignSystem을 import 하세요.Thread 1: Fatal error: No ObservableObject
// 실제 디자인 토스트를 쓰려면 이 ToastHost를 App 레이어로 옮겨 DesignSystem을 import 하세요.

@gomminjae
gomminjae merged commit 5a5fb37 into develop Jul 12, 2026
2 checks passed
@gomminjae
gomminjae deleted the refactor/navigation-per-tab-router branch July 12, 2026 00:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant