From 3483f84044dfa40c1a25441d3ecda80f5dc0bee2 Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Mon, 13 Jul 2026 00:03:11 +0900 Subject: [PATCH] feat(dotnet): add migration boundary registry --- .../Services/MigrationBoundaryRegistry.cs | 112 ++++++++++++++++++ .../MigrationBoundaryRegistryTests.cs | 22 ++++ 2 files changed, 134 insertions(+) create mode 100644 src/dotnet/QuantEngine.Application/Services/MigrationBoundaryRegistry.cs create mode 100644 src/dotnet/QuantEngine.Core.Tests/MigrationBoundaryRegistryTests.cs diff --git a/src/dotnet/QuantEngine.Application/Services/MigrationBoundaryRegistry.cs b/src/dotnet/QuantEngine.Application/Services/MigrationBoundaryRegistry.cs new file mode 100644 index 00000000..c5c1887d --- /dev/null +++ b/src/dotnet/QuantEngine.Application/Services/MigrationBoundaryRegistry.cs @@ -0,0 +1,112 @@ +using System.Collections.Generic; + +namespace QuantEngine.Application.Services; + +public enum MigrationDisposition +{ + Keep, + Migrate +} + +public sealed record MigrationBoundaryRoute( + string RouteId, + string Classification, + MigrationDisposition Disposition, + string[] Paths, + string Reason); + +/// +/// Canonical boundary registry for WBS-10 .NET migration planning. +/// This is a planning aid, not an execution engine. +/// +public static class MigrationBoundaryRegistry +{ + public static readonly IReadOnlyList Routes = new[] + { + new MigrationBoundaryRoute( + "python_harness_validation", + "python_harness", + MigrationDisposition.Keep, + new[] + { + "tools/validate_quant_engine_wbs_v1.py", + "tools/validate_dotnet_migration_roadmap_v1.py", + "tools/validate_dotnet_migration_execution_plan_v1.py", + "tests/unit/test_validate_dotnet_migration_roadmap_v1.py", + "tests/unit/test_validate_dotnet_migration_execution_plan_v1.py" + }, + "검증 도구는 운영 엔진이 아니라 하네스/계약 검사 계층이다."), + + new MigrationBoundaryRoute( + "python_wbs_source", + "python_harness", + MigrationDisposition.Keep, + new[] + { + "spec/60_quant_engine_wbs.yaml", + "docs/WBS_10_DOTNET_MIGRATION_ROADMAP.yaml", + "docs/WBS_10_DOTNET_MIGRATION_INVENTORY.yaml", + "docs/WBS_10_DOTNET_MIGRATION_EXECUTION_PLAN.yaml" + }, + "권위 문서와 상세 로드맵은 운영 실행물이 아니라 계약 문서다."), + + new MigrationBoundaryRoute( + "dotnet_core_formula_engine", + "dotnet_domain", + MigrationDisposition.Migrate, + new[] + { + "src/dotnet/QuantEngine.Core/Domain/FormulaEngine.cs", + "src/dotnet/QuantEngine.Core/Domain/FactorCalculator.cs", + "src/dotnet/QuantEngine.Core/Domain/AntiChasingCalculator.cs", + "src/dotnet/QuantEngine.Core/Domain/ProfitLockCalculator.cs", + "src/dotnet/QuantEngine.Core/Domain/PullbackTriggerCalculator.cs", + "src/dotnet/QuantEngine.Core/Domain/SellPriceSanityChecker.cs", + "src/dotnet/QuantEngine.Core/Domain/KrxTickNormalizer.cs" + }, + "운영 계산의 canonical engine 후보이며 parity harness의 주 대상이다."), + + new MigrationBoundaryRoute( + "dotnet_application_orchestration", + "dotnet_application", + MigrationDisposition.Migrate, + new[] + { + "src/dotnet/QuantEngine.Application/Services/PipelineOrchestrator.cs", + "src/dotnet/QuantEngine.Application/Services/KisDataCollectionOrchestrator.cs", + "src/dotnet/QuantEngine.Application/Services/HistoryIngestionService.cs", + "src/dotnet/QuantEngine.Application/Services/PriceDataNormalizer.cs", + "src/dotnet/QuantEngine.Application/Services/SourcePriorityResolver.cs", + "src/dotnet/QuantEngine.Application/Services/DataCollectionService.cs" + }, + "Python 오케스트레이션/수집/정규화 흐름을 .NET 서비스 계층으로 수렴시킨다."), + + new MigrationBoundaryRoute( + "dotnet_web_scheduler", + "dotnet_web", + MigrationDisposition.Migrate, + new[] + { + "src/dotnet/QuantEngine.Web/Services/SchedulerService.cs", + "src/dotnet/QuantEngine.Web/Endpoints/CollectionEndpoints.cs", + "src/dotnet/QuantEngine.Web/Pages/Admin/Operations/Index.cshtml.cs" + }, + "스케줄러와 운영 제어면은 서비스 수준으로 고도화 대상이다."), + + new MigrationBoundaryRoute( + "dotnet_read_models", + "read_model", + MigrationDisposition.Migrate, + new[] + { + "src/dotnet/QuantEngine.Web/Pages/Admin/Dashboard/Index.cshtml.cs", + "src/dotnet/QuantEngine.Web/Pages/Admin/Collection/Index.cshtml.cs", + "src/dotnet/QuantEngine.Web/Pages/Admin/Monitoring/Index.cshtml.cs", + "src/dotnet/QuantEngine.Web/Pages/Admin/Database/Index.cshtml.cs" + }, + "운영 조회는 역정규화 read model로 분리한다.") + }; + + public static MigrationBoundaryRoute? Find(string routeId) + => System.Linq.Enumerable.FirstOrDefault(Routes, route => route.RouteId == routeId); +} diff --git a/src/dotnet/QuantEngine.Core.Tests/MigrationBoundaryRegistryTests.cs b/src/dotnet/QuantEngine.Core.Tests/MigrationBoundaryRegistryTests.cs new file mode 100644 index 00000000..63e2dd76 --- /dev/null +++ b/src/dotnet/QuantEngine.Core.Tests/MigrationBoundaryRegistryTests.cs @@ -0,0 +1,22 @@ +using System.Linq; +using QuantEngine.Application.Services; +using Xunit; + +namespace QuantEngine.Core.Tests; + +public class MigrationBoundaryRegistryTests +{ + [Fact] + public void RoutesContainCanonicalKeepAndMigrateEntries() + { + Assert.NotNull(MigrationBoundaryRegistry.Find("python_harness_validation")); + Assert.NotNull(MigrationBoundaryRegistry.Find("dotnet_core_formula_engine")); + Assert.NotNull(MigrationBoundaryRegistry.Find("dotnet_application_orchestration")); + Assert.NotNull(MigrationBoundaryRegistry.Find("dotnet_web_scheduler")); + Assert.NotNull(MigrationBoundaryRegistry.Find("dotnet_read_models")); + + var routes = MigrationBoundaryRegistry.Routes; + Assert.Equal(4, routes.Count(r => r.Disposition == MigrationDisposition.Migrate)); + Assert.Equal(2, routes.Count(r => r.Disposition == MigrationDisposition.Keep)); + } +}