Skip to content

refactor(platform): ViewModel 오케스트레이션의 UseCase 경계를 전 모듈에서 정리한다 #1688

Closed

Description

@OnlyReadOneBook

작업 유형

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

주 담당 모듈

platform — Android 앱·CI·빌드·릴리스·저장소 운영

개요

origin/develop@9471a1359acc 기준으로 ViewModel의 Repository 직접 호출을 전 모듈에서 다시 감사했다. 목적은 모든 호출을 기계적으로 UseCase로 감싸는 것이 아니라, 여러 호출의 순서·부분 실패·취소·재사용·도메인 불변식을 실제로 소유하는 경계만 UseCase로 분리하는 것이다.

이번 감사의 출발점은 #246에서 제거한 SaveAfternoteUseCase다. 당시 남은 구현은 단일 호출처의 sealed command dispatch뿐이었지만, command는 domain에 유지되고 동일한 dispatch는 ViewModel로 이동했다. 이를 “유스케이스로서 부적합”이라고 일반화하지 않고, 저장 명령의 애플리케이션 경계로 복원한다.

공통 판단 기준

다음 중 하나 이상을 실제로 소유할 때만 UseCase 후보로 본다.

  • 둘 이상의 Repository·UseCase 호출 순서와 short-circuit
  • 부분 성공·부분 실패·fallback·보상 결과
  • 취소 전파와 시간 예산·재시도·폴링
  • 여러 ViewModel이 재사용하는 동일 정책
  • UI와 무관한 도메인 불변식 또는 폐쇄된 command 해석 경계

다음은 계속 ViewModel에서 Repository를 직접 호출한다.

  • 단일 상세 조회·삭제·paging·캐시 I/O
  • 화면 입력 정규화, 중복 탭 방지, 로딩·문구·navigation event
  • Android Uri·리소스처럼 presentation에 남아야 하는 처리

UseCase 위치는 이름만 보고 domain 모듈로 강제하지 않는다. cross-feature 집계는 의존 방향을 지킬 수 있는 application/presentation usecase에 둘 수 있고, domain 타입·Repository만 쓰는 경계만 domain에 둔다.

감사 결과와 우선순위

우선순위 점수는 (Impact + Risk) × (6 - Effort)이며 각 축은 1~5다.

순위 경계 I/R/E 점수 비고
1 수신자 마스터키 검증 → 전역 인증 컨텍스트 커밋 5/5/3 30 #607·#1554 착지 후
2 수신자 이메일 검증 → 발신자별 인증 캐시 커밋 4/3/2 28 두 번째 suspend 실패 포함
3 수신자 홈 4-source 집계·부분 실패 5/3/3 24 #1462 이동 후
4 설정 수신자 정보 → 마지막 인사 2단계 저장 4/4/3 24 부분 성공을 명시
5 설정 전달조건 보존·합성 4/4/3 24 다른 content type 보존
6 마음기록 draft 조회·일괄 삭제 4/3/3 21 3개 VM 재사용·부분 삭제
7 애프터노트 저장 command 해석 3/2/2 20 SaveAfternoteUseCase 복원
8 타임레터 생성·수정·등록 게이트 4/4/4 16 #470·#881 계약과 조율
9 주간 리포트 조회·제한 폴링 4/4/4 16 가상 시간 검증
10 추억 공간 다중 조회·부분 실패 3/4/4 14 음수 ID 우회 제거

단계

  1. 독립적이고 저비용인 애프터노트 저장 경계와 설정 저장 정책부터 분리한다.
  2. 이동·계약 선행 이슈가 끝난 뒤 수신자 홈과 인증 흐름을 분리한다.
  3. 마음기록과 타임레터의 다중 조회·저장 정책을 순수 결과 계약과 단위 테스트로 고정한다.

공통 완료 조건

  • 아래 자식 이슈가 각 모듈 담당자에게 자동 배정되고 선행 이슈가 명시된다.
  • 각 UseCase가 소유하는 순서·부분 실패·취소·불변식을 domain/application 단위 테스트로 검증한다.
  • ViewModel에는 UI 상태·문구·telemetry·navigation 매핑만 남긴다.
  • 프로덕션 visibility를 테스트 때문에 넓히지 않는다.
  • 기존 동작과 오류 복구 경계를 바꾸지 않으며, 바뀌어야 하는 계약은 별도 기능/버그 이슈로 분리한다.

자식 이슈

참고

Activity

  1. added
    refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업
    area:platformCI·빌드·릴리스·저장소 운영 영역
    on Aug 31, 2026
  2. OnlyReadOneBook commented on Sep 13, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    착수 전 점검 결과 이 총괄 이슈의 감사표가 현황과 어긋나 있어 대조 결과를 남깁니다. 기준 리비전은 origin/develop 86ab223 이고, 본문이 인용한 9471a1359acc 에서 681 커밋 뒤입니다.

    감사표 10행 대조

    착지한 것 4행.

    행 상태 착지 위치
    3행 수신자 홈 4-source 집계 해소 GetReceiverHomeSummaryUseCase.kt (abb9f8e, #1689)
    6행 마음기록 draft 조회·일괄 삭제 해소 LoadMindRecordDraftsUseCase.kt · DeleteMindRecordDraftsUseCase.kt (#1875 → #1693)
    9행 주간 리포트 조회·제한 폴링 해소 ObserveWeeklyReportUseCase.kt · GetWeeklyRecordCountUseCase.kt (2e4ddd6, #1875)
    10행 추억 공간 다중 조회·부분 실패 해소 GetMemorySpaceUseCase.kt (f2a878e, #1693)

    표 밖의 #1701 열람 신청 서류 제출 불변식도 SubmitDeliveryVerificationUseCase.kt (9e64c0d)로 닫혔습니다.

    남은 6행.

    자식 목록이 현황을 반영하지 않는다

    #1689 · #1693 · #1701 은 닫혔고, #1690 은 #607 에 blocked, #1692 는 koongmai, #1694 는 PR #1838 승인 대기입니다. 문제는 #1691 입니다. 그 구현이 자식 트리 밖의 PR #1967(#1502 설정 MVI 통합)에 흡수돼 본문이 "#1967 머지로 종료" 로 바뀌었습니다. 참고란의 "정확히 중복되는 열린 UseCase 구조 이슈는 현재 없다" 도 낡았습니다. #1693 이 #1875 로 한 번 더 갈라졌습니다.

    공통 완료 조건

    "ViewModel 에는 UI 상태·문구·telemetry·navigation 매핑만 남긴다" 는 전 모듈 기준으로 미달성입니다. 위 1 · 2 · 4 · 5 · 7 · 8 행이 남아 있습니다. 나머지 세 조건(단위 테스트 · visibility · 동작 보존)은 닫힌 자식 PR 들이 각자 충족했고 #1688 자체가 검증할 대상은 없습니다.

    "자식 이슈가 각 모듈 담당자에게 자동 배정" 은 배정 자체는 됐지만 receiver(#1690) · setting(#1691) · afternote(#1694) 세 모듈이 한 사람에게 몰려 있습니다. 그사이 모듈 담당이 바뀌었을 수 있어 규칙 위반으로 단정하지는 않습니다.

    git log --grep '#1688' origin/develop 은 0건이고 워크트리도 없습니다. 이 이슈 자체는 코드 범위가 0인 총괄이라 그게 맞습니다.

    제안

    지금 상태로는 감사표를 보고 무엇이 남았는지 알 수 없습니다. 세 가지를 정리하면 총괄로서 다시 쓸모가 생깁니다.

    1. 착지한 4행에 완료 표시와 착지 커밋을 적는다.
    2. refactor(setting): 수신자 저장·전달조건 정책을 UseCase로 분리한다 #1691 의 실제 구현 위치가 PR refactor: 설정 MVI와 저장·Repository 책임을 최종 계약으로 통합 (#1502) #1967 이라는 것을 자식 목록에 반영한다. 자식 트리 밖에서 끝나는 자식이 하나 있다는 사실이 지금은 어디에도 없다.
    3. 1행의 선행을 받은 기록함이 서버 목록 API 를 쓰지 않고 로컬 stub 으로 동작 — record-boxes 미연동 #607 · refactor(receiver): 마스터 키 UUID 의 이름 3종과 fromRaw 의 숨은 와이어 관용 정리 #1554 에서 받은 기록함이 서버 목록 API 를 쓰지 않고 로컬 stub 으로 동작 — record-boxes 미연동 #607 · security(receiver): 기록함 접근 자격·마스터키 비노출 서버 계약을 확정하고 검증한다 #1949 · security(receiver): 다중 수신자 컨텍스트·키 보관 정책을 서버 기록함 기준으로 분리 확정한다 #1950 으로 고친다.
  3. OnlyReadOneBook commented on Sep 23, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    추적 역할이 끝나 닫는다 (2026-09-23)

    이 이슈는 코드 범위가 0인 총괄이다. 감사표 10행이 전부 착지했거나, 결정 대기로 닫혔거나, 담당 큐의 하위 이슈와 열린 PR이 쥐고 있다. 부모에 남길 일이 없으므로 #928·#945 와 같은 방식으로 닫는다. 기준은 origin/develop f69332d 다.

    행 경계 귀속 담당 상태
    1 수신자 마스터키 검증 → 전역 인증 컨텍스트 커밋 #1690 결정 대기로 닫힘, 미이행
    2 수신자 이메일 검증 → 발신자별 인증 캐시 커밋 #1690 결정 대기로 닫힘, 미이행
    3 수신자 홈 4-source 집계·부분 실패 #1689 착지 abb9f8e
    4 설정 수신자 정보 → 마지막 인사 2단계 저장 #1691 1hyok PR #2124 리뷰 대기
    5 설정 전달조건 보존·합성 #1691 1hyok PR #2124 리뷰 대기
    6 마음기록 draft 조회·일괄 삭제 #1875 (#1693) 착지 749b7b4 (PR #1711)
    7 애프터노트 저장 command 해석 #1694 1hyok PR #1838 승인, 스택 밑단 대기
    8 타임레터 생성·수정·등록 게이트 #1692 koongmai 미착수
    9 주간 리포트 조회·제한 폴링 #1875 (#1693) 착지 2e4ddd6 (PR #1711)
    10 추억 공간 다중 조회·부분 실패 #1693 착지 f2a878e

    표 밖의 #1701 열람 신청 서류 제출 불변식도 9e64c0d 로 착지했다.

    행별 보정

    하위와의 관계는 본문 목록에만 있고 GitHub sub-issue 관계는 걸려 있지 않다. 이 이슈를 닫아도 하위 상태는 바뀌지 않으며, PR #1838 은 Refs #1688 로만 걸려 있어 영향이 없다.

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

Metadata

Metadata

Labels

area:platformCI·빌드·릴리스·저장소 운영 영역refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions