# 원본 호환 마이그레이션 기준선 ## 결정 기존 저장소와 검증된 `Core / Infrastructure / Playout`은 유지한다. 기존 루트 WinUI 앱은 비교용 프로토타입으로 보존하고, 원본 UI와 이벤트를 먼저 재현하는 `MBN_STOCK_WEBVIEW.LegacyParityApp`을 같은 솔루션에서 병행 개발한다. WebView는 HTML 컨트롤 표시와 사용자 입력 전달만 담당한다. 검색 정책, 선택 상태, 플레이리스트 필드, 장면 alias, PageN 및 송출 상태의 권위는 C# Application 계층에 둔다. ## 기준 원본 - 읽기 전용 저장소: `C:\Users\MD\source\repos\MBN_STOCK_N` - 조사 시 HEAD: `309286309eaf20b58172247263f575753a860700` - 실제 실행 컷 목록: `MBN_STOCK_N\bin\Debug\Res\종목.ini` - 실행 컷 목록 SHA-256: `45DFB1804828F0E4A45F73D681AF0709CE5662872FAA49CFC9F7A0B940409E20` - 실행 컷 목록은 구분행 2개를 포함한 33개 물리행이며 실제 컷은 31개다. - 3번 컷은 고객 화면과 실행본을 따라 `1열판기본_시간외단일가`를 사용한다. 소스 `Res`의 `시간외종가`는 기준으로 사용하지 않는다. 원본 작업 트리에는 기존 수정이 있으므로 커밋 SHA만으로 동등성을 판단하지 않는다. 원본은 계속 읽기 전용으로 취급한다. ## 신규 프로젝트 | 프로젝트 | 책임 | |---|---| | `MBN_STOCK_WEBVIEW.LegacyApplication` | 원본 MainForm/UC 상태, 이벤트 및 업무 규칙 | | `MBN_STOCK_WEBVIEW.LegacyBridge` | 허용된 WebView 입력 intent와 표시 snapshot 계약 | | `MBN_STOCK_WEBVIEW.LegacyParityApp` | WinUI 3 창, WebView2, DB composition root, 별도 개발 MSIX | | `LegacyApplication.Tests` | 원본 이벤트 및 결과 DTO 동등성 테스트 | | `LegacyBridge.Tests` | strict JSON과 Web 권한 경계 테스트 | | `LegacyWeb.Tests` | Visual Studio에서 항상 실행되는 Web thin-client 계약 테스트 | 개발 패키지 identity는 `Wickedness.MBNStockWebView.LegacyParity`다. 운영 identity `Wickedness.MBNStockWebView`를 대체하지 않는다. ## 첫 수직 흐름 상태 구현됨: - 검색 버튼의 정확한 빈 문자열 no-op과 Enter 빈 검색 허용 - KOSPI → KOSDAQ → NXT KOSPI → NXT KOSDAQ 순서 및 DB 반환 순서 유지 - trim, 전체 정렬, 결과 제한 및 wildcard escape를 하지 않는 원본 호환 검색 - 바인드 파라미터를 통한 SQL injection 방지 - master snapshot을 이름으로 다시 순회하고 마지막 일치를 채택하는 `jongmokCode` 규칙 - 33개 물리 컷 행과 31개 display 번호 - 원본 `ClientSize 1905 x 1015`, `FixedSingle`, 최대화 불가 창 계약 - 일반/Ctrl/Shift/Ctrl+Shift 선택을 C# 상태로 처리 - 0.5초 이내, 동일 행, 동일 좌표 조건의 원본 더블클릭 판정 - 선택 컷 drag/drop과 물리 index 오름차순 추가 - 원본 7필드 플레이리스트 행과 중복 추가 허용 - NXT `1열판기본_현재가`만 허용하고 나머지는 원본 경고 표시 - PREPARE 직전 `LegacyPlaylistEntry`로 변환할 수 있는 31개 컷 행의 alias 매핑 아직 이관하지 않음: - 좌측 수동 입력 GraphE 4개 모달 - 중앙 UC1~UC7과 모든 탭 이벤트 - 플레이리스트 선택/삭제/정렬/DB 저장·불러오기 - 배경, 이동평균, Fade/Update 시간 컨트롤 - PREPARE/TAKE IN/NEXT/TAKE OUT 실제 연결 - 운영 DB write와 Tornado2/PGM 검증 미이관 버튼은 현재 disabled 상태이며, 연결 상태는 `미연결`로 명시한다. 새 앱은 Tornado2에 연결하지 않는다. ## Visual Studio 실행 1. `MBN_STOCK_WEBVIEW.sln`을 연다. 2. 솔루션 구성을 `ParityDebug | x64`로 선택한다. 3. `MBN_STOCK_WEBVIEW.LegacyParityApp`을 시작 프로젝트로 지정한다. 4. 실행한다. `PrototypeDebug | x64`는 기존 루트 앱을 배포하는 비교용 구성이다. 두 앱은 서로 다른 MSIX identity와 single-instance key를 사용한다. 기존 `Release | x64`의 자동 배포 대상은 비교용 루트 앱으로 유지한다. 호환 앱 Release는 두 패키지를 동시에 배포하지 않도록 `MBN_STOCK_WEBVIEW.LegacyParityApp` 프로젝트의 MSIX 생성 명령으로 명시적으로 만든다. ## 2026-07-15 기준선 검증 - `ParityDebug | x64`와 `Release | x64` 솔루션 빌드: 경고 0, 오류 0 - Debug/Release 각각 C# 테스트 1,980개 통과 - Core 1,383 / Infrastructure 173 / Playout 393 - LegacyApplication 17 / LegacyBridge 7 / LegacyWeb 7 - Node 기반 JavaScript syntax 및 Web 계약 테스트 7개 통과 - Release x64 개발 MSIX `0.1.0.0` 생성 및 `CN=Comtrophy` 서명 검증 - MSIX SHA-256: `D3FF9CF1F63E6BC68AA147C0ED47690FE130CF425C0276B3201F763EC5C50A4B` - 패키지 76개 항목 중 인증서, 비밀번호, 라이선스, `.t2s`, 운영 설정 파일 0개 - 패키지의 `Web/index.html`, `styles.css`, `app.js`가 소스와 byte 단위로 일치 - 별도 패키지 전체 이름 `Wickedness.MBNStockWebView.LegacyParity_0.1.0.0_x64__qbv3jkvsn3aj0`, package family `Wickedness.MBNStockWebView.LegacyParity_qbv3jkvsn3aj0` 설치·실행 성공 - 패키지 창의 실제 WebView client bounds `1905 x 1015` 확인 - 격리 WinForms ListView trace로 최초 Shift의 native 선택 `0..현재행`과 별도 pointer 목록의 `-1..현재행`, 같은 행 Shift의 native 선택 유지와 pointer 목록 clear를 확인하고 두 상태를 분리 - 실제 DB read-only 경로로 `삼성` 검색 → `삼성출판사` 선택 → `현재가` 동일 좌표 더블클릭 → 원본 7필드 플레이리스트 행 생성 확인 - 검색 시작 직후 정상 창 닫기 경합 검증에서 10초 이내 종료 및 Windows Application 오류 이벤트 0개 이 검증에서는 DB write, PREPARE, TAKE IN, NEXT, TAKE OUT 및 Tornado2 연결을 실행하지 않았다. 화면의 송출 버튼도 계속 비활성 상태다. ## 다음 이관 순서 1. 플레이리스트 row 선택·Ctrl/Shift·삭제·전체/개별 enabled 2. 중앙 탭과 UC1부터 원본 이벤트 단위로 수직 이관 3. 수동 입력 Form과 격리 DB write/read-back 4. C# playlist authority를 기존 `LegacyPlayoutWorkflow`에 연결한 DryRun PREPARE 5. 35개 scene/PageN differential trace 6. 승인된 실제 Tornado2/PGM 검증 각 기능은 원본 입력과 신규 입력의 snapshot, DB 파라미터, 플레이리스트 7필드 및 K3D trace를 비교한 뒤 완료 처리한다.