### 작업 유형 refactor — 동작 변경 없는 구조·책임·경계 개선 ### 주 담당 모듈 timeletter — 타임레터 ### 개요 timeletter 의 ViewModel 7개를 `MviViewModel` 로 전환한다. #### 현황 (develop 실측) | 항목 | 수치 | |---|---| | ViewModel | 7개 | | Screen / `on*` 콜백 | 7개 / 45개 | | presentation `@Test` | 20개 | `TimeLetterWriteViewModel` 이 public fun 19개 · 524줄로 이 모듈에서 가장 크고, `TimeLetterWriteScreen` 은 콜백 26개로 레포 2위다. #### 완료 조건 - [ ] ViewModel 7개가 `MviViewModel` 상속이고 `onIntent` 단일 진입점이다 - [ ] 상태 전이가 `reduce` 안에만 있다 - [ ] Screen 7개가 `Screen`/`Content` 2단이다 - [ ] `@Test` 20개가 초록이다 - [ ] konsist allowlist 에서 timeletter ViewModel 7개가 빠진다 ### 자식 이슈 _No response_ ### 참고 `TimeLetterWriteScreen.onTextStyleClick` 은 미배선 의심으로 #778 에서 추적 중이다 — Intent 로 접을 때 배선 여부가 드러나면 그 이슈에 결과를 남긴다. 본문 HTML 왕복은 라이브러리가 다시 쓴다 — 에디터 상태를 리듀서로 옮길 때 `RichTextState` 왕복까지 확인한다. **네비게이션은 이 전환 범위 밖이다.** timeletter 는 #1696(Navigation 3 로컬 스택 이관)과 #1301(단순 back 위임 5개 통합)이 열려 있다 — 착수 순서를 담당자가 정한다.
Activity