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

@@ -10,7 +10,9 @@
- **v0 구현 plan (W1~W4, 13 task)**: `docs/v0-plan.md` - **v0 구현 plan (W1~W4, 13 task)**: `docs/v0-plan.md`
- **brainstorming 원본**: `docs/brainstorming-raw.md` - **brainstorming 원본**: `docs/brainstorming-raw.md`
## v0 상태 (2026-05-24 기준) ## v0 상태 (2026-05-25 기준)
### 사전 액션
| 항목 | 상태 | | 항목 | 상태 |
|---|---| |---|---|
@@ -19,11 +21,34 @@
| v0 plan (W1~W4) | ✅ | | v0 plan (W1~W4) | ✅ |
| Day 0 검증 (도메인·앱스토어·인스타·상표) | ✅ | | Day 0 검증 (도메인·앱스토어·인스타·상표) | ✅ |
| @lapie_app 인스타 핸들 선점 | ✅ | | @lapie_app 인스타 핸들 선점 | ✅ |
| macOS 접근 방안 결정 | ✅ 박재오 Mac 보유 (2026-05-24) |
| lapie.kr / lapie.io 도메인 등록 | ⏸ 7월 착수 직전 | | lapie.kr / lapie.io 도메인 등록 | ⏸ 7월 착수 직전 |
| macOS 접근 방안 결정 | ⏸ Pre-Task 0.2 |
| 변리사 정식 상표 조사 | ⏸ 출원 직전 | | 변리사 정식 상표 조사 | ⏸ 출원 직전 |
| Figma 와이어프레임 5화면 | ⏸ W1 첫 주 | | Figma 와이어프레임 5화면 | ⏸ 가능하면 W1 첫 주 |
| **W1 Task 1 (Expo 세팅) 착수** | ⏸ 2026-07 예정 |
### v0 코드 진행 (W1~W4, 7월 → 2026-05-24 앞당김)
| Task | 상태 | 비고 |
|---|---|---|
| Gitea repo 연결 (`gahusb/lapie_app`) | ✅ SSH ED25519 키 (`windows-pc`) |
| **W1 Task 1** Expo + RN + TS 셋업 | ✅ Windows 가능 범위 (SDK 56, RN 0.85, TS 6) | `prebuild` + `run:ios`는 Mac |
| **W1 Task 2** 카메라 화면 + 권한 | ⏸ Mac 실기기 |
| **W1 Task 3** Segmentation Swift 브릿지 | ⏸ Mac |
| **W2 Task 4** Pose Swift 브릿지 | 🟡 TS wrapper + mock test ✅ / Swift Mac |
| **W2 Task 5** validatePose | ✅ TDD 3 케이스 / UI는 Task C |
| **W2 Task 6** splitMask | ✅ TDD 4 케이스 |
| **W3 Task 7** Skia 합성 컴포넌트 | ⏸ Mac 실기기 |
| **W3 Task 8** 자동 스케일 (핵심 차별화) | ✅ calculateScale TDD + 폴백 + usePinchScale / Mac 검증 |
| **W4 Task 9** LiveFittingScreen | ⏸ Task C UI 골격 + Mac |
| **W4 Task 10** CaptureResultScreen | ⏸ Task C UI 골격 + Mac |
| **W4 Task 11** Onboarding + 네비게이션 | ⏸ Task C UI 골격 + Mac |
| **W5~6 Task 12** 자동 스케일 보강 | ⏸ 버퍼 |
| **W5~6 Task 13** 마케팅 콘텐츠 5편 | ⏸ 버퍼 |
검증:
- `npx tsc --noEmit`: 무에러
- `npm test`: 6 suites / 17 tests passed (sanity 1 + pose 1 + photoValidation 3 + maskSplit 4 + calculateScale 6 + detectClothBounds 2)
- 푸시: 7 commits → Gitea
## 기술 스택 (v0) ## 기술 스택 (v0)

View File

@@ -78,7 +78,7 @@
- Create: `lapie/app.json` - Create: `lapie/app.json`
- Create: `lapie/tsconfig.json` - Create: `lapie/tsconfig.json`
- [ ] **Step 1: Expo 프로젝트 생성** - [x] **Step 1: Expo 프로젝트 생성** ✅ 2026-05-24 (SDK 56, Windows 임시폴더 → 파일 복사 방식)
```bash ```bash
cd C:/Users/jaeoh/Desktop/workspace/ cd C:/Users/jaeoh/Desktop/workspace/
@@ -88,7 +88,7 @@ cd lapie
Expected: `lapie/` 디렉터리에 `App.tsx`, `package.json`, `tsconfig.json` 생성. Expected: `lapie/` 디렉터리에 `App.tsx`, `package.json`, `tsconfig.json` 생성.
- [ ] **Step 2: Bare workflow로 전환 (네이티브 모듈 필요)** - [ ] **Step 2: Bare workflow로 전환 (네이티브 모듈 필요)** ⏸ Mac 작업
```bash ```bash
npx expo prebuild --platform ios npx expo prebuild --platform ios
@@ -96,14 +96,14 @@ npx expo prebuild --platform ios
Expected: `lapie/ios/` 디렉터리 생성, CocoaPods install. (Windows에서는 prebuild 실패 가능 — mac 환경 또는 EAS에서 실행). 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 ```bash
npm install react-native-vision-camera @shopify/react-native-skia react-native-worklets-core zustand react-native-safe-area-context 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 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 ```json
{ {
@@ -122,7 +122,7 @@ npm install --save-dev jest @types/jest ts-jest
} }
``` ```
- [ ] **Step 5: 첫 빌드 확인** - [ ] **Step 5: 첫 빌드 확인** ⏸ Mac 작업 (`npx expo run:ios`)
```bash ```bash
npx expo run:ios npx expo run:ios
@@ -130,7 +130,7 @@ npx expo run:ios
Expected: iOS 시뮬레이터에 기본 화면 표시. Expected: iOS 시뮬레이터에 기본 화면 표시.
- [ ] **Step 6: Git 초기화 + 첫 커밋** - [x] **Step 6: Git 초기화 + 첫 커밋** ✅ 2026-05-24 (Gitea SSH remote 연결 + ED25519 키 + 2 commits push)
```bash ```bash
cd lapie cd lapie
@@ -367,7 +367,7 @@ git commit -m "feat: iOS Vision person segmentation native bridge"
- Create: `lapie/src/features/pose/index.ts` - Create: `lapie/src/features/pose/index.ts`
- Test: `lapie/src/features/pose/__tests__/pose.test.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`: `lapie/modules/pose/ios/PoseModule.swift`:
```swift ```swift
@@ -418,7 +418,7 @@ class PoseModule: NSObject {
} }
``` ```
- [ ] **Step 2: Obj-C 브릿지** - [ ] **Step 2: Obj-C 브릿지** ⏸ Mac 작업
`lapie/modules/pose/ios/PoseModule.m`: `lapie/modules/pose/ios/PoseModule.m`:
```objc ```objc
@@ -431,7 +431,7 @@ RCT_EXTERN_METHOD(detectPose:(NSString *)imageUri
@end @end
``` ```
- [ ] **Step 3: TS 래퍼 + 타입** - [x] **Step 3: TS 래퍼 + 타입** ✅ 2026-05-24 (Keypoint/Joint/PoseResult + NativeModules wrapper, 매번 조회 패턴)
`lapie/src/features/pose/index.ts`: `lapie/src/features/pose/index.ts`:
```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`: `lapie/src/features/pose/__tests__/pose.test.ts`:
```ts ```ts
@@ -485,7 +485,7 @@ describe('detectPose', () => {
}); });
``` ```
- [ ] **Step 5: 실기기 manual test** - [ ] **Step 5: 실기기 manual test** ⏸ Mac 작업
- 정면사진 1장 입력 → 어깨·골반·발목 keypoint가 사진 위 정확한 위치에 표시되는지 시각 검증 - 정면사진 1장 입력 → 어깨·골반·발목 keypoint가 사진 위 정확한 위치에 표시되는지 시각 검증
- 임시 화면 `PoseDebugScreen.tsx`에 keypoint를 점으로 overlay - 임시 화면 `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` - Create: `lapie/src/features/photoValidation/validatePose.ts`
- Test: `lapie/src/features/photoValidation/__tests__/validatePose.test.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`: `lapie/src/features/photoValidation/__tests__/validatePose.test.ts`:
```ts ```ts
@@ -550,7 +550,7 @@ describe('validatePose', () => {
}); });
``` ```
- [ ] **Step 2: 실행 → 실패 확인** - [x] **Step 2: 실행 → 실패 확인** ✅ 2026-05-24
```bash ```bash
npx jest src/features/photoValidation npx jest src/features/photoValidation
@@ -558,7 +558,7 @@ npx jest src/features/photoValidation
Expected: FAIL — validatePose not defined. Expected: FAIL — validatePose not defined.
- [ ] **Step 3: 구현** - [x] **Step 3: 구현** ✅ 2026-05-24 (한국어 격조사 정확화: '어깨가/골반이/발목이')
`lapie/src/features/photoValidation/validatePose.ts`: `lapie/src/features/photoValidation/validatePose.ts`:
```ts ```ts
@@ -599,7 +599,7 @@ export function validatePose(pose: PoseResult): ValidationResult {
} }
``` ```
- [ ] **Step 4: 테스트 통과 확인** - [x] **Step 4: 테스트 통과 확인** ✅ 2026-05-24 — 3 passed
```bash ```bash
npx jest src/features/photoValidation npx jest src/features/photoValidation
@@ -607,7 +607,7 @@ npx jest src/features/photoValidation
Expected: 3 passed. Expected: 3 passed.
- [ ] **Step 5: 사진 등록 화면 (UI)** - [ ] **Step 5: 사진 등록 화면 (UI)** ⏸ Task C에서 진행 + Mac 실기기 검증
`lapie/src/screens/PhotoCaptureScreen.tsx`: `lapie/src/screens/PhotoCaptureScreen.tsx`:
```tsx ```tsx
@@ -668,7 +668,7 @@ const styles = StyleSheet.create({
}); });
``` ```
- [ ] **Step 6: 의존성 추가 + 커밋** - [ ] **Step 6: 의존성 추가 + 커밋** ⏸ Task C에서 진행 (expo-image-picker)
```bash ```bash
npx expo install expo-image-picker 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로 처리. > 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`: `lapie/src/features/maskSplit/__tests__/splitMask.test.ts`:
```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`: `lapie/src/features/maskSplit/splitMask.ts`:
```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 ```bash
npx jest src/features/maskSplit npx jest src/features/maskSplit
@@ -772,7 +772,7 @@ npx jest src/features/maskSplit
Expected: 3 passed. Expected: 3 passed.
- [ ] **Step 4: 커밋** - [x] **Step 4: 커밋** ✅ 2026-05-24 — `8ec53d9 feat(maskSplit): computeSplitRegions TDD (v0-plan Task 6)`
```bash ```bash
git add src/features/maskSplit 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` - Create: `lapie/src/features/autoScale/detectClothBounds.ts`
- Test: `lapie/src/features/autoScale/__tests__/calculateScale.test.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`: `lapie/src/features/autoScale/__tests__/calculateScale.test.ts`:
```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`: `lapie/src/features/autoScale/calculateScale.ts`:
```ts ```ts
@@ -976,7 +976,7 @@ export function calculateScale({ photoShoulderPx, cameraClothWidthPx }: ScaleInp
} }
``` ```
- [ ] **Step 3: 테스트 통과** - [x] **Step 3: 테스트 통과** ✅ 2026-05-25 — 6 passed
```bash ```bash
npx jest src/features/autoScale/calculateScale npx jest src/features/autoScale/calculateScale
@@ -984,7 +984,7 @@ npx jest src/features/autoScale/calculateScale
Expected: 3 passed. 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`: `lapie/src/features/autoScale/detectClothBounds.ts`:
```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 검증. > ⚠ 옷 윤곽 검출은 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`: `lapie/src/features/autoScale/usePinchScale.ts`:
```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 ```bash
npx expo install react-native-gesture-handler npx expo install react-native-gesture-handler