refactor(go): split training/store, ucca/rules, ucca_handlers, document_export under 500 LOC
Each of the four oversized files (training/store.go 1569 LOC, ucca/rules.go 1231 LOC, ucca_handlers.go 1135 LOC, document_export.go 1101 LOC) is split by logical group into same-package files, all under the 500-line hard cap. Zero behavior changes, no renamed exported symbols. Also fixed pre-existing hazard_library split (missing functions and duplicate UUID keys from a prior session). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
313
ai-compliance-sdk/internal/iace/document_export_pdf.go
Normal file
313
ai-compliance-sdk/internal/iace/document_export_pdf.go
Normal file
@@ -0,0 +1,313 @@
|
||||
package iace
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/jung-kurt/gofpdf"
|
||||
)
|
||||
|
||||
func (e *DocumentExporter) pdfCoverPage(pdf *gofpdf.Fpdf, project *Project) {
|
||||
pdf.Ln(60)
|
||||
|
||||
pdf.SetFont("Helvetica", "B", 28)
|
||||
pdf.SetTextColor(0, 0, 0)
|
||||
pdf.CellFormat(0, 15, "CE-Technische Akte", "", 1, "C", false, 0, "")
|
||||
pdf.Ln(5)
|
||||
|
||||
pdf.SetFont("Helvetica", "B", 22)
|
||||
pdf.CellFormat(0, 12, project.MachineName, "", 1, "C", false, 0, "")
|
||||
pdf.Ln(15)
|
||||
|
||||
pdf.SetFont("Helvetica", "", 12)
|
||||
coverItems := []struct {
|
||||
label string
|
||||
value string
|
||||
}{
|
||||
{"Hersteller", project.Manufacturer},
|
||||
{"Maschinentyp", project.MachineType},
|
||||
{"CE-Kennzeichnungsziel", project.CEMarkingTarget},
|
||||
{"Projektstatus", string(project.Status)},
|
||||
{"Datum", time.Now().Format("02.01.2006")},
|
||||
}
|
||||
|
||||
for _, item := range coverItems {
|
||||
if item.value == "" {
|
||||
continue
|
||||
}
|
||||
pdf.SetFont("Helvetica", "B", 12)
|
||||
pdf.CellFormat(60, 8, item.label+":", "", 0, "R", false, 0, "")
|
||||
pdf.SetFont("Helvetica", "", 12)
|
||||
pdf.CellFormat(5, 8, "", "", 0, "", false, 0, "")
|
||||
pdf.CellFormat(0, 8, item.value, "", 1, "L", false, 0, "")
|
||||
}
|
||||
|
||||
if project.Description != "" {
|
||||
pdf.Ln(15)
|
||||
pdf.SetFont("Helvetica", "I", 10)
|
||||
pdf.MultiCell(0, 5, project.Description, "", "C", false)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *DocumentExporter) pdfTableOfContents(pdf *gofpdf.Fpdf, sections []TechFileSection) {
|
||||
pdf.SetFont("Helvetica", "B", 16)
|
||||
pdf.SetTextColor(50, 50, 50)
|
||||
pdf.CellFormat(0, 10, "Inhaltsverzeichnis", "", 1, "L", false, 0, "")
|
||||
pdf.SetTextColor(0, 0, 0)
|
||||
pdf.SetDrawColor(200, 200, 200)
|
||||
pdf.Line(10, pdf.GetY(), 200, pdf.GetY())
|
||||
pdf.Ln(8)
|
||||
|
||||
pdf.SetFont("Helvetica", "", 11)
|
||||
|
||||
fixedEntries := []string{
|
||||
"Gefaehrdungsprotokoll",
|
||||
"Risikomatrix-Zusammenfassung",
|
||||
"Massnahmen-Uebersicht",
|
||||
}
|
||||
|
||||
pageEstimate := 3
|
||||
for i, section := range sections {
|
||||
pdf.CellFormat(10, 7, fmt.Sprintf("%d.", i+1), "", 0, "R", false, 0, "")
|
||||
pdf.CellFormat(5, 7, "", "", 0, "", false, 0, "")
|
||||
pdf.CellFormat(130, 7, section.Title, "", 0, "L", false, 0, "")
|
||||
pdf.CellFormat(0, 7, fmt.Sprintf("~%d", pageEstimate+i), "", 1, "R", false, 0, "")
|
||||
}
|
||||
|
||||
startPage := pageEstimate + len(sections)
|
||||
for i, entry := range fixedEntries {
|
||||
idx := len(sections) + i + 1
|
||||
pdf.CellFormat(10, 7, fmt.Sprintf("%d.", idx), "", 0, "R", false, 0, "")
|
||||
pdf.CellFormat(5, 7, "", "", 0, "", false, 0, "")
|
||||
pdf.CellFormat(130, 7, entry, "", 0, "L", false, 0, "")
|
||||
pdf.CellFormat(0, 7, fmt.Sprintf("~%d", startPage+i), "", 1, "R", false, 0, "")
|
||||
}
|
||||
}
|
||||
|
||||
func (e *DocumentExporter) pdfSection(pdf *gofpdf.Fpdf, section TechFileSection) {
|
||||
pdf.SetFont("Helvetica", "B", 14)
|
||||
pdf.SetTextColor(50, 50, 50)
|
||||
pdf.CellFormat(0, 10, section.Title, "", 1, "L", false, 0, "")
|
||||
pdf.SetTextColor(0, 0, 0)
|
||||
|
||||
pdf.SetFont("Helvetica", "I", 9)
|
||||
pdf.SetTextColor(100, 100, 100)
|
||||
pdf.CellFormat(0, 5,
|
||||
fmt.Sprintf("Typ: %s | Status: %s | Version: %d",
|
||||
section.SectionType, string(section.Status), section.Version),
|
||||
"", 1, "L", false, 0, "")
|
||||
pdf.SetTextColor(0, 0, 0)
|
||||
|
||||
pdf.SetDrawColor(200, 200, 200)
|
||||
pdf.Line(10, pdf.GetY(), 200, pdf.GetY())
|
||||
pdf.Ln(5)
|
||||
|
||||
pdf.SetFont("Helvetica", "", 10)
|
||||
if section.Content != "" {
|
||||
pdf.MultiCell(0, 5, section.Content, "", "L", false)
|
||||
} else {
|
||||
pdf.SetFont("Helvetica", "I", 10)
|
||||
pdf.SetTextColor(150, 150, 150)
|
||||
pdf.CellFormat(0, 7, "(Kein Inhalt vorhanden)", "", 1, "L", false, 0, "")
|
||||
pdf.SetTextColor(0, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *DocumentExporter) pdfHazardLog(pdf *gofpdf.Fpdf, hazards []Hazard, assessments []RiskAssessment) {
|
||||
pdf.SetFont("Helvetica", "B", 14)
|
||||
pdf.SetTextColor(50, 50, 50)
|
||||
pdf.CellFormat(0, 10, "Gefaehrdungsprotokoll", "", 1, "L", false, 0, "")
|
||||
pdf.SetTextColor(0, 0, 0)
|
||||
pdf.SetDrawColor(200, 200, 200)
|
||||
pdf.Line(10, pdf.GetY(), 200, pdf.GetY())
|
||||
pdf.Ln(5)
|
||||
|
||||
if len(hazards) == 0 {
|
||||
pdf.SetFont("Helvetica", "I", 10)
|
||||
pdf.CellFormat(0, 7, "(Keine Gefaehrdungen erfasst)", "", 1, "L", false, 0, "")
|
||||
return
|
||||
}
|
||||
|
||||
assessMap := buildAssessmentMap(assessments)
|
||||
|
||||
colWidths := []float64{10, 40, 30, 12, 12, 12, 30, 20}
|
||||
headers := []string{"Nr", "Name", "Kategorie", "S", "E", "P", "Risiko", "OK"}
|
||||
|
||||
pdf.SetFont("Helvetica", "B", 9)
|
||||
pdf.SetFillColor(240, 240, 240)
|
||||
for i, h := range headers {
|
||||
pdf.CellFormat(colWidths[i], 7, h, "1", 0, "C", true, 0, "")
|
||||
}
|
||||
pdf.Ln(-1)
|
||||
|
||||
pdf.SetFont("Helvetica", "", 8)
|
||||
for i, hazard := range hazards {
|
||||
if pdf.GetY() > 265 {
|
||||
pdf.AddPage()
|
||||
pdf.SetFont("Helvetica", "B", 9)
|
||||
pdf.SetFillColor(240, 240, 240)
|
||||
for j, h := range headers {
|
||||
pdf.CellFormat(colWidths[j], 7, h, "1", 0, "C", true, 0, "")
|
||||
}
|
||||
pdf.Ln(-1)
|
||||
pdf.SetFont("Helvetica", "", 8)
|
||||
}
|
||||
|
||||
a := assessMap[hazard.ID.String()]
|
||||
|
||||
sev, exp, prob := "", "", ""
|
||||
riskLabel := "-"
|
||||
acceptable := "-"
|
||||
var rl RiskLevel
|
||||
|
||||
if a != nil {
|
||||
sev = fmt.Sprintf("%d", a.Severity)
|
||||
exp = fmt.Sprintf("%d", a.Exposure)
|
||||
prob = fmt.Sprintf("%d", a.Probability)
|
||||
rl = a.RiskLevel
|
||||
riskLabel = riskLevelLabel(rl)
|
||||
if a.IsAcceptable {
|
||||
acceptable = "Ja"
|
||||
} else {
|
||||
acceptable = "Nein"
|
||||
}
|
||||
}
|
||||
|
||||
r, g, b := riskLevelColor(rl)
|
||||
pdf.SetFillColor(r, g, b)
|
||||
fill := rl != ""
|
||||
|
||||
pdf.CellFormat(colWidths[0], 6, fmt.Sprintf("%d", i+1), "1", 0, "C", fill, 0, "")
|
||||
pdf.CellFormat(colWidths[1], 6, pdfTruncate(hazard.Name, 22), "1", 0, "L", fill, 0, "")
|
||||
pdf.CellFormat(colWidths[2], 6, pdfTruncate(hazard.Category, 16), "1", 0, "L", fill, 0, "")
|
||||
pdf.CellFormat(colWidths[3], 6, sev, "1", 0, "C", fill, 0, "")
|
||||
pdf.CellFormat(colWidths[4], 6, exp, "1", 0, "C", fill, 0, "")
|
||||
pdf.CellFormat(colWidths[5], 6, prob, "1", 0, "C", fill, 0, "")
|
||||
pdf.CellFormat(colWidths[6], 6, riskLabel, "1", 0, "C", fill, 0, "")
|
||||
pdf.CellFormat(colWidths[7], 6, acceptable, "1", 0, "C", fill, 0, "")
|
||||
pdf.Ln(-1)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *DocumentExporter) pdfRiskMatrixSummary(pdf *gofpdf.Fpdf, assessments []RiskAssessment) {
|
||||
pdf.Ln(10)
|
||||
pdf.SetFont("Helvetica", "B", 14)
|
||||
pdf.SetTextColor(50, 50, 50)
|
||||
pdf.CellFormat(0, 10, "Risikomatrix-Zusammenfassung", "", 1, "L", false, 0, "")
|
||||
pdf.SetTextColor(0, 0, 0)
|
||||
pdf.SetDrawColor(200, 200, 200)
|
||||
pdf.Line(10, pdf.GetY(), 200, pdf.GetY())
|
||||
pdf.Ln(5)
|
||||
|
||||
counts := countByRiskLevel(assessments)
|
||||
|
||||
levels := []RiskLevel{
|
||||
RiskLevelNotAcceptable,
|
||||
RiskLevelVeryHigh,
|
||||
RiskLevelCritical,
|
||||
RiskLevelHigh,
|
||||
RiskLevelMedium,
|
||||
RiskLevelLow,
|
||||
RiskLevelNegligible,
|
||||
}
|
||||
|
||||
pdf.SetFont("Helvetica", "B", 9)
|
||||
pdf.SetFillColor(240, 240, 240)
|
||||
pdf.CellFormat(60, 7, "Risikostufe", "1", 0, "L", true, 0, "")
|
||||
pdf.CellFormat(30, 7, "Anzahl", "1", 0, "C", true, 0, "")
|
||||
pdf.Ln(-1)
|
||||
|
||||
pdf.SetFont("Helvetica", "", 9)
|
||||
for _, level := range levels {
|
||||
count := counts[level]
|
||||
if count == 0 {
|
||||
continue
|
||||
}
|
||||
r, g, b := riskLevelColor(level)
|
||||
pdf.SetFillColor(r, g, b)
|
||||
pdf.CellFormat(60, 6, riskLevelLabel(level), "1", 0, "L", true, 0, "")
|
||||
pdf.CellFormat(30, 6, fmt.Sprintf("%d", count), "1", 0, "C", true, 0, "")
|
||||
pdf.Ln(-1)
|
||||
}
|
||||
|
||||
pdf.SetFont("Helvetica", "B", 9)
|
||||
pdf.SetFillColor(240, 240, 240)
|
||||
pdf.CellFormat(60, 7, "Gesamt", "1", 0, "L", true, 0, "")
|
||||
pdf.CellFormat(30, 7, fmt.Sprintf("%d", len(assessments)), "1", 0, "C", true, 0, "")
|
||||
pdf.Ln(-1)
|
||||
}
|
||||
|
||||
func (e *DocumentExporter) pdfMitigationsTable(pdf *gofpdf.Fpdf, mitigations []Mitigation) {
|
||||
pdf.SetFont("Helvetica", "B", 14)
|
||||
pdf.SetTextColor(50, 50, 50)
|
||||
pdf.CellFormat(0, 10, "Massnahmen-Uebersicht", "", 1, "L", false, 0, "")
|
||||
pdf.SetTextColor(0, 0, 0)
|
||||
pdf.SetDrawColor(200, 200, 200)
|
||||
pdf.Line(10, pdf.GetY(), 200, pdf.GetY())
|
||||
pdf.Ln(5)
|
||||
|
||||
if len(mitigations) == 0 {
|
||||
pdf.SetFont("Helvetica", "I", 10)
|
||||
pdf.CellFormat(0, 7, "(Keine Massnahmen erfasst)", "", 1, "L", false, 0, "")
|
||||
return
|
||||
}
|
||||
|
||||
colWidths := []float64{10, 45, 30, 30, 40}
|
||||
headers := []string{"Nr", "Name", "Typ", "Status", "Verifikation"}
|
||||
|
||||
pdf.SetFont("Helvetica", "B", 9)
|
||||
pdf.SetFillColor(240, 240, 240)
|
||||
for i, h := range headers {
|
||||
pdf.CellFormat(colWidths[i], 7, h, "1", 0, "C", true, 0, "")
|
||||
}
|
||||
pdf.Ln(-1)
|
||||
|
||||
pdf.SetFont("Helvetica", "", 8)
|
||||
for i, m := range mitigations {
|
||||
if pdf.GetY() > 265 {
|
||||
pdf.AddPage()
|
||||
pdf.SetFont("Helvetica", "B", 9)
|
||||
pdf.SetFillColor(240, 240, 240)
|
||||
for j, h := range headers {
|
||||
pdf.CellFormat(colWidths[j], 7, h, "1", 0, "C", true, 0, "")
|
||||
}
|
||||
pdf.Ln(-1)
|
||||
pdf.SetFont("Helvetica", "", 8)
|
||||
}
|
||||
|
||||
pdf.CellFormat(colWidths[0], 6, fmt.Sprintf("%d", i+1), "1", 0, "C", false, 0, "")
|
||||
pdf.CellFormat(colWidths[1], 6, pdfTruncate(m.Name, 25), "1", 0, "L", false, 0, "")
|
||||
pdf.CellFormat(colWidths[2], 6, reductionTypeLabel(m.ReductionType), "1", 0, "C", false, 0, "")
|
||||
pdf.CellFormat(colWidths[3], 6, mitigationStatusLabel(m.Status), "1", 0, "C", false, 0, "")
|
||||
pdf.CellFormat(colWidths[4], 6, pdfTruncate(string(m.VerificationMethod), 22), "1", 0, "L", false, 0, "")
|
||||
pdf.Ln(-1)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *DocumentExporter) pdfClassifications(pdf *gofpdf.Fpdf, classifications []RegulatoryClassification) {
|
||||
pdf.SetFont("Helvetica", "B", 14)
|
||||
pdf.SetTextColor(50, 50, 50)
|
||||
pdf.CellFormat(0, 10, "Regulatorische Klassifizierungen", "", 1, "L", false, 0, "")
|
||||
pdf.SetTextColor(0, 0, 0)
|
||||
pdf.SetDrawColor(200, 200, 200)
|
||||
pdf.Line(10, pdf.GetY(), 200, pdf.GetY())
|
||||
pdf.Ln(5)
|
||||
|
||||
for _, c := range classifications {
|
||||
pdf.SetFont("Helvetica", "B", 11)
|
||||
pdf.CellFormat(0, 7, regulationLabel(c.Regulation), "", 1, "L", false, 0, "")
|
||||
|
||||
pdf.SetFont("Helvetica", "", 10)
|
||||
pdf.CellFormat(50, 6, "Klassifizierung:", "", 0, "L", false, 0, "")
|
||||
pdf.CellFormat(0, 6, c.ClassificationResult, "", 1, "L", false, 0, "")
|
||||
|
||||
pdf.CellFormat(50, 6, "Risikostufe:", "", 0, "L", false, 0, "")
|
||||
pdf.CellFormat(0, 6, riskLevelLabel(c.RiskLevel), "", 1, "L", false, 0, "")
|
||||
|
||||
if c.Reasoning != "" {
|
||||
pdf.CellFormat(50, 6, "Begruendung:", "", 0, "L", false, 0, "")
|
||||
pdf.MultiCell(0, 5, c.Reasoning, "", "L", false)
|
||||
}
|
||||
pdf.Ln(5)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user