# PREBUILT — 토의 세션에서 미리 생성한 코드

> 목적: **토큰 부하가 큰 작업을 개발 세션 밖에서 선(先)생성**해 두어, 개발 세션은
> "컴파일·검증·연결"만 하도록 함. 아래 파일들은 **미검증(컴파일 안 해봄)** 상태다.
> 반드시 dev 세션에서 `dotnet build` 후 오류를 잡을 것.

## 생성된 파일과 상태
| 파일 | 대응 | 신뢰도 | 비고 |
|---|---|---|---|
| `src/DansoriEQ.Core/Eq/FilterType.cs` | M3 | 높음 | 순수 로직 |
| `src/DansoriEQ.Core/Eq/Filter.cs` | M3/M5 | 높음 | **RBJ Cookbook 수학** — 단위테스트 권장 |
| `src/DansoriEQ.Core/Eq/EqState.cs` | M3 | 높음 | |
| `src/DansoriEQ.Core/Eq/FrequencyResponse.cs` | M5 | 높음 | 그래프용 로그축 샘플링 |
| `src/DansoriEQ.Core/Eq/PreampCalculator.cs` | M3/M4 | 높음 | 클리핑 방지 |
| `src/DansoriEQ.Core/Eq/ApoRenderer.cs` | M3 | 높음 | EqState → APO config 텍스트 |
| `src/DansoriEQ.Core/Ai/EqDelta.cs` | M4 | 높음 | AI 구조화 출력 모델 |
| `src/DansoriEQ.Core/Ai/EqPromptBuilder.cs` | M4 | 중간 | **시스템 프롬프트/툴 스키마 — 여기서 튜닝** |
| `src/DansoriEQ.App/Controls/EqGraphControl.cs` | **M7** | 중간 | **최대 토큰 싱크**. WPF API 검증 필요 |
| `src/DansoriEQ.App/MainWindow.xaml`(+cs) | M1/M5 | 중간 | 플레인 WPF 레이아웃(목업 재현) |
| `src/DansoriEQ.App/App.xaml`(+cs), `*.csproj` | M1 | 높음 | 프로젝트 뼈대 |
| `src/DansoriEQ.Core/Profiles/DbInfo.cs` | M2 | 높음 | DB 정보 DTO(+표시 헬퍼) |
| `src/DansoriEQ.Core/Profiles/IProfileDbService.cs` | M2 | 높음 | DB 서비스 계약(GetInfo/UpdateAsync) |
| `src/DansoriEQ.App/Design/DesignProfileDbService.cs` | M2 | 높음 | **디자인 스텁**(샘플 데이터/모의 업데이트) |
| `src/DansoriEQ.App/DbManagerWindow.xaml`(+cs) | M2 | 중간 | **DB 관리 팝업**(현재 상태·출처·업데이트 진행) |
| `src/DansoriEQ.Core/Security/ISecretStore.cs` | M8 | 높음 | 암호화 저장 계약 |
| `src/DansoriEQ.App/Security/DpapiSecretStore.cs` | M8 | 높음 | **DPAPI 암호화**(평문 저장 안 함) · ProtectedData 패키지 |
| `src/DansoriEQ.Core/Ai/ProviderKeys.cs` | M8/M10 | 높음 | claude/openai/gemini 키 상수 |
| `src/DansoriEQ.App/Controls/ApiKeyRow.xaml`(+cs) | M8 | 중간 | 입력 ↔ "이미 입력됨" 상태 전환 |
| `src/DansoriEQ.App/SettingsWindow.xaml`(+cs) | M8 | 중간 | **설정 화면**(3사 API 키 입력) |
| `src/DansoriEQ.Core/Presets/EqPreset.cs` | M9 | 높음 | `.tweq` 모델 |
| `src/DansoriEQ.Core/Presets/PresetSerializer.cs` | M9 | 높음 | 직렬화/검증/EqState 변환 |
| `src/DansoriEQ.App/PresetInfoWindow.xaml`(+cs) | M9 | 중간 | 가져오기 정보 미리보기 + **DB 매칭 상태** |
| `src/DansoriEQ.Core/Profiles/AutoEqParser.cs` | M2 | 높음 | ParametricEQ.txt → EqState 파서 |
| `src/DansoriEQ.Core/Profiles/ProfileRef.cs` | M2 | 높음 | 매칭용 프로파일 참조 |
| `src/DansoriEQ.Core/Ai/ClaudeClient.cs` | M4 | 중간 | **Anthropic Messages API(tool use)** — 키 없으면 미실행 |
| `src/DansoriEQ.Core/Ai/EqDeltaApplier.cs` | M4 | 높음 | AI delta → EqState 적용 |
| `src/DansoriEQ.Core/Apo/IApoWriter.cs` | M3 | 높음 | APO 쓰기 추상화 |
| `src/DansoriEQ.App/Apo/*.cs` | M3 | 중간 | Locator/IncludeWriter(실제)/NullWriter(미리보기)/Factory |
| `src/DansoriEQ.App/AppSettings.cs` | M3 | 높음 | APO 경로 등 설정 저장(settings.json) |
| `src/DansoriEQ.App/Apo/ApoInstaller.cs` | M3/M6 | 중간 | 공식 설치파일 다운로드·실행(무인설치 불가) |
| `src/DansoriEQ.App/ApoSetupWindow.xaml`(+cs) | M3/M6 | 중간 | 시작 시 APO 없으면: **자동설치/경로설정/미리보기** |
| `tests/DansoriEQ.Core.Tests/*` | 품질 | 높음 | **단위테스트**(Filter 수학·AutoEqParser·PresetSerializer·ApoRenderer 이펙트) |
| `src/DansoriEQ.Core/Eq/EffectsConfig.cs` | M11 | 높음 | 크로스피드·밸런스·베이스부스트 |
| `ApoRenderer.cs` (이펙트 오버로드) | M11 | 높음 | EQ+이펙트 렌더 (**크로스피드=플레이스홀더**, 파일 메모) |
| `src/DansoriEQ.App/EffectsWindow.xaml`(+cs) | M11 | 중간 | **이펙트 조절 UI**(라이브) |
| `src/DansoriEQ.Core/Presets/PresetLibrary.cs` | M11 | 높음 | 로컬 프리셋 저장/목록/불러오기 |
| `src/DansoriEQ.App/PresetLibraryWindow.xaml`(+cs) | M11 | 중간 | **프리셋 라이브러리 UI** |
| MainWindow **도움말 드로어** + `ApiKeyRow` 발급 링크 | M6 | 중간 | **온보딩 도움말**(오른쪽 슬라이드) + API 키 발급 공식 링크 |
| `src/DansoriEQ.App/Audio/SystemVolumeService.cs` | M14 | 중간 | NAudio 장치별 볼륨/뮤트 + **Windows 볼륨 동기화** |
| `src/DansoriEQ.App/Audio/DefaultDeviceSwitcher.cs` | M14 | 낮음 | 기본 출력 전환(**undocumented COM**, 검증 필요) |
| `src/DansoriEQ.App/Controls/VolumePanel.xaml`(+cs) | M14 | 중간 | 그래프 옆 볼륨/장치 컨트롤 |
| `src/DansoriEQ.Core/Ai/LocalRuntime.cs` | M15 | 높음 | 로컬 런타임 레지스트리(**Ollama 전용**; 후보는 코드 메모) |
| `src/DansoriEQ.App/Ai/WingetInstaller.cs` | M15 | 중간 | winget 사일런트 설치 |
| `src/DansoriEQ.App/Ai/OllamaService.cs` | M15 | 중간 | Ollama 감지/모델목록/pull 진행률 |
| `src/DansoriEQ.App/Ai/DiskInfo.cs` | M15 | 높음 | 모델 드라이브 여유 공간 |
| `src/DansoriEQ.App/AiManagerWindow.xaml`(+cs) | M15 | 중간 | **AI 관리**(모델 선택·런타임 설치·저장공간 경고) |
| `src/DansoriEQ.App/Ai/CloudModelLister.cs` | M15 | 중간 | 클라우드 **계정 모델 목록** 동적 조회(Claude/OpenAI/Gemini) |
| `.../Ai/IAiEqProvider.cs` + `EqDeltaParser.cs` | M4/M10 | 높음 | provider 추상화 + 공유 JSON 파서 |
| `.../Ai/OpenAiProvider.cs`·`GeminiProvider.cs`·`OllamaProvider.cs` | M10 | 중간 | 클라우드/로컬 어댑터(모두 `IAiEqProvider`) |
| `src/DansoriEQ.App/Ai/AiProviderFactory.cs` | M4 | 높음 | 활성 provider 생성(AppSettings+키) |
| MainWindow **AI 프롬프트 실배선** + 편집 디바운스 | M4/M7 | 중간 | 프롬프트→provider→적용, Preamp 자동 재계산 |
| `src/DansoriEQ.App/Input/HotkeyManager.cs` | M11 | 중간 | 전역 핫키(Win32) |
| `src/DansoriEQ.App/CommandWindow.xaml`(+cs) | M11 | 중간 | 원시 APO 명령 입력 |
| `src/DansoriEQ.Core/Switching/*` | M12 | 높음 | 자동전환 규칙·평가(순수) |
| `src/DansoriEQ.App/Switching/ForegroundAppWatcher.cs` | M12 | 중간 | 포그라운드 앱 감지(Win32) |
| `.../Switching/ProfileSwitcher.cs`·`SwitchRulesStore.cs` | M12 | 중간 | 자동전환 서비스 + 규칙 저장 |
| `src/DansoriEQ.App/SwitchRulesWindow.xaml`(+cs) | M12 | 중간 | 자동전환 규칙 관리 UI |
| MainWindow **바이패스 핫키(Ctrl+Alt+B)** + '활성' 토글 | M11 | 높음 | EQ 켜기/끄기 |
| **프리셋 전환 핫키**(Ctrl+Alt+[ / ]) · **연결 테스트** · **명령창→APO config** | M11/M8 | 중간 | 소소한 배선 |
| `src/DansoriEQ.App/Profiles/SqliteProfileDbService.cs` | M2 | 중간 | **실제 SQLite 저장소**(스키마·검색·로드·업서트·AutoEq import) |
| MainWindow **되돌리기/리셋**(Undo 스택 + 베이스) | M4/M7 | 높음 | 편집 실행취소·초기화 |
| `.../Switching/DefaultDeviceWatcher.cs` | M12 | 중간 | 기본 출력장치 변경 감지(NAudio) → 장치 규칙 |
| 이펙트 **AI 자연어 제어** + 자동전환 **런타임 규칙 리로드** | M11/M12 | 중간 | effects 스키마·파서·적용 |
| `README.md` | M6 | 높음 | 프로젝트 개요·빌드·기능 |

## 지금 시점의 동작 범위
- **컴파일만 하면** Core(순수 C#) + WPF 앱이 떠서, **데모 EQ가 그래프에 그려지고**
  노드를 **드래그/휠/더블클릭/우클릭으로 편집**하는 M7 인터랙션이 동작하도록 작성됨.
- **DB 업데이트 버튼** → **DB 관리 팝업**이 뜨고, `DesignProfileDbService` 스텁 데이터로
  **현재 상태·출처(배포가능/제한 배지)** 표시 + **모의 업데이트 진행바**가 동작함.
- **⚙ 설정** → 설정 창: Claude/ChatGPT/Gemini **API 키 입력**. 저장 시 **DPAPI 암호화**되어
  `secrets.dat`에 저장되고 화면은 **"이미 입력되어 있음"(값 숨김)** 으로 전환. 삭제도 가능.
  (provider *선택* 로직은 M10 확장 — 지금은 입력/저장만.)
- **↥ 내보내기 / ↧ 가져오기** → `.tweq`(JSON) 저장/열기. 가져오기 시 **정보 미리보기 창**
  (대상 기기·히스토리·노트 + **로컬 DB 자동 매칭 상태**) 후 적용. 매칭 실패 시 **"DB 업데이트" 안내**.
  (내보내기의 대상/히스토리는 M2/M4 연결 전까지 데모값)
- **시작 시 APO 탐색**: APO가 없으면 `ApoSetupWindow`가 떠서 **① 자동설치(공식 설치파일 다운로드·실행)
  ② config 폴더 직접 지정 ③ 미리보기로 계속** 중 선택. 경로 지정 시 `settings.json`에 저장되어
  다음부터 실제 쓰기로 동작.
- **APO 미설치 환경**: `NullApoWriter`가 생성된 APO config를
  `%LOCALAPPDATA%\DansoriEQ\preview_apo_config.txt`에 써서 **파이프라인을 검증**할 수 있음.
  창 제목에 "APO 미설치(미리보기 모드)" 표시.
- **아직 없는 것(연동/배선)**: DB **실제 SQLite/AutoEQ 다운로드**(M2 — 파서는 있음, 스텁 교체),
  **AI 프롬프트창 → ClaudeClient → EqDeltaApplier → 적용** 배선 + 키 주입(M4),
  **APO 실제 적용 검증**(이 PC 미설치라 미리보기로 대체), ViewModel/바인딩, 테마 전환(M5), 마감(M6).
- **교체 지점**: `IProfileDbService` 실제 구현(SQLite) + 프롬프트창에 `ClaudeClient`(키는 `DpapiSecretStore.Load`) 연결.

## 개발 세션 착수 절차
1. 솔루션 생성:
   ```
   dotnet new sln -n DansoriEQ
   dotnet sln add src/DansoriEQ.Core/DansoriEQ.Core.csproj
   dotnet sln add src/DansoriEQ.App/DansoriEQ.App.csproj
   dotnet sln add tests/DansoriEQ.Core.Tests/DansoriEQ.Core.Tests.csproj
   dotnet build
   dotnet test        # 단위테스트 3종 실행 (Filter 수학·AutoEqParser·PresetSerializer)
   ```
2. 컴파일 오류 수정(특히 `EqGraphControl.cs`의 WPF 시그니처, XAML 네임스페이스).
3. `App.csproj` 주석의 NuGet 패키지(WPF-UI/LiveCharts2/CommunityToolkit.Mvvm/Microsoft.Data.Sqlite)
   버전 핀 후 추가. **그다음** MainWindow 루트를 `ui:FluentWindow`로 승격 + 테마 적용.
4. DEV_PLAN M0(스파이크) → M2(DB) → M3(APO IO) → M4(AI) 순으로 살 붙이기.

## 검증 우선순위(컴파일 후)
1. **`Filter.cs` 단위테스트**: 예) Peaking Fc=1k, +6dB, Q1 → `GainDbAt(1000)` ≈ +6.0.
   Low/High shelf도 통과 대역에서 목표 dB 근사 확인.
2. **EqGraphControl** 시각 확인: 데모 EQ 곡선 모양, 노드 드래그시 Fc(x)/Gain(y) 반영, 휠=Q.
3. **ApoRenderer** 출력이 APO 문법과 일치하는지 실제 `config.txt`에 붙여 확인.

## 주의(리스크)
- `EqGraphControl`은 **컴파일 안 해본 WPF 코드**다. `OnMouseDoubleClick` 등 시그니처,
  `StreamGeometry`/`DrawingContext` 사용을 dev 세션에서 확인·수정할 것.
- `MainWindow.xaml`은 **플레인 WPF**(WPF-UI 미사용)로 작성해 단독 컴파일 가능. 예쁜 Fluent는
  WPF-UI 추가 후 재적용.
- 프롬프트(`EqPromptBuilder`)는 실제 호출로 **EQ 품질을 반복 검증**하며 문구를 다듬을 것.
