Skip to content

refactor(platform): 최종 앱 루트 책임 판정과 MVI 전환 종료 검사 (#1809 분리) #2022

Open

Description

@OnlyReadOneBook

작업 유형

refactor — 동작 변경 없는 구조·책임·경계 개선

주 담당 모듈

app — 앱 셸·루트 네비게이션·앱 모듈 공통

개요

여러 모듈 전환 뒤 수행해야 하는 MainViewModel의 최종 책임 판정과 MVI 전환 종료 검사만 #1809에서 분리한다. 알림 권한 ViewModel과 직접 Effect 전환은 독립 이슈 #1809에 남겼고 여기의 구현 범위에서 제외한다.

대상

  • MainViewModel. 앱 진입·라우팅 판정을 들고 있어 화면 ViewModel 과 성격이 다르다. MviViewModel 이 맞는지 먼저 판정하고, 아니면 전환하지 않는 근거를 이 이슈에 남긴 뒤 konsist allowlist 에 영구 예외로 등재한다.

전환 종료 처리

실제로 완료된 모듈 전환 산출물을 대조한 뒤 이 이슈에서 마무리한다. NOT_PLANNED로 닫힌 #1803은 전환 완료에 포함하지 않으며, 해당 수신자 흐름의 MVI 구현을 이 이슈에서 다시 예약하지 않는다.

  • Konsist allowlist를 실제 선언과 대조한다. 존재하지 않는 com.afternote.feature.receiver.presentation.home.ReceiverHomeViewModel 항목은 제거하고, 철회된 구 수신자 흐름의 현존 예외는 유지한다. 유효한 예외가 모두 없어졌을 때만 규칙 B의 예외 분기를 제거한다.
  • 실제 MVI 전환을 완료한 범위에서 소비가 Intent.ConsumeXxx로 연결됐는지 확인한다. #1803에서 철회한 기존 흐름까지 0건 기준에 맞추려고 재작성하지 않는다. 신호를 UiState에 흡수하는 refactor: ViewModel 이벤트 → UI state 흡수 마이그레이션 (전수 9개 VM) #228 규약은 유지한다.
  • 설정의 수신자 등록 화면(ReceiverRegisterViewModel)은 BE 에서 삭제된 POST users/receivers 를 부르는 화면이라 여기서 전환하지 않는다. 초대 흐름 전환과 함께 수신자 등록 카톡 초대 전환 — 이메일 등록·인증 대체 #944 에서 MVI 로 다시 만들고, 그 전까지는 남은 ViewModel 로 센다(2026-10-04 판정).
  • MviViewModel 을 상속하지 않는 ViewModel 이 남아 있다면, 각각 그 이유가 문서나 allowlist 주석에 적혀 있다
  • docs/convention/mvi.md 가 전환 완료 시점의 실제 코드와 일치한다

자식 이슈

No response

참고

MainViewModel 은 앱 시작 경로에 있다. release 전용 R8 크래시는 런타임 게이트가 전부 debug 라 잡지 못한 전례가 있다(0903 nav enum). 전환 시 minified 빌드로 앱 진입을 한 번 확인한다.

네비게이션은 이 전환 범위 밖이다. app 모듈은 #1698(소관 그래프 Nav3 이관)과 #1795(알림 목적지 결선)가 열려 있다. MainViewModel 이 라우팅 판정을 들고 있어 겹친다.

분리 근거

#1809의 알림 권한은 현재 확정 계약으로 독립 완료한다. 이 이슈는 기존 모듈 전환의 최종 산출물을 기다리는 종료 검사이며, MainViewModel 라우팅 책임이 #1702에서 바뀌므로 지금 임시 MVI 구현을 예약하지 않는다. 실제 최종 코드로 전환 필요성을 다시 판정한다.

2026-10-04 분리

체크리스트 첫 항목(allowlist 의 존재하지 않는 FQN 제거)과 같은 파일·mvi.md 의 낡은 개수·담당 문구 정리는 선행을 기다리지 않아 #2246 으로 뗐다. 규칙 B 예외 분기 제거와 MainViewModel 판정은 여기 남는다.

Activity

  1. added
    refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업
    area:platformCI·빌드·릴리스·저장소 운영 영역
    on Sep 13, 2026
  2. changed the title [-]refactor(platform): 알림 권한 ViewModel과 Effect를 MVI로 전환 (#1809 분리)[/-] [+]refactor(platform): 최종 앱 루트 책임 판정과 MVI 전환 종료 검사 (#1809 분리)[/+] on Sep 13, 2026
  3. added
    area:app앱 셸·루트 네비게이션·앱 모듈 공통 영역
    and removed
    area:platformCI·빌드·릴리스·저장소 운영 영역
    on Sep 13, 2026
  4. OnlyReadOneBook commented on Sep 13, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    실측 기록: 본문의 konsist 처방은 실행되지 않고, 종료 검사 2항의 기준 수치는 낡았다

    기준 리비전은 origin/develop 7d87aa3f4 (2026-09-13) 다. 이 이슈로 지금 쓸 코드는 0줄이다. 다음 착수자가 죽은 처방을 따라가거나 낡은 기준으로 종료 검사를 통과시키지 않도록 실측만 남긴다. 본문과 라벨은 건드리지 않았다.

    1. "konsist allowlist 에 영구 예외로 등재한다" 는 지금 코드에서 실행되지 않는다

    MainViewModel 은 규칙 B 의 후보 집합에 애초에 들어오지 않는다. konsist/src/test/kotlin/com/afternote/konsist/MviContractKonsistTest.kt:259 가 후보를 FEATURE_PRESENTATION_MAIN (:358, 정규식 feature/[^/]+/presentation/src/main/) 으로 거르는데, MainViewModel 은 app/src/main/java/com/afternote/afternote_fe/MainViewModel.kt 에 있다.

    그래서 등재해도 세 군데가 어긋난다.

    • PENDING_MVI_MIGRATION 은 후보 집합에서 빼는 용도다 (:64 의 unmigratedViewModels(...) - PENDING_MVI_MIGRATION). 후보가 아닌 항목을 넣으면 빼 줄 것이 없다.
    • 해소된 항목은 경고로 알린다 테스트 (:79-94) 는 PENDING_MVI_MIGRATION - unmigratedViewModels(...) 를 stale 로 출력한다. MainViewModel 항목은 영구 stale 경고가 된다.
    • 이 이슈 완료 조건 1과 충돌한다. 목록이 비어야 규칙 B 의 예외 분기를 지우는데, 영구 예외를 넣으면 그 목록은 영원히 비지 않는다.

    develop 은 이미 세 자리에 app 이 규칙 B 밖이라고 적어 뒀다. MviContractKonsistTest.kt:466-469 의 KDoc, 같은 파일 :174-186 의 규칙 B fixture 단언 (app/src/main/kotlin/app/AppViewModel.kt 를 넣고도 위반 0건을 단언한다), docs/convention/mvi.md:126.

    경험적 확인도 있다. #1809 의 PR #2033 은 app 모듈의 NotificationPermissionViewModel 을 MVI 로 전환하면서 MviContractKonsistTest.kt 를 한 줄도 고치지 않았다. 그 PR 이 고친 konsist 파일은 ProductionVisibilityKonsistTest.kt 하나다. #1809 본문의 "konsist 임시 예외에서는 이 ViewModel만 제거한다" 도 같은 이유로 지울 항목이 없다.

    따라서 최종 판정이 "전환하지 않는다" 로 나오더라도 근거를 남길 자리는 allowlist 가 아니다. MainViewModel 의 KDoc 이거나 문서이거나, 규칙 B 스코프를 app 까지 넓히는 별도 결정이다. 뒤쪽을 고르면 MainViewModel 이 그 순간 위반이 되어 완료 조건 1이 요구하는 빈 목록과 다시 충돌하므로, 그 결정에는 완료 조건 1의 개정이 딸려 온다.

    위 세 자리의 문구는 분리 이후로 낡기도 했다. 셋 다 app 의 ViewModel 2개를 #1809 가 처리한다고 적는데, MainViewModel 판정은 이 이슈로 떨어져 나왔다.

    2. 종료 검사 2항의 기준 수치 갱신

    본문은 "현재 11개 VM · 참조 77곳" 인데 origin/develop 7d87aa3f4 실측은 이렇다.

    항목 본문 실측
    onXxxConsumed() 를 가진 ViewModel 11개 12개
    main 소스셋 public 선언 (없음) 22건
    저장소 전체 참조 77곳 112줄 (main 84 · test 26 · screenshotTest 2)
    git grep -nE 'fun +on[A-Za-z0-9_]*Consumed *\(' origin/develop -- '*/src/main/*'   # 22
    git grep -nE 'on[A-Za-z0-9_]*Consumed' origin/develop -- '*.kt'                    # 112
    

    선언 22건의 모듈별 분해는 onboarding 11 (ViewModel 4개) · afternote 6 (ViewModel 3개) · receiver 5 (ViewModel 5개) 이고, app 모듈은 0건이다. 즉 이 항목에는 app 쪽으로 떼어낼 조각이 없다.

    참조 112줄을 셀 때 주의할 것이 둘 있다. main 84줄 중 2줄은 core/ui 의 문서 주석 (mvi/MviContract.kt:21, mvi/ObserveSignal.kt:25) 이고, 3줄은 timeletter 의 컴포저블 파라미터 (TimeLetterNavGraph.kt:106, DraftLetterScreen.kt:45 와 :54) 라 ViewModel 선언과 무관하다. 종료 조건은 선언 0건이므로 22건 쪽을 보면 된다.

    완료 조건 1의 allowlist 수치도 어긋나 있다. PENDING_MVI_MIGRATION 의 합집합은 지금 51개 (MviContractKonsistTest.kt:471) 인데 :466 KDoc 과 docs/convention/mvi.md:126 은 49개로 적는다. 모듈별 임자 분해는 #1813 코멘트에 있다.

    3. 판정을 지금 못 하는 이유

    MainViewModel 은 69줄이고 하는 일이 둘인데, 둘 다 열린 이슈 소유다.

    지금 MVI 로 전환하면 #1702 와 #1795 가 다시 쓸 임시 구현이 된다. 이 큐 멤버들의 main 소비자가 0건인 상태와 그 사각지대는 #1795 코멘트 4절에 이미 실측해 뒀으니 여기서 반복하지 않는다.

    대기 상태는 gh api repos/Afternote/Afternote-FE/issues/2022/dependencies/blocked_by 로 확인했다. 등록된 blocked_by 10건이 전부 OPEN 이다. #1702 #1802 #1803 #1804 #1805 #1806 #1807 #1808 #1809 #2037. 본문 참고란이 열려 있다고 적은 #1698 은 지금 CLOSED 다.

    4. 지금 코드를 붙일 파일이 전부 열린 스택 안에 있다

    MainViewModel.kt 를 고치는 열린 PR 은 0건이지만, 이 이슈가 손댈 나머지 파일에는 임자가 있다. 열린 PR 62건 기준이다.

    파일 고치는 열린 PR
    konsist/.../MviContractKonsistTest.kt 10건. #2053 #2039 #2021 #2018 #2005 #1972 #1967 #1927 #1925 #1825
    docs/convention/mvi.md 2건. #2038 #1825
    app/.../navigation/AppNavigation.kt 4건. #2058 #2001 #1991 #1962

    #2038 (#1810) 은 docs/convention/mvi.md 에 네비게이션 경계 절을 새로 넣는다. 그 절이 세우는 경계는 피처 entry·host 소관이라 앱 루트 MainViewModel 을 다루지 않고 (그 PR 의 diff 에 MainViewModel 0건), 규칙 B 문장은 :126 에서 :165 로 밀릴 뿐 내용이 그대로다. 근거를 문서에 적는 선택을 하더라도 이 PR 이 들어간 뒤가 맞다.

    다음 착수자가 볼 것

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:app앱 셸·루트 네비게이션·앱 모듈 공통 영역refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions