Files
breakpilot-compliance/ai-compliance-sdk/internal/iace/document_export.go
T
Benjamin Admin 8bb90d73e5
Build + Deploy / build-backend-compliance (push) Successful in 3m34s
Build + Deploy / build-ai-sdk (push) Successful in 1m6s
Build + Deploy / build-developer-portal (push) Successful in 1m7s
Build + Deploy / build-tts (push) Successful in 1m58s
Build + Deploy / build-document-crawler (push) Successful in 57s
Build + Deploy / build-dsms-gateway (push) Successful in 34s
Build + Deploy / build-admin-compliance (push) Successful in 2m7s
Build + Deploy / build-dsms-node (push) Successful in 29s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / loc-budget (push) Failing after 17s
CI / secret-scan (push) Has been skipped
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 2m28s
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / test-go (push) Successful in 42s
CI / test-python-backend (push) Successful in 37s
CI / test-python-document-crawler (push) Successful in 27s
CI / test-python-dsms-gateway (push) Successful in 22s
CI / validate-canonical-controls (push) Successful in 15s
Build + Deploy / trigger-orca (push) Successful in 3m10s
feat(iace): benchmark system + erklaerteil + dedup-fix
- Erklaerteil-Template fuer Risikobeurteilungen (risk_assessment_template.go)
  in PDF-Export, Markdown-Export und Frontend ReportPrintView eingebaut
- Ground Truth Benchmark-System: Datenmodell, Fuzzy-Matching-Engine,
  3 API Endpoints (import-gt, benchmark, benchmark/summary)
- Frontend Benchmark-Tab mit Score-Cards, Kategorie-Breakdown,
  Hazard-Vergleichstabelle (Zugeordnet/Fehlend/Extra), Business Impact
- Erster Benchmark: 13.3% Coverage (Baseline) gegen 60 GT-Eintraege
- Dedup-Fix: seenCat[cat] -> seenCatZone[cat+zone] erlaubt mehrere
  Gefaehrdungen pro Kategorie an verschiedenen Gefahrenstellen
- Komponenten-spezifische Hazard-Namen und Zone-basierte Zuordnung

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-13 01:02:33 +02:00

157 lines
4.3 KiB
Go

package iace
import (
"bytes"
"fmt"
"time"
"github.com/jung-kurt/gofpdf"
)
// ExportFormat represents a supported document export format
type ExportFormat string
const (
ExportFormatPDF ExportFormat = "pdf"
ExportFormatXLSX ExportFormat = "xlsx"
ExportFormatDOCX ExportFormat = "docx"
ExportFormatMD ExportFormat = "md"
ExportFormatJSON ExportFormat = "json"
)
// DocumentExporter handles exporting CE technical file data into various formats
type DocumentExporter struct{}
// NewDocumentExporter creates a new DocumentExporter instance
func NewDocumentExporter() *DocumentExporter {
return &DocumentExporter{}
}
// ============================================================================
// PDF Export
// ============================================================================
// ExportPDF generates a PDF document containing the full CE technical file
func (e *DocumentExporter) ExportPDF(
project *Project,
sections []TechFileSection,
hazards []Hazard,
assessments []RiskAssessment,
mitigations []Mitigation,
classifications []RegulatoryClassification,
) ([]byte, error) {
if project == nil {
return nil, fmt.Errorf("project must not be nil")
}
pdf := gofpdf.New("P", "mm", "A4", "")
// --- Cover Page ---
pdf.AddPage()
e.pdfCoverPage(pdf, project)
// --- Methodology ("Erklaerteil") ---
pdf.AddPage()
e.pdfMethodologySection(pdf)
// --- Table of Contents ---
pdf.AddPage()
e.pdfTableOfContents(pdf, sections)
// --- Sections ---
for _, section := range sections {
pdf.AddPage()
e.pdfSection(pdf, section)
}
// --- Hazard Log ---
pdf.AddPage()
e.pdfHazardLog(pdf, hazards, assessments)
// --- Risk Matrix Summary ---
e.pdfRiskMatrixSummary(pdf, assessments)
// --- Mitigations Table ---
pdf.AddPage()
e.pdfMitigationsTable(pdf, mitigations)
// --- Regulatory Classifications ---
if len(classifications) > 0 {
pdf.AddPage()
e.pdfClassifications(pdf, classifications)
}
// --- Footer on every page ---
pdf.SetFooterFunc(func() {
pdf.SetY(-15)
pdf.SetFont("Helvetica", "I", 8)
pdf.SetTextColor(128, 128, 128)
pdf.CellFormat(0, 5,
fmt.Sprintf("CE-Akte %s | Generiert am %s | BreakPilot AI Compliance SDK",
project.MachineName, time.Now().Format("02.01.2006 15:04")),
"", 0, "C", false, 0, "")
})
var buf bytes.Buffer
if err := pdf.Output(&buf); err != nil {
return nil, fmt.Errorf("failed to generate PDF: %w", err)
}
return buf.Bytes(), nil
}
// ============================================================================
// Markdown Export
// ============================================================================
// ExportMarkdown generates a Markdown document of the CE technical file sections
func (e *DocumentExporter) ExportMarkdown(
project *Project,
sections []TechFileSection,
) ([]byte, error) {
if project == nil {
return nil, fmt.Errorf("project must not be nil")
}
var buf bytes.Buffer
buf.WriteString(fmt.Sprintf("# CE-Akte: %s\n\n", project.MachineName))
buf.WriteString("| Eigenschaft | Wert |\n")
buf.WriteString("|-------------|------|\n")
buf.WriteString(fmt.Sprintf("| Hersteller | %s |\n", project.Manufacturer))
buf.WriteString(fmt.Sprintf("| Maschinentyp | %s |\n", project.MachineType))
if project.CEMarkingTarget != "" {
buf.WriteString(fmt.Sprintf("| CE-Kennzeichnungsziel | %s |\n", project.CEMarkingTarget))
}
buf.WriteString(fmt.Sprintf("| Status | %s |\n", project.Status))
buf.WriteString(fmt.Sprintf("| Datum | %s |\n", time.Now().Format("02.01.2006")))
buf.WriteString("\n")
if project.Description != "" {
buf.WriteString(fmt.Sprintf("> %s\n\n", project.Description))
}
buf.WriteString("---\n\n")
buf.WriteString(fmt.Sprintf("## %s\n\n", RiskAssessmentMethodologySectionTitle))
buf.WriteString(RiskAssessmentMethodologyDE)
buf.WriteString("\n\n---\n\n")
for _, section := range sections {
buf.WriteString(fmt.Sprintf("## %s\n\n", section.Title))
buf.WriteString(fmt.Sprintf("*Typ: %s | Status: %s | Version: %d*\n\n",
section.SectionType, string(section.Status), section.Version))
if section.Content != "" {
buf.WriteString(section.Content)
buf.WriteString("\n\n")
} else {
buf.WriteString("*(Kein Inhalt vorhanden)*\n\n")
}
}
buf.WriteString("---\n\n")
buf.WriteString(fmt.Sprintf("*Generiert am %s mit BreakPilot AI Compliance SDK*\n",
time.Now().Format("02.01.2006 15:04")))
return buf.Bytes(), nil
}