Files
MBN_STOCK_WEBVIEW/docs/LEGACY_PARITY_VALIDATION_20260715.md

13 KiB

LegacyParityApp 이관 검증 증적 — 2026-07-15

이 문서는 현재 MBN_STOCK_WEBVIEW.LegacyParityApp의 구현 증적과 지금 채택할 수 있는 검증 경계를 한곳에 모은다. 2026-07-15의 signed Release MSIX 설치·실행, 실제 마우스/CDP UI 동작과 제한된 Live 연결 실측은 아래 범위로 기록한다. 병렬 변경 전체의 최종 Debug/Release 및 Web 회귀 수는 확정했지만, scene PREPARE/TAKE IN/PGM 출력은 이 회차의 증적으로 확정하지 않는다. 원본 C:\Users\MD\source\repos\MBN_STOCK_N은 모든 조사와 테스트에서 읽기 전용으로 취급했다.

제품 형태와 권위 경계

항목 결과
제품 형태 .NET 8 / C# / WinUI 3 / Windows App SDK 1.8 / WebView2 / x64 / MSIX Windows 데스크톱 앱
웹사이트 여부 웹사이트가 아님. WinUI 3 프로세스가 패키지의 로컬 Web 자산을 WebView2로 표시
업무 권위 LegacyOperatorController의 C# 상태와 검증된 DTO가 권위
Web 경계 LegacyBridgeProtocol의 strict JSON intent allowlist; Web은 DB identity, scene alias, playlist 또는 송출 상태를 확정하지 않음
벤더 경계 COM/K3D/Tornado 구현은 IPlayoutEngine 뒤에 격리하고 STA 큐와 안전 게이트 유지
기본 송출 모드 DryRun; Live는 별도 개발 설정, 프로세스별 승인, allowlist와 명령 예산 필요
VS Development Live 정확한 --development-live + Debug + Git 제외 strict 로컬 승인 파일이 모두 맞을 때만 process-scope Live 설정; Release와 오류 경로에서는 이 bootstrap이 Live를 새로 설정하지 않음
불명확 결과 timeout/OutcomeUnknown에서 자동 재시도·반대 명령·추측 cleanup 금지

원본 UI와 클릭 이벤트

범위 현재 증적
Designer 전수 감사 원본 Designer 구독 186개, 화면별 고유 핸들러 171개를 IMPL/DEAD/VISUAL/DRAG/SAFETY로 전수 분류
업무 탭 원본 10개 탭, identity 기반 활성화와 순서 변경
종목 영역 모든 탭에서 유지되는 종목 검색, 결과, 31개 컷과 playlist 추가
고정/업종/비교 fixed 328개, 업종 44개, 비교 대상 24개와 action 9개를 폐쇄형 inventory로 고정
독립 클릭 UC4 테마, UC6 전문가, UC7 거래정지의 원본 단일 클릭과 UC4/UC6 행별 독립 처리
전용 입력 GraphE, FSell, VI, PList, AList, ThemeA, EList를 WebView 화면과 C# intent로 연결; ThemeA exact-title 중복확인 포함
해외 UC5 해외업종·해외종목·해외지수 조회와 playlist 생성
playlist 단일/Ctrl/Shift 선택, enabled, 위/아래, 선택/전체 삭제와 비연속 다중 선택 block drag; PREPARED/PROGRAM/pending/unknown 변경 차단
FarPoint 대체 Web table로 표현하되 원본 클릭·더블클릭·정렬·이동·저장, 탭 dragover 교환과 UC6/EList opaque 행 drag 의미 유지

상세 이벤트 대조는 OPERATOR_UI_PARITY.md를 따른다.

이벤트·drag·중복확인 구현 증적

줄 단위 원본 근거는 LEGACY_DESIGNER_EVENT_PARITY_AUDIT.md에 있다. 186개 구독/171개 고유 핸들러 수에는 선언만 있고 구독되지 않은 메서드를 넣지 않았다.

  • playlist drag는 opaque source/target rowId와 before/after만 Web에서 보내며, C#이 현재 선택 집합을 표시 순서대로 한 블록으로 이동한다. 체크박스 dragstart는 거부한다.
  • 시장 탭은 dragover 대상 진입 시 source/target identity와 예상 인덱스를 보낸다. C# 현재 순서가 예상값과 일치할 때만 교환하므로 같은 전달의 재처리는 no-op이다.
  • UC6의 FpSpread2.AllowDragDrop은 ThemeA/EList 편집 행의 opaque rowId 재정렬로 이관했다. Web이 DB identity나 play index를 정하지 않는다.
  • ThemeA 중복확인은 이름 하나만 strict intent로 받고 C#이 현재 KRX/NXT provider에서 exact title parameterized read를 수행한다. 불명 결과는 Indeterminate이고 write나 fallback이 없다. edit 자기 행을 제외하지 않는 원본 규칙도 유지한다.

2026-07-15 실제 마우스/CDP UI 검증

설치한 현재 Release package의 실제 WebView 화면에서 다음 운영자 입력을 확인했다.

  • 삼성 검색 결과는 63개였고 삼성출판사를 선택했다. 컷 3개를 선택한 뒤 한 번의 drop으로 playlist에 정확히 3행을 추가했다.
  • playlist 여러 행을 실제 마우스로 선택해 한 블록으로 재정렬했고, enabled 체크박스에서 시작한 drag는 행 이동을 만들지 않았다.
  • 시장 탭은 마우스 버튼을 놓기 전 dragover 대상 진입 시 순서가 바뀌었다.
  • EList 편집기에서 추천행 5개의 순서를 drag로 변경했다.
  • ThemeA 목록 500건을 불러온 상태에서 중복확인 exact-title read가 성공했다.

이 과정에서 playlist 행 drop이 조상 playlist-drop-zone으로 버블링해 아직 선택된 컷을 추가로 append하던 문제가 발견됐다. drop zone은 이제 exact legacy-selected-cuts text/plain token만 허용하고 playlist row custom MIME와 외부 text drop은 무시한다. 따라서 행 재정렬은 reorder-playlist-rows만 만들고 drop-selected-cuts를 만들지 않는다.

또한 Chromium은 체크박스를 눌러 시작한 경우에도 dragstart.target을 가장 가까운 draggable 조상 행으로 보고할 수 있어 단순 event.target.closest("input") 검사만으로는 부족했다. pointerdown 때 checkbox origin의 행 ID를 기억하고 이어지는 row dragstart를 거부하며, pointerup/pointercancel/dragend에서 상태를 지우도록 수정했다. thin-client 회귀 테스트는 이 Chromium target 형태, 다중 선택 보존, row drop의 ancestor 무시, 외부 text 거부와 exact selected-cut token의 단일 처리를 실제 DOM event 순서로 고정한다.

Development Live 시작 구성 증적

공유 .slnLaunch와 package launch profile은 LegacyParityApp을 시작 대상으로 고정한다. DEVELOPMENT_LIVE_VISUAL_STUDIO.md의 strict local authorization은 %LOCALAPPDATA% 아래 Git 제외 파일에 정확한 다섯 속성, 최대 4096바이트, canonical JSON, exact authorization 문자열과 독립 승인 native/Interop SHA-256을 요구한다. reparse, 알 수 없는/중복 속성, 파일 및 환경 설정 오류는 fail closed하며 authorization은 process scope에서 마지막에 설정된다. 이 부트스트랩은 기존 trusted Live 이중 게이트, scene allowlist, asset 검사와 timeout/OutcomeUnknown 정책을 대체하지 않는다.

실제 signed Release MSIX에 --development-live를 전달해도 compile-time Debug gate 때문에 승인 파일을 적용하지 않고 DryRun으로 실행되는 것을 확인했다. 이 Release DryRun 회차에는 Tornado TCP 연결이 없었고 Network Monitoring 내용도 변하지 않았다.

송출 흐름과 장면

항목 결과
원클릭 TAKE IN idle에서 보이는 TAKE IN/F8 한 번으로 PrepareAndTakeInAsync가 page load 1회, PREPARE 1회, TAKE IN 1회를 같은 게이트에서 수행
native PREPARE 엔지니어링 진단용 control/intent는 유지하되 운영자 UI에서는 hidden
실패 경계 PREPARE 후 TAKE IN 실패/unknown 시 prepared state 보존, 자동 재시도 없음
장면 기준선 원본 builder 35/35 inventory와 mutation/runtime 자동 기준선 통과
active alias 45개 alias의 대응 .t2s가 승인된 읽기 전용 Cuts에 존재
PageN 5·6·12개 단위, 최대 20페이지, 경계·마지막 부분 페이지·21페이지 거부 테스트
NEXT 같은 scene의 Page NEXT와 다음 enabled playlist 행 NEXT를 원본 조건으로 구분

실제 DB 검증

검증 결과
Oracle/MariaDB read-only PASS — 필수 scene selector 33/33, 전체 query 58건
GraphE write PASSINPUT_PIE, INPUT_GROW, INPUT_SELL, INPUT_PROFIT 각 create, fresh readback, delete, absence
PList/AList write PASS — named playlist 정의·항목 create/save, fresh readback, delete, absence
ThemeA KRX write PASS — create, preview/readback, delete, absence
ThemeA NXT write PASS — create, preview/readback, delete, absence
EList write PASS — expert create, preview/readback, delete, absence
ThemeA 중복확인 read PASS — 500건 목록 상태에서 현재 market의 exact title 조회; DB write 없음

개발 DB write는 총 9개 충돌 격리 시나리오다. production service/executor를 사용했으며 인증정보나 DB 원문을 출력하지 않았다. write 결과가 불명확한 경우에는 재시도와 cleanup을 하지 않는 구현·테스트 경계를 유지한다.

외부자산 판정

자산 상태 판정
45 active alias .t2s 존재 alias 준비 완료
s5006 Video\큐브배경.vrv 1개 없음 외부자산 미제공; 코드 실패 아님
s6001 국가별 영상 13개 없음 외부자산 미제공; 코드 실패 아님
sibling 배경\기본.vrv 없음 외부자산 미제공; F2/F3/default background는 fail closed

누락 자산은 Git 또는 MSIX에 임의로 넣지 않는다. 제공되면 같은 trusted-root, 0-byte, reparse, root-escape 검사를 통과한 뒤 해당 scene만 다시 검증한다.

2026-07-15 Tornado2 Live 연결 실측

아래 시각은 개발 장비 로컬 시간(KST)이다. strict local authorization을 통과한 제한된 Live 회차에서 14:28:28 HELLO request 1회와 success 1회, 14:43:10 BYE 1회를 Network Monitoring에서 확인했다. 이 회차의 scene 명령, PREPARE, TAKE 계열 명령과 DB write는 각각 0건이다.

종료 후 보관한 Network Monitoring 원문은 300,007자, SHA-256 45858322F60C135858002EB6243D0474F51F1965E23D2332D397C3A3B5DB8049다. 이 증적은 현재 코드의 Live CONNECT/handshake/DISCONNECT 경로만 확인한다. scene load/mutation, PREPARE, TAKE IN, NEXT/Page NEXT, TAKE OUT 또는 PGM 화면 출력을 검증했다는 뜻이 아니다.

별도의 Release DryRun 회차에서는 --development-live가 무시됐고 TCP 연결이 생성되지 않았으며 Network Monitoring 최종 내용도 변하지 않았다. 이는 Debug-only bootstrap 경계를 확인한 결과이지 Release Live 송출 결과가 아니다.

현재 package와 범위 회귀 기록

항목 2026-07-15 확인 결과
signed Release x64 MSIX 15,213,188 bytes, SHA-256 357E17426C45FF516592EE0177D0F95502A98AF084759348ABC191BA5ED21FD5
설치·실행 설치된 package-context 앱 실행 확인
Release --development-live Debug-only gate에 따라 무시되고 DryRun; TCP 연결과 Network Monitoring 변경 없음
실제 마우스/CDP UI 범위 삼성 63건 검색→삼성출판사→3컷 단일 drop, playlist multi-row reorder, checkbox drag 차단, tab dragover 교환, EList 5행 reorder, EList 수량 입력칸 origin drag 차단, ThemeA 500건과 중복확인 read 확인
제한된 Live Network 범위 HELLO request/success 각 1회와 BYE 1회; scene/PREPARE/TAKE/DB write 0
.NET Debug/Release x64 2,446/2,446, 실패·건너뜀 0, 경고·오류 0
Web Node 회귀 438/438, 실패·취소·건너뜀·TODO 0
Visual Studio 2026 build VS 18.7.3 / MSBuild 18.7.8, Debug·Release x64 모두 경고 0 / 오류 0

playlist drop MIME 경계, checkbox-origin drag와 EList input/button-origin drag 회귀는 thin-client DOM event 테스트로도 고정했다. 설치된 최종 Release package에서 실제 마우스로 EList 수량 입력칸에서 시작한 drag가 순서를 바꾸지 않고, 같은 행의 비입력 영역에서 시작한 drag만 5행 순서를 바꾸는 것도 확인했다. .NET Debug/Release 합계 4,892회와 Web 438회를 모두 통과했지만, scene PREPARE/TAKE/PGM을 실행하지 않은 이 Live 연결 회차를 전체 방송 송출 PASS로 확대하지 않는다.

판정 경계

  • 35/35 자동 장면 동등성은 모든 장면의 실제 PGM 출력 완료를 뜻하지 않는다.
  • 33/33 DB selector 통과는 외부 영상/배경 자산 준비를 뜻하지 않는다.
  • 개발 DB 9개 write 시나리오 통과는 운영 DB에 쓰기를 허용하거나 수행했다는 뜻이 아니다.
  • 현재 signed Release MSIX의 설치·DryRun 실행, 실제 마우스/CDP UI, .NET Debug/Release 각 2,446개와 Web 438개 회귀를 확인했다.
  • Live 증적은 HELLO/BYE만 확인한 연결 회차다. scene/PREPARE/TAKE/DB write가 0이므로 PGM 송출 또는 원클릭 TAKE IN 전체 통합 성공으로 판정하지 않는다.
  • 원본 저장소, 실제 Cuts, 라이선스와 인증정보는 계속 읽기 전용 또는 Git 외부로 유지한다.