feat: advance legacy UI behavior parity
This commit is contained in:
@@ -233,7 +233,9 @@
|
||||
- Busy/고정 섹션 배치 중에는 action뿐 아니라 로컬 disclosure 변경도 차단한다.
|
||||
- MA5/MA20은 행 추가 시 저장하지 않고 s8010 PREPARE, F8, NEXT, 자동 갱신의 장면 생성 시점마다
|
||||
현재 전역 체크 상태를 다시 읽는다. named playlist identity에도 MA 플래그를 저장하지 않는다.
|
||||
- 원본의 `uc_3 == null` 부모 더블클릭 예외와 부분 추가 버그는 재현하지 않는 명시적 결함 제외다.
|
||||
- 공용 UC1의 부모 일괄 추가 중 부분 mutation은 재현하지 않는다. 다만 업종 탭의 부모는 실제로
|
||||
22개 루프 전에 `uc_3 == null` 예외가 발생해 아무 행도 추가하지 않으므로, 이 항목은 Slice 12의
|
||||
재감사 결과에 따라 실제 관찰 동작인 no-op으로 고정했다.
|
||||
|
||||
상세 근거와 결함 제외는 `docs/UC1_TREE_EVENT_PARITY.md`에 기록했다.
|
||||
|
||||
@@ -329,11 +331,198 @@
|
||||
비활성화하고 API 실패나 0 이하는 축별 4 DIP로 fail-safe한다. 실제 drop 내용은 payload가
|
||||
아니라 C#의 현재 선택 집합과 physical 순서가 계속 권위본이다.
|
||||
|
||||
## Slice 11: UC3 종목 비교 중복행과 전체 삭제
|
||||
|
||||
상태: 코드 및 자동 테스트 완료, 실제 파일·DB·Tornado 명령은 실행하지 않음.
|
||||
|
||||
원본 근거:
|
||||
|
||||
- `Control/UC3.cs:100-145` 비교쌍 추가와 `File_Save`
|
||||
- `Control/UC3.cs:147-154` 선택 행 삭제
|
||||
- `Control/UC3.cs:156-168` 전체 삭제 Yes/No
|
||||
- `Control/UC3.cs:171-183` Up/Down 저장
|
||||
|
||||
고정한 계약:
|
||||
|
||||
- 원본 `btnAdd_Click`에는 중복 검사가 없으므로 같은 두 대상을 같은 순서로 여러 번 추가할 수
|
||||
있다. 각 행은 별도 stable row ID를 가지며, 이동·선택 삭제는 그중 활성 행 하나에만 적용한다.
|
||||
- 화면의 비교 조작 표시는 원본 Designer와 같은 `◀▶`, `추가`, `UP`, `DOWN`, `DEL`,
|
||||
`DEL ALL`을 사용하고, 원본에 없던 별도 초기화 버튼은 표시하지 않는다.
|
||||
- CP949 parser/import도 같은 비교쌍의 반복을 허용하되 물리 순서, 연속 RowNumber, 최대 행 수와
|
||||
형식·인코딩 검증은 유지한다. 저장 후 재로드해도 반복 행과 순서가 보존된다.
|
||||
- `DEL ALL`은 Web의 `window.confirm`이나 직접 파일 변경으로 처리하지 않는다. C#이 정확한
|
||||
`MmoneyCoder` caption과 `모두 삭제하겠습니까?` 문구의 Yes/No 상태를 소유하며, No는
|
||||
0회, Yes는 confirmation을 먼저 소비한 뒤 정확히 1회만 mutation한다.
|
||||
- confirmation 동안에는 화면 재연결용 ready와 confirm/cancel 이외의 bridge intent를 모두
|
||||
무시한다. 이는 원본의 modal `MessageBox`가 MainForm과 다른 child action을 막던 동작을
|
||||
native 경계에서도 보장한다.
|
||||
- Yes/No bridge payload는 빈 객체만 허용하며 row ID, 종목 identity 또는 action kind를 받지
|
||||
않는다. 삭제 대상 목록의 revision이 바뀌면 저장하지 않는다.
|
||||
|
||||
재현하지 않은 원본 버그:
|
||||
|
||||
- 원본 `File_Save`는 RowCount가 0이면 파일을 쓰지 않아 마지막/전체 삭제가 재시작 뒤 되살아난다.
|
||||
새 구현은 빈 CP949 파일을 원자적으로 1회 저장해 삭제를 영속화한다. 이는 기존 one-time import와
|
||||
재시작 영속성 계약을 깨지 않기 위한 명시적 데이터 안전 교정이다.
|
||||
|
||||
## Slice 12: UC2 업종 목록·비교 입력과 업종 UC1 단일 루트
|
||||
|
||||
상태: 코드 및 자동 테스트 완료, 실제 DB/Tornado/UI 명령은 실행하지 않음.
|
||||
|
||||
원본 근거:
|
||||
|
||||
- `Control/UC2.cs:32-76` 목록 조회, 즉시 선택, double-click 회전과 텍스트 swap
|
||||
- `Control/UC2.Designer.cs:43-106` 목록 위/비교 입력 아래 배치와 편집 가능한 txt1/txt2
|
||||
- `Control/UC1.cs:154-180`, `204-220`, `330-351` 업종 루트·리프와 1열/2열 조건
|
||||
- `MainForm.cs:2966-2985` 업종 UC1을 `uc_3 == null`로 생성하는 실제 경로
|
||||
|
||||
고정한 계약:
|
||||
|
||||
- 업종 액션 트리는 원본 INI처럼 `[코스피]` 또는 `[코스닥]` 루트 하나와 원본 순서의 자식
|
||||
22개만 표시한다. 기존 Web의 인위적인 5개 그룹은 제거했다.
|
||||
- 업종 루트 double-click은 공용 UC1이 22개 루프 전에 null인 `uc_3`를 읽고 바깥 catch가
|
||||
예외를 삼키므로 실제 바이너리처럼 조용한 no-op이다. 자식 double-click만 한 컷을 추가한다.
|
||||
- 목록 single-click은 지연 없이 C# 활성행을 바꾸고, state 회신은 기존 DOM을 교체하지 않아
|
||||
같은 행의 두 번째 click과 double-click을 잃지 않는다.
|
||||
- 목록 전체가 하나의 tab stop이며 ArrowUp/Down, Home/End가 원본 ListBox처럼 활성행을 즉시
|
||||
바꾼다. 행 버튼은 개별 Tab 순서에 들어가지 않는다.
|
||||
- 화면 배치는 목록, `업종비교`, txt1/교환/txt2 순서이고 교환 버튼은 원본 `◀▶` 표기다.
|
||||
- txt1/txt2는 편집 가능하다. Web은 slot/value만 닫힌 intent로 보내며 C#의 `FirstText`와
|
||||
`SecondText`가 권위 상태를 가진다. action intent에는 입력 문자열을 섞지 않는다.
|
||||
- 목록 double-click은 수동 txt1을 txt2로 민 뒤 새 업종명을 txt1에 넣고, 교환은 한 칸만
|
||||
채워진 경우까지 두 문자열을 그대로 바꾼다. 1열판은 계속 활성 목록 행을 사용하고 2열판만
|
||||
두 편집 문자열을 사용한다.
|
||||
- 입력 state 회신은 focused input을 덮거나 workspace를 교체하지 않아 blur 직후 swap이나
|
||||
자식 double-click이 사라지지 않는다.
|
||||
- 원본 쿼리가 돌려준 중복 이름·코드 행은 500행 안전 상한 안에서 순서 그대로 표시하고 클릭한
|
||||
인덱스로 구분한다. 장면 데이터 조회의 exact-one-row 검증은 유지해 모호한 결과는 PREPARE 전에
|
||||
fail closed한다.
|
||||
|
||||
명시적 안전 교정:
|
||||
|
||||
- 원본 TextBox 기본 최대 길이 대신 실제 scene selector 경계인 128자로 제한하고 control,
|
||||
surrogate, U+FFFD를 거부한다. 편집 중 빈 값은 허용하되 2열판 생성 때 공백뿐인 값과 subject
|
||||
구분자인 `-`가 든 값은 거부한다. SQL은 계속 parameterized equality로만 실행된다.
|
||||
|
||||
## Slice 13: UC4 테마 검색·세션·미리보기
|
||||
|
||||
상태: 코드 및 자동 테스트 완료, 실제 DB/Tornado/UI 명령은 실행하지 않음.
|
||||
|
||||
원본 근거:
|
||||
|
||||
- `Control/UC4.cs:109-247`, `429-439` 테마 검색, 선택, 현재가·예상체결가와 6·12종목 버튼
|
||||
- `Control/UC4.Designer.cs` 검색 → 결과 → 정렬 → 액션 → 종목 미리보기의 세로 배치
|
||||
- `Control/UC4.cs` NXT 조회의 현재 시각 기준 오전/오후 세션 선택
|
||||
|
||||
고정한 계약:
|
||||
|
||||
- UC4 검색 intent는 검색어만 받는다. 원본 화면에 없던 NXT 세션 선택기는 제거했고, C#이 로컬
|
||||
시각 0~12시에는 장전, 13~23시에는 장후 세션을 탭 진입과 검색 시점마다 결정한다.
|
||||
- 화면은 검색 입력, 테마 결과, 정렬 라디오, `6종목`, `12종목`, `현재가`, `예상체결가`, 종목
|
||||
미리보기 순서의 한 열 구조다. 결과·미리보기의 인위적인 좌우 2열 구조는 제거했다.
|
||||
- 검색 결과는 원본처럼 KRX 결과 다음 NXT 결과이며 각 DB 결과 순서를 그대로 유지한다. Web은
|
||||
결과 ID와 action ID만 전송하고 테마 코드·종목 코드·세션을 만들지 않는다.
|
||||
- 결과 클릭은 C# receipt를 기다리지 않고 즉시 선택 표시를 바꾸되 opaque ID를 정확히 한 번만
|
||||
보낸다. 동일 구조의 receipt는 결과 DOM을 교체하지 않아 연속 클릭과 focus를 잃지 않는다.
|
||||
- NXT 테마의 예상체결가 버튼은 Web에서 임의로 비활성화하지 않는다. 클릭하면 원본과 같은
|
||||
`NXT는 데이터가 없습니다.` 안내를 native 경계에서 표시하고 플레이리스트 mutation은 0회다.
|
||||
- 플레이리스트에는 원본의 표시 열과 내부 scene identity를 분리해 저장하고, 미리보기가 0행인
|
||||
선택으로는 빈 컷을 만들지 않는다.
|
||||
|
||||
명시적 안전 교정:
|
||||
|
||||
- DB 검색·미리보기 결과는 generation과 opaque selection ID로 연결한다. 늦게 끝난 이전 검색이
|
||||
새 결과나 선택을 덮지 못하며, 동일 이름이 모호하거나 미리보기가 비어 있으면 fail closed한다.
|
||||
|
||||
## Slice 14: UC5 해외지수·해외업종·해외종목
|
||||
|
||||
상태: 코드 및 자동 테스트 완료, Debug/Release x64와 unsigned MSIX 생성 완료. 실제 DB/Tornado
|
||||
명령은 실행하지 않음.
|
||||
|
||||
원본 근거:
|
||||
|
||||
- `Control/UC5.cs:33-47`, `50-137`, `141-243` 초기 목록, 검색, 선택과 컷 추가 순서
|
||||
- `Control/UC5.Designer.cs` 해외지수 → 해외 업종지수 → 해외 종목의 세로 배치와 액션 버튼
|
||||
- `Data/Request/봉차트/CandleforeignStock.cs` 해외종목 봉차트의 이름·심볼·국가 조건
|
||||
- `Data/Request/판데이터기본/종목/STOCK_FORGIEN_PAN.cs` 해외종목 1열판의 정확한 종목 identity
|
||||
|
||||
고정한 계약:
|
||||
|
||||
- 화면은 원본과 같은 세로 3그룹이며, 별도 action tree·상세 패널·선택 개수·국가 코드는
|
||||
표시하지 않는다. 검색 Enter, 즉시 선택, 한 번의 Tab 진입과 ArrowUp/Down/Home/End 선택을
|
||||
지원한다.
|
||||
- 빈 검색은 원본처럼 미국·대만 초기 목록만 조회하고, 검색어가 있으면 `F_FDTC='1'`인 모든
|
||||
해외 국가를 이름으로 조회한다. DB 순서와 같은 이름의 서로 다른 종목을 그대로 보존한다.
|
||||
- 원본 FarPoint `SheetView`는 `ActiveRowIndex=-1`, `RowCount=0`에서 첫 `AddRows` 직후 활성행을
|
||||
0으로 바꾼다. 고정 지수와 검색 결과의 첫 행을 같은 방식으로 자동 활성화해 별도 선행 클릭
|
||||
없이 원본처럼 액션 버튼을 사용할 수 있다.
|
||||
- 원본에는 결과 상한이 없으므로 기존 100건 기본 상한을 데이터 경계의 안전 상한인 500건으로
|
||||
넓혔다. 500건을 넘으면 조용히 숨기지 않고 목록 제목에 `검색 결과가 많아 500건까지만 표시합니다.`를
|
||||
표시한다.
|
||||
- Web에는 generation에 묶인 opaque selection ID와 표시명만 전달한다. 심볼·국가·data code는
|
||||
C# 권위 상태에만 보관하며 action intent에는 포함하지 않는다.
|
||||
- 플레이리스트 표시 열은 원본처럼 `해외지수/해외업종/해외종목`, 종목명,
|
||||
`1열판기본` 또는 `5/20/60/120/240일`, `1/1`만 사용한다.
|
||||
- 해외종목은 내부 `symbol|nation|1` identity로 5001 봉차트와 8010 1열판에 전달해 같은
|
||||
표시명도 정확한 심볼·국가로 조회한다. 기존 이름만 저장된 레거시 행은 미국·대만 name-only
|
||||
조회와 계속 호환한다.
|
||||
- 현재 K3D 장면 경계가 처리하는 두 글자 국가 코드는 전 국가에 대해 실행 가능하다. 세 글자
|
||||
국가 코드 결과는 목록에는 보존하되 컷 생성 단계에서 명시적으로 fail closed한다.
|
||||
- 동일 구조의 native 회신은 목록 DOM과 focus를 교체하지 않으며, 늦게 끝난 검색은 새로운
|
||||
generation의 결과나 선택을 덮지 못한다.
|
||||
|
||||
명시적 안전 교정:
|
||||
|
||||
- 원본의 이름 단독 장면 조회가 같은 이름의 여러 국가·심볼을 혼동할 수 있어, 신규 행은 정확한
|
||||
내부 identity를 필수로 사용한다. 이 identity는 WebView 경계를 통과하지 않는다.
|
||||
- 지원하지 않는 국가 코드, 모호한 name-only 결과, 빈 선택은 PREPARE 전에 차단한다.
|
||||
|
||||
## Slice 15: Release 패키지 컨텍스트와 실제 개발 환경 사전 검증
|
||||
|
||||
상태: Release x64 개발 등록 패키지의 UI-only/DryRun 검증, 실제 개발 DB SELECT-only 검증,
|
||||
원본 Cuts 범위 검사와 K3D/Tornado 읽기 전용 사전 검사를 완료했다. COM/KTAP 송출 명령과 DB write는
|
||||
실행하지 않았으며 검증 뒤 `MBN_STOCK_WEBVIEW` 프로세스는 남아 있지 않다.
|
||||
|
||||
검증 결과:
|
||||
|
||||
- 패키지는 정확한 `Wickedness.MBNStockWebView.LegacyParity_0.1.0.0_x64__qbv3jkvsn3aj0` Release x64
|
||||
개발 등록에서 실행했다. URL은 `https://legacy-parity.mbn.local/index.html`, 상태는 `DRY RUN`/`IDLE`였고,
|
||||
guard 이후 native postMessage, mouse/keyboard 입력, DB read/write intent, 단일 인스턴스 재활성화와
|
||||
Tornado 포트 연결은 모두 0건이었다. 중립 종료 대화상자의 기본 종료 동작을 정확히 1회 사용해 정상 종료했다.
|
||||
- 패키지 증거 JSON은
|
||||
`C:\Users\MD\source\repos\MBN_STOCK_WEBVIEW\artifacts\package-ui-only-smoke\legacy-package-ui-only-20260718T011058894Z.json`
|
||||
(SHA-256 `2AD2C06EB14DB9684548A5D086B9FA4EC53E504D6722400E1F16B6E600BCD341`)이고,
|
||||
화면 캡처는 같은 폴더의 `legacy-package-ui-only-20260718T011058894Z.png`
|
||||
(SHA-256 `1CC02BEE872A15E64D4A74F8E489A212B4547464FB27784C4975E523B5132806`)이다.
|
||||
- 생성된 MSIX는
|
||||
`C:\Users\MD\source\repos\MBN_STOCK_WEBVIEW\src\MBN_STOCK_WEBVIEW.LegacyParityApp\AppPackages\MBN_STOCK_WEBVIEW.LegacyParityApp_0.1.0.0_x64_Test\MBN_STOCK_WEBVIEW.LegacyParityApp_0.1.0.0_x64.msix`
|
||||
(SHA-256 `3F68625C0D2ACBBFD673F2F2869944C5818A8732E94A91BA7E5C7F2707458228`)이며,
|
||||
금지된 외부 자산·비밀 값은 포함하지 않았다.
|
||||
- 실제 개발 Oracle/MariaDB에 SELECT-only smoke를 실행해 Oracle 21 연결, MariaDB 연결, 종목·해외 선택기,
|
||||
전문가·거래정지·PList 조회를 확인했다. 필수 scene data 33/33, 전체 query 58개가 통과했고 DB write는 0건이다.
|
||||
현재 NXT theme preview 48건이 빈 결과인 것은 실제 데이터 상태이며 코드 실패로 판정하지 않는다.
|
||||
- 원본 읽기 전용 Cuts의 reachable builder 34개와 active alias 45개를 검사했다. `.t2s` 누락·unsafe path·root escape는
|
||||
모두 0건이다. 의존 자산은 23개 중 14개가 없으며, `s5006 Video\큐브배경.vrv` 1개와
|
||||
`s6001 Video\20201008_<13 countries>.vrv` 13개 패턴이다. 따라서 5001은 실제 검증 후보로 유지하고
|
||||
5006/6001은 자산 제공 전까지 차단한다.
|
||||
- K3D 등록은 HKLM Registry64, native AMD64 type library와 KAEngine/KAEventHandler 상호 매핑이 모두 유효했다.
|
||||
현재 `Tornado2 v2.7.5.49 x64 DSX10.0 S.R2`의 PID 41308, 제목 `PGM`, listener
|
||||
`0.0.0.0:30001`을 읽기 전용으로 확인했다. COM activation, CONNECT, PREPARE, TAKE IN, NEXT,
|
||||
TAKE OUT과 DISCONNECT는 실행하지 않았다.
|
||||
|
||||
남은 실제 검증:
|
||||
|
||||
- 현재 PGM의 5001 page 1 검증은 이전 승인을 재사용하지 않고 새 회차·계획 해시로 승인받는다.
|
||||
먼저 CONNECT/PREPARE의 known outcome과 Network Monitoring 기록을 확인하고, 그 뒤 TAKE IN/PGM 화면/
|
||||
TAKE OUT은 허용 횟수를 명시한 별도 승인 범위에서만 실행한다. 결과가 불명확하면 재시도하지 않는다.
|
||||
- Network Monitoring 기록과 PGM 출력은 사용자가 함께 확인한 증거를 남긴다.
|
||||
- 5006/6001은 누락된 외부 동영상 자산이 안전하게 제공되고 coverage가 다시 통과하기 전에는 실제 검증하지 않는다.
|
||||
|
||||
## 다음 대조 순서
|
||||
|
||||
1. 새 package에서 실제 마우스·키보드·컷/playlist drag 회귀
|
||||
2. ThemeA/EList 편집 save/delete/close의 세부 확인 문구와 focus 순서 대조
|
||||
3. 자동 갱신 UI의 실제 실행 상태 기반 통합 테스트와 종료 상태 행렬
|
||||
4. 다음 Designer handler 묶음의 원본 코드·상태 전이 대조
|
||||
1. 새 회차 승인으로 현재 PGM 대상 5001 page 1 CONNECT/PREPARE known outcome 검증
|
||||
2. Network Monitoring과 PGM 출력 확인 뒤 별도 승인 범위의 TAKE IN/TAKE OUT 검증
|
||||
3. s5006/s6001 외부 동영상 자산 보완과 Cuts coverage 재검증
|
||||
4. 전체 근거 검토 뒤 변경 사항 커밋·원격 반영
|
||||
|
||||
각 항목은 실제 원본 코드 근거와 회귀 테스트가 모두 생기기 전에는 완료로 판정하지 않는다.
|
||||
|
||||
Reference in New Issue
Block a user