Files
Dansori_EQ/docs/DEV_PLAN.md
T
2026-07-04 10:34:46 +09:00

164 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DEV PLAN
> **개발 세션 진행 로그는 `PROGRESS.md` 참조.** 아래 체크박스의 `[x]`는 선구현 또는 dev 세션 완료.
> **다음 최우선 작업: 그래프 도트(노드) 위치 정상화 (`PROGRESS.md` ▶ 참조).**
## 마일스톤
### M0 — 스파이크/검증 (0.5일)
- [ ] APO `Include:` 절대경로 허용 여부 확인 → 저권한 전략 확정(ARCHITECTURE §4).
- [ ] AutoEQ repo 최신 구조 + 소스별 라이선스 확인 → open/restricted 분류 규칙 확정.
- [ ] WPF-UI + LiveCharts2 스켈레톤에서 Mica + 로그축 차트 렌더 PoC.
### M1 — 솔루션 스캐폴딩 (0.5~1일)
- [ ] `DansoriEQ.sln` + App/Core/Setup 프로젝트.
- [ ] WPF-UI 테마(다크 Fluent) 적용, 목업 레이아웃(사이드바/메인/AI독) 정적 배치.
- [ ] 설정 저장소(%LOCALAPPDATA%\DansoriEQ) + API 키 보관(DPAPI 암호화).
### M2 — 프로파일 DB (1~1.5일)
- [ ] AutoEQ 수집 스크립트(개발용, 1회) → open/restricted 분류 → SQLite 적재.
- [x] (선구현) **`SqliteProfileDbService`**(스키마·GetInfo·Search·LoadEq·Upsert·ImportFromFolder·UpdateAsync=AutoEq zip 다운로드). `AutoEqParser` 있음. [ ] (dev) 사이드바 바인딩 + DesignStub→Sqlite 교체.
- [ ] 사이드바: IEM/헤드폰 그룹 분리, 검색, 선택. (라이선스 구분 없이 병합 표시)
- [ ] "DB 업데이트" 기능(zip 재확보→upsert→날짜 표시).
- [ ] **가져오기 자동 매칭**: `.tweq` 가져올 때 대상 기기를 로컬 DB와 매칭(`FindMatch`) →
있으면 연결, **없으면 "DB 업데이트로 받기" 안내**(가져오기 미리보기 창에서 DbManager 연결).
### M3 — EQ 엔진 + APO (1일)
- [ ] `EqState`/`Filter` 모델, `ApoRenderer`, `PreampCalculator`.
- [ ] `ApoLocator`(레지스트리), `ApoConfigInstaller`(최초 1회 승격), `IncludeWriter`(무승격).
- [ ] 프로파일 선택→베이스 EQ 로드→APO 적용→그래프 반영 왕복.
- [x] (선구현) **시작 시 APO 탐색 → 없으면 설정창(자동설치/경로지정/미리보기)**. `ApoSetupWindow`·
`ApoInstaller`·`AppSettings`. ※ APO 무인설치는 불가(장치 선택+재부팅) → 설치파일 실행까지만.
- [x] (선구현) **APO 미설치 시 미리보기 writer**(`NullApoWriter`)로 파이프라인 동작.
### M4 — AI 레이어 (1일)
- [x] (선구현) `ClaudeClient` + **`IAiEqProvider` 추상화** + `EqDeltaParser`(공유). `EqPromptBuilder`.
- [x] (선구현) **프롬프트창 → 활성 provider → `EqDeltaApplier` → APO 적용 + 설명 출력** 실배선.
- [x] (dev) **Gemini 무료 API로 자연어→EQ 적용 동작 확인**(PROGRESS.md). 되돌리기/리셋 배선됨. [ ] 응답 품질 평가(사용자 추후), 히스토리 UI.
### M5 — 그래프 시각화 + 테마 (1.5일)
- [ ] LiveCharts2로 현재 EQ 합성 곡선 + 타깃 곡선 + 필터 노드.
- [ ] 애니메이션 전환, Preamp/활성 토글 연동.
- [ ] **테마 전환**: Dark / Light / System(윈도우 추종) — WPF-UI ApplicationThemeManager.
- [ ] **강조색(Accent) 프리셋 5종 내외**(기본=틸/시안) + '윈도우 강조색 추종' 옵션 + 설정 저장.
- [ ] **그래프 색을 테마·강조색 리소스에 바인딩**(라이트 모드에서도 자연스럽게).
- [ ] 인터랙티브 노드 편집은 M7로 분리(아래).
### M6 — 마감/패키징 (1일)
- [ ] 최초 설정 마법사 UX, 예외/권한 실패 폴백 안내.
- [ ] 패키징 + **`--exclude-restricted` 배포 옵션**(restricted 폴더/행 제외).
- [ ] 아이콘/브랜딩, 기본 프리셋, README.
- [x] (선구현) **도움말 드로어**(❓ 도움말 → 오른쪽 슬라이드): 3단계 온보딩 + 버튼 안내 +
**API 키 발급 공식 링크**(Claude/OpenAI/Gemini). 설정의 각 키 행에도 '키 발급 방법' 링크.
### M7 — 인터랙티브 그래프 EQ 편집 (fast-follow, +1.5~2.5일)
> MVP(M1~M6) 출시 후 붙이는 최우선 확장. 가장 무거운 UI 파트라 분리한다.
> AI 없이 순수 수동 편집만 하려는 사용자도 이걸로 커버된다.
- [ ] **커스텀 WPF 에디터 컨트롤**(Canvas 기반) 또는 LiveCharts2 곡선 위 드래그 오버레이(Thumb/Adorner).
※ LiveCharts2 기본 포인트 드래그로는 폴리시가 부족 → **전용 컨트롤 권장**.
- [x] 인터랙션: 노드 좌우=Fc / 상하=Gain / 휠=Q / 더블클릭=밴드 추가 / 우클릭=삭제. [ ] **노드 위치 정상화(다음 작업, PROGRESS.md ▶1)**, 타입 변경(팝업서 지원).
- [x] (dev) **필터 칩 더블클릭 → 자체 그래픽 편집 팝업**(`FilterEditWindow`): **전체 18종 필터 타입** + 컨텍스트 UI(Q/기울기/차수) + **Peace식 정밀 수치 입력** + 그래프 축 라벨. `Filter`/`FilterType`/`ApoRenderer` 확장.
- [x] (선구현) **가변 밴드 개수**(`List<Filter>`, 상한 `MaxBands=40`; Peace는 31). 그래프 더블클릭/우클릭 +
' 밴드 추가'/'전체 지우기' 버튼(`AddBand`/`ClearBands`).
- [ ] 드래그 중 **Fc/Gain/Q 실시간 수치 표시**.
- [x] (선구현) **APO 쓰기 디바운스(120ms) + Preamp 실시간 재계산**(수동 편집 시 클리핑 방지).
- [x] (선구현) **AI 양방향 루프**: `SendPromptAsync`가 현재 EQ(수동 편집 포함)를 컨텍스트로 전달. **되돌리기/리셋**(Undo 스택+베이스) 배선.
### M8 — 설정 화면 & Claude API 키 관리 (0.5~1일) · MVP 필수
> 별도 메뉴 화면(WPF-UI NavigationView: Home/EQ ↔ Settings).
> AI(M4)의 전제이므로 실제 착수는 M1~M4와 **병행 권장**. 상세: ARCHITECTURE §9.
- [ ] 설정 화면: 섹션 = [AI · API 키] / [테마] / [APO] / [데이터베이스].
- [x] (선구현) **API 키 등록/삭제/교체 + DPAPI 암호화**(3사) + **연결 테스트**(AI 관리).
- [ ] 모델 선택(기본 Sonnet / 옵션 Opus). 키 미등록 시 프롬프트 독 비활성 + 안내.
### M9 — EQ 프리셋 공유(내보내기/가져오기) (1일)
> 사용자가 만든 EQ를 다른 사용자와 공유. 파일 규격: **ARCHITECTURE §8 (`.tweq`)**.
- [ ] **내보내기**: 현재 EQ + 대상 IEM/헤드폰 메타 + **AI 대화 히스토리(간략)**`.tweq`(JSON)로 저장.
- [ ] **가져오기**: 파싱·검증 → **정보 패널(대상 기기 / 히스토리 / 작성자 노트) 표시** → EQ 적용.
- [ ] 로컬 DB 동일 기기와 매칭(있으면 연결, 없으면 메타만으로 standalone 적용).
- [ ] 입력값 검증/클램프(Fc/Gain/Q), 히스토리 크기 상한, 텍스트는 표시 전용(코드 실행 없음).
- [ ] (참고) 공유 파일엔 **측정 데이터가 아니라 기기 이름/메타만** 담기므로 라이선스 문제 없음.
### M10 — 멀티 AI 프로바이더 (확장, +1~2일) · MVP 이후
> 기본은 **Claude 단일**. 향후 OpenAI(ChatGPT)/Gemini를 사용자가 선택하도록 확장.
> EqDelta JSON 스키마가 provider 중립적이라 어댑터만 추가하면 됨.
- [x] (선구현) `IAiEqProvider` 추상화 + `AiProviderFactory`(AppSettings 기반).
- [x] (선구현) 어댑터: **Claude(tool use) / OpenAI(function) / Gemini(json) / Ollama(json, 로컬)**.
- [ ] 설정 화면(M8)에 **provider 선택 + provider별 API 키** 저장(DPAPI).
- [ ] provider별 구조화 출력 신뢰도/프롬프트 미세조정 검증.
### M11 — Peace 벤치마킹 기능 (확장)
> 모델/렌더러/서비스는 **선구현됨**. 남은 건 UI·배선.
- [x] (선구현) **크로스피드 / 좌우 프리앰프·밸런스 / 베이스부스트** 모델(`EffectsConfig`) + APO 렌더 + `.tweq` 저장.
- [x] (선구현) 이펙트 **조절 UI**(`EffectsWindow`: 크로스피드/베이스부스트/좌우 트림, 라이브 적용) + **AI 자연어 제어 선구현**(effects 스키마·파서·적용: 크로스피드/밸런스/베이스).
**크로스피드 렌더는 플레이스홀더**`ApoRenderer` 메모대로 저역통과+딜레이 정식 구현 필요.
- [x] (선구현) **명령 창**(`CommandWindow`) — APO 설치 시 config 폴더에 `custom_apo.txt` 저장(config.txt Include 안내).
- [x] (선구현) **핫키**: Ctrl+Alt+B=바이패스, Ctrl+Alt+[ / ]=프리셋 이전/다음. [ ] 사용자 바인딩 UI.
- [x] (선구현) **프리셋 라이브러리**(`PresetLibrary` + `PresetLibraryWindow` UI: 저장/목록/불러오기/삭제). [ ] 핫키 전환.
### M12 — 앱/장치 자동 전환 (확장)
- [x] (선구현) `ForegroundAppWatcher` + `SwitchRule`/`SwitchRuleEvaluator`(순수).
- [x] (선구현) **`ProfileSwitcher`(watcher→evaluator→프리셋 적용) + `SwitchRulesStore` + `SwitchRulesWindow`(규칙 관리 UI)** + 설정 진입 + `AutoSwitchEnabled`.
- [x] (선구현) **장치 변경 감지**(`DefaultDeviceWatcher`) → 앱+장치 모두 규칙 매칭. [ ] (dev) 런타임 규칙 리로드, (AI 결합) 자연어 규칙 생성.
### M13 — 이펙트 확장 (향후)
- [ ] **가상 서라운드 / 리버브** 렌더링(`EffectsConfig`에 자리만 있음). '정확도' 컨셉과 분리된 '이펙트' 영역으로.
> 스피커 확장(스피커 모드/룸 보정)은 **범위에서 제외**한다(측정 기반이 정석인데 그 트랙은 진행 안 함).
### M14 — 시스템 볼륨 / 출력장치 제어 (선구현)
- [x] (선구현) `SystemVolumeService`(NAudio Core Audio): 출력장치 목록 + 장치별 **볼륨/뮤트** +
**Windows 볼륨 변경 → 앱 동기화**(`OnVolumeNotification`, 양방향).
- [x] (선구현) `VolumePanel` UI(그래프 옆): 장치 선택 + 세로 볼륨 슬라이더 + 뮤트 + % 표시.
- [~] `DefaultDeviceSwitcher`(IPolicyConfig): ⚠️ **미검증 COM vtable이 오디오 손상 유발 → 호출 제거함. 재도입 금지.**
- [x] (dev) NAudio 볼륨 확인. **하드웨어/디지털(APO) 하이브리드 볼륨** 구현(라인아웃 DAC 대응). [ ] 라인아웃 DAC 볼륨 UX 추후 재검토(PROGRESS.md).
### M15 — 로컬 AI(오프라인) + AI 관리 (선구현)
- [x] (선구현) **AI 관리 창**(`AiManagerWindow`): 활성 제공자/모델 선택(클라우드+로컬) + 로컬 런타임
자동설치 + 모델 다운로드 진행률 + **저장공간 경고(개당 2~8GB, 다수/대형 모델 시 수십~수백 GB)**.
- [x] (선구현) `WingetInstaller`(winget silent) — **Ollama 전용**(무인 자동화 확실). `OllamaService`(감지/목록/`/api/pull`). `DiskInfo`.
- [x] (선구현) 설정→'AI 관리' 진입 + `AppSettings.AiProvider/AiModel` 저장.
- [x] (선구현) **클라우드 계정 모델 동적 조회**(`CloudModelLister`): 저장된 키로 Claude/OpenAI/Gemini의
list-models API 호출 → 계정별 사용 가능 모델 드롭다운. 실패/키없음 시 기본 목록 + 직접 입력.
- [ ] (dev) **`OllamaProvider`(IAiEqProvider) 어댑터** — 선택 로컬 모델로 EQ 생성(+GBNF/JSON 스키마 제약).
- [ ] (dev) 프롬프트창이 `AppSettings`의 제공자/모델을 사용하도록 배선(M4/M10 연동).
- [ ] (dev) Ollama 사일런트 폴백(`OllamaSetup.exe /VERYSILENT`, winget 부재 시).
- [ ] **추후 테스트 후보**(자동화·헤드리스 무인 운용 검증되면 UI에 추가): **LM Studio, GPT4All, Jan, LocalAI, llamafile**.
※ 초보자 친화 목표상, 검증 전엔 노출하지 않는다. (코드 메모: `LocalRuntime.cs`)
## 공수/토큰 추정
- **시간(파트타임):** MVP(M0~M6 + M8 설정/키 필수) ~**6~8.5일**.
- **+ M9 공유(1일)** + **M7 인터랙티브 편집(+1.5~2.5일)** + **M10 멀티 프로바이더(+1~2일)**
+ **M11~M13(Peace 기능·자동전환·이펙트/스피커): 코어 선구현, UI/배선 +2~4일** → 전체 ~**11~18일**.
- **개발 토큰(Claude 페어프로그래밍):** MVP+M8 ~**0.7M~1.5M** + M9 ~**0.15M~0.3M** + M7 ~**0.2M~0.4M** + M10 ~**0.15M~0.3M**.
- **런타임 토큰:** EQ 요청당 **2~5k**(무시 가능).
## 미결정/결정 필요
- [ ] 저권한 최종 방식: `%APPDATA%` 절대경로 Include vs config폴더+ACL (M0 스파이크로 확정).
- [ ] 차트 라이브러리 최종: LiveCharts2(예쁨) vs ScottPlot(가벼움). 기본=LiveCharts2.
- [ ] 음성 입력(🎤) 포함 시점: MVP 이후 확장(Whisper/Windows STT).
- [ ] 다중 출력 장치별 프로파일: MVP 이후.
- [ ] 인터랙티브 편집(M7) 구현 방식: 커스텀 Canvas 컨트롤 vs LiveCharts2 오버레이(착수 시 확정).
- [ ] 강조색 프리셋 목록 확정(기본=틸/시안) + '윈도우 강조색 추종' 옵션 여부.
- [ ] `.tweq` 확장자/포맷 버전 정책(향후 호환) 확정.
- [ ] M10(멀티 프로바이더)은 MVP 이후 확장으로 확정 — AI 호출부는 M4부터 `IAiEqProvider`로 추상화.
- [ ] 제품명 **확정: Dansori EQ**(표시) / 코드 식별자 **DansoriEQ**.
## 리스크
| 리스크 | 완화 |
|---|---|
| APO Include 절대경로 미지원 | config폴더+ACL 방식 폴백(둘 다 저권한 만족) |
| AutoEQ 소스 라이선스 변동 | manifest에 소스별 license/distributable 기록, restricted 격리 |
| 민감 IEM에서 EQ 후 클리핑 | Preamp 자동 안전값(음수) 강제 |
| API 키 노출 | DPAPI로 로컬 암호화 저장, 로그 미출력 |
| LiveCharts2 노드 편집 폴리시 부족(M7) | 커스텀 Canvas 컨트롤/오버레이로 구현 |
| 라이트 테마에서 그래프 색 어색 | 그래프 색을 테마·강조색 리소스에 바인딩 |
| 그래프 드래그 시 APO 파일 쓰기 폭주 | 쓰로틀/디바운스, 드래그 종료 시 적용 |
| 신뢰 불가한 공유(.tweq) 가져오기 | 스키마 검증·값 클램프·크기 상한, 텍스트 표시 전용 |
| 공유 파일 버전 불일치 | format/version 필드로 하위호환 처리, 미지원 시 안내 |
| API 키 평문 노출 | DPAPI 암호화, 로그·공유파일에 키 미포함 |
## 참고 소스
- AutoEQ: github.com/jaakkopasanen/AutoEq (results = APO ParametricEQ.txt)
- squig.link(향후 추가 소스 후보), oratory1990(측정)
- Equalizer APO 문서: sourceforge.net/projects/equalizerapo (config 문법/Include)
- WPF-UI: github.com/lepoco/wpfui · LiveCharts2: livecharts.dev