in doc-architect/doc-architect-cli/src/main/java/com/docarchitect/cli/ScanCommand.java [518:601]
private void appendQualityMetrics(StringBuilder sb, ArchitectureModel model) {
var report = model.qualityReport();
sb.append("## đ Scan Quality Report\n\n");
// Overall coverage
sb.append("### Overall Coverage\n\n");
sb.append(String.format("- â
**%d / %d files analyzed** (%.1f%%)\n",
report.filesAnalyzed(),
report.totalFilesInProject(),
report.getCoveragePercentage()));
if (report.filesSkipped() > 0) {
sb.append(String.format("- â ī¸ **%d files skipped** (%.1f%%)\n",
report.filesSkipped(),
(double) report.filesSkipped() / report.totalFilesInProject() * 100));
}
sb.append("\n");
// Coverage by component
if (!report.coverageByComponent().isEmpty()) {
sb.append("### Coverage by Architecture Component\n\n");
sb.append("| Component | Expected | Scanned | Coverage |\n");
sb.append("|-----------|----------|---------|----------|\n");
report.coverageByComponent().forEach((type, metrics) -> {
String status = metrics.isHighCoverage() ? "â
" :
(metrics.isLowCoverage() ? "â ī¸" : "");
sb.append(String.format("| %s | %d | %d | %.0f%% %s |\n",
metrics.componentType(),
metrics.expectedFiles(),
metrics.scannedFiles(),
metrics.coveragePercentage(),
status));
});
sb.append("\n");
}
// Confidence levels
if (report.getTotalFindings() > 0) {
sb.append("### Confidence Levels\n\n");
int total = report.getTotalFindings();
if (report.getHighConfidenceFindings() > 0) {
double pct = (double) report.getHighConfidenceFindings() / total * 100;
sb.append(String.format("- **HIGH (AST-based):** %d findings (%.0f%%)\n",
report.getHighConfidenceFindings(), pct));
}
if (report.getMediumConfidenceFindings() > 0) {
double pct = (double) report.getMediumConfidenceFindings() / total * 100;
sb.append(String.format("- **MEDIUM (Regex-based):** %d findings (%.0f%%)\n",
report.getMediumConfidenceFindings(), pct));
}
if (report.getLowConfidenceFindings() > 0) {
double pct = (double) report.getLowConfidenceFindings() / total * 100;
sb.append(String.format("- **LOW (Heuristic):** %d findings (%.0f%%)\n",
report.getLowConfidenceFindings(), pct));
}
sb.append("\n");
}
// Quality gaps
if (report.hasGaps()) {
sb.append("### â ī¸ Known Gaps\n\n");
var errors = report.getGapsBySeverity(com.docarchitect.core.model.GapSeverity.ERROR);
var warnings = report.getGapsBySeverity(com.docarchitect.core.model.GapSeverity.WARNING);
var infos = report.getGapsBySeverity(com.docarchitect.core.model.GapSeverity.INFO);
if (!errors.isEmpty()) {
errors.forEach(gap ->
sb.append(String.format("- â **%s:** %s\n", gap.scannerId(), gap.message())));
}
if (!warnings.isEmpty()) {
warnings.forEach(gap ->
sb.append(String.format("- â ī¸ **%s:** %s\n", gap.scannerId(), gap.message())));
}
if (!infos.isEmpty()) {
infos.forEach(gap ->
sb.append(String.format("- âšī¸ **%s:** %s\n", gap.scannerId(), gap.message())));
}
sb.append("\n");
}
}