docs: record 1.0.4 package verification
This commit is contained in:
@@ -30,22 +30,22 @@
|
||||
| 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,259/1,259, Playout Debug/Release 387/387과 앱 Debug/Release x64 build를 통과했다. signed 패키지에서 별도 root 상태 메시지와 F2/F3를 확인하고, 자산 제공 뒤 다음 PREPARE mutation/PGM은 승인 회차에서 검증한다. |
|
||||
| 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 371/371과 signed 1.0.3 패키지 반영을 확인했다. | 새 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.3 package context에서 Startup→DryRunReady→Oracle/MariaDB Healthy→Shutdown→재시작이 같은 파일에 잔존했고 SQL·경로·인증·requestId 금지 문자열은 0건이었다. | 운영 회차에서도 로그를 명령 재시도 근거로 사용하지 않고 authoritative 출력과 함께 판독한다. |
|
||||
| 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-external`과 `reload` 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.js`의 `renderStockWorkflow`; 테스트 `operator-ui-app-integration.test.cjs` | 종목 검색·31컷을 catalog panel 밖의 독립 열로 옮기고 모든 업무 메뉴에서 항상 표시한다. 1920 브라우저에서 11개 메뉴를 이동해 검색어, 표시, 31개 행이 유지되고 문서 가로 overflow가 없음을 확인했다. | signed MSIX에서 실제 DB 검색 결과·선택 종목이 모든 탭 전환 뒤 유지되고 컷 추가가 같은 identity를 쓰는지 확인한 뒤 완료로 올린다. |
|
||||
| LF-017 | P1 | 모든 업무 탭에서 계속 보이는 종목 검색·31컷 | 완료 | 원본 `MBN_STOCK_N/MainForm.Designer.cs:2022-2036,2454-2462`; 현재 `Web/index.html`의 독립 `stock-panel`, `Web/app.js`의 `renderStockWorkflow`; 테스트 `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, 00~12 PRE/13~23 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/제목/요청을 해외로 맞춰다. 실제 브라우저에서 해외만 active, 최초 요청 1회, dashboard 진입·복귀를 확인했고 signed 1.0.3에 같은 Web 31개가 byte 일치했다. | 후속 탭 추가 시에도 초기 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.3 패키지에 Web 31개 일치로 반영했다. |
|
||||
| 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 371/371과 signed 1.0.3 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 371/371과 signed 1.0.3 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 371/371 통과. |
|
||||
| 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 371/371, 실제 브라우저에서 접근 라벨/가로 overflow 0, signed 1.0.3 Web 일치 통과. |
|
||||
| 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 재분류
|
||||
|
||||
|
||||
Reference in New Issue
Block a user