HTML archetype·Excel dashboard·PPT 골든 회귀를 추가 고도화

- HtmlSkill에 board_report와 strategy_brief 구조화 섹션 타입을 추가해 이사회 보고형/전략 요약형 HTML 산출물 표현력을 확장
- ArtifactQualityReviewService HTML 리뷰에 board-report-panel, strategy-brief-panel 인식과 보완 포인트 규칙을 추가
- Excel dashboard sheet에 KPI, highlights, actions를 함께 렌더링해 executive dashboard 시트 밀도를 강화
- PptxSkillGoldenDeckTests에 strategy deck 회귀 샘플을 추가해 strong 전략 덱 품질 기준을 고정
- README.md와 docs/DEVELOPMENT.md에 2026-04-14 23:32 (KST) 기준 이력과 검증 명령을 반영

검증 결과
- dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify_doc_next5\\ -p:IntermediateOutputPath=obj\\verify_doc_next5\\ : 경고 0 / 오류 0
- dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter ArtifactQualityReviewServiceTests|ExcelSkillDashboardSummaryTests|HtmlSkillConsultingSectionsTests|HtmlSkillPrintFrameTests|DeckQualityReviewServiceTests|PptxSkillGoldenDeckTests|PptxSkillAutoRepairTests|PptxSkillConsultingDeckTests -p:OutputPath=bin\\verify_doc_next5_tests\\ -p:IntermediateOutputPath=obj\\verify_doc_next5_tests\\ : 통과 14
This commit is contained in:
2026-04-14 23:33:23 +09:00
parent 116c420bf6
commit e1f6caf11a
9 changed files with 318 additions and 2 deletions

View File

@@ -618,7 +618,9 @@ public class ExcelSkill : IAgentTool
AppendDecisionSummarySection(summarySheet, sheetData, merges, ref rowIndex);
AppendScorecardSection(summarySheet, sheetData, ref rowIndex);
AppendTrendSection(summarySheet, sheetData, ref rowIndex);
AppendKpiSection(summarySheet, sheetData, merges, ref rowIndex);
AppendSheetSummarySection(summarySheet, sheetData, ref rowIndex);
AppendSummaryTextSection(summarySheet, "highlights", "Key Highlights", sheetData, merges, ref rowIndex);
AppendSummaryTextSection(summarySheet, "actions", "Priority Actions", sheetData, merges, ref rowIndex);
if (detailSheetNames.Count > 0)
@@ -789,6 +791,35 @@ public class ExcelSkill : IAgentTool
rowIndex++;
}
private static void AppendKpiSection(JsonElement summarySheet, SheetData sheetData, MergeCells merges, ref uint rowIndex)
{
if (!summarySheet.SafeTryGetProperty("kpis", out var kpis) || kpis.ValueKind != JsonValueKind.Array || kpis.GetArrayLength() == 0)
return;
AppendMergedTextRow(sheetData, merges, rowIndex++, "A", "F", "Key KPIs", 1);
var headerRow = new Row { RowIndex = rowIndex++ };
headerRow.Append(CreateSummaryCell("A", headerRow.RowIndex!.Value, "Metric", 1));
headerRow.Append(CreateSummaryCell("B", headerRow.RowIndex!.Value, "Value", 1));
headerRow.Append(CreateSummaryCell("C", headerRow.RowIndex!.Value, "Trend", 1));
headerRow.Append(CreateSummaryCell("D", headerRow.RowIndex!.Value, "Note", 1));
sheetData.Append(headerRow);
var index = 0;
foreach (var kpi in kpis.EnumerateArray())
{
var stripeStyle = index % 2 == 0 ? (uint)0 : (uint)2;
var row = new Row { RowIndex = rowIndex++ };
row.Append(CreateSummaryCell("A", row.RowIndex!.Value, kpi.SafeTryGetProperty("label", out var labelEl) ? labelEl.SafeGetString() ?? string.Empty : string.Empty, 1));
row.Append(CreateSummaryCell("B", row.RowIndex!.Value, kpi.SafeTryGetProperty("value", out var valueEl) ? valueEl.SafeGetString() ?? string.Empty : string.Empty, 3));
row.Append(CreateSummaryCell("C", row.RowIndex!.Value, kpi.SafeTryGetProperty("trend", out var trendEl) ? trendEl.SafeGetString() ?? string.Empty : string.Empty, stripeStyle));
row.Append(CreateSummaryCell("D", row.RowIndex!.Value, kpi.SafeTryGetProperty("note", out var noteEl) ? noteEl.SafeGetString() ?? string.Empty : string.Empty, stripeStyle));
sheetData.Append(row);
index++;
}
rowIndex++;
}
private static bool HasDashboardSheet(JsonElement summarySheet)
{
if (summarySheet.ValueKind != JsonValueKind.Object)