Files
QuantEngineByItz/docs/WBS_10_DOTNET_MIGRATION_HARDENING_2026_06_30.md
T
kjh2064 227b563ba2
WBS-9.3 - NULL Policy CI Gate / NULL Policy Validation (pull_request) Failing after 5s
Quant Engine CI/CD Pipeline / validate-core (pull_request) Failing after 8s
Quant Engine CI/CD Pipeline / validate-ui-and-storage (pull_request) Has been skipped
docs(ui): UI 표준을 MudBlazor + Interactive WebAssembly + API-First 로 전환
Fluent UI Blazor v5 / InteractiveServer 방침을 폐기하고 MudBlazor 컴포넌트 +
Interactive WebAssembly 렌더 모드 + API-First 를 신규 표준으로 확정한다.
기존 CLAUDE.md(Fluent UI)와 AGENTS.md §5b(MudBlazor)의 상충을 해소한다.

- CLAUDE.md: Framework & Design System, Component Rules, 매핑표를 MudBlazor 로 갱신
- AGENTS.md §5b: 렌더 모드 표준(Interactive WebAssembly) 신설, Server 표기 정렬
- ROADMAP_WBS.md: WBS-10 보강 문서 상호 참조 링크 추가
- WBS_10_DOTNET_MIGRATION_HARDENING: 마이그레이션 완성/상용화 로드맵 신규,
  UI 코드 전환을 WBS-A7 로 등록

코드 전환(csproj/Program.cs/.razor)은 미수행, 본 커밋은 방침 문서만 수정.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 18:03:26 +09:00

15 KiB

WBS-10 보강: .NET Core 마이그레이션 완성 & 상용화 로드맵 (2026-06-30)

본 문서는 docs/ROADMAP_WBS.mdWBS-10(.NET 엔진 고도화) 을 현 시점 실측 기준으로 재진단하고, 마이그레이션 완성과 단일 사용자 상용 운영에 필요한 잔여 작업을 재정의한다.

작성 배경: 기존 WBS-10 의 다수 항목이 완료 로 표기되어 있으나, 2026-06-30 소스 실측 결과 표기와 실제 상태 간 괴리가 확인되었다. 본 문서는 그 괴리를 정리하고 실제 잔여 작업을 추적한다.

의사결정(사용자 확정): ① 우선순위 = 마이그레이션 완성 우선, ② 산출물 = 로드맵/WBS 문서, ③ 인증 모델 = 단일 사용자 + 기본 보호.


1. Context — 왜 이 보강이 필요한가

QuantEngine 은 은퇴자산 포트폴리오 운용을 위한 결정론적 퀀트 엔진이다. canonical 권위는 여전히 Python 구현(219 파일, 24,683 lines) 에 있고, .NET 10 마이그레이션은 Core / Application / Infrastructure / Web / Tools / Tests 6개 프로젝트로 구조화되어 Phase 1(Web UI)·Phase 2(KIS 수집)까지 도달했다.

그러나 다음 세 가지 근본 결손으로 마이그레이션 완료 및 상용 기준에 미달한다.

  1. 마이그레이션 미완성 — 도메인 단일 권위가 Python 에 잔존. PipelineOrchestrator 가 실제 로직이 아닌 시뮬레이션 스텁. Python↔.NET 패리티가 일부 도메인 계산기에만 존재. GAS 공식 14건 미이관.
  2. 상용 운영 결손 — 소스에 하드코딩 시크릿 잔존, .gitignorebin/obj 누락으로 빌드 산출물 git 추적, 헬스체크·메트릭·재시도·스케줄러·운영 구성(appsettings.Production.json) 부재.
  3. 검증 공백 — KIS→스냅샷→정성매도 전 구간 E2E 와 CI 커버리지 게이트 부재.

2. 표기 vs 실제 괴리 정리 (2026-06-30 실측)

기존 WBS 기존 표기 실측 상태 괴리 / 조치
WBS-10.6 파이프라인 오케스트레이터 완료 PipelineOrchestrator.cs 가 각 단계를 Task.Delay(10) 로만 시뮬레이션. 실제 서비스 호출 없음 🔴 실질 미완성. → 본 문서 A1 로 재추적
WBS-10.9 보안 강화 완료 appsettings.jsonPassword=; 처리됨. 그러나 Program.cs:19 텔레그램 토큰 평문, Program.cs:34 DB 패스워드 폴백 평문 잔존. .gitignorebin/obj 없음 → 산출물 git 추적 🔴 부분 완료(핵심 누락). → 본 문서 P0 로 재추적
WBS-10.8 데이터 수집 오케스트레이터 TODO 실제로는 DataCollectionService.cs(KIS 수집 오케스트레이션) 구현·커밋됨. 단 파일명/구조가 WBS 기재(DataCollectionOrchestrator.cs)와 불일치 🟡 표기 미갱신. → 본 문서 A3 로 정합화
WBS-10.3~10.5 도메인/공식/하네스 패리티 완료 DomainParityTests, FormulaEngineTests, HarnessInjector 패리티 존재 확인 유효. 단 패리티 범위가 도메인 계산기에 한정 → 수집/정성매도/스냅샷은 미커버 (A2 확장)
WBS-10.7 Application 서비스 부분 완료 4개 서비스 구현 확인 유효

핵심 시사점: 기존 WBS-10 은 "완료" 표기가 실제보다 앞서 있다. 특히 보안(10.9)과 파이프라인(10.6)은 표기와 달리 실질 미완성이므로, 후속 작업은 표기를 신뢰하지 말고 본 문서의 실측 기준을 따른다.


3. 로드맵 (마이그레이션 완성 우선)

[P0 선행 게이트] 보안·위생 차단  ──►  반드시 먼저
        │
        ▼
[Track A] 마이그레이션 완성 (PRIMARY)        [Track B] 상용 안정화 (SECONDARY, 병행)
  A1 PipelineOrchestrator 실구현               B1 구성/시크릿 체계화
  A2 패리티 하네스 확장(수집·정성매도)          B2 기본 인증(단일 사용자)
  A3 데이터 수집 파이프라인 E2E 정합화          B3 헬스체크·메트릭
  A4 정성매도/스냅샷 어드민 포팅                B4 재시도(Polly)·스케줄러
  A5 GAS 잔여 14개 공식 이관                    B5 배포(Docker/CI 게이트)
  A6 SQLite→PostgreSQL 단일화 + Python 폐기     B6 통합/E2E 테스트·커버리지 게이트

마일스톤

마일스톤 구성 완료 기준
M1 위생 확보 P0 git 에서 시크릿/산출물 제거, 시크릿 외부화·회전
M2 패리티 기반 A1·A2 .NET 도메인이 Python 골든 벡터와 1:1 일치, 실 파이프라인 산출
M3 수집 자립 A3·A4·B4 .NET 단독 KIS→스냅샷→정성매도 무인 실행
M4 단일 권위 전환 A5·A6 Python 런타임 의존 제거, .NET canonical 승격
M5 상용 운영 B1~B6 단일 사용자 보호·관측·배포 체계 가동

4. WBS (작업 분해 구조)

각 항목: 목표 / 완료 판정(Acceptance) / 주요 파일 / 검증 명령.

P0 — 선행 보안·위생 게이트 (🔴 Critical, 최우선)

WBS-P0.1 빌드 산출물 git 추적 제거

  • 목표: .gitignore 에 .NET 표준 패턴(bin/, obj/, publish-output/, *.user) 추가, 추적 중 산출물 git rm -r --cached 처리.
  • 판정: git statusbin/obj 변경 미표시.
  • 파일: .gitignore.
  • 검증: git status --porcelain | grep -E 'bin/|obj/' → 0건.

WBS-P0.2 하드코딩 시크릿 제거·회전

  • 목표: Program.cs:19 텔레그램 토큰·채팅ID, Program.cs:34 DB 패스워드 폴백을 환경변수/dotnet user-secrets/appsettings.Production.json(비추적)로 이전. 노출 토큰·DB 비밀번호 회전.
  • 판정: 소스 전역 시크릿 평문 0건, 구성 누락 시 앱 기동 거부(fail-fast).
  • 파일: Program.cs, appsettings*.json, Infrastructure/TelegramSink.cs.
  • 검증: Select-String -Pattern '8734507814|C8RFlZ9f' src/dotnet -Recurse → 0건.

WBS-P0.3 git 이력 시크릿 정리 (선택)

  • 목표: 노출 토큰 회전 완료 시 이력 재작성 생략 가능. 회전 불가 시 git filter-repo 로 이력 제거 검토.
  • 판정: 회전 완료 또는 이력 정리 완료 중 택1 기록.

주의: WBS-10.9 가 완료 로 표기되어 있으나 위 P0.1·P0.2 는 미해결 상태다. 본 게이트 완료 전까지 후속 트랙 착수를 보류한다.

Track A — 마이그레이션 완성 (PRIMARY)

WBS-A1 PipelineOrchestrator 실제 구현

  • 목표: Task.Delay 시뮬레이션 제거. 7단계(수집→정규화→팩터→결정→리스크게이트→리포트→영속화)를 실제 서비스 호출로 연결.
  • 판정: 입력 스냅샷에 대해 결정 패킷 산출, 각 단계 결과가 engine_history 에 기록.
  • 파일: QuantEngine.Application/Services/PipelineOrchestrator.cs, 관련 Services/*.
  • 검증: dotnet test --filter Pipeline → 실데이터 기반 산출물 gate: PASS.

WBS-A2 패리티 하네스 확장 (수집·정성매도)

  • 목표: 기존 도메인 계산기 패리티(10.3~10.5)를 수집 정규화·정성매도·하네스 주입 전체로 확장. spec/13_formula_registry.yaml(149 공식) 기준 골든 벡터를 Python 에서 추출해 .NET 결과와 비교.
  • 판정: 핵심 공식 전부 Python 과 동일 출력(부동소수 허용오차 내), 패리티 리포트 JSON 생성.
  • 파일: QuantEngine.Core.Tests/ParityTests/, tests/golden/.
  • 검증: dotnet test --filter Parity → 전건 PASS.

WBS-A3 데이터 수집 파이프라인 E2E 정합화

  • 목표: DataCollectionService.cs(구현됨)를 기준으로 WBS 표기 정합화, kis_data_collection_v1.py 잔여 로직 완전 이관, KIS→PostgreSQL 스냅샷 E2E 검증. Naver/Yahoo 폴백 다중화 명문화.
  • 판정: .NET 단독 실데이터 수집·저장 성공, 폴백 동작 확인.
  • 파일: Application/Services/DataCollectionService.cs, Infrastructure/External/*.

WBS-A4 정성매도·스냅샷 어드민 포팅

  • 목표: qualitative_sell_strategy_v1.py, snapshot_admin_*_v1.py.NET 서비스/엔드포인트로 이관.
  • 판정: 정성매도 5팩터 confluence 결과 Python 일치, 스냅샷 승인 워크플로우가 Web UI 에서 동작.
  • 파일: QuantEngine.Core/Domain/, QuantEngine.Web/Endpoints/, Components/Pages/.

WBS-A5 GAS 잔여 14개 공식 이관

  • 목표: governance/gas_logic_migration_ledger_v1.yaml 의 TODO 14건을 .NET 포팅 + parity.
  • 판정: 원장 전 항목 status: DONE, parity 통과.
  • 파일: QuantEngine.Core/Domain/, governance/gas_logic_migration_ledger_v1.yaml.

WBS-A6 SQLite→PostgreSQL 단일화 및 Python 런타임 폐기

  • 목표: canonical DB 를 PostgreSQL 로 일원화, src/quant_engine/*.db 의존 제거, Python 런타임 도구를 .NET/Tools 로 대체.
  • 판정: 운영 경로 Python 호출 0건, 모든 데이터 PostgreSQL 단일 소스.
  • 파일: Infrastructure/Data/DbMigrator.cs, Makefile, tools/.

WBS-A7 UI 프레임워크 전환 — Fluent UI → MudBlazor + Interactive WebAssembly (2026-06-30 방침)

  • 배경: UI 표준을 MudBlazor 컴포넌트 + Interactive WebAssembly 렌더 모드 + API-First 로 전환(방침 확정). 기존 Fluent UI v5 / InteractiveServer 는 폐기. 정책은 CLAUDE.mdAGENTS.md §5b 에 반영 완료.
  • 목표:
    • csproj 패키지 교체: Microsoft.FluentUI.AspNetCore.Components* 제거 → MudBlazor 추가.
    • 렌더 모드 전환: Program.csAddInteractiveServerComponents/AddInteractiveServerRenderModeAddInteractiveWebAssemblyComponents/AddInteractiveWebAssemblyRenderMode, 클라이언트 프로젝트(QuantEngine.Web.Client) 분리.
    • App.razor: Fluent CSS/JS·FluentDesignSystemProvider 제거 → MudBlazor <MudThemeProvider>/<MudDialogProvider>/<MudSnackbarProvider> + MudBlazor.min.css/js 삽입.
    • 전체 .razor 컴포넌트의 Fluent*Mud* 치환(매핑표는 CLAUDE.md Component Mapping 참조).
    • API-First: UI 의 직접 DI 호출을 IXxxBrowserClient(HTTP) 경유로 전환, TokenRefreshHandler 패턴 적용.
  • 판정: Fluent UI 패키지/참조 0건, dotnet build 오류 0, WASM 로드 후 /quant/ 및 주요 페이지 정상 렌더, 비-API 라우트 동작 확인.
  • 주요 파일: QuantEngine.Web/QuantEngine.Web.csproj, Program.cs, Components/App.razor, Components/Layout/*.razor, Components/Pages/*.razor, 신규 QuantEngine.Web.Client/.
  • 검증: Select-String -Pattern 'Fluent' src/dotnet/QuantEngine.Web -Recurse → 0건; 브라우저에서 WASM 모드 동작 확인.

Track B — 상용 안정화 (SECONDARY, 단일 사용자)

WBS-B1 구성·시크릿 체계화

  • 목표: appsettings.Production.json(비추적), IOptions<T> + 시작 시 구성 검증(fail-fast), 연결 문자열/토큰 환경변수 표준화.
  • 판정: 개발/운영 구성 분리, 필수 구성 누락 시 명확 오류로 기동 중단.

WBS-B2 기본 인증 (단일 사용자 보호)

  • 목표: 공개 서버 노출 방어용 최소 인증 — 리버스 프록시 Basic Auth 또는 API Key 미들웨어 1종(/api/*·UI 보호). 본격 Identity/JWT 는 범위 외.
  • 판정: 비인증 요청 401, 인증 요청만 수집/조회 가능.
  • 파일: Program.cs, Endpoints/CollectionEndpoints.cs, Nginx 구성.

WBS-B3 헬스체크·메트릭

  • 목표: MapHealthChecks("/health")(liveness) + /health/ready(PostgreSQL/KIS 토큰 점검), prometheus-net 기반 기본 메트릭.
  • 판정: 배포 스크립트 헬스체크가 /health/ready 사용, 메트릭 엔드포인트 응답.
  • 파일: Program.cs, .gitea/workflows/deploy-prod.yml.

WBS-B4 재시도(Polly)·백그라운드 스케줄러

  • 목표: KIS/Naver/Yahoo HTTP 호출에 Polly 재시도·서킷브레이커, 주기적 수집을 BackgroundService(또는 systemd timer 연계)로 자동화.
  • 판정: 일시적 5xx/네트워크 오류 자동 복구, 정해진 스케줄 무인 수집.
  • 파일: Program.cs(HttpClient+Polly), 신규 Application/Services/*BackgroundService.cs.

WBS-B5 배포 (Docker/CI 게이트)

  • 목표: 멀티스테이지 Dockerfile + docker-compose.yml(app+PostgreSQL), .gitea CI 에 dotnet build+dotnet test 게이트 추가.
  • 판정: 컨테이너 로컬 기동 성공, CI 에서 테스트 실패 시 배포 차단.
  • 파일: 신규 Dockerfile, docker-compose.yml, .gitea/workflows/ci.yml.

WBS-B6 통합·E2E 테스트 및 커버리지 게이트

  • 목표: Testcontainers(PostgreSQL) 통합테스트, KIS→스냅샷→정성매도 E2E, coverlet 커버리지 임계값을 CI 게이트로 연결.
  • 판정: E2E 1건 이상 그린, 커버리지 임계 미달 시 CI 실패.
  • 파일: QuantEngine.Core.Tests/(통합/E2E), .gitea/workflows/ci.yml.

5. 개선·보완·고도화 제안 (Track A/B 외 권고)

  • 결정 재현성 감사: 동일 입력 → 동일 출력 결정론 검증을 CI 상시 게이트로 편입 (governance/adr/0003-no-llm-numeric-generation.md 정신 계승).
  • 캘리브레이션 실증 연계: spec/27_bch_calibration_runbook.yaml0/190 CALIBRATED 문제를 마이그레이션과 분리된 데이터 트랙으로 별도 추적(본 WBS 범위 밖, 링크 유지).
  • 장애 단일점 보강: Naver Cloudflare 403 폴백 경로를 Yahoo/KIS 다중화로 명문화(WBS-A3 연동).
  • 운영 가시성: 구조화 로깅에 상관관계 ID(correlation id) 추가, 수집 실행별 추적 가능화.
  • 비밀 회전 정책: KIS appkey/secret, 텔레그램 토큰, DB 비밀번호의 주기적 회전 절차를 docs/runbook.md 에 문서화.
  • WBS 표기 정합성 거버넌스: 본 문서에서 드러난 "완료 표기 vs 실측" 괴리 재발 방지를 위해, 각 WBS 완료 시 검증 명령 출력 캡처를 증빙으로 첨부하는 규칙을 강화(AGENTS.md 의 검증·증빙 강제 원칙 적용).

6. 검증 방법 (각 단계 실행 시)

  • P0: git status 산출물 미추적 확인, 시크릿 평문 grep 0건, 회전된 자격증명으로 정상 기동.
  • Track A: cd src/dotnet && dotnet test 로 패리티/단위/E2E 그린. 패리티 리포트 JSON 을 Python 출력과 diff. 운영 경로 Python 호출 0건.
  • Track B: curl /health/ready 200, 비인증 요청 401, docker compose up 기동, CI 테스트/커버리지 게이트 동작. Polly 재시도는 장애 주입 테스트로 검증.

7. 실행 순서 요약

  1. P0 선행 게이트 (WBS-P0.1~P0.3) — 보안·위생 차단. (기존 10.9 完了 표기 무시, 실측 기준 처리)
  2. Track A (A1→A2→A3→A4→A5→A6) — 마이그레이션 완성(우선).
  3. Track B (B1~B6) — 단일 사용자 상용 안정화(A 와 병행, B1·B3 조기 착수 권장).