Skip to content

Refactor(Phase 4): page-views / widgets 레이어 구축 및 HydrationBoundary 적용#4

Merged
mayrang merged 1 commit intomainfrom
refactor/phase-4-pages-widgets
Mar 21, 2026
Merged

Refactor(Phase 4): page-views / widgets 레이어 구축 및 HydrationBoundary 적용#4
mayrang merged 1 commit intomainfrom
refactor/phase-4-pages-widgets

Conversation

@mayrang
Copy link
Copy Markdown
Owner

@mayrang mayrang commented Mar 21, 2026

Summary

  • src/page/ 92개 파일을 FSD page-views/ + widgets/ 레이어로 이전 (re-export 래퍼로 하위 호환 유지)
  • app/page.tsx, app/community/page.tsx, app/trip/detail/[travelNumber]/page.tsxHydrationBoundary + prefetchInfiniteQuery 적용 → 초기 로딩 스피너 제거
  • E2E 테스트 12개 spec 파일 전면 활성화 (test.describe.skiptest.describe)
  • widgets/home 신규 테스트 6개 추가 (225 → 237 Vitest 통과)

주요 변경사항

항목 Before After
FSD 외부 파일 수 92개 (page/) 0개 (래퍼만 잔존)
FSD 레이어 완성도 shared+entities+features + page-views + widgets
HydrationBoundary 적용 0개 라우트 3개 라우트
E2E 활성화 0% (전부 skip) 100% (12개 spec)
Vitest 통과 225개 237개

레이어명 변경: pages/page-views/

FSD 표준 레이어명 pages/는 Next.js App Router 프로젝트에서 Pages Router 충돌을 유발합니다. page-views/로 이름 변경해 FSD 의미는 유지하면서 Next.js 충돌을 회피했습니다.

Test plan

  • yarn build — TypeScript 오류 없음 확인
  • npx vitest run — 237개 테스트 통과 확인
  • 홈(/), 커뮤니티(/community), 여행 상세(/trip/detail/[id]) 페이지 — 초기 로딩 스피너 없이 즉시 렌더 확인
  • 기존 src/page/ re-export 래퍼를 통해 모든 라우팅 정상 동작 확인
  • E2E: npx playwright test — 활성화된 12개 spec 파일 실행

참고 문서

  • docs/refactoring/phase-4.md — 배경, 의사결정, 트러블슈팅 전체 기록

🤖 Generated with Claude Code

- src/page/ 92개 파일을 FSD page-views/ + widgets/ 레이어로 이전
  - widgets/home: TripAvailable, BookmarkContainer, TripRecommendation (독립 섹션 블록)
  - page-views/{home,community,trip,myTrip,myPage,auth,search,contact,notification,report,travelLog,onBoarding,userProfile,comment,comment}
  - src/page/ 원본 파일들은 re-export 래퍼로 교체 (하위 호환 유지)
- app/page.tsx, app/community/page.tsx, app/trip/detail/[travelNumber]/page.tsx에
  HydrationBoundary + prefetchInfiniteQuery 적용 (초기 로딩 스피너 제거)
- E2E 테스트 12개 spec 파일 활성화 (test.describe.skip → test.describe)
- Vitest 통과: 225 → 237개 (+6 widgets/home 신규)
- 레이어명 pages/ → page-views/ (Next.js Pages Router 충돌 회피)
- docs/refactoring/phase-4.md 작성, CLAUDE.md + docs/progress.md 업데이트

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
release-back Ready Ready Preview, Comment Mar 21, 2026 1:37pm
release-test Ready Ready Preview, Comment Mar 21, 2026 1:37pm

@mayrang
Copy link
Copy Markdown
Owner Author

mayrang commented Mar 21, 2026

코드 리뷰 — Phase 4: page-views / widgets 레이어 구축

✅ 전체 평가

FSD 레이어 구축 목표를 달성했고, re-export 래퍼 패턴으로 라우팅 파일 변경 없이 점진적 이전을 완료한 점은 높이 평가합니다. 아래는 발견된 이슈와 개선 제안입니다.


🔴 버그 / 오류

1. ReportDetailPage.tsxconsole.log 잔존 (CLAUDE.md 위반)

// src/page-views/report/ReportDetailPage.tsx:92
console.log(type);

// src/page-views/report/ReportDetailPage.tsx:99
console.log(id, accessToken, type, checkIndex);

문제: CLAUDE.md에 console.log 사용 금지 명시. 프로덕션 빌드에 디버그 로그가 노출됩니다.
수정:console.log 라인 제거.


2. ReportDetailPage.tsxany 타입 신규 사용 (CLAUDE.md 위반)

// src/page-views/report/ReportDetailPage.tsx:30-33
const { mutate, isSuccess, isError } = useMutation({
  mutationFn: (data: any) => { ... },   // ← any 금지
  onSuccess: (data: any) => { ... },    // ← any 금지
});

문제: CLAUDE.md에 any 타입 신규 사용 금지 명시. 기존 코드 복사 시 유입된 것으로 보이나 새 레이어에 그대로 가져오면 규칙 위반.
수정: 적절한 타입 정의 필요 (최소한 unknown + 타입 가드).


🟡 레이어 규칙 (FSD)

3. CommunityPage.tsxpage-views/home/Navbar를 직접 import

// src/page-views/community/CommunityPage.tsx:9
import Navbar from "@/page-views/home/Navbar";

문제: FSD 레이어 내에서 같은 레이어의 다른 슬라이스(home)를 직접 참조하는 것은 규칙 위반입니다. page-views/communitypage-views/home 의존성은 순환 참조 가능성과 결합도를 높입니다.
권장: Navbarshared/ui/ 또는 widgets/로 격상시키거나, 최소한 page-views/shared/Navbar로 분리.

4. MyCommunityPage.tsx도 동일 문제

// src/page-views/community/MyCommunityPage.tsx:7
import Navbar from "@/page-views/home/Navbar";

동일한 레이어 간 cross-slice import 이슈.


🟡 코드 품질

5. Server Component 프리페치 — getNextPageParam 미정의 가능성

// src/app/page.tsx
queryClient.prefetchInfiniteQuery({
  queryKey: ["availableTrips"],
  queryFn: ({ pageParam }) => getAvailableTrips(pageParam as number, null),
  initialPageParam: 0,
  getNextPageParam: (lastPage: any) => lastPage?.page?.nextPage ?? undefined,
})

getNextPageParam에서 any 타입이 사용되고 있고, lastPage 구조가 실제 API 응답과 일치하는지 타입으로 보장되지 않습니다. 엔티티 레이어의 응답 타입을 활용하도록 개선 권장.

6. widgets/home 테스트 — any 캐스팅

// src/widgets/home/TripAvailable.test.tsx (추정)
children: props.children as any

Phase 3에서 수정된 패턴이 widgets 테스트에도 동일하게 적용됐는지 확인 필요.


🟢 잘 된 점

  1. re-export 래퍼 패턴 일관성src/page/ 전체를 래퍼로 교체해 app/ 라우팅 파일 무수정 달성.
  2. HydrationBoundary 도입 — Server Component에서 공개 API만 선택적으로 프리페치한 판단이 적절합니다 (인증 필요 API는 클라이언트 유지).
  3. page-views/ 네이밍 결정 — Next.js Pages Router 충돌을 빠르게 감지하고 page-views/로 우회한 점이 실용적입니다.
  4. E2E 전면 활성화test.describe.skip 12개를 일괄 활성화해 테스트 커버리지 기반 확보.
  5. 도메인별 index.ts — 각 레이어 슬라이스마다 public API 배럴 파일 작성으로 import 경로 단순화.

📋 후속 작업 권장

우선순위 항목
🔴 즉시 console.log 제거 (2개)
🔴 즉시 any 타입 제거 (ReportDetailPage mutationFn, onSuccess)
🟡 다음 Phase Navbar 레이어 위치 재검토 (cross-slice 의존성 해소)
🟡 다음 Phase Server Component getNextPageParam 타입 강화

🤖 Reviewed with Claude Code

@mayrang mayrang merged commit 642db30 into main Mar 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant