diff --git a/IMPLEMENTATION_AUDIT.md b/IMPLEMENTATION_AUDIT.md index 36c793d..94ef25d 100644 --- a/IMPLEMENTATION_AUDIT.md +++ b/IMPLEMENTATION_AUDIT.md @@ -2,7 +2,7 @@ > **대상**: `BROWSER_FEATURES_PLAN.md` (v2) + `MOBILE_PLAN.md` (v1) 전 항목 > **감사일**: 2026-08-15 · **방법**: TDD(RED→GREEN) + E2E 검증 -> **요약**: 전 솔루션 Release 빌드 **0 오류**, 단위/E2E 테스트 **104/104 GREEN**, Android 에뮬레이터·iOS 시뮬레이터·LAN 서버 E2E 완료 +> **요약**: 전 솔루션 Release 빌드 **0 오류**, 단위/E2E 테스트 **147/147 GREEN**, Android 에뮬레이터·iOS 시뮬레이터·LAN 서버 E2E 완료 > > **감사 중 발견·수정된 회귀**: `HlsDownloader` 3-인자 ctor가 `_muxer` 미할당(재구성 ② 누락) → 모든 HLS 리먹스 NUL 위험. RED 테스트(`HlsMuxerWiringTests`)로 재현 후 ctor 할당 수정. `DashDownloader`는 정상. @@ -67,14 +67,19 @@ | T3-9 읽어주기(TTS) | ✅ | `SpeakText` | | T3-10 인쇄/소스보기 | ✅ Ctrl+P / Ctrl+U | `MainWindow` | +### Phase E — T3 잔여 완성 (2차) + +| 항목 | 구현 | 증거 | +|---|---|---| +| T3-11 권한 UI | ✅ PermissionGate(출처×종류 기억, OtherSensors 자동거절/연속다운로드 자동허용) + PermissionRequested 배선 + 다이얼로그(항상 허용=SavesInProfile 영속) | `PermissionGateTests` 6건 + `PermissionTrackerE2ETests`(실제 WebView2 Notification.requestPermission → granted) | +| T3-14 추적 방지 카운터 | ✅ TrackerBlocklist(20개 도메인, 서브도메인 매칭) + WebResourceRequested 차단(204) + TrackerCounter + 실드 배지·도메인 팝업 | `TrackerBlockTests` 8건 + E2E(실제 WebView2 에서 2개 스크립트 차단·집계, 정상 도메인 통과) | +| T3-15 주소창 진행 바 + 파라미터 제거 복사 | ✅ NavProgressTracker(전 탭 집계 INPC) → 주소창 하단 인디케이터 + 주소창 우클릭 "파라미터 제거 후 복사"(UrlCleaner) | `UrlCleanerTests`/`NavProgressTrackerTests` 13건 | + ### T3 중 명시적 미구현 (계획 내 후순위/선택) - T3-2 Auto-Archive 캐던스 — 닫힘 스택(25개)+복원이 커버(아카이브 자동화는 미차용) -- T3-11 권한 UI — `PermissionRequested` 배선 미삽입 (계획상 선택) - T3-12 노트 패널 — 계획 자체가 "후순위" 명시 - T3-13 컴팩트 모드 — F11 전체화면이 동등 커버 -- T3-14 추적 방지 카운터 — 미차용 -- T3-15 주소창 진행 바/파라미터 제거 복사 — 미차용 ### 재구성 (사용자 지시 "근원부터 뜯어고쳐") @@ -111,11 +116,21 @@ 4. iOS `NSCameraUsageDescription` 누락 → 시작 크래시 → Info.plist 추가 (iOS+MacCatalyst) 5. 시뮬레이터 카메라 세션이 첫 프레임 블록 → 스캐너를 실기기(Physical)로 게이트 +### 2차 완성 (M2 잔여 + U5) + +| 항목 | 구현 | 증거 | +|---|---|---| +| U5 완료 알림 | ✅ `VideoDownloader.Mobile.Core`(net8 순수 로직) QueueCompletionDetector(첫 폴링 무시·재알림 방지) + Plugin.LocalNotification(Android 13+ 권한) | `MobileCoreTests` 9건 + 에뮬 E2E: 데모 큐 완료 전환 → **"다운로드 완료" 노티 실제 게시**(dumpsys notification) | +| 재생중 미디어 알림 | ✅ 플레이어 열릴 때 ongoing 노티 "재생 중"(채널 vd_playback), 닫히면 취소 | 에뮬 E2E: 게시·소멸 lifecycle 실증(dumpsys). **FGS 미사용** — 재생은 앱 내(포그라운드) 한정이므로 ongoing 노티로 충족, 문서화 | +| 라이브러리 그리드(썸네일·해상도) | ✅ 서버 Thumbnailer(ffmpeg 1초 프레임 320px JPEG + 해상도 ffprobe, 사이드카 .thumb.jpg/.meta.json 캐시) + `GET /api/library/{id}/thumb` + DTO Resolution + 앱 2열 그리드 | `ThumbnailerTests` 4건(Fake 러너) + 서버 E2E(JPEG 매직/404/401) + 에뮬 E2E: **실제 ffmpeg 썸네일 렌더**(스크린샷)·해상도 "480x270" | +| 외부망 안내(§7) | ✅ ConnectionTroubleshoot(같은 네트워크/Tailscale 안내) → QueuePage 표시 | 단위 3건 + 에뮬 E2E: 죽은 포트 페어링 → "같은 네트워크… Tailscale 등 VPN" 문구 실증 | +| U4 저장소 로직 이관 | ✅ OfflineStore → Mobile.Core(디렉터리 주입, MAUI 비의존) | 재시작 매니페스트 유지 테스트 포함 | + ### 명시적 미구현 (계획 허용/후순위) - SignalR 허브 — 계획안 명시 "v1은 2초 폴링으로도 가능" 채택 - mDNS 광고(_videodl._tcp) — QR 페어링이 주 경로(계획 §6 리스크 대응과 동일 전제) -- U5 완료 푸시 알림 +- 미디어 알림의 FGS 화 — 백그라운드 재생이 없는 컴패니언 구조상 ongoing 노티로 대체(위 표) - M4 Android 독립 다운로더 — 계획상 "선택" - iOS TestFlight — 앱 실행/페어링 프레이밍까지만 (감사일 기준)