feat: restore legacy drag events and Tornado launch integration
This commit is contained in:
@@ -28,6 +28,16 @@ playlist, PageN과 송출 상태는 `LegacyOperatorController`의 C# snapshot이
|
||||
- 원본 `Cuts`도 읽기 전용 검증에만 사용하며 수정·복사하지 않는다.
|
||||
- 비밀번호, 라이선스, 벤더 DLL, 인증서, 실제 컷·영상·배경과 로컬 설정은 Git에 넣지 않는다.
|
||||
|
||||
## 원본 Designer 이벤트 전수 감사
|
||||
|
||||
원본 `*.Designer.cs`가 실제로 구독하는 이벤트를 전수 조사한 결과는 **186개 Designer
|
||||
구독, 화면별 중복을 합친 171개 고유 핸들러**다. 선언만 있고 Designer에서 구독하지 않는
|
||||
메서드는 수에 넣지 않았다. 171개는 `IMPL` 131, `DEAD` 20, `VISUAL` 10, `DRAG` 9,
|
||||
`SAFETY` 1로 모두 분류했다. 같은 이름의 핸들러라도 화면이 다르면 별도 바인딩으로 센다.
|
||||
|
||||
상세 원본 파일·구독 줄·분류 근거는
|
||||
[`LEGACY_DESIGNER_EVENT_PARITY_AUDIT.md`](LEGACY_DESIGNER_EVENT_PARITY_AUDIT.md)에 있다.
|
||||
|
||||
## 원본 실행 action inventory
|
||||
|
||||
동적 테마·전문가 DB 행과 전용 편집기의 데이터 행은 아래 고정 수량에 중복해 더하지 않는다.
|
||||
@@ -61,8 +71,8 @@ playlist, PageN과 송출 상태는 `LegacyOperatorController`의 C# snapshot이
|
||||
| VIList | 종목 추가·삭제·이동, 5개 단위 page, 확인 시 저장+추가+닫기 | `LegacyManualListsWorkflow` + trusted store | 원본 형식 read와 격리 write 검증 | `s5074` 전용 입력 PGM 별도 |
|
||||
| PList | 목록, 행 더블클릭 load/save, 확인, 삭제 | `LegacyNamedPlaylistWorkflow` | 개발 DB create/save/read/delete/absence PASS | 복원 항목별 scene PGM 별도 |
|
||||
| AList | 다음 코드와 프로그램명 신규 생성 | named playlist workflow에 통합 | 위 named playlist 시나리오로 PASS | 해당 없음 |
|
||||
| ThemeA | KRX/NXT 테마 생성·편집·삭제, 종목 구성·순서 | `LegacyOperatorCatalogWorkflow` | 개발 DB KRX/NXT 각 1개 PASS | scene PGM 별도 |
|
||||
| EList | 전문가 생성·편집·삭제, 추천 종목·금액·순서 | `LegacyOperatorCatalogWorkflow` | 개발 DB expert 1개 PASS | scene PGM 별도 |
|
||||
| ThemeA | KRX/NXT 테마 생성·편집·삭제, 이름 중복확인, 종목 구성·순서 | `LegacyOperatorCatalogWorkflow` + exact-title 조회 | 개발 DB KRX/NXT 각 1개 PASS | scene PGM 별도 |
|
||||
| EList | 전문가 생성·편집·삭제, 추천 종목·금액·드래그 순서 | `LegacyOperatorCatalogWorkflow` + opaque row reorder | 개발 DB expert 1개 PASS | scene PGM 별도 |
|
||||
|
||||
UC4/UC6의 결과 행은 고정 action 트리의 click handler에 버블링하지 않는다. UC4 테마,
|
||||
UC6 전문가와 UC7 거래정지는 원본처럼 **단일 클릭**으로 선택/playlist 동작을 수행하고,
|
||||
@@ -74,10 +84,10 @@ fixed/industry/comparison 트리의 원본 double-click과 독립적으로 처
|
||||
|---|---|---|
|
||||
| `Form1_Load` | 자산·DB·탭·Tornado 초기화 | WebView local UI와 C# composition root 초기화; 기본 `DryRun` |
|
||||
| `tabControl1_SelectedIndexChanged` | 탭별 최초 데이터 조회 | 10개 identity별 C# activation gate; 최초 진입 1회 load, 재진입 snapshot 유지 |
|
||||
| 탭 drag 이벤트 | 10개 탭 표시 순서 교환 | identity 기반 drag/키보드 이동; active tab·playlist 불변 |
|
||||
| 탭 drag 이벤트 | 10개 탭 표시 순서 교환 | dragover 대상 진입 시 identity와 예상 위치를 C#이 검증해 교환; 중복 전달은 no-op, active tab·playlist 불변 |
|
||||
| 검색 버튼/Enter | 종목 검색 | 원본 KOSPI→KOSDAQ→NXT 순서와 마지막 이름 일치 규칙 유지 |
|
||||
| 컷 click/double-click/drag | 원본 31컷 선택·추가 | plain/Ctrl/Shift/Ctrl+Shift와 원본 double-click 판정, batch 추가 |
|
||||
| playlist click/key/buttons | 선택, enabled, 이동, 삭제 | C# playlist authority; PREPARED/PROGRAM/pending/unknown에서 mutation 차단 |
|
||||
| playlist click/key/buttons/drag | 선택, enabled, 이동, 삭제, 다중 선택 행 이동 | 선택된 행은 원래 순서를 보존한 한 블록으로 임의 위치에 이동; C# playlist authority와 PREPARED/PROGRAM/pending/unknown mutation 차단 유지 |
|
||||
| F2/F3 | 배경 선택·없음 | trusted sibling background root만 허용; 누락·reparse·escape fail closed |
|
||||
| F8 | TAKE IN | idle이면 내부 PREPARE → TAKE IN을 한 번에 실행 |
|
||||
| NEXT | Page NEXT 또는 다음 행 | 같은 scene PageN 여부를 C#이 판정 |
|
||||
@@ -91,6 +101,8 @@ FarPoint UI는 Web table/list로 표현한다. 다음 의미는 원본과 같이
|
||||
- plain/Ctrl/Shift/Ctrl+Shift 선택과 현재 행
|
||||
- column header 정렬과 현재 표시 순서
|
||||
- 위/아래 이동, 선택/전체 삭제와 enabled 토글
|
||||
- playlist의 비연속 다중 선택을 한 블록으로 유지하는 행 drag와 임의 before/after drop
|
||||
- UC6/EList 추천 행의 opaque `rowId` 기반 drag 재정렬
|
||||
- single-click과 double-click을 컨트롤별로 구분
|
||||
- 부모 section 전체 추가는 모든 자식을 먼저 materialize한 뒤 한 번에 commit
|
||||
- 수동/지원 불가 child가 있으면 부분 추가 없이 전체 차단
|
||||
@@ -101,6 +113,34 @@ GraphE 행 double-click은 fresh DB record를 다시 확인한 뒤 한 행을
|
||||
Theme 결과 double-click은 원본의 5행 현재가 경로를 사용한다. PList 행 double-click은
|
||||
현재 save/load 모드에 맞춰 동작하며, 이름만으로 DB identity를 추정하지 않는다.
|
||||
|
||||
### drag 이관 경계
|
||||
|
||||
| 원본 동작 | Web 입력 | C# 권위와 중복 안전 |
|
||||
|---|---|---|
|
||||
| `PlayList_DragDrop/DragOver` | 내부 custom MIME와 opaque source/target `rowId`, before/after | source가 선택 행이면 현재 선택 전체를 표시 순서대로 이동한다. 체크박스에서 시작한 drag는 거부하고 PREPARED/PROGRAM/pending/unknown에서는 변경하지 않는다. |
|
||||
| `tab_DragOver/MouseDown/Move/Up` | drop을 기다리지 않고 dragover로 `hover-swap-tabs` 전송 | C# 탭 identity와 `expectedSourceIndex/expectedTargetIndex`가 현재 순서와 일치할 때만 교환하므로 같은 메시지의 중복 전달이 순서를 되돌리지 않는다. |
|
||||
| UC6 `FpSpread2.AllowDragDrop` | ThemeA/EList 편집행의 내부 custom MIME와 opaque `rowId` | 워크플로가 임의 before/after 위치를 계산한다. 존재하지 않는 ID, 같은 행, 추가 payload 필드는 strict bridge에서 거부하거나 no-op 처리한다. |
|
||||
|
||||
실제 마우스 검증에서는 playlist 행 drop이 조상 drop zone으로 버블링해 현재 선택된 컷을
|
||||
한 번 더 추가하는 문제가 드러났다. 조상은 이제 exact `legacy-selected-cuts` `text/plain`
|
||||
token만 처리하고 playlist row custom MIME와 외부 text는 무시한다. 따라서 한 row drop에서
|
||||
reorder와 cut append가 함께 발생하지 않는다.
|
||||
|
||||
체크박스 origin도 브라우저 동작을 반영해 보강했다. Chromium의 `dragstart.target`은 실제
|
||||
pointer가 체크박스에서 시작했어도 draggable 조상 행일 수 있다. pointerdown 때 checkbox
|
||||
origin row를 기억해 이어지는 dragstart를 거부하고 pointerup/pointercancel/dragend에서 지운다.
|
||||
회귀 테스트는 이 target 형태, 다중선택 보존, row MIME의 조상 무시, 외부 text 거부와 exact
|
||||
selected-cut token의 1회 처리를 DOM event 순서로 재현한다.
|
||||
|
||||
### ThemeA 이름 중복확인
|
||||
|
||||
원본 ThemeA의 `중복확인` 버튼을 `operator-catalog-name-check`로 이관했다. Web은 이름만
|
||||
`check-operator-catalog-theme-name` intent로 전송하고 KRX/NXT, 코드와 테이블 identity는
|
||||
C# workflow가 소유한다. 선택된 provider의 `SB_LIST`에 exact title parameterized
|
||||
`COUNT(*)` 조회를 한 번 수행하며 DB mutation은 실행하지 않는다. 중복, 사용 가능,
|
||||
결과 불명 상태를 구분하고, 조회 결과를 확정할 수 없으면 쓰기 없이 fail closed한다.
|
||||
원본처럼 편집 중 자기 행을 제외하지 않으므로 이름을 바꾸지 않은 행은 중복으로 판정된다.
|
||||
|
||||
## 원클릭 TAKE IN과 숨김 PREPARE
|
||||
|
||||
원본 운영 화면의 핵심 동작은 별도 PREPARE를 먼저 누르는 것이 아니라 F8/TAKE IN 한 번으로
|
||||
@@ -115,6 +155,46 @@ Theme 결과 double-click은 원본의 5행 현재가 경로를 사용한다. PL
|
||||
`hidden`이다. TAKE IN 실패·timeout·`OutcomeUnknown`이면 자동 재시도하지 않으며 성공한
|
||||
prepared ownership을 추측해 지우지 않는다.
|
||||
|
||||
## Visual Studio Development Live 시작 경계
|
||||
|
||||
공유 `MBN_STOCK_WEBVIEW.slnLaunch`와 패키지 시작 프로필은
|
||||
`MBN_STOCK_WEBVIEW.LegacyParityApp`을 명시적인 시작 프로젝트로 사용한다. 저장소의
|
||||
기본값은 계속 `DryRun`이고 이 Development Live 부트스트랩은 Release에서 적용되지 않는다.
|
||||
Development Live는 정확한 `--development-live`
|
||||
인자, Debug 빌드, `%LOCALAPPDATA%` 아래 Git 제외 승인 파일의 세 조건을 모두 만족한
|
||||
프로세스에서만 구성된다.
|
||||
|
||||
승인 파일은 정확한 다섯 속성, 최대 4096바이트, canonical JSON, exact authorization
|
||||
문자열과 독립 검수된 native/Interop SHA-256 두 개를 요구한다. 알 수 없는 속성, 중복 속성,
|
||||
reparse 경로, I/O 오류 또는 일부 환경 설정 실패는 모두 fail closed한다. Live authorization은
|
||||
process scope에서 마지막에 설정되고 `MainWindow`/engine 생성 시 한 번 캡처된다. 이 경로는
|
||||
기존 `trustedLiveOutputEnabled`, scene allowlist, asset 검사와 명령 안전 게이트를 완화하지
|
||||
않는다. 상세 절차는
|
||||
[`DEVELOPMENT_LIVE_VISUAL_STUDIO.md`](DEVELOPMENT_LIVE_VISUAL_STUDIO.md)에 있다.
|
||||
|
||||
## 2026-07-15 실제 UI·package·연결 검증
|
||||
|
||||
설치한 signed Release x64 MSIX는 **15,213,188 bytes**, SHA-256
|
||||
`357E17426C45FF516592EE0177D0F95502A98AF084759348ABC191BA5ED21FD5`다. 설치와
|
||||
package-context 실행을 확인했다. Release에 `--development-live`를 전달한 회차는 Debug-only
|
||||
gate 때문에 `DryRun`으로 남았고 Tornado TCP 연결과 Network Monitoring 변경이 없었다.
|
||||
|
||||
실제 WebView 마우스/CDP 입력의 확인 범위는 다음과 같다.
|
||||
|
||||
- `삼성` 검색 결과 **63개**, `삼성출판사` 선택, 선택한 컷 3개를 한 번의 drop으로
|
||||
playlist 3행에 추가
|
||||
- playlist multi-row block reorder와 enabled 체크박스 origin drag 차단
|
||||
- mouse release 전에 dragover로 시장 탭 순서 교환
|
||||
- EList 추천행 **5개** drag reorder. 수량 입력칸에서 시작한 실제 마우스 drag는 순서를
|
||||
바꾸지 않고, 행의 비입력 영역에서 시작한 drag만 순서를 바꾸는 것을 확인
|
||||
- ThemeA 결과 **500건**과 exact-title `중복확인` read 성공
|
||||
|
||||
별도 승인된 Development Live 회차의 장비 로컬 시간(KST) **14:28:28**에 HELLO request와
|
||||
success를 각 1회, **14:43:10**에 BYE 1회를 확인했다. scene, PREPARE, TAKE 계열, DB write는
|
||||
모두 0건이다. 최종 Network Monitoring 원문은 **300,007자**, SHA-256
|
||||
`45858322F60C135858002EB6243D0474F51F1965E23D2332D397C3A3B5DB8049`다. 이 회차는
|
||||
Live 연결/해제 경로만 검증하며 scene/PGM 방송 송출 성공을 뜻하지 않는다.
|
||||
|
||||
## PageN과 NEXT
|
||||
|
||||
| scene | page size | 규칙 |
|
||||
@@ -167,9 +247,12 @@ create/save → fresh readback → delete → absence를 통과했다.
|
||||
| GraphE | [LegacyManualFinancialWorkflow.cs](../src/MBN_STOCK_WEBVIEW.LegacyApplication/ManualFinancial/LegacyManualFinancialWorkflow.cs) | [manual-financial tests](../tests/MBN_STOCK_WEBVIEW.LegacyApplication.Tests/ManualFinancial) |
|
||||
| PList/AList | [LegacyNamedPlaylistWorkflow.cs](../src/MBN_STOCK_WEBVIEW.LegacyApplication/NamedPlaylist/LegacyNamedPlaylistWorkflow.cs) | [named-playlist tests](../tests/MBN_STOCK_WEBVIEW.LegacyApplication.Tests/NamedPlaylist) |
|
||||
| ThemeA/EList | [LegacyOperatorCatalogWorkflow.cs](../src/MBN_STOCK_WEBVIEW.LegacyApplication/OperatorCatalog/LegacyOperatorCatalogWorkflow.cs) | [catalog tests](../tests/MBN_STOCK_WEBVIEW.LegacyApplication.Tests/OperatorCatalog) |
|
||||
| Designer 이벤트 감사 | [LEGACY_DESIGNER_EVENT_PARITY_AUDIT.md](LEGACY_DESIGNER_EVENT_PARITY_AUDIT.md) | 186 subscriptions / 171 unique handlers |
|
||||
| VS Development Live | [DEVELOPMENT_LIVE_VISUAL_STUDIO.md](DEVELOPMENT_LIVE_VISUAL_STUDIO.md) | strict local authorization와 Debug-only bootstrap |
|
||||
| scene matrix | [SCENE_EQUIVALENCE.md](SCENE_EQUIVALENCE.md) | 35/35 builder, 45 alias, PageN matrix |
|
||||
| 2026-07-15 증적 | [LEGACY_PARITY_VALIDATION_20260715.md](LEGACY_PARITY_VALIDATION_20260715.md) | 최종 전체 회귀 기록란 포함 |
|
||||
| 2026-07-15 증적 | [LEGACY_PARITY_VALIDATION_20260715.md](LEGACY_PARITY_VALIDATION_20260715.md) | signed Release, 실제 UI와 제한된 Live 연결 범위 |
|
||||
|
||||
최종 Debug/Release 전체 테스트 개수, 새 MSIX SHA-256와 개발 PGM 결과는 병렬 변경을
|
||||
모두 합친 뒤 위 검증 문서에 기록했다. 이전 package 숫자나 hash를 현재 결과로
|
||||
재사용하지 않았다.
|
||||
현재 signed Release MSIX의 hash·크기·설치·DryRun 실행과 위 실제 마우스/CDP UI 범위는
|
||||
확인했다. 최종 회귀는 .NET Debug/Release x64에서 각각 **2,446/2,446**, Web Node에서
|
||||
**438/438**, Visual Studio 2026 Debug/Release x64 빌드에서 경고 0·오류 0이다. 다만
|
||||
HELLO/BYE만 수행한 Live 회차를 scene PREPARE/TAKE/PGM 성공으로 확대하지 않는다.
|
||||
|
||||
Reference in New Issue
Block a user