PPT 생성 고도화 3차를 반영하고 deck planning·quality gate를 추가

- DeckPlanningService와 DeckQualityReviewService를 추가해 deck brief 정규화, consulting storyline 보강, 누락된 Executive Summary/Recommendation/Roadmap/Appendix 자동 보강, deck-level 품질 점수와 경고 계산을 지원합니다.

- PptxSkill에 audience/objective/decision_ask/storyline 파라미터를 추가하고, issue_tree/before_after/decision_matrix/risk_heatmap/benefit_waterfall/operating_model/appendix_evidence 레이아웃을 네이티브 슬라이드 타입으로 정규화한 뒤 planning summary와 quality summary를 함께 반환하도록 보강했습니다.

- pptx-creator 및 strategy-deck/board-update/pmo-steering/sales-review-deck/operating-model-deck 번들 스킬을 추가·정리하고, DeckPlanningServiceTests/DeckQualityReviewServiceTests/PptxSkillAutoRepairTests로 회귀 검증을 보강했습니다.

- README.md와 docs/DEVELOPMENT.md에 2026-04-14 21:50, 22:00 (KST) 기준 변경 이력과 검증 결과를 반영했습니다.

- 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\verify_ppt_phase3\ -p:IntermediateOutputPath=obj\verify_ppt_phase3\ (경고 0 / 오류 0)

- 검증: dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter 'DeckPlanningServiceTests|DeckQualityReviewServiceTests|PptxSkillAutoRepairTests|PptxSkillConsultingDeckTests' -p:OutputPath=bin\verify_ppt_phase3_tests\ -p:IntermediateOutputPath=obj\verify_ppt_phase3_tests\ (통과 5)
This commit is contained in:
2026-04-14 22:01:41 +09:00
parent 6c7fba9dff
commit 8571a83ed0
14 changed files with 1450 additions and 85 deletions

View File

@@ -0,0 +1,79 @@
using System.IO;
using System.Text.Json;
using AxCopilot.Services.Agent;
using DocumentFormat.OpenXml.Packaging;
using FluentAssertions;
using Xunit;
namespace AxCopilot.Tests.Services;
public class PptxSkillAutoRepairTests
{
[Fact]
public async Task ExecuteAsync_ShouldAugmentDeckAndReturnQualitySummary()
{
var workDir = Path.Combine(Path.GetTempPath(), "ax-pptx-repair-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(workDir);
try
{
var context = new AgentContext
{
WorkFolder = workDir,
Permission = "Auto",
OperationMode = "external",
};
var tool = new PptxSkill();
var args = JsonDocument.Parse(
"""
{
"path": "auto-repair-deck.pptx",
"title": "Operating Improvement",
"objective": "operating model proposal",
"decision_ask": "approve phase-1 launch",
"slides": [
{
"layout": "before_after",
"title": "Current vs Future",
"before": ["Manual coordination", "Slow approvals", "Fragmented KPI tracking"],
"after": ["Standard workflow", "Faster approvals", "Single KPI view"]
},
{
"layout": "benefit_waterfall",
"title": "Benefits",
"benefits": [
{ "label": "Cost", "value": 8 },
{ "label": "Speed", "value": 12 },
{ "label": "Quality", "value": 6 }
]
}
]
}
""").RootElement;
var result = await tool.ExecuteAsync(args, context, CancellationToken.None);
var outputPath = Path.Combine(workDir, "auto-repair-deck.pptx");
result.Success.Should().BeTrue();
result.Output.Should().Contain("PPT quality");
result.Output.Should().Contain("Storyline:");
File.Exists(outputPath).Should().BeTrue();
using var doc = PresentationDocument.Open(outputPath, false);
doc.PresentationPart!.Presentation.SlideIdList!.Count().Should().BeGreaterThanOrEqualTo(6);
}
finally
{
try
{
if (Directory.Exists(workDir))
Directory.Delete(workDir, true);
}
catch
{
}
}
}
}