Add one-click PoC run flow

This commit is contained in:
2026-06-09 14:43:19 +09:00
parent 11559c8ba8
commit c7adde3df2
4 changed files with 94 additions and 4 deletions

View File

@@ -153,6 +153,26 @@ namespace TornadoAce_CJOnStyle.Services
.ToArray();
}
public PocRunResult RunFullPoc(int selectedCueSheetIndex, SceneTemplateDefinition template)
{
var selection = SelectCueSheet(selectedCueSheetIndex);
var schedule = FindSchedule(selection.Record);
var generatedScene = GenerateScene(selection.Record, template);
var mappingValidations = ValidateMappingProfile(template);
var adapterChecks = GetTornadoAdapterChecks();
var inspectionSummary = InspectWorkspace(template);
var llmRequests = BuildLlmReviewRequests(inspectionSummary.Results);
return new PocRunResult(
selection,
schedule,
generatedScene,
mappingValidations,
adapterChecks,
inspectionSummary,
llmRequests);
}
private InspectionResult Inspect(CueSheetRecord cueSheet, SceneDataSnapshot snapshot, SceneTemplateDefinition template)
{
var expectedObjects = BuildVisibleTextObjects(cueSheet, template);
@@ -317,4 +337,13 @@ namespace TornadoAce_CJOnStyle.Services
int PassedCount,
int ReviewCount,
double AverageMatchRate);
public sealed record PocRunResult(
CueSheetSelection Selection,
ErpScheduleRecord? Schedule,
SceneDataSnapshot GeneratedScene,
IReadOnlyList<MappingValidationResult> MappingValidations,
IReadOnlyList<TornadoAdapterCheck> AdapterChecks,
PocInspectionSummary InspectionSummary,
IReadOnlyList<LlmReviewRequest> LlmReviewRequests);
}

View File

@@ -231,6 +231,37 @@ namespace TornadoAce_CJOnStyle.ViewModels
LoadLlmReviewRequests(summary.Results);
}
[RelayCommand]
private void RunPoc()
{
var result = automationEngine.RunFullPoc(selectedCueSheetIndex, workspace.ActiveTemplate);
activeCueSheet = result.Selection.Record;
activeSchedule = result.Schedule;
activeScene = result.GeneratedScene;
LastCueSheetSyncText = FormatCueSheetSelection(result.Selection);
ActiveTemplateName = workspace.ActiveTemplate.TemplateName;
InspectionSummary = FormatInspectionSummary(result.InspectionSummary);
OperatorMessage = FormatPocRunSummary(result);
StatusCards[0].Metric = result.Selection.TotalCount.ToString();
StatusCards[0].Detail = $"ERP {FormatScheduleStatus(result.Schedule)}";
StatusCards[1].Metric = workspace.ActiveTemplate.Mappings.Count.ToString();
StatusCards[1].Detail = "Scene 생성 완료";
StatusCards[2].Metric = $"{result.InspectionSummary.AverageMatchRate:0.0}%";
StatusCards[2].Detail = $"LLM 후보 {result.LlmReviewRequests.Count}건";
StatusCards[3].Metric = "Adapter";
StatusCards[3].Detail = "Scene API Mock";
ApplySceneSnapshot(result.GeneratedScene);
LoadMappingValidation(result.MappingValidations);
LoadTornadoAdapterChecks(result.AdapterChecks);
LoadScheduleMatches();
LoadInspectionQueue(result.InspectionSummary.Results);
LoadInspectionDetails(result.InspectionSummary.Results);
LoadLlmReviewRequests(result.InspectionSummary.Results);
}
private void LoadStatusCards()
{
StatusCards.Add(new StatusCardViewModel("큐시트 API", "12", "수신 대기", Symbol.Sync, Brush(0xFF45D6D1)));
@@ -257,10 +288,15 @@ namespace TornadoAce_CJOnStyle.ViewModels
}
private void LoadMappingValidation()
{
LoadMappingValidation(automationEngine.ValidateMappingProfile(workspace.ActiveTemplate));
}
private void LoadMappingValidation(IEnumerable<MappingValidationResult> validations)
{
MappingValidations.Clear();
foreach (var validation in automationEngine.ValidateMappingProfile(workspace.ActiveTemplate))
foreach (var validation in validations)
{
MappingValidations.Add(new MappingValidationViewModel(
validation.CheckId,
@@ -280,10 +316,15 @@ namespace TornadoAce_CJOnStyle.ViewModels
}
private void LoadTornadoAdapterChecks()
{
LoadTornadoAdapterChecks(automationEngine.GetTornadoAdapterChecks());
}
private void LoadTornadoAdapterChecks(IEnumerable<TornadoAdapterCheck> checks)
{
TornadoAdapterChecks.Clear();
foreach (var check in automationEngine.GetTornadoAdapterChecks())
foreach (var check in checks)
{
TornadoAdapterChecks.Add(new TornadoAdapterCheckViewModel(
check.CheckId,
@@ -404,6 +445,17 @@ namespace TornadoAce_CJOnStyle.ViewModels
: $"ERP 편성 {schedule.ProgramCode}와 매칭됐습니다.";
}
private static string FormatScheduleStatus(ErpScheduleRecord? schedule)
{
return schedule is null ? "대기" : "매칭";
}
private static string FormatPocRunSummary(PocRunResult result)
{
var scheduleText = result.Schedule is null ? "ERP 미확인" : result.Schedule.ProgramCode;
return $"PoC 실행 완료: {result.Selection.Record.CueSheetId} / {scheduleText} / {result.GeneratedScene.SceneName} / 검수 확인 {result.InspectionSummary.ReviewCount}건 / LLM 후보 {result.LlmReviewRequests.Count}건";
}
private static SolidColorBrush SeverityBrush(string severity)
{
return severity switch

View File

@@ -119,6 +119,14 @@
Orientation="Horizontal"
Spacing="10"
VerticalAlignment="Top">
<Button
Command="{x:Bind ViewModel.RunPocCommand}"
Style="{StaticResource PrimaryActionButtonStyle}">
<StackPanel Orientation="Horizontal" Spacing="7">
<SymbolIcon Symbol="Play" />
<TextBlock Text="PoC 실행" />
</StackPanel>
</Button>
<Button
Command="{x:Bind ViewModel.RefreshCueSheetCommand}"
Style="{StaticResource GhostActionButtonStyle}">
@@ -129,7 +137,7 @@
</Button>
<Button
Command="{x:Bind ViewModel.GenerateSceneCommand}"
Style="{StaticResource PrimaryActionButtonStyle}">
Style="{StaticResource GhostActionButtonStyle}">
<StackPanel Orientation="Horizontal" Spacing="7">
<SymbolIcon Symbol="Play" />
<TextBlock Text="Scene 생성" />

View File

@@ -26,7 +26,7 @@
1. Windows 데스크톱 앱으로 실행 가능한 WinUI 3 빌드가 유지된다.
2. CJ OnStyle/TornadoAce 정체성이 드러나는 로그인 도입 화면과 앱 아이콘이 적용된다.
3. 큐시트 샘플 선택, Scene 스냅샷 생성, 자동 검수 결과 갱신이 버튼 흐름으로 동작한다.
3. `PoC 실행`으로 큐시트 선택, ERP 매칭, Scene 스냅샷 생성, 자동 검수, LLM 후보 생성이 한 번에 갱신된다.
4. RFP 구축 범위가 화면 또는 문서에서 추적 가능해야 한다.
5. 추후 실제 큐시트 API, ERP API, Tornado SDK, LLM 서비스로 교체할 인터페이스 경계가 유지된다.
@@ -37,3 +37,4 @@
- 실제 Tornado2 SDK 구현체와 Tornado3 SDK 구현체의 메서드 차이를 `ITornadoSceneAdapter`에 맞춰 정리한다.
- Scene 내부 비노출 객체를 구분할 메타데이터 규칙을 정의한다.
- LLM 응답 스키마와 감사 로그 보관 정책을 실제 사내 정책에 맞춘다.
- PoC 실행 결과를 파일 또는 운영 로그로 저장하는 정책을 정한다.