docs: v0-plan task step 체크박스 + README 상태 표 갱신

docs/v0-plan.md ( 표시 + Mac 작업 명시):
- Task 1 (Expo 셋업): Step 1/3/4/6  (Step 2/5 Mac)
- Task 4 (Pose Swift 브릿지): Step 3/4 TS+test  (Step 1/2/5/6 Mac)
- Task 5 (validatePose + 사진 등록 UI): Step 1-4 TDD  (Step 5/6 Task C)
- Task 6 (splitMask): Step 1-4 
- Task 8 (자동 스케일): Step 1-6  (Step 7 Mac 검증)

README.md:
- "v0 상태"를 사전 액션 + v0 코드 진행으로 2분할
- W1 Task 1 ⏸ →  Windows 가능 범위
- macOS 접근 방안 ⏸ →  Mac 보유
- W1~W4 Task 별 상태 한눈에 (Task 4 🟡 일부, Task 5/6/8 , Task 2/3/7/9/10/11 ⏸ Mac)
- 검증 결과 한 줄: 17 tests passed, 7 commits

검증:
- npx tsc --noEmit: 무에러
- npm test: 6 suites / 17 tests passed (docs 변경이라 기존 테스트 영향 없음 확인)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-25 16:32:00 +09:00
parent 005d612ef3
commit 69d61231b9
2 changed files with 56 additions and 31 deletions

View File

@@ -78,7 +78,7 @@
- Create: `lapie/app.json`
- Create: `lapie/tsconfig.json`
- [ ] **Step 1: Expo 프로젝트 생성**
- [x] **Step 1: Expo 프로젝트 생성** ✅ 2026-05-24 (SDK 56, Windows 임시폴더 → 파일 복사 방식)
```bash
cd C:/Users/jaeoh/Desktop/workspace/
@@ -88,7 +88,7 @@ cd lapie
Expected: `lapie/` 디렉터리에 `App.tsx`, `package.json`, `tsconfig.json` 생성.
- [ ] **Step 2: Bare workflow로 전환 (네이티브 모듈 필요)**
- [ ] **Step 2: Bare workflow로 전환 (네이티브 모듈 필요)** ⏸ Mac 작업
```bash
npx expo prebuild --platform ios
@@ -96,14 +96,14 @@ npx expo prebuild --platform ios
Expected: `lapie/ios/` 디렉터리 생성, CocoaPods install. (Windows에서는 prebuild 실패 가능 — mac 환경 또는 EAS에서 실행).
- [ ] **Step 3: 필수 의존성 설치**
- [x] **Step 3: 필수 의존성 설치** ✅ 2026-05-24 (vision-camera v5, skia v2.6, worklets-core, zustand, gesture-handler, safe-area-context, jest-expo 등)
```bash
npm install react-native-vision-camera @shopify/react-native-skia react-native-worklets-core zustand react-native-safe-area-context
npm install --save-dev jest @types/jest ts-jest
```
- [ ] **Step 4: 권한 설정 (`app.json`)**
- [x] **Step 4: 권한 설정 (`app.json`)** ✅ 2026-05-24 (iOS NSCamera/Photo/PhotoAdd 3종 + bundleIdentifier com.lapie.app)
```json
{
@@ -122,7 +122,7 @@ npm install --save-dev jest @types/jest ts-jest
}
```
- [ ] **Step 5: 첫 빌드 확인**
- [ ] **Step 5: 첫 빌드 확인** ⏸ Mac 작업 (`npx expo run:ios`)
```bash
npx expo run:ios
@@ -130,7 +130,7 @@ npx expo run:ios
Expected: iOS 시뮬레이터에 기본 화면 표시.
- [ ] **Step 6: Git 초기화 + 첫 커밋**
- [x] **Step 6: Git 초기화 + 첫 커밋** ✅ 2026-05-24 (Gitea SSH remote 연결 + ED25519 키 + 2 commits push)
```bash
cd lapie
@@ -367,7 +367,7 @@ git commit -m "feat: iOS Vision person segmentation native bridge"
- Create: `lapie/src/features/pose/index.ts`
- Test: `lapie/src/features/pose/__tests__/pose.test.ts`
- [ ] **Step 1: Swift 모듈 작성 (17개 keypoint 반환)**
- [ ] **Step 1: Swift 모듈 작성 (17개 keypoint 반환)** ⏸ Mac 작업
`lapie/modules/pose/ios/PoseModule.swift`:
```swift
@@ -418,7 +418,7 @@ class PoseModule: NSObject {
}
```
- [ ] **Step 2: Obj-C 브릿지**
- [ ] **Step 2: Obj-C 브릿지** ⏸ Mac 작업
`lapie/modules/pose/ios/PoseModule.m`:
```objc
@@ -431,7 +431,7 @@ RCT_EXTERN_METHOD(detectPose:(NSString *)imageUri
@end
```
- [ ] **Step 3: TS 래퍼 + 타입**
- [x] **Step 3: TS 래퍼 + 타입** ✅ 2026-05-24 (Keypoint/Joint/PoseResult + NativeModules wrapper, 매번 조회 패턴)
`lapie/src/features/pose/index.ts`:
```ts
@@ -459,7 +459,7 @@ export async function detectPose(imageUri: string): Promise<PoseResult> {
}
```
- [ ] **Step 4: 유닛 테스트 (모킹)**
- [x] **Step 4: 유닛 테스트 (모킹)** ✅ 2026-05-24 (1 passed, jest-expo 호이스팅 충돌 회피 — NativeModules 직접 할당 패턴 사용)
`lapie/src/features/pose/__tests__/pose.test.ts`:
```ts
@@ -485,7 +485,7 @@ describe('detectPose', () => {
});
```
- [ ] **Step 5: 실기기 manual test**
- [ ] **Step 5: 실기기 manual test** ⏸ Mac 작업
- 정면사진 1장 입력 → 어깨·골반·발목 keypoint가 사진 위 정확한 위치에 표시되는지 시각 검증
- 임시 화면 `PoseDebugScreen.tsx`에 keypoint를 점으로 overlay
@@ -503,7 +503,7 @@ git commit -m "feat: iOS Vision human body pose native bridge (17 keypoints)"
- Create: `lapie/src/features/photoValidation/validatePose.ts`
- Test: `lapie/src/features/photoValidation/__tests__/validatePose.test.ts`
- [ ] **Step 1: 자세 검증 함수 (TDD)**
- [x] **Step 1: 자세 검증 함수 (TDD)** ✅ 2026-05-24 — RED 단계 (Cannot find module → 실패 확인)
`lapie/src/features/photoValidation/__tests__/validatePose.test.ts`:
```ts
@@ -550,7 +550,7 @@ describe('validatePose', () => {
});
```
- [ ] **Step 2: 실행 → 실패 확인**
- [x] **Step 2: 실행 → 실패 확인** ✅ 2026-05-24
```bash
npx jest src/features/photoValidation
@@ -558,7 +558,7 @@ npx jest src/features/photoValidation
Expected: FAIL — validatePose not defined.
- [ ] **Step 3: 구현**
- [x] **Step 3: 구현** ✅ 2026-05-24 (한국어 격조사 정확화: '어깨가/골반이/발목이')
`lapie/src/features/photoValidation/validatePose.ts`:
```ts
@@ -599,7 +599,7 @@ export function validatePose(pose: PoseResult): ValidationResult {
}
```
- [ ] **Step 4: 테스트 통과 확인**
- [x] **Step 4: 테스트 통과 확인** ✅ 2026-05-24 — 3 passed
```bash
npx jest src/features/photoValidation
@@ -607,7 +607,7 @@ npx jest src/features/photoValidation
Expected: 3 passed.
- [ ] **Step 5: 사진 등록 화면 (UI)**
- [ ] **Step 5: 사진 등록 화면 (UI)** ⏸ Task C에서 진행 + Mac 실기기 검증
`lapie/src/screens/PhotoCaptureScreen.tsx`:
```tsx
@@ -668,7 +668,7 @@ const styles = StyleSheet.create({
});
```
- [ ] **Step 6: 의존성 추가 + 커밋**
- [ ] **Step 6: 의존성 추가 + 커밋** ⏸ Task C에서 진행 (expo-image-picker)
```bash
npx expo install expo-image-picker
@@ -684,7 +684,7 @@ git commit -m "feat: photo capture screen with pose-based validation"
> Selfie Segmentation 마스크(전체 실루엣) + Pose keypoint(어깨·골반·발목)로 상의/하의/전신 3 마스크를 잘라낸다. Skia로 처리.
- [ ] **Step 1: 분할 로직 테스트 (TDD)**
- [x] **Step 1: 분할 로직 테스트 (TDD)** ✅ 2026-05-24 — RED 단계
`lapie/src/features/maskSplit/__tests__/splitMask.test.ts`:
```ts
@@ -720,7 +720,7 @@ describe('computeSplitRegions', () => {
});
```
- [ ] **Step 2: 구현**
- [x] **Step 2: 구현** ✅ 2026-05-24 (requireJoint helper로 invariant explicit — `!` 안티패턴 회피)
`lapie/src/features/maskSplit/splitMask.ts`:
```ts
@@ -764,7 +764,7 @@ export function computeSplitRegions(
}
```
- [ ] **Step 3: 테스트 통과 확인**
- [x] **Step 3: 테스트 통과 확인** ✅ 2026-05-24 — 4 passed (top/bottom/full y + x 범위 별도)
```bash
npx jest src/features/maskSplit
@@ -772,7 +772,7 @@ npx jest src/features/maskSplit
Expected: 3 passed.
- [ ] **Step 4: 커밋**
- [x] **Step 4: 커밋** ✅ 2026-05-24 — `8ec53d9 feat(maskSplit): computeSplitRegions TDD (v0-plan Task 6)`
```bash
git add src/features/maskSplit
@@ -916,7 +916,7 @@ git commit -m "feat: Skia composite view masking camera live into base photo"
- Create: `lapie/src/features/autoScale/detectClothBounds.ts`
- Test: `lapie/src/features/autoScale/__tests__/calculateScale.test.ts`
- [ ] **Step 1: 스케일 계산 테스트 (TDD)**
- [x] **Step 1: 스케일 계산 테스트 (TDD)** ✅ 2026-05-25 — 6 케이스 (정상비율/0폴백/음수폴백/상한클램핑/하한클램핑/클램핑X)
`lapie/src/features/autoScale/__tests__/calculateScale.test.ts`:
```ts
@@ -948,7 +948,7 @@ describe('calculateScale', () => {
});
```
- [ ] **Step 2: 구현**
- [x] **Step 2: 구현** ✅ 2026-05-25 (MIN_SCALE/MAX_SCALE export — usePinchScale에서 재사용)
`lapie/src/features/autoScale/calculateScale.ts`:
```ts
@@ -976,7 +976,7 @@ export function calculateScale({ photoShoulderPx, cameraClothWidthPx }: ScaleInp
}
```
- [ ] **Step 3: 테스트 통과**
- [x] **Step 3: 테스트 통과** ✅ 2026-05-25 — 6 passed
```bash
npx jest src/features/autoScale/calculateScale
@@ -984,7 +984,7 @@ npx jest src/features/autoScale/calculateScale
Expected: 3 passed.
- [ ] **Step 4: 옷 경계 검출 (단순화: 카메라 프레임에서 person mask 제외 영역의 bbox)**
- [x] **Step 4: 옷 경계 검출 (단순화: 카메라 프레임에서 person mask 제외 영역의 bbox)** ✅ 2026-05-25 — v0 폴백 함수 (항상 0 반환) + 회귀 테스트 2 케이스. 정식 구현은 Task 12 (Vision Saliency)
`lapie/src/features/autoScale/detectClothBounds.ts`:
```ts
@@ -1005,7 +1005,7 @@ export async function detectClothWidthPx(cameraFrameUri: string): Promise<number
> ⚠ 옷 윤곽 검출은 v0 W3 가장 어려운 부분. **v0 1차 출시는 자동 검출 폴백(scale=1) + 핀치만으로 운영**, 정확도는 W5~6 버퍼·v1에 보강. 본 단계의 핵심은 calculateScale 순수 함수의 TDD 검증.
- [ ] **Step 5: 핀치 줌 hook**
- [x] **Step 5: 핀치 줌 hook** ✅ 2026-05-25 — `.runOnJS(true)` 명시로 reanimated 의존 회피, Mac 실기기 검증 대기
`lapie/src/features/autoScale/usePinchScale.ts`:
```ts
@@ -1036,7 +1036,7 @@ export function usePinchScale(initialScale = 1) {
}
```
- [ ] **Step 6: 의존성 + 커밋**
- [x] **Step 6: 의존성 + 커밋** ✅ 2026-05-25 — gesture-handler는 W1 Task 1에서 이미 설치, `005d612 feat(autoScale): detectClothBounds 폴백 + usePinchScale hook`
```bash
npx expo install react-native-gesture-handler