# MBN Stock WebView

기존 `MBN_STOCK_N` WinForms 애플리케이션을 단계적으로 대체하기 위한 Windows 데스크톱 프로젝트입니다.

> 현재 유일한 개발·실행 대상은
> [`src/MBN_STOCK_WEBVIEW.LegacyParityApp`](src/MBN_STOCK_WEBVIEW.LegacyParityApp)입니다.
> Visual Studio F5, 개발 MSIX, 신규 기능과 회귀 검증은 모두 이 앱을 기준으로 합니다.

루트 `MBN_STOCK_WEBVIEW.csproj`와 루트 `MainWindow*`/`Web`은 이전 비교 프로토타입입니다.
현행 솔루션과 기본 F5 대상에서는 제외하되, 연결된 과거 비교 테스트를 별도로 정리할 때까지
참고 소스로 보존합니다. 현재 완료·제한·외부 결정 범위는
[이관 현재 기준선](docs/MIGRATION_STATUS.md)이 유일한 우선 문서이며, 문서별 용도는
[문서 안내](docs/README.md)에서 확인할 수 있습니다.

현재 기준 기술 스택은 다음과 같습니다.

- .NET 8 / C#
- WinUI 3 (XAML)
- Windows App SDK 1.8.6 (`1.8.260317003`)
- WebView2 기반 운영 UI
- Windows x64 전용
- 단일 프로젝트 MSIX

## 현재 화면/계약 구현 범위

- WinUI 3 네이티브 창과 WebView2 간 JSON 메시지 브리지
- FarPoint 플레이리스트를 대체하는 Web UI
  - 첫 열 송출 포함, 행/Ctrl+행 작업 선택
  - 드래그 정렬 및 위/아래 이동
  - 선택 삭제
  - 로컬 저장/불러오기
- Oracle/MariaDB 4개 국내 시장 종목 검색과 실행 파일 옆 `Res` INI 기반 컷/UI 구성
- 원본 자산이 있는 전체 빌드는 읽기 전용 `bin\Debug\Cuts`를 실행 파일 옆 `Cuts`로 같은 구조로 배치
- 기존 운영 흐름을 반영한 `PREPARE` / `TAKE IN` / `NEXT` / `TAKE OUT` UI
- `F8`, `Esc` 단축키와 원본 배경 선택용 F2의 안전 예약
- 원본의 공급자 비의존 SQL/데이터 요청 71개를 .NET 8 Core 프로젝트로 이관
- Oracle/MariaDB 실제 비동기 `IDataQueryExecutor`와 소스별 health/retry/timeout
- WebView 코스피·코스닥·NXT·5개 지수·해외 실데이터 조회와 장애 UI
- COM 중립 `IPlayoutEngine`, x64 K3D late binding, 전용 STA 큐와 프로세스 감시
- 네이티브 결과가 성공한 뒤에만 갱신되는 `PREPARE` / `TAKE IN` / `NEXT` / `TAKE OUT` WebView 브리지
- 지정 개발 PC의 보호된 Live 전용 기동, Test 전용 인스턴스·채널·씬 allowlist 및 Live 이중 승인 안전 게이트
- MSIX 패키지 매니페스트와 x64 게시 프로필

Oracle/MariaDB 조회 계층, 원본 10초 DB 상태 감시, Tornado/K3D 어댑터와 35개 scene 계약을 구현했습니다. 2026-07-22 현재 최신 개발 MSIX의 전체 UI/DB·로컬 상태 물리 검증과 실제 PGM runtime route code 33/34가 승인된 action 범위에서 끝났습니다. `s5006` 큐브 배경 action과 `s6001` 국가 영상 13 action만 원본에도 없는 외부 제작 자산 때문에 fail closed 상태이며, `s6001`의 두바이유·WTI·브렌트유·금 4 action은 실제 PGM 검증을 완료했습니다. 지정 개발 PC의 Debug·Release 패키지는 보호된 `Live` 설정으로만 기동하며 `DryRun`으로 폴백하지 않습니다. Live allowlist, 명령 예산, callback/`OutcomeUnknown` 게이트는 완화하지 않습니다. 이 개발 PC의 Tornado2/PGM 마이그레이션 검증은 사용자가 반복 승인 없이 진행하도록 상시 허용했으며, 적용 범위와 중단 조건은 [개발 환경 상시 권한](docs/DEVELOPMENT_ENVIRONMENT_AUTHORIZATION.md)에 기록했습니다. DB 설정은 [DB 운영 가이드](docs/DATABASE.md), 송출 설정·실제 검증 증거·롤백은 [Tornado/K3D 운영 가이드](docs/PLAYOUT.md), 원본 Scene/PageN 대조는 [송출 흐름 분석](docs/LEGACY_PLAYOUT_ANALYSIS.md), 장면별 현황은 [35개 Scene 동등성 매트릭스](docs/SCENE_EQUIVALENCE.md), 전체 412개 실행 action과 전용 편집 화면은 [운영자 UI 동등성 인벤토리](docs/OPERATOR_UI_PARITY.md)를 참고하세요.

35개 Scene/PageN 런타임과 원본 MainForm·UC1~UC7·GraphE·FSell·VIList·PList·AList·ThemeA·EList의 화면·bridge 계약은 WinUI 3/WebView2에 연결했습니다. 최신 패키지에서 실제 Windows 입력 1,838건으로 검색·키보드·컷/플레이리스트 drag·PList 모달과 화면별 버튼, 개발 DB create/save→fresh readback→delete를 검증했고 cleanup까지 확인했습니다. PList 2,213행은 모두 목록과 scene alias를 복원하며, 그중 1,617행은 fresh typed selection까지 증명됐고 596행은 식별정보 부족으로 추정 없이 보류합니다. `5077` 6행 20페이지 전체, 마지막 페이지, `5088` 12행 전환, 장기 실행 뒤 unload와 `s6001` 영상 비의존 4 action도 실제 PGM에서 확인했습니다. 고객 배포용 서명 MSIX, 외부 영상·배경 자산, 보류 596행의 DBA 결정은 아직 남아 있습니다.

## 과거 검증 자료

`1.0.5` 패키지와 날짜가 붙은 Gate·Release·Live 문서는 당시 실행의 역사적 증거입니다.
현행 완료 판정이나 새 패키지 승인으로 재사용하지 않습니다. 당시 상세 내용은
[1.0.5 패키지 감사](docs/RELEASE_1_0_5_AUDIT.md)와
[동작 동등성 작업 기록](docs/LEGACY_BEHAVIOR_PARITY_WORKLOG.md)에 보존되어 있습니다.

## Visual Studio 2026에서 실행

상사 PC처럼 기존 코더 자산과 K3D가 설치된 개발 PC에서는 별도 PowerShell 명령을 먼저 실행할
필요가 없습니다.

1. `MBN_STOCK_WEBVIEW.sln`을 엽니다.
2. 솔루션 구성을 `Debug`, 플랫폼을 `x64`로 선택합니다.
3. 공유 시작 프로필 `Legacy Parity App (VS F5)` 또는
   `src\MBN_STOCK_WEBVIEW.LegacyParityApp`을 시작 프로젝트로 선택합니다.
4. 실행 프로필이
   `MBN_STOCK_WEBVIEW.LegacyParityApp - Development Live (Package)`인지 확인합니다.
5. `F5`로 빌드·배포·실행합니다.
6. 첫 실행 설정 창에서 기존 코더의 `Cuts` 폴더와 `Res` 폴더, 두 폴더만 각각 선택하고
   `설정 시작`을 누릅니다.
7. `설정 완료`가 표시되면 창을 닫고 `F5`를 한 번 더 누릅니다.

새로 받은 clone에 아직 이 PC의 검증된 runtime 연결이 없으면, 주변에 과거
`MBN_STOCK_N\...\bin\Debug`가 있더라도 첫 F5는 안전한
**소스 전용 첫 실행 설정 앱**으로 빌드됩니다. 이 첫 프로세스는 과거 로컬 송출 프로필·환경
변수·Development Live 실행 인수를 무시하고 DB와 송출 엔진을 만들지 않으므로 설정 중에는
Tornado2/PGM에 연결하거나 명령을 보내지 않습니다. 출력과 중간 패키징 파일도 이전 전체
빌드의 `Cuts`, `Res` 또는 DB 설정을 잘못 재사용하지 않도록 `bin\SourceOnly`와
`obj\SourceOnly`에 분리됩니다.

### 기존 설치가 있는 개발 PC에서 실제 송출

상사 PC처럼 `Cuts`, `Res\MmoneyCoder.ini`, Tornado2/K3D x64와 장비 라이선스가 이미 있는
지정 개발 장비에서는 Git에 자산·DB 설정·DLL·라이선스를 넣거나 runtime ZIP을 다시 전달할
필요가 없습니다. 첫 실행 창에는 다음 두 폴더만 입력합니다.

- `Cuts`: 실제 실행 자산의 `Cuts` 폴더
- `설정/INI (Res)`: 기존 코더가 사용하는 실제 `Res` 폴더

첫 실행 설정은 두 폴더 안의 파일을 열거·파싱·복사하지 않습니다. 폴더 경로만
`%LOCALAPPDATA%\MBN_STOCK_WEBVIEW\Config\runtime-folders.local.json`에 저장하고,
같은 공통 부모를 Git 제외 `Directory.Build.local.props`에 기록합니다.
두 폴더는 같은 공통 부모 아래에 나란히 있어야 하며 폴더 이름도 각각 `Cuts`, `Res`여야
합니다. 소스 트리의 오래된 `RES`나 이름이 비슷한 백업 폴더가 아니라 기존 코더가 실제
실행에 사용하던 `bin\Debug\Cuts`, `bin\Debug\Res` 성격의 폴더를 선택합니다.

`설정 시작`은 PowerShell, `dotnet build`, DB 복사, K3D 검사 또는 Tornado2/PGM 작업을
실행하지 않으므로 즉시 완료되어야 합니다. 전체 앱 빌드는 창을 닫고 누르는 다음 F5에서
진행됩니다. 이때도 `Cuts`는 복사하지 않고 선택한 원래 경로를 직접 사용합니다.

Development Live용 DB overlay, K3D pin과 승인 파일이 아직 없는 PC는 별도의
`Initialize-ExistingDevelopmentPc.ps1` 수동 절차를 완료하기 전까지 전체 앱 기동이
차단됩니다. 첫 실행 폴더 저장은 이 보호 설정을 만들거나 변경하지 않습니다.

초기화가 성공하면 Visual Studio에서 `Debug|x64`, `Legacy Parity App (VS F5)`,
`MBN_STOCK_WEBVIEW.LegacyParityApp - Development Live (Package)`를 선택해 F5로 시작합니다.
앱이나 빌드 출력이 `SourceOnly` 또는 Live 기동 차단이라고 표시되면 송출을 시도하지 말고
Development Live 준비 상태를 확인합니다. 최초 실제 확인은 [개발 PGM 인수 절차](docs/DEVELOPMENT_LIVE_HANDOFF.md)에 따라
`5001` 하나로 진행합니다. Debug와 Release의 일반 실행은 모두 같은 보호된 Live
부트스트랩을 사용합니다. 이 프로필은 보호된 LocalAppData 설정만 읽고 상속된
`MBN_STOCK_PLAYOUT_*`·DB 환경 변수를 무시합니다. scene root는 첫 실행에서 저장한 원래
`Cuts` 경로로 고정하며 strict
검증이 실패하면 Live 엔진을 만들지 않고 명확한 기동 오류를 표시합니다.

같은 clone에서는 로컬 연결 파일이 Git에 덮어써지지 않으므로 이후에는 `git pull` 후 F5로
확인할 수 있습니다. 저장소를 새 폴더에 다시 clone하거나 자산·DB 폴더 연결이 바뀌면 첫 실행
설정을 다시 진행합니다. K3D DLL이 최초 기준과 달라진 경우에는 경로 저장을 반복해도 자동
재승인되지 않습니다. 벤더 변경을 독립적으로 검증한 뒤 두 SHA-256을 명시해 수동 교체해야
합니다. pull 뒤 Required 자산 검증이 실패하는 경우에도 F5를 계속 시도하지 말고 설정 오류를
바로잡습니다.

화면을 열 수 없는 장애 대응이나 기존 로컬 설정의 명시적 교체가 필요할 때만
`scripts\Initialize-ExistingDevelopmentPc.ps1`을 수동 도구로 사용합니다. 일반적인 새
clone 인수 절차에서는 이 스크립트를 직접 실행하지 않습니다. K3D 기준 교체의 정확한
`-ReplaceK3DPin` 절차는
[개발 PGM 인수 절차](docs/DEVELOPMENT_LIVE_HANDOFF.md#k3d-dll이-정식으로-교체된-경우)에
따릅니다.

해당 PC에 `Cuts`/`Res`가 없을 때만
`New-LegacyRuntimeBundle.ps1`과 `Initialize-LegacyRuntimeBundle.ps1`의 검증 ZIP 절차를
대안으로 사용합니다. 자세한 두 흐름은 [개발 PGM 인수 절차](docs/DEVELOPMENT_LIVE_HANDOFF.md)와
[Cuts/Res 런타임 배치](docs/LEGACY_RUNTIME_ASSETS.md)에 있습니다.

이 프로젝트는 MSIX 패키지 ID가 필요한 앱입니다. `bin` 아래의 EXE를 직접 실행하지 말고 반드시 Package 프로필이나 설치된 MSIX로 실행하세요.

기존 중복 형식 오류(`CS0121`, `CS0436`)는 루트 앱 프로젝트가 하위 Core 소스까지 다시 컴파일하던 문제였으며, 현재 `src\**\*.cs`를 앱 컴파일 대상에서 제외해 해결했습니다. Visual Studio가 이전 진단을 계속 표시하면 `빌드 > 솔루션 정리` 후 다시 빌드하세요.

## 명령줄 빌드

```powershell
dotnet restore MBN_STOCK_WEBVIEW.sln -p:Platform=x64
dotnet build MBN_STOCK_WEBVIEW.sln -c Debug -p:Platform=x64
```

K3D 등록 상태를 COM 활성화 없이 확인:

```powershell
powershell -NoProfile -ExecutionPolicy Bypass `
  -File .\scripts\Inspect-K3DRegistration.ps1
dotnet run --project .\tools\MBN_STOCK_WEBVIEW.PlayoutSmoke `
  -c Debug -p:Platform=x64 -- --probe
```

격리 Tornado TEST의 프로세스·Network Server 포트·loopback 주소·LISTEN 소유권은 COM을 열기 전에 [읽기 전용 점검 스크립트](scripts/Inspect-TornadoTestIsolation.ps1)로 확인합니다. 설치 폴더의 다른 Tornado2 버전 EXE는 현재 사용자 설정과 출력 장치를 공유할 수 있으므로 PGM 옆에서 TEST 대용으로 실행하지 않습니다.

별도 Test 인스턴스 검증은 [Tornado/K3D 운영 가이드](docs/PLAYOUT.md)의 단계별 CLI를 사용합니다. `--test-plan`은 절대 경로 로컬 JSON과 씬 자산만 확인하며 엔진/COM을 만들지 않습니다. PGM/PROGRAM이 전혀 없는 격리 출력에서만 `--test-connect`로 연결·해제를 확인한 뒤 `--test-sequence`로 `PREPARE → TAKE IN → NEXT → TAKE OUT`을 실행합니다. Test 명령은 `MBN_STOCK_PLAYOUT_*` 환경 override와 Live 설정을 거부하고 자동 재연결·재생을 하지 않습니다. 승인된 Test 씬 후보는 basename `5001`, `5006`이며 실제 자산 경로는 저장소에 기록하지 않습니다.

중요: `--probe`와 `--test-plan`은 `KTAPConnect`를 호출하지 않습니다. 정상 앱 실행은 보호된 `Live`이며 자동으로 비송출 모드로 전환되지 않습니다. CLI 절차에서는 모든 안전 게이트를 통과한 격리 `Test`의 `--test-connect`에서 처음 네트워크 기록을 기대하며, 별도로 승인된 UI Test 실행도 기록을 만들 수 있습니다. 사용할 포트는 예제 숫자가 아니라 해당 격리 Test Tornado의 `Tools > Option > Control > Network Server > TCP Port` 실값이어야 합니다.

Tornado2의 `PGM` 창은 본 프로그램의 KTAP 명령을 렌더링하는 출력 창입니다. 현재 PGM과의 네트워크 왕복만 진단할 때는 일반 Test/Live 엔진을 완화하지 않고 `--pgm-connect-diagnostic`을 사용합니다. 이 명령은 Registry64에서 계산한 x64 K3D 네이티브 DLL과 Interop이 운영자 승인 SHA-256 핀 `MBN_STOCK_K3D_NATIVE_SHA256`/`MBN_STOCK_K3D_INTEROP_SHA256`과 각각 일치할 때만 동적으로 사용하며 `KTAPConnect → Disconnect`만 한 번 수행합니다. Scene player, 장면 로드, PREPARE, PLAY, STOP 계열 API 표면은 포함하지 않으며 해시 승인 절차와 판정 방법은 [Tornado/K3D 운영 가이드](docs/PLAYOUT.md)에 있습니다.

MSIX 생성:

```powershell
dotnet build .\src\MBN_STOCK_WEBVIEW.LegacyParityApp\MBN_STOCK_WEBVIEW.LegacyParityApp.csproj `
  -c Release `
  -p:Platform=x64 `
  -p:GenerateAppxPackageOnBuild=true `
  -p:AppxPackageSigningEnabled=false
```

위 명령은 서명되지 않은 개발 패키지를 `AppPackages`에 만듭니다. 배포용 MSIX는 `Package.appxmanifest`의 `Identity/Publisher` 값과 정확히 일치하는 인증서로 서명해야 합니다. 인증서와 개인 키는 저장소에 커밋하지 않습니다.
Release MSIX는 전체 런타임 자산을 필수로 검증합니다. 원본 위치가 기본 형제 경로와 다르면
`-p:LegacyRuntimeSourceRoot="D:\path\to\MBN_STOCK_N\MBN_STOCK_N\bin\Debug"`를
추가해야 합니다.

## 구성과 보안

원본 `Res/MmoneyCoder.ini`의 값은 저장소에 복사하지 않았습니다. 전체 자산 Debug 빌드,
소스 전용 빌드, 게시와 MSIX 모두 이 자격증명 파일을 빌드 입력이나 출력으로 사용하지 않습니다.
전체 자산 Debug/MSIX는 `%LOCALAPPDATA%\MBN_STOCK_WEBVIEW\Res\MmoneyCoder.ini` 또는 기존
`database.local.json`을 사용하고, 소스 전용 빌드는 DB 미연결을 강제합니다. 일반 실행에서는
환경 변수가 선택된 파일보다 우선하지만, 검증된 Development Live 프로필은 이 override를
의도적으로 무시하고 위 LocalAppData 파일만 사용합니다. 설정 우선순위, 보안과 실제 DB 스모크 방법은
[DB 운영 가이드](docs/DATABASE.md)에 정리했습니다.

MSIX 설치 폴더는 읽기 전용입니다. 전체 자산 빌드에서는 읽기 전용 원본 `Cuts` 179개와 허용된
UI용 `Res` 파일이 실행 출력·게시·MSIX에 포함되지만, DB 자격증명 INI·백업·인증서·벤더 DLL은
포함하지 않습니다. 현재 원본에 없는 `s5006`/`s6001` 영상과 일부 배경은 별도 원본 제작 자산을
확보해야 합니다. 로그, 플레이리스트, 운영자 설정과 미리보기 파일은
`ApplicationData.Current.LocalFolder` 또는 `LocalCacheFolder`에 저장합니다.

## 프로젝트 구조

```text
src/MBN_STOCK_WEBVIEW.LegacyParityApp/ WinUI 3 / WebView2 / 원본 동작 호환 MSIX 앱
  MainWindow*.cs, Web/         네이티브 권위·보안 경계와 로컬 운영 UI
MBN_STOCK_WEBVIEW.csproj       이전 프로토타입 앱(솔루션/F5 제외, 참고용 보존)
src/MBN_STOCK_WEBVIEW.Core/    이관된 데이터 요청 및 공급자 비의존 Core
src/MBN_STOCK_WEBVIEW.Infrastructure/ Oracle/MariaDB 공급자·설정·복원력·health
src/MBN_STOCK_WEBVIEW.Playout/ x64 Tornado/K3D STA·COM 어댑터와 안전 게이트
tests/                         Core/Infrastructure/Playout 단위 테스트
tools/MBN_STOCK_WEBVIEW.DbSmoke/ 비밀값을 출력하지 않는 실제 DB 스모크
tools/MBN_STOCK_WEBVIEW.PlayoutSmoke/ COM 비활성 probe/plan과 격리 Test 연결·시퀀스 CLI
Config/                        비밀값 없는 구성 템플릿
ThirdPartyNotices/             공급자 재배포 라이선스 고지
docs/                          마이그레이션 기록과 다음 단계
```

원본 `C:\Users\MD\source\repos\MBN_STOCK_N`은 수정하거나 초기화하지 않았습니다.
