Skip to content

렌더 입자성 캠페인 Phase 3 — 파일럿 바인딩 (라이브 운동 화면)

통합 기록(형식 표준, Phase 현황·결과·남은 것): 2026-08-24-render-granularity.md

  • 날짜: 2026-08-23 (Phase 2 #614 직후, 오너 결정 D2 (나))
  • 목표: 컨테이너 계층에 WorkoutFlowBinding을 세워 Phase 4 확산의 템플릿(구독 → 조립 → 같은 props)을 만들고, renderCtx에서 드래프트 몫 키를 처음으로 은퇴시킨다. 화면(ui/**)은 무접촉 — 같은 props를 받는다.

바뀐 것

항목파일내용
Phase 3-1 바인딩features/active-workout/WorkoutFlowBinding.tsx (신설)useOwnerStores().workoutDraft를 uSES로 구독해 인텐트 파생(backfill·lockedStart·planMode)·제목·계획 편집 상태를 읽고, 라이브 스냅샷은 ref에서. mobileApp에 있던 props 조립(buildWorkoutPlanData 드래프트 몫·lgFlowInitialDraft·lgNormalizeWorkoutSnapshotForUi·buildMobileWorkoutYearStats)과 화면 lazy 정의(WorkoutFlow + workout.css)를 verbatim 이동. onDraftSnapshot은 스토어의 handleWorkoutSnapshot 직결
Phase 3-1 mobileAppmobileApp.tsx운동 화면 분기는 드래프트 밖 입력(plans·sessionDate·gymData·카탈로그·프로필·1RM·이력·볼륨·sessionsByDate)과 커맨드만 바인딩에 건넨다. 탭 이탈 persist는 useOwnerStores()의 스토어를 직접 읽는다. Suspense 경계(탭 골격 스켈레톤)는 그대로 mobileApp
Phase 3-2 키 은퇴appController.tsxrenderCtx에서 11키 은퇴: workoutStartOptions currentPlanDraft flowBackfill flowLockedStart workoutSnapshot workoutSnapshotRef selectedPlanDraft workoutPlanOptions liveTitle planName handleWorkoutSnapshot. 조립 루트의 buildWorkoutPlanData 호출은 양쪽 셸이 쓰는 exerciseCatalog만 남기고 제거(드래프트 몫 계산이 루트에서 사라짐). 루트는 게이트 키(flow·planMode·locked·isWorkoutActive)만 유지

데스크톱 셸은 은퇴한 키를 하나도 소비하지 않는다(실측). TS Pick<>가 은퇴 키의 잔여 소비자를 컴파일 단계에서 적발했다(0건).

검증

  • npm run check 1807/1807(rebase 후) · check:unused · ts-boundary(바인딩을 mobileApp과 같은 "mobile component bridge boundary"로 등재).
  • 재조준 1: mobileCssBoundaries(WorkoutFlow lazy + 스타일시트 동일 경계를 바인딩 파일에서 확인, pending-changes 기존 항목에 사유 병합). 청크 프리로드 목록·Suspense fallback 계약은 mobileApp에 그대로 남아 변경 없음.
  • 브라우저 회귀 CASE-001·004·011·015 4/4(프로덕션 빌드, 로컬 스택).
  • 계획 편집 모드 스모크(dev 서버, 임시 스크립트): 일지 → 오늘 날짜 시트 → 운동 계획 작성(flow plan mode, 바인딩 경유) → 종목·세트 입력 → 저장 → planned_sessions 행 생성, 콘솔 오류 0.
  • Phase 0-2 계측 재실행: 시나리오 ① 세트 입력당 루트 커밋 0 유지(Phase 1과 동일), ②·③ 불변.

전 → 후

지표
renderCtx 키176165 (−11)
드래프트 몫 props 조립 위치조립 루트 + mobileApp바인딩 1곳(드래프트 스토어 직접 구독)
바인딩 템플릿WorkoutFlowBinding (구독 → 조립 → 같은 props)
렌더 효과없음(계획대로 — 루트는 게이트를 위해 드래프트 스토어 구독 유지)

남는 것(Phase 4 판정 재료)

  • 루트가 드래프트 스토어 전체를 구독하는 구조는 그대로다. 제목 편집(liveTitle 변화)은 여전히 루트를 깨운다 — 홈 이어하기 카드의 원천이라 필요하다. 루트의 드래프트 구독을 게이트 슬라이스로 좁히려면 쓰기 커맨드 env의 드래프트 값(exercises·planName·saving·selPlanId) 도 ref/getter로 바꿔야 한다(핫 키 규칙) — 실측상 편집당 루트 커밋이 이미 0이라 Phase 4 후보 목록의 뒤쪽.