feat: restore legacy drag events and Tornado launch integration
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
# LegacyParityApp 이관 검증 증적 — 2026-07-15
|
||||
|
||||
이 문서는 현재 `MBN_STOCK_WEBVIEW.LegacyParityApp`의 구현·통합 최종 검증 결과를
|
||||
한곳에 모은다. 원본
|
||||
이 문서는 현재 `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`은 모든 조사와 테스트에서 읽기 전용으로
|
||||
취급했다.
|
||||
|
||||
@@ -15,23 +18,79 @@
|
||||
| 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로 연결 |
|
||||
| 전용 입력 | GraphE, FSell, VI, PList, AList, ThemeA, EList를 WebView 화면과 C# intent로 연결; ThemeA exact-title 중복확인 포함 |
|
||||
| 해외 | UC5 해외업종·해외종목·해외지수 조회와 playlist 생성 |
|
||||
| playlist | 단일/Ctrl/Shift 선택, enabled, 위/아래, 선택/전체 삭제, drag/batch 경계 |
|
||||
| FarPoint 대체 | Web table로 표현하되 원본 클릭·더블클릭·정렬·이동·저장 이벤트 의미 유지 |
|
||||
| playlist | 단일/Ctrl/Shift 선택, enabled, 위/아래, 선택/전체 삭제와 비연속 다중 선택 block drag; PREPARED/PROGRAM/pending/unknown 변경 차단 |
|
||||
| FarPoint 대체 | Web table로 표현하되 원본 클릭·더블클릭·정렬·이동·저장, 탭 dragover 교환과 UC6/EList opaque 행 drag 의미 유지 |
|
||||
|
||||
상세 이벤트 대조는 [`OPERATOR_UI_PARITY.md`](OPERATOR_UI_PARITY.md)를 따른다.
|
||||
|
||||
### 이벤트·drag·중복확인 구현 증적
|
||||
|
||||
줄 단위 원본 근거는
|
||||
[`LEGACY_DESIGNER_EVENT_PARITY_AUDIT.md`](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`](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 내용도 변하지 않았다.
|
||||
|
||||
## 송출 흐름과 장면
|
||||
|
||||
| 항목 | 결과 |
|
||||
@@ -54,6 +113,7 @@
|
||||
| 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을
|
||||
@@ -71,54 +131,50 @@
|
||||
누락 자산은 Git 또는 MSIX에 임의로 넣지 않는다. 제공되면 같은 trusted-root,
|
||||
0-byte, reparse, root-escape 검사를 통과한 뒤 해당 scene만 다시 검증한다.
|
||||
|
||||
## 개발 Tornado2와 PGM 실측
|
||||
## 2026-07-15 Tornado2 Live 연결 실측
|
||||
|
||||
2026-07-15 개발 Tornado2 `2.7.5.49 x64 DSX10.0 S.R2`의 단일 `30001/tcp`
|
||||
listener와 K3D x64 등록·라이선스를 고정한 뒤, 설치된 MSIX package-context 앱에서 다음
|
||||
시퀀스를 실행했다.
|
||||
아래 시각은 개발 장비 로컬 시간(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건**이다.
|
||||
|
||||
1. 삼성전자 검색 → `5001` playlist 추가
|
||||
2. 원본과 같은 fixed leaf **더블클릭**으로 VI 수동 목록 9종목 조회 → `5074` 2페이지 추가
|
||||
3. `PREPARE 5001 page 1` → `TAKE IN` → `OnScenePlayed` → 자동 갱신 정확히 1회
|
||||
4. `NEXT`로 다음 playlist 항목 `5074 page 1/2` → 자동 갱신 정확히 1회
|
||||
5. 같은 scene `Page NEXT`로 `5074 page 2/2`의 마지막 4종목 송출
|
||||
6. `TAKE OUT All` → `IDLE` → 정상 종료 확인 → `BYE`
|
||||
종료 후 보관한 Network Monitoring 원문은 **300,007자**, SHA-256
|
||||
`45858322F60C135858002EB6243D0474F51F1965E23D2332D397C3A3B5DB8049`다. 이 증적은 현재
|
||||
코드의 Live CONNECT/handshake/DISCONNECT 경로만 확인한다. scene load/mutation,
|
||||
PREPARE, TAKE IN, NEXT/Page NEXT, TAKE OUT 또는 PGM 화면 출력을 검증했다는 뜻이 아니다.
|
||||
|
||||
첫 실측과 화면 증적용 known-outcome 재현은 모두 `OutcomeUnknown=false`로 끝났다. 불명확
|
||||
결과 뒤 명령 재시도는 없었다. Network Monitoring 최종 원문은 1,863줄,
|
||||
299,616문자, SHA-256
|
||||
`7CDB183A2518EF47E5CC3819C2EB14C06492DE0C8E018350A0633E0FBBB5B994`다. 두 실측을
|
||||
합쳐 `LOAD_SCENE` 4/4, `BEGIN_TRANSACTION` 12/12, `VALUE_SET` 258/258,
|
||||
`VISIBLE` 568/568, `SCENE_PREPARE` 12/12, `PLAY` 10/10, `STOPAL` 2/2,
|
||||
`UNLOAD_SCENE` 4/4가 요청/성공으로 일치했고 `SCENE_PLAYED` 10회를 수신했다. 정상
|
||||
종료에서는 `BYE` 요청 1회가 기록됐고 이후 established 연결과 앱/CDP process는 0개다.
|
||||
별도의 Release DryRun 회차에서는 `--development-live`가 무시됐고 TCP 연결이 생성되지
|
||||
않았으며 Network Monitoring 최종 내용도 변하지 않았다. 이는 Debug-only bootstrap 경계를
|
||||
확인한 결과이지 Release Live 송출 결과가 아니다.
|
||||
|
||||
화면 증적은 300프레임 중 72프레임이 검은 기준 화면과 달랐다. `5001` 삼성전자 화면,
|
||||
`5074` page 1의 5종목, page 2의 4종목을 직접 확인했고 TAKE OUT 뒤 기준 검은 화면으로
|
||||
복귀했다. 프레임 원본과 Network Monitoring 원문은 실제 컷·운영자료를 Git에 넣지 않는
|
||||
정책에 따라 로컬 `artifacts/final-validation-20260715`에만 보관한다.
|
||||
## 현재 package와 범위 회귀 기록
|
||||
|
||||
## 최종 전체 회귀 기록
|
||||
|
||||
아래 값은 모든 병렬 변경과 fixed-leaf 더블클릭 회귀 테스트가 합쳐진 뒤 다시 실행한
|
||||
최종값이다.
|
||||
|
||||
| 항목 | 최종 결과 |
|
||||
| 항목 | 2026-07-15 확인 결과 |
|
||||
|---|---|
|
||||
| Debug x64 전체 빌드·테스트 | **PASS** — .NET 2,394/2,394, VS 2026 `ParityDebug|x64`, 경고 0·오류 0 |
|
||||
| Release x64 전체 빌드·테스트 | **PASS** — .NET 2,394/2,394, VS 2026 `Release|x64`, 경고 0·오류 0 |
|
||||
| Web/LegacyParity 전체 테스트 | **PASS** — 47파일, 435/435 (`Test-WebPlayout` 415 + thin-client 20) |
|
||||
| Release x64 MSIX 경로·버전 | `artifacts/final-validation-20260715/package/MBN_STOCK_WEBVIEW.LegacyParityApp_0.1.0.0_x64_Test/MBN_STOCK_WEBVIEW.LegacyParityApp_0.1.0.0_x64.msix`, `0.1.0.0`, 15,200,545 bytes |
|
||||
| 새 MSIX SHA-256·서명 | `FC4EEE1509675E643D2B4CB435E279CAC4611B28534048D9B9EE611E361E0E1F`, **Valid**, `CN=Comtrophy` |
|
||||
| 설치된 package-context 실행 | **PASS** — `Wickedness.MBNStockWebView.LegacyParity_0.1.0.0_x64__qbv3jkvsn3aj0`, DryRun 전체 흐름과 Live 개발 PGM 실행, 정상 종료 |
|
||||
| 개발 Tornado2 Network Monitoring | **PASS** — HELLO, transaction/mutation/query/prepare/play, event, unload, STOPAL, BYE와 연결 해제 확인 |
|
||||
| 개발 PGM PREPARE → TAKE IN → NEXT/Page NEXT → TAKE OUT | **PASS** — `5001` → `5074` 1/2 → `5074` 2/2 → 검은 화면 복귀 |
|
||||
| Gitea main commit/push | **PASS** — 이 최종 검증 문서를 포함한 커밋을 `origin/main`에 fast-forward push |
|
||||
| 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에 쓰기를 허용하거나 수행했다는 뜻이 아니다.
|
||||
- 개발 Tornado2/PGM은 안전 게이트를 유지한 별도 통합 검증 대상이다.
|
||||
- 현재 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 외부로 유지한다.
|
||||
|
||||
Reference in New Issue
Block a user