refactor(go/iace): split tech_file_generator, hazard_patterns, models, completeness
Split 4 oversized files (503-679 LOC each) into focused units all under 500 LOC: - tech_file_generator.go → +_prompts, +_prompt_builder, +_fallback - hazard_patterns_extended.go → +_extended2.go (HP074-HP102 extracted) - models.go → +_entities.go, +_api.go (enums / DB entities / API types) - completeness.go → +_gates.go (gate definitions extracted) All files remain in package iace. Zero behavior changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
141
ai-compliance-sdk/internal/iace/tech_file_generator_fallback.go
Normal file
141
ai-compliance-sdk/internal/iace/tech_file_generator_fallback.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package iace
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ============================================================================
|
||||
// Fallback content (when LLM is unavailable)
|
||||
// ============================================================================
|
||||
|
||||
func buildFallbackContent(sctx *SectionGenerationContext, sectionType string) string {
|
||||
var b strings.Builder
|
||||
|
||||
b.WriteString("[Automatisch generiert — LLM nicht verfuegbar]\n\n")
|
||||
|
||||
sectionTitle := sectionDisplayName(sectionType)
|
||||
b.WriteString(fmt.Sprintf("# %s\n\n", sectionTitle))
|
||||
|
||||
b.WriteString(fmt.Sprintf("**Maschine:** %s (%s)\n", sctx.Project.MachineName, sctx.Project.MachineType))
|
||||
b.WriteString(fmt.Sprintf("**Hersteller:** %s\n", sctx.Project.Manufacturer))
|
||||
if sctx.Project.Description != "" {
|
||||
b.WriteString(fmt.Sprintf("**Beschreibung:** %s\n", sctx.Project.Description))
|
||||
}
|
||||
b.WriteString("\n")
|
||||
|
||||
// Section-specific data summaries
|
||||
switch sectionType {
|
||||
case SectionComponentList, SectionGeneralDescription, SectionDesignSpecifications:
|
||||
if len(sctx.Components) > 0 {
|
||||
b.WriteString("## Komponenten\n\n")
|
||||
b.WriteString(fmt.Sprintf("Anzahl: %d\n\n", len(sctx.Components)))
|
||||
for _, c := range sctx.Components {
|
||||
safety := ""
|
||||
if c.IsSafetyRelevant {
|
||||
safety = " [SICHERHEITSRELEVANT]"
|
||||
}
|
||||
b.WriteString(fmt.Sprintf("- %s (Typ: %s)%s\n", c.Name, string(c.ComponentType), safety))
|
||||
}
|
||||
b.WriteString("\n")
|
||||
}
|
||||
|
||||
case SectionRiskAssessmentReport, SectionHazardLogCombined:
|
||||
b.WriteString("## Risikoueberblick\n\n")
|
||||
b.WriteString(fmt.Sprintf("Anzahl Gefaehrdungen: %d\n\n", len(sctx.Hazards)))
|
||||
riskCounts := countRiskLevels(sctx)
|
||||
for level, count := range riskCounts {
|
||||
b.WriteString(fmt.Sprintf("- %s: %d\n", level, count))
|
||||
}
|
||||
b.WriteString("\n")
|
||||
for _, h := range sctx.Hazards {
|
||||
b.WriteString(fmt.Sprintf("- **%s** (%s) — Status: %s\n", h.Name, h.Category, string(h.Status)))
|
||||
}
|
||||
b.WriteString("\n")
|
||||
|
||||
case SectionMitigationReport:
|
||||
design, protective, info := groupMitigations(sctx)
|
||||
total := len(design) + len(protective) + len(info)
|
||||
b.WriteString("## Massnahmenueberblick\n\n")
|
||||
b.WriteString(fmt.Sprintf("Gesamt: %d Massnahmen\n", total))
|
||||
b.WriteString(fmt.Sprintf("- Design: %d\n- Schutzmassnahmen: %d\n- Benutzerinformation: %d\n\n", len(design), len(protective), len(info)))
|
||||
writeFallbackMitigationList(&b, "Design", design)
|
||||
writeFallbackMitigationList(&b, "Schutzmassnahmen", protective)
|
||||
writeFallbackMitigationList(&b, "Benutzerinformation", info)
|
||||
|
||||
case SectionClassificationReport:
|
||||
if len(sctx.Classifications) > 0 {
|
||||
b.WriteString("## Klassifizierungen\n\n")
|
||||
for _, c := range sctx.Classifications {
|
||||
b.WriteString(fmt.Sprintf("- **%s:** %s (Risiko: %s)\n",
|
||||
string(c.Regulation), c.ClassificationResult, string(c.RiskLevel)))
|
||||
}
|
||||
b.WriteString("\n")
|
||||
}
|
||||
|
||||
case SectionEvidenceIndex:
|
||||
b.WriteString("## Nachweisverzeichnis\n\n")
|
||||
b.WriteString(fmt.Sprintf("Anzahl Nachweise: %d\n\n", len(sctx.Evidence)))
|
||||
for _, e := range sctx.Evidence {
|
||||
desc := e.Description
|
||||
if desc == "" {
|
||||
desc = "(keine Beschreibung)"
|
||||
}
|
||||
b.WriteString(fmt.Sprintf("- %s — %s\n", e.FileName, desc))
|
||||
}
|
||||
b.WriteString("\n")
|
||||
|
||||
default:
|
||||
// Generic fallback data summary
|
||||
b.WriteString(fmt.Sprintf("- Komponenten: %d\n", len(sctx.Components)))
|
||||
b.WriteString(fmt.Sprintf("- Gefaehrdungen: %d\n", len(sctx.Hazards)))
|
||||
b.WriteString(fmt.Sprintf("- Klassifizierungen: %d\n", len(sctx.Classifications)))
|
||||
b.WriteString(fmt.Sprintf("- Nachweise: %d\n", len(sctx.Evidence)))
|
||||
b.WriteString("\n")
|
||||
}
|
||||
|
||||
b.WriteString("---\n")
|
||||
b.WriteString("*Dieser Abschnitt wurde ohne LLM-Unterstuetzung erstellt und enthaelt nur eine Datenuebersicht. Bitte erneut generieren, wenn der LLM-Service verfuegbar ist.*\n")
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func writeFallbackMitigationList(b *strings.Builder, title string, measures []Mitigation) {
|
||||
if len(measures) == 0 {
|
||||
return
|
||||
}
|
||||
b.WriteString(fmt.Sprintf("### %s\n\n", title))
|
||||
for _, m := range measures {
|
||||
b.WriteString(fmt.Sprintf("- %s [%s]\n", m.Name, string(m.Status)))
|
||||
}
|
||||
b.WriteString("\n")
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Utility helpers
|
||||
// ============================================================================
|
||||
|
||||
func countRiskLevels(sctx *SectionGenerationContext) map[string]int {
|
||||
counts := make(map[string]int)
|
||||
for _, h := range sctx.Hazards {
|
||||
if assessments, ok := sctx.Assessments[h.ID]; ok && len(assessments) > 0 {
|
||||
latest := assessments[len(assessments)-1]
|
||||
counts[string(latest.RiskLevel)]++
|
||||
}
|
||||
}
|
||||
return counts
|
||||
}
|
||||
|
||||
func acceptableLabel(isAcceptable bool) string {
|
||||
if isAcceptable {
|
||||
return "[AKZEPTABEL]"
|
||||
}
|
||||
return "[NICHT AKZEPTABEL]"
|
||||
}
|
||||
|
||||
func truncateForPrompt(text string, maxLen int) string {
|
||||
if len(text) <= maxLen {
|
||||
return text
|
||||
}
|
||||
return text[:maxLen] + "..."
|
||||
}
|
||||
Reference in New Issue
Block a user