diff --git a/CLAUDE.md b/CLAUDE.md index a14923d..55b7f39 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -245,7 +245,7 @@ npm run preview # 빌드 결과물 미리보기 ## 기능 모듈 구조 (컨벤션) -대형 기능 페이지는 단일 파일이 아니라 아래 모듈 구조로 분해한다 (레퍼런스: `src/pages/listings/`, `src/pages/subscription/`). +대형 기능 페이지는 단일 파일이 아니라 아래 모듈 구조로 분해한다 (레퍼런스: `src/pages/listings/`, `src/pages/subscription/`, `src/pages/realestate/`). ``` src/pages// @@ -258,6 +258,24 @@ src/pages// 규칙: 파일당 단일 책임·권장 ≤300줄; 순수 로직은 `*Utils.js`로 추출 + 유닛 테스트; shell은 데이터 페칭/비즈니스 로직을 직접 갖지 않고 조합만; 컴포넌트는 props/훅 인터페이스로만 통신. +**중첩 적용** — 기존 기능의 대형 하위 컴포넌트도 같은 규칙으로 in-place 분해한다. 예: `src/pages/stock/components/PortfolioTab.jsx`(671줄)는 74줄 shell + `stock/components/portfolio/` 하위 모듈로 분해됨: + +``` +src/pages/stock/components/ +├── PortfolioTab.jsx # shell(74줄): 에러 + 관리 section 조합 + CashPanel + brokerGroups.map(BrokerSection) + 빈 상태 +└── portfolio/ + ├── portfolioUtils.js # formatPriceTime (순수) + portfolioUtils.test.js + ├── PriceSessionBadge.jsx # NXT 세션 뱃지 + PriceSessionBadge.test.jsx + ├── AddHoldingForm.jsx # ({ pf }) 종목 추가 폼 (addFormOpen 가드) + ├── PortfolioSummary.jsx # ({ pf }) 총매입/평가/손익 요약 카드 + ├── AssetHistoryChart.jsx # ({ asset, pf, handleSaveSnapshot }) recharts 자산 추이 + ├── CashPanel.jsx # ({ pf }) 예수금 테이블(인라인 편집/삭제) + 추가 폼 + ├── BrokerSection.jsx # ({ broker, items, pf, handleSell }) 브로커 섹션 + HoldingRow 반복 + └── HoldingRow.jsx # ({ item, pf, handleSell }) 보유 1행 (view/편집/매도확인/삭제확인 4상태) +``` + +`pf`(usePortfolio 훅 객체 전체)를 props로 스레딩하는 behavior-preserving 순수 추출. 각 하위는 실제 참조하는 `pf.*`/`asset.*` 심볼만 사용. + --- ## Sonic Forge — AI 음악 생성 스튜디오 (`/lab/music`) diff --git a/README.md b/README.md index b89ea4d..cd3de5f 100644 --- a/README.md +++ b/README.md @@ -227,4 +227,6 @@ apiPost('/api/travel/sync'); ### 기능 모듈 구조 -대형 기능 페이지는 `src/pages//` 아래 **shell(`.jsx`) + `components/` + `hooks/` + `Utils.js`(+테스트)** 로 책임을 분해합니다. 파일당 단일 책임·권장 ≤300줄, 순수 로직은 유틸로 뽑아 유닛 테스트합니다. (레퍼런스: `listings`, `subscription`) +대형 기능 페이지는 `src/pages//` 아래 **shell(`.jsx`) + `components/` + `hooks/` + `Utils.js`(+테스트)** 로 책임을 분해합니다. 파일당 단일 책임·권장 ≤300줄, 순수 로직은 유틸로 뽑아 유닛 테스트합니다. (레퍼런스: `listings`, `subscription`, `realestate`) + +기존 기능의 대형 하위 컴포넌트도 같은 규칙으로 in-place 분해합니다. 예: `stock/components/PortfolioTab.jsx`(671줄) → 74줄 shell + `stock/components/portfolio/`(AddHoldingForm·PortfolioSummary·AssetHistoryChart·CashPanel·BrokerSection·HoldingRow·PriceSessionBadge + portfolioUtils).