refactor(go/iace): split hazard_library and store into focused files under 500 LOC
All oversized iace files now comply with the 500-line hard cap: - hazard_library_ai_sw.go split into ai_sw (false_classification..communication) and ai_fw (unauthorized_access..update_failure) - hazard_library_software_hmi.go split into software_hmi (software_fault+hmi) and config_integration (configuration_error+logging+integration) - hazard_library_machine_safety.go split to keep mechanical/electrical/thermal/emc, safety_functions extracted into hazard_library_safety_functions.go - store_hazards.go split: hazard library queries moved to store_hazard_library.go - store_projects.go split: component and classification ops to store_components.go - store_mitigations.go split: evidence/verification/ref-data to store_evidence.go - hazard_library.go GetBuiltinHazardLibrary() updated to call all sub-functions - All iace tests pass (go test ./internal/iace/...) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
172
ai-compliance-sdk/internal/iace/store_hazard_library.go
Normal file
172
ai-compliance-sdk/internal/iace/store_hazard_library.go
Normal file
@@ -0,0 +1,172 @@
|
||||
package iace
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
// ============================================================================
|
||||
// Hazard Library Operations
|
||||
// ============================================================================
|
||||
|
||||
// ListHazardLibrary lists hazard library entries, optionally filtered by category and component type
|
||||
func (s *Store) ListHazardLibrary(ctx context.Context, category string, componentType string) ([]HazardLibraryEntry, error) {
|
||||
query := `
|
||||
SELECT
|
||||
id, category, COALESCE(sub_category, ''), name, description,
|
||||
default_severity, default_probability,
|
||||
COALESCE(default_exposure, 3), COALESCE(default_avoidance, 3),
|
||||
applicable_component_types, regulation_references,
|
||||
suggested_mitigations,
|
||||
COALESCE(typical_causes, '[]'::jsonb),
|
||||
COALESCE(typical_harm, ''),
|
||||
COALESCE(relevant_lifecycle_phases, '[]'::jsonb),
|
||||
COALESCE(recommended_measures_design, '[]'::jsonb),
|
||||
COALESCE(recommended_measures_technical, '[]'::jsonb),
|
||||
COALESCE(recommended_measures_information, '[]'::jsonb),
|
||||
COALESCE(suggested_evidence, '[]'::jsonb),
|
||||
COALESCE(related_keywords, '[]'::jsonb),
|
||||
is_builtin, tenant_id,
|
||||
created_at
|
||||
FROM iace_hazard_library WHERE 1=1`
|
||||
|
||||
args := []interface{}{}
|
||||
argIdx := 1
|
||||
|
||||
if category != "" {
|
||||
query += fmt.Sprintf(" AND category = $%d", argIdx)
|
||||
args = append(args, category)
|
||||
argIdx++
|
||||
}
|
||||
if componentType != "" {
|
||||
query += fmt.Sprintf(" AND applicable_component_types @> $%d::jsonb", argIdx)
|
||||
componentTypeJSON, _ := json.Marshal([]string{componentType})
|
||||
args = append(args, string(componentTypeJSON))
|
||||
argIdx++
|
||||
}
|
||||
|
||||
query += " ORDER BY category ASC, name ASC"
|
||||
|
||||
rows, err := s.pool.Query(ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list hazard library: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var entries []HazardLibraryEntry
|
||||
for rows.Next() {
|
||||
var e HazardLibraryEntry
|
||||
var applicableComponentTypes, regulationReferences, suggestedMitigations []byte
|
||||
var typicalCauses, relevantPhases, measuresDesign, measuresTechnical, measuresInfo, evidence, keywords []byte
|
||||
|
||||
err := rows.Scan(
|
||||
&e.ID, &e.Category, &e.SubCategory, &e.Name, &e.Description,
|
||||
&e.DefaultSeverity, &e.DefaultProbability,
|
||||
&e.DefaultExposure, &e.DefaultAvoidance,
|
||||
&applicableComponentTypes, ®ulationReferences,
|
||||
&suggestedMitigations,
|
||||
&typicalCauses, &e.TypicalHarm, &relevantPhases,
|
||||
&measuresDesign, &measuresTechnical, &measuresInfo,
|
||||
&evidence, &keywords,
|
||||
&e.IsBuiltin, &e.TenantID,
|
||||
&e.CreatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list hazard library scan: %w", err)
|
||||
}
|
||||
|
||||
json.Unmarshal(applicableComponentTypes, &e.ApplicableComponentTypes)
|
||||
json.Unmarshal(regulationReferences, &e.RegulationReferences)
|
||||
json.Unmarshal(suggestedMitigations, &e.SuggestedMitigations)
|
||||
json.Unmarshal(typicalCauses, &e.TypicalCauses)
|
||||
json.Unmarshal(relevantPhases, &e.RelevantLifecyclePhases)
|
||||
json.Unmarshal(measuresDesign, &e.RecommendedMeasuresDesign)
|
||||
json.Unmarshal(measuresTechnical, &e.RecommendedMeasuresTechnical)
|
||||
json.Unmarshal(measuresInfo, &e.RecommendedMeasuresInformation)
|
||||
json.Unmarshal(evidence, &e.SuggestedEvidence)
|
||||
json.Unmarshal(keywords, &e.RelatedKeywords)
|
||||
|
||||
if e.ApplicableComponentTypes == nil {
|
||||
e.ApplicableComponentTypes = []string{}
|
||||
}
|
||||
if e.RegulationReferences == nil {
|
||||
e.RegulationReferences = []string{}
|
||||
}
|
||||
|
||||
entries = append(entries, e)
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
// GetHazardLibraryEntry retrieves a single hazard library entry by ID
|
||||
func (s *Store) GetHazardLibraryEntry(ctx context.Context, id uuid.UUID) (*HazardLibraryEntry, error) {
|
||||
var e HazardLibraryEntry
|
||||
var applicableComponentTypes, regulationReferences, suggestedMitigations []byte
|
||||
var typicalCauses, relevantLifecyclePhases []byte
|
||||
var recommendedMeasuresDesign, recommendedMeasuresTechnical, recommendedMeasuresInformation []byte
|
||||
var suggestedEvidence, relatedKeywords []byte
|
||||
|
||||
err := s.pool.QueryRow(ctx, `
|
||||
SELECT
|
||||
id, category, name, description,
|
||||
default_severity, default_probability,
|
||||
applicable_component_types, regulation_references,
|
||||
suggested_mitigations, is_builtin, tenant_id,
|
||||
created_at,
|
||||
COALESCE(sub_category, ''),
|
||||
COALESCE(default_exposure, 3),
|
||||
COALESCE(default_avoidance, 3),
|
||||
COALESCE(typical_causes, '[]'),
|
||||
COALESCE(typical_harm, ''),
|
||||
COALESCE(relevant_lifecycle_phases, '[]'),
|
||||
COALESCE(recommended_measures_design, '[]'),
|
||||
COALESCE(recommended_measures_technical, '[]'),
|
||||
COALESCE(recommended_measures_information, '[]'),
|
||||
COALESCE(suggested_evidence, '[]'),
|
||||
COALESCE(related_keywords, '[]')
|
||||
FROM iace_hazard_library WHERE id = $1
|
||||
`, id).Scan(
|
||||
&e.ID, &e.Category, &e.Name, &e.Description,
|
||||
&e.DefaultSeverity, &e.DefaultProbability,
|
||||
&applicableComponentTypes, ®ulationReferences,
|
||||
&suggestedMitigations, &e.IsBuiltin, &e.TenantID,
|
||||
&e.CreatedAt,
|
||||
&e.SubCategory,
|
||||
&e.DefaultExposure, &e.DefaultAvoidance,
|
||||
&typicalCauses, &e.TypicalHarm,
|
||||
&relevantLifecyclePhases,
|
||||
&recommendedMeasuresDesign, &recommendedMeasuresTechnical, &recommendedMeasuresInformation,
|
||||
&suggestedEvidence, &relatedKeywords,
|
||||
)
|
||||
if err == pgx.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get hazard library entry: %w", err)
|
||||
}
|
||||
|
||||
json.Unmarshal(applicableComponentTypes, &e.ApplicableComponentTypes)
|
||||
json.Unmarshal(regulationReferences, &e.RegulationReferences)
|
||||
json.Unmarshal(suggestedMitigations, &e.SuggestedMitigations)
|
||||
json.Unmarshal(typicalCauses, &e.TypicalCauses)
|
||||
json.Unmarshal(relevantLifecyclePhases, &e.RelevantLifecyclePhases)
|
||||
json.Unmarshal(recommendedMeasuresDesign, &e.RecommendedMeasuresDesign)
|
||||
json.Unmarshal(recommendedMeasuresTechnical, &e.RecommendedMeasuresTechnical)
|
||||
json.Unmarshal(recommendedMeasuresInformation, &e.RecommendedMeasuresInformation)
|
||||
json.Unmarshal(suggestedEvidence, &e.SuggestedEvidence)
|
||||
json.Unmarshal(relatedKeywords, &e.RelatedKeywords)
|
||||
|
||||
if e.ApplicableComponentTypes == nil {
|
||||
e.ApplicableComponentTypes = []string{}
|
||||
}
|
||||
if e.RegulationReferences == nil {
|
||||
e.RegulationReferences = []string{}
|
||||
}
|
||||
|
||||
return &e, nil
|
||||
}
|
||||
Reference in New Issue
Block a user