228 lines
19 KiB
Markdown
228 lines
19 KiB
Markdown
# MBN Stock WebView
|
|
|
|
기존 `MBN_STOCK_N` WinForms 애플리케이션을 단계적으로 대체하기 위한 Windows 데스크톱 프로젝트입니다.
|
|
|
|
> 현재 유일한 개발·실행 대상은
|
|
> [`src/MBN_STOCK_WEBVIEW.LegacyParityApp`](src/MBN_STOCK_WEBVIEW.LegacyParityApp)입니다.
|
|
> Visual Studio F5, 개발 MSIX, 신규 기능과 회귀 검증은 모두 이 앱을 기준으로 합니다.
|
|
|
|
루트 `MBN_STOCK_WEBVIEW.csproj`와 루트 `MainWindow*`/`Web`은 이전 비교 프로토타입입니다.
|
|
현행 솔루션과 기본 F5 대상에서는 제외하되, 연결된 과거 비교 테스트를 별도로 정리할 때까지
|
|
참고 소스로 보존합니다. 현재 완료·제한·외부 결정 범위는
|
|
[이관 현재 기준선](docs/MIGRATION_STATUS.md)이 유일한 우선 문서이며, 문서별 용도는
|
|
[문서 안내](docs/README.md)에서 확인할 수 있습니다.
|
|
|
|
현재 기준 기술 스택은 다음과 같습니다.
|
|
|
|
- .NET 8 / C#
|
|
- WinUI 3 (XAML)
|
|
- Windows App SDK 1.8.6 (`1.8.260317003`)
|
|
- WebView2 기반 운영 UI
|
|
- Windows x64 전용
|
|
- 단일 프로젝트 MSIX
|
|
|
|
## 현재 화면/계약 구현 범위
|
|
|
|
- WinUI 3 네이티브 창과 WebView2 간 JSON 메시지 브리지
|
|
- FarPoint 플레이리스트를 대체하는 Web UI
|
|
- 첫 열 송출 포함, 행/Ctrl+행 작업 선택
|
|
- 드래그 정렬 및 위/아래 이동
|
|
- 선택 삭제
|
|
- 로컬 저장/불러오기
|
|
- Oracle/MariaDB 4개 국내 시장 종목 검색과 실행 파일 옆 `Res` INI 기반 컷/UI 구성
|
|
- 원본 자산이 있는 전체 빌드는 읽기 전용 `bin\Debug\Cuts`를 실행 파일 옆 `Cuts`로 같은 구조로 배치
|
|
- 기존 운영 흐름을 반영한 `PREPARE` / `TAKE IN` / `NEXT` / `TAKE OUT` UI
|
|
- `F8`, `Esc` 단축키와 원본 배경 선택용 F2의 안전 예약
|
|
- 원본의 공급자 비의존 SQL/데이터 요청 71개를 .NET 8 Core 프로젝트로 이관
|
|
- Oracle/MariaDB 실제 비동기 `IDataQueryExecutor`와 소스별 health/retry/timeout
|
|
- WebView 코스피·코스닥·NXT·5개 지수·해외 실데이터 조회와 장애 UI
|
|
- COM 중립 `IPlayoutEngine`, x64 K3D late binding, 전용 STA 큐와 프로세스 감시
|
|
- 네이티브 결과가 성공한 뒤에만 갱신되는 `PREPARE` / `TAKE IN` / `NEXT` / `TAKE OUT` WebView 브리지
|
|
- 기본 `DryRun`, Test 전용 인스턴스·채널·씬 allowlist 및 Live 이중 승인 안전 게이트
|
|
- MSIX 패키지 매니페스트와 x64 게시 프로필
|
|
|
|
Oracle/MariaDB 조회 계층, 원본 10초 DB 상태 감시, Tornado/K3D 어댑터와 35개 scene 계약을 구현했습니다. 2026-07-22 현재 최신 개발 MSIX의 전체 UI/DB·로컬 상태 물리 검증과 실제 PGM runtime route code 33/34가 승인된 action 범위에서 끝났습니다. `s5006` 큐브 배경 action과 `s6001` 국가 영상 13 action만 원본에도 없는 외부 제작 자산 때문에 fail closed 상태이며, `s6001`의 두바이유·WTI·브렌트유·금 4 action은 실제 PGM 검증을 완료했습니다. 앱과 Release 패키지의 기본 모드는 계속 `DryRun`이며 Live allowlist, 명령 예산, callback/`OutcomeUnknown` 게이트를 완화하지 않습니다. 이 개발 PC의 Tornado2/PGM 마이그레이션 검증은 사용자가 반복 승인 없이 진행하도록 상시 허용했으며, 적용 범위와 중단 조건은 [개발 환경 상시 권한](docs/DEVELOPMENT_ENVIRONMENT_AUTHORIZATION.md)에 기록했습니다. DB 설정은 [DB 운영 가이드](docs/DATABASE.md), 송출 설정·실제 검증 증거·롤백은 [Tornado/K3D 운영 가이드](docs/PLAYOUT.md), 원본 Scene/PageN 대조는 [송출 흐름 분석](docs/LEGACY_PLAYOUT_ANALYSIS.md), 장면별 현황은 [35개 Scene 동등성 매트릭스](docs/SCENE_EQUIVALENCE.md), 전체 412개 실행 action과 전용 편집 화면은 [운영자 UI 동등성 인벤토리](docs/OPERATOR_UI_PARITY.md)를 참고하세요.
|
|
|
|
35개 Scene/PageN 런타임과 원본 MainForm·UC1~UC7·GraphE·FSell·VIList·PList·AList·ThemeA·EList의 화면·bridge 계약은 WinUI 3/WebView2에 연결했습니다. 최신 패키지에서 실제 Windows 입력 1,838건으로 검색·키보드·컷/플레이리스트 drag·PList 모달과 화면별 버튼, 개발 DB create/save→fresh readback→delete를 검증했고 cleanup까지 확인했습니다. PList 2,213행은 모두 목록과 scene alias를 복원하며, 그중 1,617행은 fresh typed selection까지 증명됐고 596행은 식별정보 부족으로 추정 없이 보류합니다. `5077` 6행 20페이지 전체, 마지막 페이지, `5088` 12행 전환, 장기 실행 뒤 unload와 `s6001` 영상 비의존 4 action도 실제 PGM에서 확인했습니다. 고객 배포용 서명 MSIX, 외부 영상·배경 자산, 보류 596행의 DBA 결정은 아직 남아 있습니다.
|
|
|
|
## 과거 검증 자료
|
|
|
|
`1.0.5` 패키지와 날짜가 붙은 Gate·Release·Live 문서는 당시 실행의 역사적 증거입니다.
|
|
현행 완료 판정이나 새 패키지 승인으로 재사용하지 않습니다. 당시 상세 내용은
|
|
[1.0.5 패키지 감사](docs/RELEASE_1_0_5_AUDIT.md)와
|
|
[동작 동등성 작업 기록](docs/LEGACY_BEHAVIOR_PARITY_WORKLOG.md)에 보존되어 있습니다.
|
|
|
|
## Visual Studio 2026에서 실행
|
|
|
|
상사 PC처럼 기존 코더 자산과 K3D가 설치된 개발 PC에서는 별도 PowerShell 명령을 먼저 실행할
|
|
필요가 없습니다.
|
|
|
|
1. `MBN_STOCK_WEBVIEW.sln`을 엽니다.
|
|
2. 솔루션 구성을 `Debug`, 플랫폼을 `x64`로 선택합니다.
|
|
3. 공유 시작 프로필 `Legacy Parity App (VS F5)` 또는
|
|
`src\MBN_STOCK_WEBVIEW.LegacyParityApp`을 시작 프로젝트로 선택합니다.
|
|
4. 실행 프로필이
|
|
`MBN_STOCK_WEBVIEW.LegacyParityApp - Development Live (Package)`인지 확인합니다.
|
|
5. `F5`로 빌드·배포·실행합니다.
|
|
6. 첫 실행 설정 창에서 기존 코더의 `Cuts` 폴더와 여러 INI가 함께 있는 `Res` 폴더, 두
|
|
폴더만 각각 선택하고 `설정 시작`을 누릅니다.
|
|
7. 이 앱의 이전 로컬 설정이 다른 경우에만 업데이트 확인 창이 한 번 표시됩니다. 선택한
|
|
두 폴더와 기본 Tornado2 설정으로 갱신하려면 `업데이트`를 누릅니다. K3D 기준값은 이
|
|
확인으로 바뀌지 않습니다.
|
|
8. `설정 완료`가 표시되면 창을 닫고 `F5`를 한 번 더 누릅니다.
|
|
|
|
새로 받은 clone에 아직 이 PC의 검증된 runtime 연결이 없으면, 주변에 과거
|
|
`MBN_STOCK_N\...\bin\Debug`가 있더라도 첫 F5는 안전한
|
|
**소스 전용 첫 실행 설정 앱**으로 빌드됩니다. 이 첫 프로세스는 과거 로컬 송출 프로필·환경
|
|
변수·Development Live 실행 인수를 무시하고 DB 미연결과 DryRun을 강제하므로 설정 중에는
|
|
Tornado2/PGM에 연결하거나 명령을 보내지 않습니다. 출력과 중간 패키징 파일도 이전 전체
|
|
빌드의 `Cuts`, `Res` 또는 DB 설정을 잘못 재사용하지 않도록 `bin\SourceOnly`와
|
|
`obj\SourceOnly`에 분리됩니다.
|
|
|
|
### 기존 설치가 있는 개발 PC에서 실제 송출
|
|
|
|
상사 PC처럼 `Cuts`, `Res\MmoneyCoder.ini`, Tornado2/K3D x64와 장비 라이선스가 이미 있는
|
|
지정 개발 장비에서는 Git에 자산·DB 설정·DLL·라이선스를 넣거나 runtime ZIP을 다시 전달할
|
|
필요가 없습니다. 첫 실행 창에는 다음 두 폴더만 입력합니다.
|
|
|
|
- `Cuts`: 실제 실행 자산의 `Cuts` 폴더
|
|
- `설정/INI (Res)`: `MmoneyCoder.ini`, `종목.ini`, `업종_코스피.ini`,
|
|
`업종_코스닥.ini`, `해외.ini`, `환율.ini`, `지수.ini`, `종목비교.ini`가 함께 있는
|
|
실제 `Res` 폴더
|
|
|
|
개별 INI를 따로 고르는 입력은 없습니다. 첫 실행 설정이 위 **활성 INI 8개**를 모두
|
|
확인하며, `MmoneyCoder.ini`는 DB 설정으로, 나머지 7개는 컷/UI 구성 정보로 처리합니다.
|
|
두 폴더는 같은 공통 부모 아래에 나란히 있어야 하며 폴더 이름도 각각 `Cuts`, `Res`여야
|
|
합니다. 소스 트리의 오래된 `RES`나 이름이 비슷한 백업 폴더가 아니라 기존 코더가 실제
|
|
실행에 사용하던 `bin\Debug\Cuts`, `bin\Debug\Res` 성격의 폴더를 선택합니다.
|
|
|
|
초기화기는 기존 자산을 검증한 뒤 사용자 전용 LocalAppData에 검증된 runtime 복사본을 만들고,
|
|
그 경로를 명시해 전체 Debug 빌드를 먼저 검증합니다. Git 제외
|
|
`Directory.Build.local.props`는 DB/K3D/Development Live 설정까지 성공한 뒤 마지막 성공
|
|
표식으로 기록되어, 중간에 Visual Studio가 종료되면 다음 F5도 첫 실행 설정 화면으로
|
|
돌아옵니다.
|
|
DB INI도 사용자 전용 LocalAppData overlay로 복사해 ACL을 보호하고, K3D x64 등록을 읽기
|
|
전용으로 점검합니다. 예상 HKLM x64 등록·CLSID·ProgID·TypeLib·vendor 배치가 모두 맞는
|
|
설치본의 두 DLL 해시를 이 PC의 최초 기준값으로 자동 고정하고, 이후 파일이 바뀌면
|
|
Development Live를 차단합니다. 기준값은 사용자 전용
|
|
`%LOCALAPPDATA%\MBN_STOCK_WEBVIEW\Config\k3d-pins.local.json`에 지속 저장되며 Git에는
|
|
들어가지 않습니다. 지정 개발 환경의 Tornado2는 별도 입력 없이 회사 기본값
|
|
`127.0.0.1:30001`로 구성합니다. 보호된 Development Live 설정은 모든 검증이 성공한
|
|
마지막 기능 설정 단계에서만 발급되고, 그 뒤 로컬 build binding이 성공 표식으로 기록됩니다.
|
|
|
|
테스트 개발 서버라 자격증명 노출 위험을 수용하는 경우에도 저장소 계약은 바뀌지 않습니다.
|
|
`MmoneyCoder.ini`와 DB 자격증명은 사용자 전용 LocalAppData에만 두고 Git, 빌드 출력,
|
|
runtime bundle과 MSIX에는 포함하지 않습니다.
|
|
|
|
Debug x64 빌드 출력은 선택한 manifest와 경로·길이·SHA-256·파일 집합이 정확히 일치하고
|
|
SourceOnly가 아닌지까지 자동 확인합니다. 중간 단계가 실패하면 기존 runtime 연결과 DB
|
|
overlay를 원래 내용·ACL로 되돌리고 Live 승인 파일을 남기지 않습니다. 이 과정은 Tornado에
|
|
`CONNECT`하거나 장면을 송출하지 않습니다.
|
|
|
|
초기화가 성공하면 Visual Studio에서 `Debug|x64`, `Legacy Parity App (VS F5)`,
|
|
`MBN_STOCK_WEBVIEW.LegacyParityApp - Development Live (Package)`를 선택해 F5로 시작합니다.
|
|
앱이나 빌드 출력이 `SourceOnly` 또는 `DryRun`이라고 표시되면 송출을 시도하지 말고 초기화를
|
|
바로잡습니다. 최초 실제 확인은 [개발 PGM 인수 절차](docs/DEVELOPMENT_LIVE_HANDOFF.md)에 따라
|
|
`5001` 하나로 진행합니다. Development Live는 이 Debug 프로세스에만 적용되며 Release와 기본
|
|
프로필은 계속 `DryRun`입니다. 이 프로필은 보호된 LocalAppData 설정만 읽고 상속된
|
|
`MBN_STOCK_PLAYOUT_*`·DB 환경 변수와 기존 운영자 scene/resource/background 선택을 무시합니다.
|
|
endpoint는 숫자형 loopback, scene root는 실행 파일 옆 검증된 `Cuts`로 다시 고정하며 strict
|
|
검증이 실패하면 Live를 승인하지 않고 안전한 DryRun으로 시작합니다.
|
|
|
|
같은 clone에서는 로컬 연결 파일이 Git에 덮어써지지 않으므로 이후에는 `git pull` 후 F5로
|
|
확인할 수 있습니다. 저장소를 새 폴더에 다시 clone하거나 자산·DB 폴더 연결이 바뀌면 첫 실행
|
|
설정을 다시 진행합니다. K3D DLL이 최초 기준과 달라진 경우에는 첫 실행 설정을 반복해도 자동
|
|
재승인되지 않습니다. 벤더 변경을 독립적으로 검증한 뒤 두 SHA-256을 명시해 수동 교체해야
|
|
합니다. pull 뒤 Required 자산 검증이 실패하는 경우에도 F5를 계속 시도하지 말고 설정 오류를
|
|
바로잡습니다.
|
|
|
|
화면을 열 수 없는 장애 대응이나 기존 로컬 설정의 명시적 교체가 필요할 때만
|
|
`scripts\Initialize-ExistingDevelopmentPc.ps1`을 수동 도구로 사용합니다. 일반적인 새
|
|
clone 인수 절차에서는 이 스크립트를 직접 실행하지 않습니다. K3D 기준 교체의 정확한
|
|
`-ReplaceK3DPin` 절차는
|
|
[개발 PGM 인수 절차](docs/DEVELOPMENT_LIVE_HANDOFF.md#k3d-dll이-정식으로-교체된-경우)에
|
|
따릅니다.
|
|
|
|
해당 PC에 `Cuts`/`Res`가 없을 때만
|
|
`New-LegacyRuntimeBundle.ps1`과 `Initialize-LegacyRuntimeBundle.ps1`의 검증 ZIP 절차를
|
|
대안으로 사용합니다. 자세한 두 흐름은 [개발 PGM 인수 절차](docs/DEVELOPMENT_LIVE_HANDOFF.md)와
|
|
[Cuts/Res 런타임 배치](docs/LEGACY_RUNTIME_ASSETS.md)에 있습니다.
|
|
|
|
이 프로젝트는 MSIX 패키지 ID가 필요한 앱입니다. `bin` 아래의 EXE를 직접 실행하지 말고 반드시 Package 프로필이나 설치된 MSIX로 실행하세요.
|
|
|
|
기존 중복 형식 오류(`CS0121`, `CS0436`)는 루트 앱 프로젝트가 하위 Core 소스까지 다시 컴파일하던 문제였으며, 현재 `src\**\*.cs`를 앱 컴파일 대상에서 제외해 해결했습니다. Visual Studio가 이전 진단을 계속 표시하면 `빌드 > 솔루션 정리` 후 다시 빌드하세요.
|
|
|
|
## 명령줄 빌드
|
|
|
|
```powershell
|
|
dotnet restore MBN_STOCK_WEBVIEW.sln -p:Platform=x64
|
|
dotnet build MBN_STOCK_WEBVIEW.sln -c Debug -p:Platform=x64
|
|
```
|
|
|
|
K3D 등록 상태와 COM을 열지 않는 dry-run 송출 흐름 확인:
|
|
|
|
```powershell
|
|
powershell -NoProfile -ExecutionPolicy Bypass `
|
|
-File .\scripts\Inspect-K3DRegistration.ps1
|
|
dotnet run --project .\tools\MBN_STOCK_WEBVIEW.PlayoutSmoke `
|
|
-c Debug -p:Platform=x64 -- --dry-run
|
|
```
|
|
|
|
격리 Tornado TEST의 프로세스·Network Server 포트·loopback 주소·LISTEN 소유권은 COM을 열기 전에 [읽기 전용 점검 스크립트](scripts/Inspect-TornadoTestIsolation.ps1)로 확인합니다. 설치 폴더의 다른 Tornado2 버전 EXE는 현재 사용자 설정과 출력 장치를 공유할 수 있으므로 PGM 옆에서 TEST 대용으로 실행하지 않습니다.
|
|
|
|
별도 Test 인스턴스 검증은 [Tornado/K3D 운영 가이드](docs/PLAYOUT.md)의 단계별 CLI를 사용합니다. `--test-plan`은 절대 경로 로컬 JSON과 씬 자산만 확인하며 엔진/COM을 만들지 않습니다. PGM/PROGRAM이 전혀 없는 격리 출력에서만 `--test-connect`로 연결·해제를 확인한 뒤 `--test-sequence`로 `PREPARE → TAKE IN → NEXT → TAKE OUT`을 실행합니다. Test 명령은 `MBN_STOCK_PLAYOUT_*` 환경 override와 Live 설정을 거부하고 자동 재연결·재생을 하지 않습니다. 승인된 Test 씬 후보는 basename `5001`, `5006`이며 실제 자산 경로는 저장소에 기록하지 않습니다.
|
|
|
|
중요: 앱의 기본 `DryRun`, `--probe`, `--dry-run`, `--test-plan`은 `KTAPConnect`를 호출하지 않습니다. 따라서 이 단계에서 Tornado2의 `View > Network Monitoring Window`에 앱이 보낸 통신 기록이 없는 것은 정상입니다. 이 CLI 절차에서는 모든 안전 게이트를 통과한 격리 `Test`의 `--test-connect`에서 처음 네트워크 기록을 기대하며, 별도로 승인된 UI Test 실행도 기록을 만들 수 있습니다. 사용할 포트는 예제 숫자가 아니라 해당 격리 Test Tornado의 `Tools > Option > Control > Network Server > TCP Port` 실값이어야 합니다.
|
|
|
|
Tornado2의 `PGM` 창은 본 프로그램의 KTAP 명령을 렌더링하는 출력 창입니다. 현재 PGM과의 네트워크 왕복만 진단할 때는 일반 Test/Live 엔진을 완화하지 않고 `--pgm-connect-diagnostic`을 사용합니다. 이 명령은 Registry64에서 계산한 x64 K3D 네이티브 DLL과 Interop이 운영자 승인 SHA-256 핀 `MBN_STOCK_K3D_NATIVE_SHA256`/`MBN_STOCK_K3D_INTEROP_SHA256`과 각각 일치할 때만 동적으로 사용하며 `KTAPConnect → Disconnect`만 한 번 수행합니다. Scene player, 장면 로드, PREPARE, PLAY, STOP 계열 API 표면은 포함하지 않으며 해시 승인 절차와 판정 방법은 [Tornado/K3D 운영 가이드](docs/PLAYOUT.md)에 있습니다.
|
|
|
|
MSIX 생성:
|
|
|
|
```powershell
|
|
dotnet build .\src\MBN_STOCK_WEBVIEW.LegacyParityApp\MBN_STOCK_WEBVIEW.LegacyParityApp.csproj `
|
|
-c Release `
|
|
-p:Platform=x64 `
|
|
-p:GenerateAppxPackageOnBuild=true `
|
|
-p:AppxPackageSigningEnabled=false
|
|
```
|
|
|
|
위 명령은 서명되지 않은 개발 패키지를 `AppPackages`에 만듭니다. 배포용 MSIX는 `Package.appxmanifest`의 `Identity/Publisher` 값과 정확히 일치하는 인증서로 서명해야 합니다. 인증서와 개인 키는 저장소에 커밋하지 않습니다.
|
|
Release MSIX는 전체 런타임 자산을 필수로 검증합니다. 원본 위치가 기본 형제 경로와 다르면
|
|
`-p:LegacyRuntimeSourceRoot="D:\path\to\MBN_STOCK_N\MBN_STOCK_N\bin\Debug"`를
|
|
추가해야 합니다.
|
|
|
|
## 구성과 보안
|
|
|
|
원본 `Res/MmoneyCoder.ini`의 값은 저장소에 복사하지 않았습니다. 전체 자산 Debug 빌드,
|
|
소스 전용 빌드, 게시와 MSIX 모두 이 자격증명 파일을 빌드 입력이나 출력으로 사용하지 않습니다.
|
|
전체 자산 Debug/MSIX는 `%LOCALAPPDATA%\MBN_STOCK_WEBVIEW\Res\MmoneyCoder.ini` 또는 기존
|
|
`database.local.json`을 사용하고, 소스 전용 빌드는 DB 미연결을 강제합니다. 일반 실행에서는
|
|
환경 변수가 선택된 파일보다 우선하지만, 검증된 Development Live 프로필은 이 override를
|
|
의도적으로 무시하고 위 LocalAppData 파일만 사용합니다. 설정 우선순위, 보안과 실제 DB 스모크 방법은
|
|
[DB 운영 가이드](docs/DATABASE.md)에 정리했습니다.
|
|
|
|
MSIX 설치 폴더는 읽기 전용입니다. 전체 자산 빌드에서는 읽기 전용 원본 `Cuts` 179개와 허용된
|
|
UI용 `Res` 파일이 실행 출력·게시·MSIX에 포함되지만, DB 자격증명 INI·백업·인증서·벤더 DLL은
|
|
포함하지 않습니다. 현재 원본에 없는 `s5006`/`s6001` 영상과 일부 배경은 별도 원본 제작 자산을
|
|
확보해야 합니다. 로그, 플레이리스트, 운영자 설정과 미리보기 파일은
|
|
`ApplicationData.Current.LocalFolder` 또는 `LocalCacheFolder`에 저장합니다.
|
|
|
|
## 프로젝트 구조
|
|
|
|
```text
|
|
src/MBN_STOCK_WEBVIEW.LegacyParityApp/ WinUI 3 / WebView2 / 원본 동작 호환 MSIX 앱
|
|
MainWindow*.cs, Web/ 네이티브 권위·보안 경계와 로컬 운영 UI
|
|
MBN_STOCK_WEBVIEW.csproj 이전 프로토타입 앱(솔루션/F5 제외, 참고용 보존)
|
|
src/MBN_STOCK_WEBVIEW.Core/ 이관된 데이터 요청 및 공급자 비의존 Core
|
|
src/MBN_STOCK_WEBVIEW.Infrastructure/ Oracle/MariaDB 공급자·설정·복원력·health
|
|
src/MBN_STOCK_WEBVIEW.Playout/ x64 Tornado/K3D STA·COM 어댑터와 안전 게이트
|
|
tests/ Core/Infrastructure/Playout 단위 테스트
|
|
tools/MBN_STOCK_WEBVIEW.DbSmoke/ 비밀값을 출력하지 않는 실제 DB 스모크
|
|
tools/MBN_STOCK_WEBVIEW.PlayoutSmoke/ COM 비활성 probe/plan과 격리 Test 연결·시퀀스 CLI
|
|
Config/ 비밀값 없는 구성 템플릿
|
|
ThirdPartyNotices/ 공급자 재배포 라이선스 고지
|
|
docs/ 마이그레이션 기록과 다음 단계
|
|
```
|
|
|
|
원본 `C:\Users\MD\source\repos\MBN_STOCK_N`은 수정하거나 초기화하지 않았습니다.
|