40 KiB
운영자 UI 동등성 인벤토리
문서 목적과 판정 기준
이 문서는 원본 WinForms 운영 화면의 사용자 동작을 새 WinUI 3/WebView 구현에 1:1로 연결한다. 장면 builder가 존재하는 것, 네이티브 bridge와 workflow 모듈이 존재하는 것, 실제 Web 화면에서 운영자가 사용할 수 있는 것은 서로 다른 완료 조건으로 취급한다.
상태 표기는 다음과 같다. 아래 기존 행의 화면 통합 완료 표현도 화면/계약 구현과 같은 구조적 도달성만 뜻하며, 운영 동등성 완료로 읽지 않는다.
| 상태 | 의미 |
|---|---|
| 화면/계약 구현 | 현재 Web/index.html과 Web/app.js에서 검색·선택·플레이리스트 추가 또는 저장 동작에 도달하며 native bridge·workflow 계약이 있다. |
| 화면/계약 구현 / 실환경 검증 대기 | 화면, native bridge, workflow와 자동 테스트까지 연결됐지만 운영 DB write, 기존 데이터 identity/문자 복원 또는 해당 경로의 실제 PGM 확인을 수행하지 않았다. |
| 운영 동등성 일부 검증 | 승인된 제한 데이터·scene·회차만 실제 DB/PGM으로 확인했다. 확인하지 않은 범위로 확대하지 않는다. |
| 운영 동등성 완료 | 원본과 같은 입력·저장·재조회·identity·PGM 결과를 해당 기능 범위 전체에서 확인한 상태다. 현재 전체 UI에 이 판정을 적용하지 않는다. |
DB-W는 운영 데이터베이스에 실제 쓰기를 수행해 확인했는지를 뜻한다. PGM은 실제 Tornado2 PGM 출력으로 해당 UI 경로를 확인했는지를 뜻한다. fake executor, DryRun, SQL 계약 테스트는 자동 테스트 근거이지 실제 DB-W 또는 PGM 검증으로 계산하지 않는다.
기능별 미적용·적용 중·외부자산 필요 판정과 완료에 필요한 증거는 LEGACY_FEATURE_AUDIT.md를 따른다.
원본 보존 상태
- 원본 저장소는 읽기 전용으로만 분석했고 파일을 수정하지 않았다.
- 분석 시작 시 원본에 이미 존재하던 dirty 파일은
MBN_STOCK_N/MainForm.cs,MBN_STOCK_N/RES/MmoneyCoder.ini두 개였다. 두 파일의 기존 변경을 그대로 보존했다. - 이 문서에는 비밀번호, 실제 방송 데이터, 자산·경로 해시를 기록하지 않는다.
412개 실행 action의 고정 분해
412는 다음 네 집합의 합이다. 동적 테마·전문가 목록과 GraphE 편집 행 수는 이 숫자에 중복해 더하지 않는다.
| 집합 | 원본 UI | 수량 | 새 구현 | 자동 근거 | 상태 |
|---|---|---|---|---|---|
| 고정 action | MainForm의 해외·환율·지수 탭과 Control/UC1.cs |
328 | Web/legacy-fixed-workflow.js |
tests/Web/legacy-fixed-workflow.test.cjs가 328개, 직접 생성 가능한 322개, 수동 전제 6개를 고정한다. |
화면 통합 완료. 수동 6개는 아래 대체 경계를 통과해야 한다. |
| 업종 action | Control/UC1.cs + Control/UC2.cs의 코스피·코스닥 |
44 | Web/industry-workflow.js의 시장별 22개 |
tests/Web/industry-workflow.test.cjs |
화면 통합 완료 |
| 종목 action | MainForm 좌측 종목 검색·컷 목록 |
31 | Web/operator-workflow.js |
tests/Web/operator-workflow.test.cjs가 실행 자산 순서의 31개를 고정한다. |
화면 통합 완료 |
| 비교 action | Control/UC1.cs + Control/UC3.cs |
9 | Web/comparison-workflow.js |
tests/Web/comparison-workflow.test.cjs가 24개 비교 대상과 9개 action을 별도로 고정한다. |
화면 통합 완료 |
| 합계 | 412 |
고정 action 328개 안의 수동 전제 6개는 일반 고정 DTO로 임의 생성하지 않는다.
| 원본 고정 항목 | 수량 | 원본 전용 폼 | 새 대체 경계 | 관계 |
|---|---|---|---|---|
| 개인·외국인·기관 순매도 상위(수동) | 3 | Form/FSell.cs |
MainWindow.ManualLists.cs, Web/manual-lists-workflow.js, 신뢰된 s5025 파일 저장소 |
각 audience의 검증된 5행 입력이 있어야 s5025/5025 플레이리스트 항목을 만든다. |
| 5단·6종목·12종목 섹션의 VI 발동(수동) placeholder | 3 | Form/VIList.cs |
MainWindow.ManualLists.cs, Web/manual-lists-workflow.js, 신뢰된 VI 저장소 |
세 placeholder 모두 원본 VIList가 만든 하나의 s5074/5074 5행 페이지 결과로 대체된다. 6·12행 장면으로 바꾸지 않는다. |
현재 이 수동 6개는 FSell/VIList 대체 화면까지 통합됐다. 고정 카탈로그에서 임의 DTO로 직접 활성화하지 않고, 전용 입력 화면이 저장 후 재조회한 신뢰 데이터와 버전을 공급한 뒤에만 플레이리스트에 넣는다.
화면 단위 완료 요약
| 원본 화면 | 핵심 역할 | 화면/계약 구현 상태 | 운영 동등성 DB-W | 운영 동등성 PGM |
|---|---|---|---|---|
| MainForm | 종목 검색, 31개 컷, playlist, 송출·배경·저장 | 화면/계약 구현. sibling 배경 root 코드는 적용됐고 실제 외부 배경 자산·package 검증 대기 |
없음/해당 없음 | 일부: 승인된 5001, 5074, TAKE OUT |
| UC1 | 328 fixed, 업종·비교 action 트리 | 412 action과 수동 6개 전용 편집 화면/계약 구현 | 해당 없음 | 일부: generic 5074; 전체 action 미검증 |
| UC2 | 업종 목록과 두 업종 선택 | 화면/계약 구현 | 해당 없음 | 미검증 |
| UC3 | 비교 대상·저장 비교쌍·9 action | 화면/계약과 strict 종목비교.dat one-time importer 구현 |
importer는 read-only이며 DB-W 없음 | signed package에서 8쌍 1회 실행·재시작 영속성 통과; PGM 미검증 |
| UC4 | 테마 검색·preview·5/6/12행 항목 | 조회/선택 및 ThemeA CRUD 화면/identity 계약 구현 | CRUD 미실행; 실제 KRX/NXT identity 미검증 | 미검증 |
| UC5 | 해외업종·해외종목·해외지수 | 화면/계약 구현 | 해당 없음 | 미검증; s6001 국가 영상 13개 외부자산 필요 |
| UC6 | 전문가 조회·추천 preview·5행 항목 | 조회/선택 및 EList/추천 CRUD 화면/identity 계약 구현 | CRUD 미실행; 실제 identity 미검증 | 미검증 |
| UC7 | 거래정지 검색·현재/120일 캔들 | 화면/계약 구현 | 해당 없음 | 미검증 |
| GraphE | 4개 수동 재무 CRUD와 playlist 추가 | 화면/계약 구현 / 실환경 검증 대기 | 미실행 | 미검증 |
| FSell | 개인·외국인·기관 수동 순매도 5행 | 화면/계약, 원본 importer와 production parser 구현 | 운영 데이터 write 미실행 | 현재 3 audience×5행 read-only 검증; 기존 파일 불변 |
| VIList | 수동 VI 목록·순서·5개 단위 page | 화면/계약, 원본 importer와 versioned production parser 구현 | 운영 데이터 write 미실행 | 현재 9항목·2 page read-only 검증; 기존 파일 불변 |
| PList | 이름 있는 playlist 목록·저장·불러오기·삭제 | 화면/계약과 한국어 legacy/KRX/NXT/해외종목/manual restore 구현 | 운영 DB write 미실행 | 2,213행 무손상, 통합 selection 1,603/차단 610; scene/PGM 별도 |
| AList | 프로그램 코드·이름 생성 | PList 화면/계약에 통합 | 운영 DB write 미실행 | 해당 없음 |
| ThemeA | KRX/NXT 테마 구성 CRUD | 화면/identity 계약 구현 / 실환경 검증 대기 | 미실행 | 미검증 |
| EList | 전문가 생성과 추천 구성 CRUD | 화면/identity 계약 구현 / 실환경 검증 대기 | 미실행 | 미검증 |
MainForm 매핑
원본 파일은 MainForm.cs와 MainForm.Designer.cs다.
| 원본 이벤트·컨트롤 | 원본 동작과 입력/저장 경계 | 새 구현 파일·bridge/workflow | 현재 상태 | 자동 테스트 근거 | DB-W / PGM |
|---|---|---|---|---|---|
Form1_Load, tabControl1_SelectedIndexChanged |
실행 자산을 읽고 UC1~UC7을 탭에 배치하며 Tornado에 연결한다. | MainWindow.xaml.cs, MainWindow.Playout.cs, Web/index.html, Web/app.js |
화면 통합 완료 | LegacyWebWorkflowIntegrationTests.cs, PlayoutBridgeProtocolTests.cs, Web 전체 회귀 |
DB-W 해당 없음 / PGM 일부 완료 |
tab_MouseDown/tab_MouseMove/tab_DragOver, swapTabPages |
원본 10개 업무 탭의 표시 순서를 drag 중 identity 단위로 교환한다. | Web/market-nav-reorder.js; dashboard 고정; data-market 기반 drag와 Alt+위/아래; 세션 한정 |
코드 적용 / signed package 검증 대기. active view·DB 요청·playlist 상태를 변경하지 않음 | 전용 10/10, 전체 Web 353/353, Debug/Release x64 build | DB-W·PGM 해당 없음 |
button9_Click, txtSearch_KeyPress, searchStock, jongmokCode |
코스피·코스닥·NXT 두 시장씩 검색하고 이름, 코드, 시장을 선택한다. | src/MBN_STOCK_WEBVIEW.Core/Data/StockSearch.cs; native search-stocks; Web/operator-workflow.js |
화면 통합 완료 | LegacyStockSearchServiceTests.cs, operator-workflow.test.cjs |
DB-W 없음 / 5001 경로 일부 PGM 완료 |
listView1_*, GridView1_*, SetPlayList, PlayList_DragDrop |
실행 자산의 종목 컷을 선택·드래그해 enabled, 시장, 종목, 종류, 세부사항, page, 종목코드 행을 만든다. | Web/operator-workflow.js, Web/app.js의 종목 workflow와 표준 playlist entry |
화면 통합 완료 | operator-workflow.test.cjs, candle-options-workflow.test.cjs |
DB-W 없음 / 전체 31개 PGM 미검증 |
b1_Click (주요매출 구성, 성장성 지표, 매출액, 영업이익) |
GraphE 네 모드를 연다. |
MainWindow.ManualFinancial.cs, Web/manual-financial-workflow.js, Web/manual-financial-ui.js |
화면 통합 완료 / 실환경 검증 대기 | GraphE 표 참조 | DB-W 없음 / PGM 없음 |
PlayList_CellClick, PlayList_KeyPress, checkBox1_CheckedChanged, btnup_Click, btndown_Click, btndelete_Click, btntdelete_Click |
단일·Ctrl·Shift 선택, Space/전체 송출 체크, 순서 이동, 선택·전체 삭제. 송출 중 이동·전체 삭제를 막는다. | Web/app.js의 playlist 상태, snapshot lock, Web/playout-safety.js |
화면 통합 완료 | playout-safety.test.cjs, named/각 workflow의 trusted restore 테스트 |
DB-W 없음 / PGM 제어 일부 완료 |
button5_Click, btnload_Click |
PList를 열어 이름 있는 DB 플레이리스트를 저장·불러온다. |
MainWindow.NamedPlaylists.cs, src/MBN_STOCK_WEBVIEW.Core/Data/NamedPlaylistPersistence.cs, src/MBN_STOCK_WEBVIEW.Infrastructure/Execution/OracleNamedPlaylistMutationExecutor.cs, Web/named-playlist-workflow.js |
화면/계약 구현. 기존 한국어 행과 manual 항목의 실DB fresh restore는 적용 중 | named playlist Core/Infrastructure/Web/bridge 테스트 | DB-W 없음 / 복원 항목별 PGM 없음 |
btnPrepare_Click, btnTake_Click/F8, btnNext_Click, btnTakeout_Click/Esc |
PREPARE, TAKE IN, 같은 장면 page NEXT 또는 다음 행 NEXT, StopAll 기반 TAKE OUT. | MainWindow.Playout.cs; IPlayoutEngine; native playout-command, request-playlist-page-plans; Web/playout-safety.js |
화면 통합 완료 | playout/Core/PageN/PGM sequence 테스트와 playout-safety.test.cjs |
DB-W 해당 없음 / 승인된 5001, 5074 page 1·2 및 TAKE OUT만 PGM 확인 |
btnback_Click/F2, ckback_CheckedChanged/F3 |
허용 배경 파일 선택, 배경 없음 토글, 송출 중 변경 금지. | MainWindow.Background.cs; 별도 LegacyBackgroundDirectory; opened-handle/hardlink/reparse 검증; native request-background-status, choose-background, toggle-background; Web 배경 컨트롤 |
sibling 배경 root와 기본.vrv 코드 적용. 현재 원본 외부 폴더가 없어 fail closed이며 package/PGM 검증 대기 |
별도 root 내부/escape/reparse/hardlink/opened-handle/누락 fixture, Core·Playout Debug/Release 전부 통과, 앱 Debug/Release build | DB-W 해당 없음 / 기능별 PGM 미검증 |
timer1_Tick, timer2_Tick, timer3_Tick, MainForm_FormClosing, MainForm_Resize, keyboard handlers |
자동 갱신, 상태 표시, 종료 정리, 단축키를 담당한다. | playout refresh scheduler, cancellation/lifetime hooks, Web 상태·단축키 | 화면 통합 완료 | refresh epoch/scheduler, playout safety, bridge 테스트 | DB-W 해당 없음 / 일부 PGM 완료 |
실제 PGM 완료는 이미 승인된 제한 회차의 5001과 5074 흐름만 뜻한다. 412개 전체나 아래 편집 화면의 실제 PGM 동등성을 뜻하지 않는다.
UC1~UC7 매핑
UC1 — 해외·환율·지수·업종·비교 action 트리
원본: Control/UC1.cs, Control/UC1.Designer.cs
| 원본 이벤트·버튼 | 원본 경계 | 새 구현 | 상태·검증 |
|---|---|---|---|
UC1_Load, INI_parser |
탭별 실행 자산을 읽어 category/leaf TreeView를 구성한다. | legacy-fixed-workflow.js, industry-workflow.js, comparison-workflow.js의 폐쇄형 inventory |
화면 통합 완료. 각 Web 테스트가 수량·중복·매핑을 고정한다. |
chE_CheckedChanged, treeView_BeforeSelect, treeView_BeforeExpand/BeforeCollapse, treeView_DrawNode, treeView_MouseDown |
전체 expand/collapse와 트리 표시를 제어한다. | Web category/section 렌더링과 펼침 상태 | 화면 통합 완료. 시각 상호작용이며 DB-W/PGM 대상 아님. |
treeView_DoubleClick |
category 전체 또는 leaf를 playlist에 넣고 5·6·12개 PageN, NXT 제한, 업종 쌍, 비교 쌍을 계산한다. FSell·VI 수동 항목이면 전용 폼으로 분기한다. | 고정 328, 업종 44, 비교 9 workflow의 create*PlaylistEntry; page plan bridge; 수동 6개는 manual-lists-workflow.js와 manual-lists-ui.js로 분리 |
전체 화면 통합 완료. 실제 DB-W 없음, 전체 PGM 미검증. |
treeView_AfterSelect, btnswap_Click |
원본에서 실질 동작이 없거나 주석 처리된 이벤트다. | 별도 기능 없음 | 의도적으로 추가 동작을 만들지 않는다. |
UC2 — 코스피·코스닥 업종 선택과 쌍
원본: Control/UC2.cs, Control/UC2.Designer.cs
| 원본 이벤트·버튼 | 원본 경계 | 새 구현·bridge | 상태·검증 |
|---|---|---|---|
UC2_Load |
코스피/코스닥 업종 이름·코드를 DB에서 읽는다. | src/MBN_STOCK_WEBVIEW.Core/Data/IndustrySelection.cs; native request-industries |
화면 통합 완료. LegacyIndustrySelectionServiceTests.cs, industry-workflow.test.cjs. |
listbox_DoubleClick, btnswap_Click |
선택 업종을 두 슬롯에 회전 입력하고 순서를 바꾼다. | Web/industry-workflow.js의 selected/primary/secondary 입력 |
화면 통합 완료. 시장 혼합과 빈 슬롯을 fail closed 한다. |
| UC1 업종 leaf 실행 | 단일, 2열, 수익률 5종, 캔들 12종, 시장 전체 3종으로 시장별 22개를 만든다. | industry-workflow.js |
44개 화면 통합 완료. 실제 DB-W 없음 / 업종별 PGM 없음. |
UC3 — 비교 대상·저장 비교쌍
원본: Control/UC3.cs, Control/UC3.Designer.cs
| 원본 이벤트·버튼 | 원본 경계 | 새 구현·bridge | 상태·검증 |
|---|---|---|---|
UC3_Load, Data_Load |
24개 고정 비교 대상을 읽고 로컬 종목비교.dat의 저장쌍을 불러온다. |
Web/comparison-workflow.js; 24개 typed target; schema-versioned pair list; LegacyComparisonPairImport의 고정 read-only source와 strict CP949 9필드 importer |
signed package에서 실제 DB identity를 다시 읽어 8쌍을 한 번 가져왔고, 정상 재시작 뒤 private marker·순서를 확인했다. 원본을 계속 참조하지 않는다. |
btnsearch_Click, listBox_DoubleClick, listBox1_DoubleClick, btnsearch2_Click, FpSpread2_CellDoubleClick |
국내 종목, 24개 시장 대상, 해외 종목을 두 슬롯에 회전 입력한다. | native search-stocks, search-world-stocks; comparison target normalizer |
화면 통합 완료. comparison-workflow.test.cjs가 회전·시장·해외 identity를 검증한다. |
btnswap_Click, btnAdd_Click, btn1/2/3/4_Click, File_Save |
쌍 교환, 추가, 선택/전체 삭제, 위/아래 이동 후 저장한다. | comparison pair append/delete/delete-all/reorder와 Web storage; explicit legacy import button | 화면/계약 구현. 기존 CP949 파일은 exact 9필드·fresh DB identity·중복·500쌍 경계를 모두 통과해야 전체가 원자적으로 저장된다. 실제 8쌍 import와 재시작 marker를 확인했다. |
| UC1 비교 leaf 실행 | 현재/예상 2열, 비교 캔들/라인, 5일·1/3/6/12개월 수익률의 9개 action | comparison-workflow.js |
9개 화면 통합 완료. 실제 DB-W 없음 / 비교 PGM 없음. |
UC4 — 테마 검색·미리보기·송출 선택
원본: Control/UC4.cs, Control/UC4.Designer.cs
| 원본 이벤트·버튼 | 원본 경계 | 새 구현·bridge | 상태·검증 |
|---|---|---|---|
btn1_Click, GetThemeByKeyword |
KRX Oracle과 NXT 저장소에서 테마명·코드를 검색한다. | src/MBN_STOCK_WEBVIEW.Core/Data/ThemeSelection.cs; native search-themes; Web/theme-workflow.js |
검색 화면 통합 완료. LegacyThemeSelectionServiceTests.cs, theme-workflow.test.cjs. |
FpSpread1_CellClick |
선택 테마의 구성 종목과 입력 순서를 DB에서 읽고 중지 종목을 제외한다. | native request-theme-preview와 typed preview |
화면 통합 완료. 중복 key·시장 불일치·truncated preview를 거부한다. |
btnnow_Click, btnpre_Click, btnnow_6_Click, btnnow_12_Click, double-click |
5단 현재/예상, 6종목 현재, 12종목 현재를 입력순·상승률·하락률로 만들고 5/6/12 page 수를 계산한다. NXT 예상은 차단한다. | theme-workflow.js의 compatibility, page preview, playlist entry |
화면 통합 완료. 실제 DB-W 없음 / 테마 PGM 없음. |
btn2_Click, btn3_Click, btn4_Click |
ThemeA 추가·편집 폼을 열거나 선택 테마와 구성 종목을 삭제한다. | MainWindow.OperatorCatalogs.cs, Web/operator-catalog-workflow.js, Web/operator-catalog-ui.js |
ThemeA CRUD 화면 통합 완료. 실제 DB-W/PGM 없음. |
UC5 — 해외업종·해외종목·해외지수
원본: Control/UC5.cs, Control/UC5.Designer.cs
| 원본 이벤트·버튼 | 원본 경계 | 새 구현·bridge | 상태·검증 |
|---|---|---|---|
UC5_Load |
고정 해외지수 목록을 표시한다. | Web/overseas-workflow.js의 고정 지수 asset |
화면 통합 완료. |
btnsearch1_Click, upjong_search |
미국 해외업종의 입력명·표시명·symbol을 조회한다. | src/MBN_STOCK_WEBVIEW.Core/Data/OverseasIndustryIndexSearch.cs; native search-overseas-industries |
화면 통합 완료. LegacyOverseasIndustryIndexSearchServiceTests.cs. |
btnsearch2_Click, jongmok_search |
US/TW 해외종목 이름·symbol을 조회한다. | src/MBN_STOCK_WEBVIEW.Core/Data/WorldStockSearch.cs; native search-world-stocks |
화면 통합 완료. LegacyWorldStockSearchServiceTests.cs. |
btn1_Click, Account_Graph |
업종/종목 현재 1열과 지수·종목 5/20/60/120/240일 캔들을 playlist에 넣는다. | Web/overseas-workflow.js |
화면 통합 완료. overseas-workflow.test.cjs; 실제 DB-W 없음 / 해외 PGM 없음. |
UC6 — 전문가 목록·추천 종목·송출 선택
원본: Control/UC6.cs, Control/UC6.Designer.cs
| 원본 이벤트·버튼 | 원본 경계 | 새 구현·bridge | 상태·검증 |
|---|---|---|---|
UC6_Load, Data_Load, FpSpread1_CellClick |
EXPERT_LIST를 읽고 선택 전문가의 RECOMMEND_LIST를 PLAYINDEX 순서로 미리 본다. |
src/MBN_STOCK_WEBVIEW.Core/Data/ExpertSelection.cs; native search-experts, request-expert-preview; Web/expert-workflow.js |
검색·선택 화면 통합 완료. LegacyExpertSelectionServiceTests.cs, expert-workflow.test.cjs. |
btlistadd_Click |
선택 전문가를 5행 page, 최대 20 page의 전문가 추천 항목으로 만든다. | expert-workflow.js의 native-normalized preview와 playlist entry |
화면 통합 완료. 실제 DB-W 없음 / 전문가 PGM 없음. |
btnAdd_Click |
EList 신규 전문가 폼을 연다. | operator catalog expert create와 operator-catalog-ui.js |
EList 신규 UI 통합 완료. |
btnDelete_Click, btndel_Click, btnsave_Click, 종목 검색·double-click |
전문가 삭제, 추천 종목 편집·삭제·재정렬·저장. 원본은 전문가/추천 행을 삭제 후 재삽입한다. | MainWindow.OperatorCatalogs.cs, src/MBN_STOCK_WEBVIEW.Core/Data/ExpertCatalogPersistence.cs, src/MBN_STOCK_WEBVIEW.Infrastructure/Execution/OperatorCatalogMutationExecutor.cs, Web/operator-catalog-workflow.js, Web/operator-catalog-ui.js |
EList/전문가 CRUD 화면 통합 완료. 실제 DB-W/PGM 없음. |
UC7 — 거래정지 종목
원본: Control/UC7.cs, Control/UC7.Designer.cs
| 원본 이벤트·버튼 | 원본 경계 | 새 구현·bridge | 상태·검증 |
|---|---|---|---|
btnsearch_Click, txts_KeyPress, search |
거래정지 코스피와 코스닥 종목을 빈 검색 또는 부분 검색으로 합친다. | src/MBN_STOCK_WEBVIEW.Core/Data/TradingHaltSelection.cs; native search-trading-halts; Web/trading-halt-workflow.js |
화면 통합 완료. LegacyTradingHaltSelectionServiceTests.cs. |
FpSpread1_CellClick |
종목명 열 정렬 | Web 정규화 결과의 결정적 정렬 | 화면 통합 완료. |
btn4_Click (현재가, 120일 캔들) |
시장·종목 identity로 현재 1열 또는 거래정지 120일 캔들 항목을 만든다. | trading-halt-workflow.js |
화면 통합 완료. trading-halt-workflow.test.cjs; 실제 DB-W 없음 / PGM 없음. |
전용 Form 매핑
GraphE — 네 가지 수동 재무 편집기
원본: Form/GraphE.cs, Form/GraphE.Designer.cs
| 원본 이벤트·버튼 | 원본 입력·저장 경계 | 새 구현·bridge | 상태·검증 |
|---|---|---|---|
GraphE_Load, Data_Init, FpSpread1_CellClick, Data_Load |
네 테이블 전체/검색 목록을 읽고 선택 행을 편집 DTO로 분해한다. | src/MBN_STOCK_WEBVIEW.Core/Data/ManualFinancialScreens.cs; native request-manual-financial-list, request-manual-financial-load; Web/manual-financial-ui.js |
화면 통합 완료 / 실환경 검증 대기 |
종목 검색, listBox_DoubleClick, upSearch_Click, downSearch_Click |
정확한 종목을 선택하고 테이블 내 이름을 위/아래로 찾는다. | native stock master 재검증과 manual financial list/search | 화면 통합 완료. 이름만으로 시장·코드를 추정하지 않는다. |
btadd_Click |
기존 이름이면 update, 아니면 insert. INPUT_PIE, INPUT_GROW, INPUT_SELL, INPUT_PROFIT의 폐쇄형 필드를 저장한다. |
native create-manual-financial-record, update-manual-financial-record; src/MBN_STOCK_WEBVIEW.Infrastructure/Execution/OracleManualFinancialMutationExecutor.cs |
화면 통합 완료. 단일 트랜잭션, optimistic rowVersion, no retry, OutcomeUnknown quarantine 구현. 실제 DB-W 없음. |
btndel_Click, btnall_Click |
선택 이름 삭제 또는 테이블 전체 삭제 확인 | native delete-manual-financial-record, delete-all-manual-financial-records |
화면 통합 완료. 실제 DB-W 없음. |
btnAdd_Click, row double-click, Select_Item |
DB에 존재하는 행을 정확한 시장/종목과 결합해 1 page playlist 항목으로 추가한다. | native request-manual-financial-selection; Web/manual-financial-workflow.js |
화면 통합 완료. 저장 복원본은 fresh load + rowVersion/record 일치 + stock 재검증 + native selection 전까지 PREPARE 불가. PGM 없음. |
화면별 폐쇄형 매핑은 다음과 같다.
| 원본 모드 | 테이블 | 입력 | builder/code |
|---|---|---|---|
| 주요매출 구성 | INPUT_PIE |
종목, 기준일, 최대 5개 구성명·비율 | s5076/5076 |
| 성장성 지표 | INPUT_GROW |
매출·영업이익·순자산·순이익 증가율 각 4개와 분기 4개 | s5079/5079 |
| 매출액 | INPUT_SELL |
분기·금액 6쌍 | s5080/5080 |
| 영업이익 | INPUT_PROFIT |
분기·금액 6쌍 | s5081/5081 |
자동 근거는 LegacyManualFinancialScreenServiceTests.cs, OracleManualFinancialMutationExecutorTests.cs, manual-financial-workflow.test.cjs, manual-financial-bridge-integration.test.cjs다.
FSell — 수동 순매도 3종
원본: Form/FSell.cs, Form/FSell.Designer.cs
| 원본 이벤트·버튼 | 원본 입력·저장 경계 | 새 구현·bridge | 상태·검증 |
|---|---|---|---|
FSell_Load, data_load, ReadListFile |
개인·외국인·기관별 로컬 파일에서 5행, 행마다 좌/우 종목·금액을 읽는다. | src/MBN_STOCK_WEBVIEW.Infrastructure/Playout/S5025TrustedManualFileDataSource.cs의 store/data source; native request-manual-net-sell-data; Web/manual-lists-ui.js |
화면 통합 완료 / 실환경 검증 대기 |
btnok_Click, WriteListFile |
정확히 5행을 저장하고 수동 순매도 항목 생성을 허용한다. | native save-manual-net-sell-data; Web/manual-lists-workflow.js |
화면 통합 완료. 검증된 versioned 데이터만 s5025/5025로 변환한다. 실제 파일 write는 자동 테스트 임시 디렉터리에서만 확인, 운영 데이터 write 없음. |
btncn_Click |
취소 시 placeholder 행을 유지하지 않는다. | workflow가 저장 성공·신뢰 데이터 없이는 항목을 만들지 않는다. | 화면 통합 완료. PGM 없음. |
자동 근거는 TrustedManualSceneDataLoader5025Tests.cs, S5025TrustedManualFileDataSourceTests.cs, S5025TrustedManualFileStoreTests.cs, manual-lists-workflow.test.cjs다.
VIList — 수동 VI 목록
원본: Form/VIList.cs, Form/VIList.Designer.cs
| 원본 이벤트·버튼 | 원본 입력·저장 경계 | 새 구현·bridge | 상태·검증 |
|---|---|---|---|
VILIST_Load |
로컬 VI 목록을 읽는다. | src/MBN_STOCK_WEBVIEW.Infrastructure/Playout/ViTrustedManualFileStore.cs; native request-vi-manual-list; Web/manual-lists-ui.js |
화면 통합 완료 / 실환경 검증 대기 |
종목 검색, listBox_DoubleClick |
종목 master에서 코스피/코스닥 prefix와 종목명을 추가한다. | native search-stocks, manual-lists-workflow.js의 strict VI item |
화면 통합 완료. |
btn1/2/3/4_Click |
선택/전체 삭제와 위/아래 이동 | manual lists draft operations | 화면 통합 완료. |
btnok_Click |
목록을 저장하고 종목명을 comma로 결합해 항상 5단 표그래프 / VI 발동(수동)으로 추가하며 page를 5개 단위로 계산한다. |
native save-vi-manual-list; trusted s5074/5074, 5개 단위 page entry |
화면 통합 완료. 자동 테스트는 ViTrustedManualFileStoreTests.cs, manual-lists-workflow.test.cjs, fixed workflow의 VI placeholder 테스트. 운영 write 없음. |
btncancel_Click |
저장·추가 없이 닫는다. | workflow 취소 시 mutation 없음 | 화면 통합 완료. 수동 VI dataset의 PGM 없음. 기존 generic 5074 PGM 검증을 VI 입력 검증으로 간주하지 않는다. |
PList + AList — 이름 있는 DB 플레이리스트
원본: Form/PList.cs, Form/AList.cs와 각 Designer
| 원본 이벤트·버튼 | 원본 입력·저장 경계 | 새 구현·bridge | 상태·검증 |
|---|---|---|---|
PList_Load, Get_FileName_Folder |
DC_LIST의 프로그램 제목·코드를 조회한다. |
native request-named-playlist-list; named-playlist-workflow.js |
화면 통합 완료 |
AList_Load, GetNextCode, btnok_Click |
다음 8자리 코드와 프로그램명을 생성해 DC_LIST에 추가한다. |
native create-named-playlist |
화면 통합 완료. parameterized transaction 사용. |
PList.data_save, double-click/확인 |
기존 PLAY_LIST를 지운 뒤 enabled와 6개 표시 필드를 LIST_TEXT 및 ITEM_INDEX 순서로 저장한다. |
native replace-named-playlist; trusted entry serialization |
화면/계약 구현. raw·untrusted entry는 저장 또는 PREPARE 불가. GraphE·FSell·VI 등 manual 항목의 실제 save→reload→fresh identity/version 보존은 미검증. |
PList.data_load, double-click/확인 |
프로그램 코드별 PLAY_LIST를 ITEM_INDEX 순으로 읽어 playlist를 교체한다. |
native request-named-playlist-load; resolver 기반 materialization |
화면/계약 구현. 실제 2,213행의 한국어 DC_TITLE/7필드 LIST_TEXT round-trip과 typed persistence는 전부 일치했다. KRX·해외종목·GraphE를 포함한 통합 read-only 증거는 selectionMapped=1,603, 차단 610이며 raw DB row는 scene data/asset/page를 재검증할 때까지 PREPARE 불가다. |
PList.button1_Click |
프로그램 정의 삭제 | native delete-named-playlist |
화면 통합 완료. 실제 운영 DB-W 없음. |
| 취소 | 아무 변경 없이 닫는다. | mutation 요청 없음 | 화면 통합 완료. |
구현은 src/MBN_STOCK_WEBVIEW.Core/Data/NamedPlaylistPersistence.cs, KRX/NXT/해외종목/manual 전용 restore, src/MBN_STOCK_WEBVIEW.Infrastructure/Execution/OracleNamedPlaylistMutationExecutor.cs, MainWindow.NamedPlaylists.cs, Web/named-playlist-workflow.js에 있다. 자동 근거는 named playlist Core/Infrastructure/Web/bridge 테스트이며 실제 기존 데이터의 read-only 대조는 docs/NAMED_PLAYLIST_READ_AUDIT.md에 있다. 실제 운영 DB write와 named playlist 전용 scene/asset/PREPARE/PGM 검증은 아직 없다.
ThemeA — 테마 추가·편집
원본: Form/ThemeA.cs, Form/ThemeA.Designer.cs
| 원본 이벤트·버튼 | 원본 입력·저장 경계 | 새 구현·bridge | 상태·검증 |
|---|---|---|---|
Theme_Load |
KRX/NXT 선택, 기존 테마 구성 종목과 순서를 로드한다. | native request-theme-catalog-list, request-operator-catalog-schema; operator-catalog-workflow.js; operator-catalog-ui.js |
화면 통합 완료 / 실환경 검증 대기 |
btnC_Click |
시장별 테마명 중복을 확인한다. | native list/identity validation | 화면 통합 완료 |
| 종목 검색·double-click | 같은 시장의 종목만 prefix가 포함된 구성 행으로 추가한다. | stock search + typed theme draft/preview | 화면 통합 완료 |
btn1/2/3/4_Click, Delete key |
선택/전체 삭제, 위/아래 이동 | operator catalog theme draft operations | 화면 통합 완료 |
btnok_Click, GetNextCode |
신규 코드를 만들거나 기존 SB_LIST/SB_ITEM을 교체하고 입력 순서를 저장한다. KRX와 NXT 저장소를 구분한다. |
native request-theme-catalog-next-code, create-theme-catalog, replace-theme-catalog; atomic mutation executor |
화면 통합 완료. 실제 운영 DB-W/PGM 없음. |
| UC4 테마 삭제 | SB_ITEM 후 SB_LIST 삭제 |
native delete-theme-catalog |
화면 통합 완료. |
구현은 src/MBN_STOCK_WEBVIEW.Core/Data/ThemeCatalogPersistence.cs, src/MBN_STOCK_WEBVIEW.Core/Data/OperatorCatalogSchemaValidation.cs, src/MBN_STOCK_WEBVIEW.Infrastructure/Execution/OperatorCatalogMutationExecutor.cs, MainWindow.OperatorCatalogs.cs, Web/operator-catalog-workflow.js다. 자동 근거는 theme catalog, schema, executor, Web workflow 테스트다. expected identity와 응답 correlation 계약은 구현했지만 실제 운영 DB에서 KRX/NXT, 동명이름, 코드가 같은 선택 행을 정확히 replace/delete하는지는 검증 대기다.
EList — 전문가 신규 생성
원본: Form/EList.cs, Form/EList.Designer.cs
| 원본 이벤트·버튼 | 원본 입력·저장 경계 | 새 구현·bridge | 상태·검증 |
|---|---|---|---|
EList_Load, GetNextCode |
EXPERT_LIST의 다음 4자리 코드를 제안한다. |
native request-expert-catalog-next-code; operator-catalog-ui.js |
화면 통합 완료 / 실환경 검증 대기 |
btnok_Click |
이름을 검증하고 EXPERT_LIST에 신규 전문가를 저장한다. |
native create-expert-catalog |
화면 통합 완료. 실제 운영 DB-W 없음. |
| UC6 저장·삭제 | 전문가와 RECOMMEND_LIST 구성 종목·금액·PLAYINDEX를 교체 또는 삭제한다. |
native replace-expert-catalog, delete-expert-catalog |
화면 통합 완료. 실제 PGM 없음. |
btncn_Click |
변경 없이 닫는다. | mutation 요청 없음 | 화면 통합 완료. |
구현은 src/MBN_STOCK_WEBVIEW.Core/Data/ExpertCatalogPersistence.cs, 공통 schema/executor/native partial, Web/operator-catalog-workflow.js다. 자동 근거는 expert catalog, schema, executor, Web workflow 테스트다. 전문가 코드·이름과 추천 행 identity 계약은 구현했지만 실제 운영 DB의 create/replace/delete read-back은 검증 대기다.
bridge와 화면 로딩 상태 요약
| 기능군 | native request | workflow | 현재 index.html/app.js |
|---|---|---|---|
| 종목/고정/업종/비교/테마 조회/해외/전문가 조회/거래정지 | search-stocks, request-industries, search-themes, request-theme-preview, search-world-stocks, search-overseas-industries, search-experts, request-expert-preview, search-trading-halts |
각 전용 workflow | 로드·연결됨 |
| 이름 있는 플레이리스트 | request-named-playlist-list, request-named-playlist-load, create-named-playlist, replace-named-playlist, delete-named-playlist |
named-playlist-workflow.js |
로드·연결됨 |
| GraphE | request-manual-financial-list, request-manual-financial-load, request-manual-financial-selection, create-manual-financial-record, update-manual-financial-record, delete-manual-financial-record, delete-all-manual-financial-records |
manual-financial-workflow.js, manual-financial-ui.js |
로드·연결됨 |
| FSell/VI | request-manual-operator-data-status, request-manual-net-sell-data, save-manual-net-sell-data, request-vi-manual-list, save-vi-manual-list |
manual-lists-workflow.js, manual-lists-ui.js |
로드·연결됨 |
| ThemeA/EList CRUD | request-theme-catalog-list, request-expert-catalog-list, request-operator-catalog-schema, theme/expert next-code, create/replace/delete requests |
operator-catalog-workflow.js, operator-catalog-ui.js |
로드·연결됨 |
근거 파일 빠른 링크
| 영역 | 구현 | 자동 테스트 |
|---|---|---|
| 공통 화면·송출·배경 | MainWindow, Playout partial, Background partial, Web app | playout safety |
| 328 fixed / 44 industry / 31 stock / 9 comparison | fixed workflow, industry workflow, stock workflow, comparison workflow | fixed, industry, stock, comparison |
| 테마 조회·해외·전문가 조회·거래정지 | theme, overseas, expert, trading halt | theme, overseas, expert, trading halt |
| GraphE | native partial, Core service, Oracle executor, workflow | Core, Infrastructure, Web, bridge |
| FSell / VI | native partial, FSell store/data source, VI store, workflow | FSell store, VI store, Web |
| PList / AList | native partial, Core service, Oracle executor, workflow | Core integration, Infrastructure, Web, bridge |
| ThemeA / EList | native partial, theme persistence, expert persistence, executor, workflow | theme, expert, Infrastructure, Web |
실제 검증 판정
| 항목 | 결과 |
|---|---|
| 자동 테스트 | Core 1,383개, Infrastructure 173개, Playout 393개가 Debug/Release x64에서 각각 통과했고 Web workflow·bridge 415/415도 통과했다. 412 action의 폐쇄형 매트릭스, 계약·경계·복원 실패와 native fail-closed gate를 검증한다. |
| 실제 운영 DB write | 미실행. GraphE, named playlist, ThemeA, EList의 mutation executor는 fake/계약 테스트로 검증했으며 운영 DB에는 쓰지 않았다. FSell/VI는 테스트용 격리 저장소만 사용했다. |
| 실제 Tornado2 PGM | 제한된 승인 회차에서 5001, 5074 page 1·2, TAKE OUT을 확인했다. 이는 전체 412 action, GraphE, FSell, VI, ThemeA, EList, 이름 있는 playlist 각각의 UI 동등성 검증이 아니다. |
| PList legacy 복원 | 실제 DC_TITLE/LIST_TEXT 2,213행의 한국어·7필드 무손상과 typed persistence 일치를 확인했다. 기본 selectionMapped=1,581/차단 632와 별도 GraphE 22/14를 합친 결과는 1,603/610이다. selection 매핑은 scene data·asset·PREPARE·PGM 완료 증거가 아니다. |
| manual named save | 현재 legacy PList manual 36행은 모두 GraphE이며 fresh proof로 22행을 복원하고 저장값 무효 9행·identity 중복 5행을 차단했다. FSell/VI PList행은 0건이고 production source read는 FSell 3×5행, VI 9항목·2 page로 전후 불변이다. 실제 Oracle save→reload와 PGM은 미검증이다. |
| ThemeA/EList identity | expected identity·상관 응답 계약은 구현했다. 실제 운영 DB의 KRX/NXT·동명이름·코드 경계와 정확한 선택 행 replace/delete는 미검증이다. |
| legacy file import | 종목비교.dat는 signed package에서 8쌍 1회 실행·재시작 marker까지 확인했다. FSell·VI importer는 strict parser, source/hash 재검증, durable intent/marker와 격리 fixture를 통과했으며 현재 운영 profile은 기존 동일 파일 때문에 no-overwrite 차단된다. |
| 남은 실환경 검증 | 다섯 전용 화면의 Web 연결과 signed 1.0.5.0 Release MSIX package-context 실행은 화면/계약 검증 범위에서 확인됐다. 1.0.5 package UI에서 실제 삼성전자 검색·현재가 5001 DryRun과 자동 refresh cap을 확인했으며, 기존 10개 업무 탭 상태·비교 8쌍 영속성 증거는 1.0.4 감사에 보존한다. 실제 입력→운영 DB write→재조회와 각 전용 scene PGM 검증은 별도 승인·테스트 데이터·rollback 회차에서만 수행한다. |