Files
MBN_STOCK_WEBVIEW/docs/LEGACY_FEATURE_AUDIT.md

28 KiB
Raw Blame History

원본 기능 재감사 기준표

감사 기준일: 2026-07-12 원본(읽기 전용): C:\Users\MD\source\repos\MBN_STOCK_N 마이그레이션 대상: C:\Users\MD\source\repos\MBN_STOCK_WEBVIEW

이 문서는 원본 WinForms/FarPoint 프로그램과 현재 WinUI 3/WebView2 프로그램을 다시 대조한 결과다. 원본 저장소와 실제 Cuts는 읽기 전용으로 조사했다. 자동 테스트나 UI 코드가 존재한다는 사실과 실제 운영 환경에서 동등성이 확인됐다는 사실을 구분한다.

상태 정의

상태 의미
미적용 원본 동작의 대응 구현 또는 필수 검증 경로가 아직 없다.
적용 중 현재 작업 트리에 구현 또는 검사 보강이 있으나 최종 패키지·실환경 검증까지 끝나지 않았다.
완료 현재 코드와 해당 자동 검증에 반영됐고 이번 재감사에서 완료로 판정했다.
외부자산 필요 코드만으로 완료할 수 없으며 Git/MSIX 밖의 승인된 자산이나 운영 환경이 필요하다.

완료 수는 증분 포팅과 최종 회귀 결과에 따라 바뀌므로 아래 표를 단일 기준으로 사용한다. 기존 문서에서 사용하는 완료, 통합 완료, 전체 통과 표현도 아래 상태와 검증 범위로 다시 해석해야 한다.

우선순위별 결과

ID 우선순위 기능·누락 후보 상태 근거 파일·메서드 현재 판정 검증 방법
LF-001 P0 s6001 해외지수 영상 자산 외부자산 필요 현재 src/MBN_STOCK_WEBVIEW.Core/Playout/Scenes/ReadOnlyPanelSceneBuilders.cs:491-513, S6001SceneMutationBuilder.Metadata/Index; 검증기 src/MBN_STOCK_WEBVIEW.Playout/Configuration/ValidatedPlayoutOptions.cs:375-406, ResolveAssetPath 해외지수 15개 target이 13개 Video\20201008_<국가>.vrv에 의존한다. 감사 시 승인 Cuts의 Video 폴더는 비어 있어 이 target들은 DryRun PREPARE에서도 COM 호출 전에 차단된다. 유가·금의 PNG/JPG는 존재한다. 승인된 파일을 Cuts root 아래에 제공한 뒤 강화된 cut/asset 검사와 s6001 각 target DryRun PREPARE를 실행한다. 실제 PGM은 별도 승인 회차에서만 확인한다.
LF-002 P0 cut coverage의 장면 종속 asset 검사 완료 scripts/LegacyCutRequirements.json, LegacyCutCoverage.psm1, Test-LegacyCutCoverage.ps1; 테스트 tests/Scripts/Test-LegacyCutCoverage.Tests.ps1, LegacyCutRequirementManifestTests.cs 45개 active alias와 23개 장면 종속 asset을 분리해 존재·0바이트·root escape·reparse·manifest 중복을 검사한다. 완전/누락/0바이트/reparse/escape fixture가 자동 테스트에 연결됐다. 실제 승인 Cuts read-only 실행은 alias missing/unsafe 0, asset unsafe 0, asset missing 14로 정확히 실패했다: s5006 1개와 s6001 13개 영상이다. 실제 누락 14개가 승인 Cuts에 제공되면 같은 명령을 다시 실행해 Status=Passed를 확인한다. 검사기 완료와 외부 자산 준비 완료는 LF-001/LF-003에서 분리한다.
LF-003 P0 s5006 큐브 배경 영상 외부자산 필요 원본 MBN_STOCK_N/Scene/s5006.cs:30-31; 현재 src/MBN_STOCK_WEBVIEW.Core/Playout/Scenes/ReadOnlyPanelSceneBuilders.cs:31-48; docs/PLAYOUT_OPERATIONS.md:81-85 Video\큐브배경.vrv가 승인 Cuts에 없다. 기존 운영 문서에는 누락이 기록돼 있으나 파일 제공 전에는 s5006 PREPARE가 완료된 것이 아니다. asset 검사 통과 후 s5006 DryRun PREPARE, 승인된 Test/PGM 회차 순으로 검증한다.
LF-004 P0 실제 운영 DB write 미적용 docs/OPERATOR_UI_PARITY.md:48-62,167-170,214-218,229-246,278; GraphE MainWindow.ManualFinancial.cs; PList MainWindow.NamedPlaylists.cs; ThemeA/EList MainWindow.OperatorCatalogs.cs mutation 계약, fake executor, rollback·OutcomeUnknown 테스트는 존재하지만 GraphE, PList/AList, ThemeA, EList의 운영 Oracle write는 실행하지 않았다. FSell/VI도 격리 저장소 write만 검증했다. 따라서 운영 데이터 쓰기 동등성은 미검증이다. 승인된 테스트용 식별자와 사전 snapshot을 정하고 create/update/delete를 각 1회 실행한다. 매 단계 후 별도 read-only 조회로 결과를 대조하고, timeout·OutcomeUnknown이면 반복하지 않는다. 운영 데이터에는 임의로 실행하지 않는다.
LF-005 P0 전체 장면·운영 UI의 실제 Tornado2/PGM 검증 미적용 docs/MIGRATION.md:69-74; docs/OPERATOR_UI_PARITY.md:48-62; docs/PLAYOUT.md:348-366 승인된 실제 회차의 범위는 5001/5074와 그 Page/playlist NEXT, refresh, TAKE OUT이다. 자동 builder/DB smoke 결과를 나머지 장면의 PGM 동등성으로 확대할 수 없다. 장면별 허용 자산과 DB 전제조건을 먼저 통과시킨다. 이후 회차별 계획 SHA-256과 명시적 승인을 받아 Network Monitoring 명령, callback, PGM 화면을 함께 기록한다.
LF-006 P1 시스템 종료 확인 완료 MainWindow.CloseConfirmation.cs, EnsureCloseConfirmationAttached, OnAppWindowClosing, BuildCloseConfirmationMessage, DetachCloseConfirmation; 연결부 MainWindow.xaml.cs:54-63,101-112,OnClosed; 테스트 tests/Web/operator-ui-app-integration.test.cjs:384-408 모든 시스템 close를 먼저 취소하고 기본 버튼이 취소인 확인창을 연다. PREPARED/PROGRAM, command pending, OutcomeUnknown에 맞는 경고를 표시하며 종료 과정에서 TAKE OUT이나 반대 명령을 자동 실행하지 않는다. Web 통합 테스트를 실행하고 패키지 앱에서 idle, prepared/on-air 경고, 취소, 명시적 종료를 수동 확인한다.
LF-007 P1 패키지 앱 단일 인스턴스 완료 App.xaml.cs:9-57, OnLaunched, OnMainInstanceActivated; 테스트 tests/Web/operator-ui-app-integration.test.cjs:72-88 AppInstance.FindOrRegisterForKey가 MainWindow와 DB/WebView/playout runtime 생성 전에 실행된다. 두 번째 인스턴스는 activation을 primary로 전달한 뒤 종료하며 기존 프로세스를 이름으로 찾아 강제 종료하지 않는다. 통합 테스트 후 설치된 MSIX를 두 번 실행해 프로세스 하나, 창 하나, 기존 창 활성화를 확인한다.
LF-008 P1 운영자 모달의 전역 단축키 격리 완료 Web/app.js:6808-6845, hasOpenOperatorModal, isolateOperatorModalShortcut; 테스트 tests/Web/operator-ui-app-integration.test.cjs:410-429 GraphE, FSell/VI, ThemeA/EList 등 modal이 열려 있으면 F2/F3/F8/Escape, Home/End/Delete/Space, Ctrl+K가 workspace 송출·playlist handler로 전달되지 않는다. F8/Escape에는 modal을 먼저 닫으라는 안내를 표시한다. Web 통합 테스트 후 각 modal 입력 필드에서 해당 키를 눌러 playout command와 playlist mutation이 발생하지 않는지 확인한다.
LF-009 P1 PList의 기존 한국어 DC_TITLE/LIST_TEXT 복원 적용 중 원본 MBN_STOCK_N/Form/PList.cs:81-124, data_load; 현재 src/MBN_STOCK_WEBVIEW.Core/Data/LegacyPListReadAudit.cs, tools/MBN_STOCK_WEBVIEW.DbSmoke/NamedPlaylistReadOnlyDbAudit.cs, tools/MBN_STOCK_WEBVIEW.DbSmoke/NamedManualRestoreReadOnlyAudit.cs; KRX/해외종목/manual 전용 restore와 테스트; 상세 docs/NAMED_PLAYLIST_READ_AUDIT.md 실제 Oracle 활성 정의 23개와 2,213행 모두 정확히 7필드이고 원문 재결합, 한국어 제목·필드, enabled, page 공백 제거 및 typed persistence가 일치했다. 기본 감사는 KRX 94행 current-code remap과 해외종목 78/78을 포함해 selectionMapped=1,581, 차단 632다. 별도 GraphE fresh 감사가 manual 36행 중 22행을 materialize하고 저장값 무효 9행·identity 중복 5행을 차단해 두 증거의 통합 결과는 selectionMapped=1,603, 차단 610이다. 이 수치는 scene data·asset·PREPARE·PGM 성공이 아니다. 집중 테스트, Release 실제 read-only DB 감사와 전체 REAL_DB_SMOKE: PASS. FSell/VI PList 행은 0건이지만 운영 production read는 FSell 3×5행, VI 9항목·2 page이고 파일 전후 불변이다. raw 값·인증정보 출력, DB write, Tornado/PGM 명령은 0건이다. 남은 KRX/NXT/live-data·GraphE identity/data·unique mapper 차단을 해소하고 scene/asset/package/PGM gate를 별도로 통과하기 전에는 전체 복원 완료로 올리지 않는다.
LF-010 P1 원본 F2/F3 배경 디렉터리 동등성 코드 적용 / 외부자산 필요 원본 MBN_STOCK_N/MainForm.cs:4008-4054, btnback_Click, ckback_CheckedChanged; 현재 MainWindow.Background.cs, PlayoutSceneCompositionFactory, TrustedPlayoutAssetPath, ValidatedPlayoutOptions; 문서 docs/TRUSTED_BACKGROUND_ROOT.md Cuts gate를 유지한 채 별도 LegacyBackgroundDirectory를 추가했고, 생략 시 원본처럼 SceneDirectory\..\배경을 계산한다. F2는 유효할 때만 picker 전 기본.vrv를 복원하고 F3-on은 항상 기본 파일을 다시 검증한다. root escape·조상/파일 reparse·hardlink·누락·opened-handle final path를 fail closed로 검사하며 Cuts fallback은 없다. 이 장비의 원본 bin\Debug\배경기본.vrv는 실제로 없어 현재 기본 배경은 잠긴다. Core Debug/Release 1,377/1,377, Playout 387/387과 VS2026 앱 Debug/Release x64 build를 통과했다. signed 1.0.4 package는 누락 상태를 별도 배경 상태로 표시한다. 자산 제공 뒤 F2/F3와 다음 PREPARE mutation/PGM은 승인 회차에서 검증한다.
LF-011 P1 종목비교.dat 기존 저장쌍 이전 완료 원본 MBN_STOCK_N/Control/UC3.cs:34-55,181-185, UC3_Load, Data_Load, File_Save; 현재 src/MBN_STOCK_WEBVIEW.Core/Data/LegacyComparisonPairImport.cs, MainWindow.LegacyComparisonImport.cs, Web/comparison-import-workflow.js, Web/app.js; 테스트 LegacyComparisonPairImportServiceTests.cs, comparison-import-workflow.test.cjs, comparison-import-app-integration.test.cjs; 실행 증거 docs/LEGACY_ONE_TIME_IMPORT_AUDIT.md 원본 CP949 358바이트·8행·9필드와 SHA-256 1EE76BC4…BFC0D2F2를 고정하고, 고정 read-only source·strict parser·현재 Oracle/MariaDB exact identity·전체 원자 저장·one-time marker를 적용했다. 설치된 signed 1.0.3 package에서 빈 상태 0 PAIRS를 확인한 뒤 명시적 버튼을 정확히 한 번 실행해 8쌍을 저장했다. 정상 종료·재시작 후에도 8 PAIRS, 원본 순서의 8행과 완료형 원본 8쌍 가져옴 gate가 유지됐고, 원본 파일 SHA-256은 불변이었다. 원본·DB·Tornado에는 쓰기나 명령을 보내지 않았다. Core 20/20, Web 12/12, 실제 read-only DB identity 8/8, package 0→8 및 재시작 marker 영속성 PASS. 손상·동명이름·기존쌍 중복·부분 실패는 계속 전체 fail closed이며 package family data를 초기화해 같은 회차를 재현하지 않는다.
LF-012 P1 FSell/VI 원본 Data의 안전한 이전과 설정 문서 적용 중 원본 MBN_STOCK_N/MainForm.cs:338-339, FSell.cs:31-88, VIList.cs:31-34,137-139; importer LegacyManualOperatorDataImport, LegacyManualOperatorDataImporter; production read S5025TrustedManualFileDataSource, ViTrustedManualFileStore; 감사 tools/MBN_STOCK_WEBVIEW.DbSmoke/NamedManualRestoreReadOnlyAudit.cs, docs/NAMED_MANUAL_RESTORE_READ_ONLY_AUDIT.md 고정 원본 경로·strict CP949·source/hash 재검증·no-overwrite staged commit·marker-last·OutcomeUnknown quarantine를 유지한다. 격리 fixture는 FSell 15행·VI 9건, aggregate SHA-256 fd39a363…a2114, 첫 실행 성공과 두 번째 AlreadyImported를 확인했다. 운영 profile은 이미 원본과 byte-identical한 4파일이 있어 importer가 DestinationNotEmpty로 차단되며 marker/intent를 만들지 않는다. production opened-handle read는 FSell 3 audience 각각 5행, VI 9항목·2 page와 안정된 두 번째 version을 확인했고 감사 전후 4파일은 불변이다. 현재 PList에는 FSell/VI 행이 0건이다. 새 빈 signed package profile의 명시적 UI importer 검증은 남아 있다. 현재 운영 profile의 동일 파일을 덮어쓰거나 marker를 임의 생성하지 않는다. PList에 향후 FSell/VI 행이 생기면 같은 fresh source/version gate를 거치며 scene data·asset·PREPARE·PGM은 별도 검증한다.
LF-013 P1 generic native bridge-error 표시 완료 producer MainWindow.xaml.cs, MainWindow.Playout.cs; consumer Web/app.js handleBridgeError/handleNativeMessage; 테스트 operator-ui-app-integration.test.cjs bounded toast/log로 소비하며 malformed status/quarantine payload에서 playout state를 변경하지 않는다. 전체 Web 413/413과 signed 1.0.4 패키지 반영을 확인했다. 새 native error producer를 추가할 때마다 같은 bounded consumer 계약을 유지한다.
LF-014 P2 영구 운영 로그 완료 원본 MBN_STOCK_N/MainForm.cs:84-180; 현재 NativeOperatorLogWriter.cs, NativeOperatorLogTransitions.cs, MainWindow.NativeOperatorLog.cs %LOCALAPPDATA%\MBN_STOCK_WEBVIEW\Logs\Log_MMdd.log에 폐쇄 event/state만 기록하며 4MiB/31일, 중복 억제, reparse/handle 검증, single terminal/OutcomeUnknown 규칙을 적용한다. signed 1.0.4 package context에서도 Startup→DryRunReady→Oracle/MariaDB Healthy가 기록됐고 playout command·PROGRAM·OutcomeUnknown은 0건이었다. SQL·경로·인증·requestId를 기록하지 않는다. 운영 회차에서도 로그를 명령 재시도 근거로 사용하지 않고 authoritative 출력과 함께 판독한다.
LF-015 P2 호출자가 없는 native bridge handler 완료 MainWindow.xaml.cs, OnWebMessageReceived; 테스트 tests/Web/operator-ui-app-integration.test.cjs Web 호출자가 없던 open-externalreload message case를 native allowlist에서 제거했다. 외부 navigation/new-window 처리와 WebView process failure의 내부 reload 복구 메서드는 별도 native event 경로로 유지한다. 정적 계약 테스트에서 두 message case와 Web 발신 literal이 모두 없음을 확인했다.
LF-016 P2 실제 preview 이미지·영상 외부자산 필요 docs/MIGRATION.md:73-74; 원본 MBN_STOCK_N/MainForm.cs:1448-1462,1894-1911,2919-2921 현재 preview는 안전한 DTO/mutation 텍스트 중심이다. 실제 이미지·영상 연결은 후속 자산이다. 다만 원본 thumbnail 호출과 watcher는 주석 또는 미호출이므로 활성 원본 동등성의 P0/P1 blocker로 보지 않는다. 승인된 preview 자산이 생기면 asset root와 노출 정보 검사를 거쳐 패키지 화면에서 확인한다.
LF-017 P1 모든 업무 탭에서 계속 보이는 종목 검색·31컷 완료 원본 MBN_STOCK_N/MainForm.Designer.cs:2022-2036,2454-2462; 현재 Web/index.html의 독립 stock-panel, Web/app.jsrenderStockWorkflow; 테스트 operator-ui-app-integration.test.cjs; package 증거 docs/RELEASE_1_0_4_AUDIT.md 종목 검색·31컷을 catalog panel 밖의 독립 열로 옮겼다. signed 1.0.4 package에서 실제 삼성 검색 63건을 확인하고 10개 업무 탭을 모두 방문한 뒤에도 검색어·결과·31개 컷이 유지됐다. package는 계속 DryRun이었다. Web 413/413, source Web 33개 package byte 일치, 설치 package UI PASS. 향후 새 업무 탭도 같은 독립 패널 계약을 유지한다.
LF-018 P2 원본 트리·컷 목록 일괄 추가 제스처 적용 중 원본 부모 double-click MBN_STOCK_N/Control/UC1.cs:141-180; 소스 컷 Ctrl/Shift 선택 MBN_STOCK_N/MainForm.cs:3427-3525,3534-3549,3635-3643; 현재 Web/legacy-batch-selection-workflow.js, Web/app.js; 테스트 legacy-batch-selection-*.test.cjs 종목 31컷의 plain/Ctrl/Shift/Ctrl+Shift 선택, 단일 double-click, 선택 컷 추가를 포팅했다. 해외·환율·지수 fixed source의 섹션 전체 추가는 모든 자식을 먼저 materialize한 뒤 원본 순서로 한 번에 commit하며, 수동/지원불가가 한 건이라도 있으면 부분 추가 없이 전체 차단한다. 실제 브라우저에서 5개 선택, 해외 43개 순서 추가, 수동 혼합 섹션 0건 추가를 확인했다. signed MSIX 확인 뒤 업종·비교·테마 등 전용 source group의 부모 전체 추가가 원본에서 실제로 필요한 범위를 계속 분리 포팅한다. source drag/drop 자체는 오조작 검증 뒤 결정한다.
LF-019 P1 저장 PList의 테마_NXT stale code 복원 코드 완료 / DB view 정합성 대기 원본 Control/UC4.cs, Scene/s5074.cs, s5077.cs, s5088.cs; 현재 src/MBN_STOCK_WEBVIEW.Core/Data/LegacyNamedNxtThemeRestore.cs, MainWindow.NamedNxtThemeRestore.cs, Web/named-nxt-theme-restore-workflow.js; 테스트 LegacyNamedNxtThemeRestoreServiceTests.cs, named-nxt-theme-restore-workflow.test.cjs, named-nxt-theme-restore-app-integration.test.cjs; 상세 docs/NAMED_NXT_THEME_RESTORE.md, docs/NXT_THEME_RESTORE_READ_ONLY_AUDIT.md 제목 exact lookup, 현재 Maria code, 5/6/12행, 정렬 fallback, 0012 PRE/1323 AFTER와 fresh PageN을 닫힌 batch로 복원한다. 실제 48행/24제목은 current identity가 유일하고 저장 code는 전부 stale다. SB_ITEM 446행과 NXT master 446행은 존재하지만 원본과 새 앱이 공통으로 쓰는 v_all_stock 조인은 0행이어서 48행 모두 PreviewEmpty로 차단된다. 통합 PList 결과에서도 selectionMapped로 계산하지 않았고 추측성 직접-table fallback을 적용하지 않았다. Core Debug/Release와 실제 read-only DB smoke PASS, DB write·Tornado/PGM 명령 0건. DBA가 v_all_stock의 NXT 포함 의도를 확인해 승인된 변경·rollback으로 복구하거나 직접-table 경로를 별도 승인한 뒤 fresh page preflight/MSIX/PGM을 검증한다.
LF-020 P2 원본 초기 업무 화면 해외 완료 원본 MainForm.Designer.cs 첫 TabPage 해외; 현재 Web/index.html, Web/app.js; 테스트 operator-ui-app-integration.test.cjs dashboard는 진단 화면으로 유지하되 초기 active identity/제목/요청을 해외로 맞췄다. signed 1.0.4 package를 새로 실행했을 때 해외만 active였고 실제 해외 DB 상태가 표시됐다. 후속 탭 추가 시에도 초기 identity를 순번이 아닌 data-market으로 유지한다.
LF-021 P2 업무 탭 드래그 순서 변경 완료 원본 MainForm.cs:3183-3312; 현재 Web/market-nav-reorder.js, Web/app.js; 테스트 market-nav-reorder*.test.cjs dashboard는 첫 위치에 고정하고 10개 업무 identity만 drag 교환/Alt+위·아래로 이동한다. active view/DB/playlist는 불변이고 입력·modal·PREPARE 잠금에서 fail closed하며 세션 종료 시 기본 순서로 돌아간다. 실제 브라우저에서 Alt+Down 후 active 해외 유지와 reload 초기화를 확인했다. signed 1.0.4 패키지에 source Web 33개 일치로 반영했다.
LF-022 P2 GraphE 위/아래 찾기 완료 원본 GraphE.cs:338-379,605-611; 현재 Web/manual-financial-ui.js/.css; 테스트 manual-financial-ui.test.cjs 위로 찾기/아래로 찾기 버튼과 Enter 다음 찾기를 포팅했다. trim·대소문자 무시 Contains, 현재 행 전/후, no-wrap, 모든 pending·잠금·hidden 차단을 유지한다. 원본의 i > 0 첫 행 누락은 명백한 off-by-one으로 보고 첫 행도 정상 후보에 포함했다. GraphE 집중 20/20, 전체 Web 413/413과 signed 1.0.4 Web 일치 통과.
LF-023 P2 ThemeA/전문가 편집기 Delete 키 완료 원본 ThemeA.cs/UC6.cs; 현재 Web/operator-catalog-ui.js; 테스트 operator-catalog-ui.test.cjs ThemeA와 expert draft의 포커스/선택 행 하나를 기존 removeDraftItem으로 삭제하고 input/textarea/contenteditable, modal 밖, 잠금/DB write 중에는 상태를 변경하지 않는다. 삭제 후 inputIndex를 재배열하며 native 요청은 보내지 않는다. 관련 UI/workflow/bridge 32/32, 전체 Web 413/413과 signed 1.0.4 Web 일치 통과.
LF-024 P2 GraphE 종목명 헤더 정렬 완료 원본 GraphE.cs:258-280; 현재 Web/manual-financial-ui.js/.css; 테스트 manual-financial-ui.test.cjs 종목명 ↕ 첫 click 내림차순/둘째 click 오름차순을 세션 로컬 display order로 적용했다. 선택 snapshot/native/playlist는 불변이고 위/아래 찾기는 현재 표시 순서를 따른다. 새 화면/목록에서 오름차순으로 초기화한다. 네 모드·한글/ASCII·빈/단일·pending·정렬된 find 집중 20/20, 전체 Web 413/413 통과.
LF-025 P2 UC7 거래정지 종목명 헤더 정렬 완료 원본 Control/UC7.cs:173-188; 현재 Web/trading-halt-workflow.js, Web/app.js, Web/index.html; 테스트 trading-halt-name-sort-app-integration.test.cjs 종목명 ↕ 첫 click 내림차순/둘째 click 오름차순을 표시 order에만 적용했다. 동명은 market+stockCode로 결정적으로 정렬하고 선택 identity를 유지하며 새 검색은 server 순서로 초기화한다. DB/native/playlist 변경은 없다. 집중 18/18, 전체 Web 413/413, 실제 브라우저에서 접근 라벨/가로 overflow 0, signed 1.0.4 Web 일치 통과.

활성 PLAY_LIST 2,213행 read-only 재분류

운영 Oracle의 활성 프로그램 정의 23개와 연결된 2,213행을 원문을 출력하지 않는 감사로 다시 분류했다. 원본 PList.data_load의 page 공백 제거를 제외하면 모든 필드를 그대로 보존했고, 현재 persistence 결과와 2,213/2,213 일치했다.

route 건수 현재 결과
기존 닫힌 매퍼 1,250 hash 고정 원본 INI와 현재 exact signature로 selection 1,250개 매핑
업종 fixed 닫힌 매퍼 24 selection 24개 매핑
비교 fresh identity 99 selection 74개 매핑, 시장 identity 유실 25개 차단
해외지수 candle fresh identity 61 selection 61개 매핑
NXT theme fresh identity 48 validated preview empty 48 차단
KRX theme fresh identity 587 current-code remap 94, identity 없음 271, 저장 행 무효 16, preview empty 193, 지원 불가 action 13
해외종목 fresh identity 78 exact 입력명에서 unique symbol/nation을 correlated materialize해 78개 매핑
GraphE fresh materialization 36 별도 double-read row-version·stock identity·cut 계약으로 22개 매핑, 저장값 무효 9·identity 중복 5 차단. FSell/VI PList행은 0
unique closed mapper 없음 30 원본 328-action runtime hash와 현재 exact signature 중 단일 후보가 없어 nearest scene 추정 없이 차단
합계 2,213 기본 감사 selectionMapped=1,581/차단 632; 별도 GraphE proof를 합치면 selectionMapped=1,603/차단 610

unique=2,213은 전부 송출 가능하다는 뜻이 아니라 모든 행이 단일 route의 selection 결과 또는 명시적 차단 사유를 가졌다는 뜻이다. selectionMapped도 장면 데이터·자산, package context, PREPARE 또는 PGM 성공이 아니다. 이들은 집계 밖의 별도 gate다. KRX/NXT theme은 원본 s5074/s5077/s5088처럼 제목 exact lookup을 사용하며, 저장 code를 가장 가까운 현재 code로 추정하지 않는다. 비교 25행도 현재 이름이 우연히 유일하더라도 저장 행이 시장을 보존하지 않았으므로 계속 차단한다. 상세 SQL 경계와 결과는 NAMED_PLAYLIST_READ_AUDIT.md에 기록했다.

s6001 asset 검사 보강 기준

s6001 해외지수 target은 다음 13개 파일을 요구한다.

  • Video\20201008_미국.vrv
  • Video\20201008_독일.vrv
  • Video\20201008_영국.vrv
  • Video\20201008_프랑스.vrv
  • Video\20201008_일본.vrv
  • Video\20201008_중국.vrv
  • Video\20201008_홍콩.vrv
  • Video\20201008_대만.vrv
  • Video\20201008_싱가포르.vrv
  • Video\20201008_태국.vrv
  • Video\20201008_필리핀.vrv
  • Video\20201008_말레이시아.vrv
  • Video\20201008_인도네시아.vrv

검사 보강은 다음 조건을 만족해야 한다.

  1. .t2s alias 결과와 asset 결과를 별도 필드로 보고한다.
  2. 상대 경로만 허용하고 Cuts root 탈출을 거부한다.
  3. 파일 존재, 0바이트 여부, reparse point를 검사한다.
  4. 누락된 상대 경로와 영향을 받는 builder를 운영자가 알 수 있게 하되 secret이나 외부 절대 경로를 출력하지 않는다.
  5. asset이 없는 현재 장비에서는 전체 migration 완료가 아니라 외부자산 필요로 끝나야 한다.
  6. 완전 fixture, 단일 누락, 복수 누락, 0바이트, reparse fixture를 자동화한다.

권장 검증 명령 형태:

powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\Test-LegacyCutCoverage.ps1 `
  -CutRoot "<승인된 읽기 전용 Cuts root>"

검사 보강 전의 Missing=0.t2s alias만 의미하며 asset-ready 증거로 사용하면 안 된다.

원본 I/O 조사에서 제외 판정한 항목

  • 활성 Print/Excel/FarPoint export/import 호출은 발견되지 않았다.
  • MainForm.cs:1767-1772,1796-1805의 CSV playlist save/load는 주석 처리돼 있다.
  • MainForm.GetThumnail과 preview watcher/SaveImageFile 호출도 활성 경로가 아니다.
  • s8086은 scene builder는 존재하지만 원본 MainForm active alias가 없어 의도적으로 unreachable이다. 이를 UI 누락으로 계산하지 않는다.
  • FarPoint의 표·선택·정렬·이동 자체는 Web table/workflow로 변환할 수 있지만, 변환 UI가 존재한다는 사실만으로 DB write나 PGM 동등성이 완료되지는 않는다.

기존 완료 문서 교정 후속

다음 문서는 구현 존재, 자동 계약 테스트, 실데이터 read smoke, 외부 asset readiness, 실제 DB write, 실제 PGM 검증을 서로 다른 열로 분리해야 한다.

문서 교정할 표현 후속 교정 내용
docs/MIGRATION.md:69-74 MainForm/UC1~UC7과 전용 화면을 포괄적으로 완료로 표현 화면·bridge 구현운영 동등성 검증을 분리한다. PList 한국어 복원, s6001 asset, 원본 파일 one-time import, DB write, 장면별 PGM 상태를 이 문서와 맞춘다.
docs/OPERATOR_UI_PARITY.md:48-62 다수 화면을 화면 통합 완료로 표현 해당 표현은 구조적 UI 도달성만 뜻한다고 명시하고 DB-W/PGM 미검증을 상단 요약과 각 행에 유지한다. 완료 판정은 실제 검증 열까지 충족할 때만 사용한다.
docs/OPERATOR_UI_PARITY.md:75,111-113,214-218 PList와 비교쌍 load/save를 완료로 표현 PList 한국어 실DB 복원과 종목비교.dat one-time import를 별도 미완료 항목으로 추가한다.
docs/OPERATOR_UI_PARITY.md:77 F2/F3 배경을 완료로 표현 별도 sibling 배경 root와 기본.vrv 코드/자동 검증은 반영됐다. 실제 자산이 없으므로 package/PGM 완료로 확대하지 않는다.
docs/SCENE_EQUIVALENCE.md:17,98 전체 real-data smoke 및 s6001을 asset 경고 없이 통과로 표현 DB→DTO→mutation smoke와 실제 asset preflight를 분리하고 s6001 국가 영상 13개를 외부자산 필요로 기록한다.
docs/PLAYOUT_OPERATIONS.md:86,94 s5025 환경 변수 안내와 alias-only cut 검사 정상 앱의 private manual store 경로와 one-time import 정책을 정확히 설명한다. cut coverage 결과에 asset 검사 상태를 추가한다.
docs/PLAYOUT.md:97,348-366 Web 배경 변경 불가 설명 및 자동 검증을 35개 완료 근거로 사용 F2/F3 native picker의 실제 경계를 반영한다. 5001/5074 PGM 성공과 나머지 scene 자동 검증을 명확히 분리한다.

이 교정은 기존 구현 성과를 취소하는 것이 아니라, 구현됨실제 방송 동등성 완료를 같은 의미로 사용하지 않기 위한 것이다.

완료 판정에 필요한 최종 증거

  1. s5006/s6001 포함 모든 reachable scene의 asset preflight 결과
  2. PList 한국어 DC_TITLE/LIST_TEXT 실DB read 비교
  3. 기존 종목비교.dat, FSell, VI 데이터의 안전한 one-time migration 결과
  4. 승인된 테스트 데이터로 수행한 GraphE/PList/ThemeA/EList 및 manual file write read-back
  5. Debug/Release x64 회귀와 Release MSIX package-context 실행
  6. 승인된 scene·회차의 Network Monitoring 명령, callback, PGM 화면
  7. timeout·OutcomeUnknown에서 재시도하지 않았다는 운영 기록

이 증거가 갖춰지기 전에는 전체 원본 UI 또는 35개 scene의 동등성 목표를 완료 처리하지 않는다.