친구 프로필 스코프 — 리포트 한 장 스왑에서 4화면 스코프·도크까지 (2026-08-25)
- 기간: 2026-08-25 (세션 1, 오너 지시 원문: "이거 디자인 반영 issue 하나 만든다음, 후속 배선작업 진행해서 pr 올리고 문제 없으면 머지해줘" — 이슈 #784)
- 랜딩: PR #785(Phase 1~5,
2518677b) — 마이그레이션 0·서버 신설 0, Vercel 배포 확인(CI pass) - 설계서: 없음(디자인 딜리버리+배선 트랙) — Phase 계획·예상 효과·개선사항 표는 이슈 #784 본문
- 정본:
feed-props.md§친구 스코프 전환(판 전환 곡선·컨테이너 소유) ·onboarding-props.md§로그인 진입 전환 ·shell-frames.mdMobileTabFramescopePane슬롯 ·src/react/ui/mobile/lib/FriendScopeBar.tsx(도크) ·src/react/ui/mobile/styles/base/core.css.fscope(판 전환 CSS) ·designContract.tsfriendScopeBar/friend.scope.nav/friend.scope.close - 도구: 없음
- 게이트:
tests/react/friendScope.test.mjs7건(도크 계약·4화면 friendNav/fband 렌더·스코프 판 배선 단언·전환 곡선) + 기존 designContract 양방향 마커 게이트 - 버그리포트: 없음(신기능 — ReportScreen 패키징 사고는 랜딩 전 zip 감사 단계에서 수복)
- 계약:
feed-props.md§친구 스코프 전환 신설,onboarding-props.md§로그인 진입 전환 신설,shell-frames.mdMobileTabFrame 행 갱신
Phase 현황
| Phase | 내용 | 상태 |
|---|---|---|
| Phase 1 | 디자인 반입(계약 v2 manifest, 3-way 2파일, v76 채택) | ✅ PR #785 (2518677b) |
| Phase 2 | 반입 정합 수리·기반 배선(스테일 복원·카피 정본화·마커·backLabel 폐기) | ✅ 〃 |
| Phase 3 | 친구 스코프 컨테이너(4화면 라우팅·fscope 판·데이터 공급) | ✅ 〃 |
| Phase 4 | 스플래시→로그인 연속 전환(컨테이너 조건 검증 — 신규 로직 0) | ✅ 〃 |
| Phase 5 | 게이트·CI·머지 | ✅ CI green 후 머지 |
| Phase 6 | 오너 실기기 확인(스코프 왕복·전환 애니·스플래시 연속) | ⬜ 오너 |
1. 배경
친구 열람은 2026-08-23 친구 리포트 v1이 전부였다: 피드 아바타 탭 → 피드 탭 자리에 리포트 화면 한 장을 스왑(backLabel="피드로 돌아가기" 행으로 복귀). 클로드 디자인이 08-25 delivery-20260825(v76 zip)로 이를 친구 스코프로 확장했다 — 4화면(랜딩=운동하기 메인 조회형·일지·리포트·피드), 하단 도크 FriendScopeBar(‹ 이탈 + 탭 4), 워드마크 행 소유자 표기(fband), 스코프 중 본 탭바 숨김. 함께 실린 것: 피드 반응 아이콘 재작도, 진행중 복귀 바 풀블리드+연필, 부팅 스플래시→로그인 연속 전환, 데이터 오류 게이트 재설계, 정리(죽은 fixture 주석·pr.css 고아).
2. 문제 제기
신 디자인은 구 복귀 행(rp-back)을 폐지해, 배선 없이는 친구 리포트의 이탈 통로가 0이 된다
ReportScreen의 "돌아가기" 행이 도크 ‹로 대체됐다 — 디자인만 반입하면 기존 친구 리포트에서 되돌아갈 수 없다. 반입과 배선이 한 PR이어야 했던 이유.
배송 zip의 ReportScreen이 앵커 슬라이스 사고로 74줄 유실 (v75)
base(#781 직전 main)의 mb-brand 워드마크 행이 로딩 화면에도 있어, 디자인 측 패키징이 첫 매치 기준으로 pending 화면부터 UiReadyReportScreen 선언부까지 통째로 잘라냈다(550→476줄, 참조되는 함수가 미정의 = 모듈 크래시). 쿠리어 헝크 감사와 디자인 측 자체 감사가 독립적으로 동일 적발 — 수복본이 서로 일치함을 확인하고 v76 재패키징본을 정본 채택했다.
델타 재적용이 #779 탭바 숨김 규칙을 되돌렸다 (스테일 리버트 1건)
nav.css의 08-19 델타(복귀 바 풀블리드)가 그 사이 main에 들어간 #779 댓글 시트 탭바 숨김 규칙(.app:has(.fd-cmsheet…) .tabbar)을 지운 채 실렸다. #779의 회귀 테스트 2종이 즉시 적발 — 계약 테스트를 상주시키는 이유의 실증.
스코프 화면을 본판 .screen 안에 넣으면 :has() 게이트가 오염된다
스코프 랜딩은 dashboard.home 마커를 렌더한다 — 본판 .screen 안이면 .screen:has([data-lg-view="dashboard.home"]) 레이아웃 게이트가 뒤의 피드 화면에까지 적용된다.
3. 해결 방안
원칙 (오너 지시, 2026-08-25)
- 오너 go: 반입 → 이슈 → 배선 → PR → 문제 없으면 머지(세션 지시 원문). Phase 계획은 이슈 #784에 게시.
- 디자인 계약 준수: 판정·전환 로직은 컨테이너 소유(
feed-props.md§친구 스코프 전환), 조회 전용 = 수정 콜백 미공급 관례.
접근
| 대안 | 판정 |
|---|---|
| 스코프를 피드 판 내부 ternary로 스왑(구 친구 리포트 방식) | 기각 — "내 피드는 뒤에 정지 유지(빈 프레임 금지)" 계약 위반 + :has() 오염 |
셸 layer 메커니즘 재사용 | 기각 — layer는 .tab-keep을 숨겨 전환 중 배경이 빈다 |
.screen 형제 오버레이(.fscope) + MobileTabFrame 옵션 슬롯 | 채택 — 본판 게이트 무오염, .fsb가 판과 함께 슬라이드(transform 잔존 시 anchoring 파괴 문제를 정지 상태 transform:none으로 회피) |
| 친구 데이터 신규 RPC 신설 | 보류 — 기존 표면만 재사용(리포트=get_following_volume_overview_v1, 일지=get_following_calendar_month_v1(계획 반영 v1 스토어 연결), 피드=내 피드 캐시 작성자 필터, 랜딩=프로필만). 부족분은 후속 서버 트랙 |
| 스코프 열림 상태 신설 스토어 | 기각 — friendReport 스토어 재사용(히스토리 레이어 #friend-report·하드웨어 백·탭 전환 정리 전부 무료로 승계) |
4. 적용한 내용
Phase 1 — 디자인 반입 (#785)
manifest 25파일 세트 일치 확인, main 전진 교집합 2파일(FeedScreen·feed.css ← #781)은 git merge-file 3-way(충돌 0, #781 델타 보존 grep 검증). ReportScreen은 v76 수복본. 오염 스캔(eslint-disable·@ts-nocheck·브랜딩·max-width) 0.
Phase 2 — 반입 정합 수리·기반 배선
nav.css #779 규칙 main 원문 복원(쿠리어 예외 ①), dead-css 기준선 재생성(pr.css 고아 정리로 기준선 잔여 0 도달), legal 문구 MOBILE_EXPERIENCE_COPY.onboarding.legal 정본화(온보딩·로그인 게이트 공용, 디자이너 재량 위임분), 데이터 게이트 재설계 구조로 authDegradedBootstrap 단언 갱신, FriendScopeBar 마커 부착+등록, backLabel 전면 폐기(4화면 데드 바인딩 제거 — unused 래칫 게이트가 강제), FeedScreen ownerName 공급.
Phase 3 — 친구 스코프 컨테이너 (mobileApp.tsx)
- 아바타 탭(
openFeedFriend) → 스코프 랜딩 즉시 마운트(중간 프로필 시트 없음 — 시트는 이전부터 미공급 데드 코드). .fscope판: 진입 0.32scubic-bezier(.25,.8,.3,1)/ 퇴장 0.28scubic-bezier(.5,0,.7,1)재생 후 언마운트(animationend + 400ms 보루), reduced-motion 즉시 전환, 정지 상태 transform none. 탭바 숨김·복원은 배송된.app:has(.fsb…)CSS가 자동 처리(컨테이너 플래그 0).- 판 내부 탭 스와프 =
friendNav.onGo(애니 없음). 열림 중 내 피드는 뒤에 정지 유지하되 상태 기반 시트(comments·moderation·세션 상세)는 스코프 판에서만 렌더(z 겹침 방지 게이트). - 데이터:
PlanAdoptionRenderContext를 mobileApp 타입 교집합에 추가하는 것만으로 친구 달력 도달(컨트롤러는 #753 시절부터 렌더 컨텍스트에 노출돼 있었음).
Phase 4 — 스플래시→로그인 연속
컨테이너 조건("같은 렌더 패스 스왑")은 #613 스플래시 소유권 구조가 이미 충족 — 검증만 수행, 신규 로직 0(계약 명시 그대로).
작업 중 드러난 것
- manifest 계약 v2도 앵커 슬라이스는 못 막는다 — 파일 단위 대조는 통과하고 파일 내부 유실은 헝크 감사만 잡는다. base 파일에 유일 앵커가 없으면 델타 재적용이 조용히 오려낸다.
- 로컬 eslint 실행 불가(기지 사실) — 판정은 CI verify 레인(pass 확인).
- 호스트 스플래시 120ms 지연(
HOST_LOADING_HIDE_DELAY_MS) 동안 로그인 락업 애니가 스플래시 밑에서 선재생 — 첫 가시 프레임이 12px가량 상승 후. 실기기에서 거슬리면 후속 조정 대상.
5. 적용 결과
| 항목 | 결과 |
|---|---|
| 친구 열람 화면 | 1(리포트 스왑) → 4(랜딩·일지·리포트·피드 스코프) |
| 친구 화면 이탈 통로 | rp-back 행 1 → 도크 ‹ + 하드웨어 백 + 탭 전환(구 행 폐지에도 0 미발생) |
| 아바타 탭 → 열람까지 단계 | 시트 개념 폐지 — 직행(계약 명문화) |
| 테스트 | 1976 → 1983 (신규 friendScope 7건), 전부 green |
| dead-css 기준선 | 1건(pr.css .p2) → 0건 |
| tsc·build·CI | 0 에러 · vite build ✓ · scope/verify/Vercel pass |
| 로컬 실측 | 부팅→신형 로그인 렌더·콘솔 에러 0 (dev 서버) |
| 미검증 | 친구 스코프 실왕복(인증 뒤 경로 — 로컬 불가)·전환 애니 체감·스플래시 연속 체감 → 오너 실기기/Vercel 확인 대기 |
6. 이번 개선으로 향상된 것
친구 페이지가 "리포트 구경"에서 "프로필 방문"이 됐다
아바타 탭이 친구의 페이지(랜딩) 직행으로 바뀌고, 일지·리포트·피드를 도크로 오간다. 소유자 표기(fband)가 전 화면에 상주해 내 화면 오인 여지가 없다.
구조적으로 남는 것
feed-props.md§친구 스코프 전환 — 판 전환의 곡선·언마운트 시점·reduced-motion까지 명문 계약.MobileTabFrame.scopePane슬롯 —.screen형제 오버레이 패턴(:has()게이트 무오염)의 재사용 가능한 자리.friendScope.test.mjs— 도크·fband·판 배선이 회귀하면 CI가 잡는다.- 배송 계약 실전 교훈: 헝크 감사는 파일 세트 일치와 별개로 필수(앵커 슬라이스 사고 적발 사례).
남은 것
- 오너 실기기 확인(Phase 6): 스코프 4화면 왕복·진입/퇴장 애니·탭바 숨김/복원·스플래시→로그인 연속.
- 친구 랜딩 데이터 공백: 친구 PR/레벨/주간 통계 RPC 부재 → 프로필+빈 상태 카드("종합 기록 카드가 없어요" 등). 채우려면 서버 트랙 신설 필요.
- HomeScreen 친구 모드 1인칭 문구 2건(즐겨찾기 빈 상태 카피·종목 검색 돋보기) — 디자인 측 후속 후보.
- 친구 일지 페이로드에 볼륨 없음(일수만 확정 표기) · 스플래시 120ms 락업 선재생(실기기 판단).