**task-1648.1 완료 보고** (dev1-team) **완료 보고서** (35분 19초) **핵심 결과** 18개 파일(생성 14 + 수정 4) 변경, 테스트 115건 전체 통과로 구현 완료. 7개 상태 전이 로직, 2단계 승인(고위험: reviewer+admin 순서 무관), 경량 수정 7조건 AND 판정(Levenshtein ≤20 + 숫자 위치 보존 비교), 라운드 로빈 배정, 감사 로그 이중화(Firestore + Cloud Logging). 마아트 독립 검증에서 HIGH 3건 + MEDIUM 3건 발견 후 전수 수정 완료. ## 작업 내용 ### 상태 머신 (CF 서버 사이드) - `VALID_TRANSITIONS` 테이블: 7개 상태(draft, in_review, approved, rejected, revision_requested, needs_re_review, published) 간 10개 합법 전이 정의 - `assessRiskLevel()`: sourceType 기반 리스크 판정 (court_ruling/regulation/policy_pdf → high) - `canApprove()`: 저위험=reviewer 1명, 고위험=reviewer+admin 2단계 (순서 무관) - `onReviewCreate` CF: reviews 서브컬렉션 onCreate 트리거, 상태 전이 + 감사 로그 - `onDocumentUpdateReview` CF: approved/published 문서 수정 시 needs_re_review 자동 전환 ### 경량 수정 면제 로직 - 7조건 AND: (1) Levenshtein ≤ 20자 (bandwidth 제한 O(n)), (2) 숫자/금액/날짜/비율 위치 보존 **발견/해결 이슈 9건** 1. **canApprove 순서 의존 버그** — 고위험 2단계 승인에서 admin 먼저 승인 시 reviewer 승인으로 approved 불가. `canApprove`를 역할 기반 검증으로 리팩토링 (existingReviews에 reviewerRole 포함, 순서 무관). 2. **[HIGH-1] 숫자 위치 교환 미탐지** — `hasNoNumericChange`가 토큰 sort 후 비교하여 "1,000↔500" swap이 면제 통과. sort 제거하여 위치 보존 비교로 변경. 3. **[HIGH-2] assignReviewer authorId 미포함** — contributorIds에 authorId 없을 경우 자기 검토 배정 가능. `AssignReviewerParams`에 `authorId?` 추가, contributorIds에 자동 병합. 4. **[HIGH-3] auditLogs 복합 인덱스 누락** — `action` + `createdAt` 복합 쿼리에 인덱스 필요. `firestore.indexes.json`에 추가. 5. **[MEDIUM-4] HIGH_RISK_CATEGORIES 데드 코드** — `types/review.ts`의 `['practice']`와 `lightweightEditExemption.ts`의 `['court_ruling', 'regulation', 'policy_pdf']` 이름 충돌. types 파일의 데드 코드 제거. 6. **[MEDIUM-5] 합법 전이 테스트 커버리지 60%** — 10건 중 6건만 테스트. 누락 4건 추가 (revision_requested→draft, revision_requested→in_review, needs_re_review→in_review, published→needs_re_review). 7. **[MEDIUM-6] AuditLogEntry.action 타입 불일치** — functions는 `AuditAction` union, nextapp는 `string`. nextapp에 `AuditAction` 타입 추가 및 동기화. 8. **Security Rules에서 리뷰 생성 시 문서 상태 미검증** — 미해결: Rules에 get() 추가 필요하나 10회 제한에 근접. API route + CF에서 3계층 방어 중이므로 LOW. 불필요한 review 누적 가능성은 있으나 상태 전이 자체는 차단됨. 9. **⚠️ 기존 테스트 실패 1건** — 미해결: `youtubeWhisper.test.ts` OPENAI_API_KEY 타임아웃 (본 작업 범위 외, 기존부터 존재)