Files
breakpilot-compliance/ai-compliance-sdk/internal/ucca/unified_facts.go
Benjamin Admin 38e278ee3c
All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 32s
CI / test-python-backend-compliance (push) Successful in 29s
CI / test-python-document-crawler (push) Successful in 20s
CI / test-python-dsms-gateway (push) Successful in 18s
feat(ucca): Pflichtendatenbank v2 (325 Obligations), Trigger-Engine, TOM-Control-Mapping
- 9 Regulation-JSON-Dateien (DSGVO 80, AI Act 60, NIS2 40, BDSG 30, TTDSG 20, DSA 35, Data Act 25, EU-Maschinen 15, DORA 20)
- Condition-Tree-Engine fuer automatische Pflichtenselektion (all_of/any_of, 80+ Field-Paths)
- Generischer JSONRegulationModule-Loader mit YAML-Fallback
- Bidirektionales TOM-Control-Mapping (291 Obligation→Control, 92 Control→Obligation)
- Gap-Analyse-Engine (Compliance-%, Priority Actions, Domain Breakdown)
- ScopeDecision→UnifiedFacts Bridge fuer Auto-Profiling
- 4 neue API-Endpoints (assess-from-scope, tom-controls, gap-analysis, reverse-lookup)
- Frontend: Auto-Profiling Button, Regulation-Filter Chips, TOM-Panel, Gap-Analyse-View
- 18 Unit Tests (Condition Engine, v2 Loader, TOM Mapper)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:51:44 +01:00

458 lines
18 KiB
Go

package ucca
// ============================================================================
// Unified Facts Model
// ============================================================================
//
// UnifiedFacts aggregates all facts about an organization that are needed
// to determine which regulations apply and what obligations arise.
// This model is regulation-agnostic and serves as input for all modules.
//
// ============================================================================
// UnifiedFacts is the comprehensive facts model for all regulatory assessments
type UnifiedFacts struct {
// Existing UCCA Facts (for backwards compatibility)
UCCAFacts *UseCaseIntake `json:"ucca_facts,omitempty"`
// Organization facts
Organization OrganizationFacts `json:"organization"`
// Sector/Industry facts (for NIS2, sector-specific regulations)
Sector SectorFacts `json:"sector"`
// Data protection facts (for DSGVO)
DataProtection DataProtectionFacts `json:"data_protection"`
// AI usage facts (for AI Act)
AIUsage AIUsageFacts `json:"ai_usage"`
// Financial sector facts (for MaRisk, DORA)
Financial FinancialFacts `json:"financial"`
// IT Security facts (for NIS2)
ITSecurity ITSecurityFacts `json:"it_security"`
// Supply chain facts
SupplyChain SupplyChainFacts `json:"supply_chain"`
// Personnel facts
Personnel PersonnelFacts `json:"personnel"`
}
// OrganizationFacts contains basic organizational information
type OrganizationFacts struct {
// Basic info
Name string `json:"name,omitempty"`
LegalForm string `json:"legal_form,omitempty"` // e.g., "GmbH", "AG", "e.V."
Country string `json:"country"` // e.g., "DE", "AT", "CH"
EUMember bool `json:"eu_member"`
// Organization type
IsPublicAuthority bool `json:"is_public_authority"` // Public authority or body
// Size metrics (KMU criteria)
EmployeeCount int `json:"employee_count"`
AnnualRevenue float64 `json:"annual_revenue"` // in EUR
BalanceSheetTotal float64 `json:"balance_sheet_total"` // in EUR
// Calculated size category
SizeCategory string `json:"size_category,omitempty"` // "micro", "small", "medium", "large"
// Group structure
IsPartOfGroup bool `json:"is_part_of_group"`
ParentCompany string `json:"parent_company,omitempty"`
GroupEmployees int `json:"group_employees,omitempty"`
GroupRevenue float64 `json:"group_revenue,omitempty"`
}
// SectorFacts contains industry/sector information for regulatory classification
type SectorFacts struct {
// Primary sector classification
PrimarySector string `json:"primary_sector"` // NIS2 Annex I/II sector codes
SubSector string `json:"sub_sector,omitempty"`
NACECode string `json:"nace_code,omitempty"`
// KRITIS classification (German critical infrastructure)
IsKRITIS bool `json:"is_kritis"`
KRITISThresholdMet bool `json:"kritis_threshold_met"`
KRITISSector string `json:"kritis_sector,omitempty"`
// Special services (NIS2-specific)
SpecialServices []string `json:"special_services,omitempty"` // "dns", "tld", "cloud", "datacenter", "cdn", "msp", "mssp", "trust_service", "public_network", "electronic_comms"
// Public administration
IsPublicAdministration bool `json:"is_public_administration"`
PublicAdminLevel string `json:"public_admin_level,omitempty"` // "federal", "state", "municipal"
// NIS2 classification (v2)
NIS2Classification string `json:"nis2_classification,omitempty"` // wichtige_einrichtung, besonders_wichtige_einrichtung, nicht_betroffen
IsAnnexI bool `json:"is_annex_i"`
IsAnnexII bool `json:"is_annex_ii"`
// Healthcare specific
IsHealthcareProvider bool `json:"is_healthcare_provider"`
HasPatientData bool `json:"has_patient_data"`
// Financial specific
IsFinancialInstitution bool `json:"is_financial_institution"`
FinancialEntityType string `json:"financial_entity_type,omitempty"` // DORA entity types
}
// DataProtectionFacts contains GDPR-relevant information
type DataProtectionFacts struct {
// Data processing basics
ProcessesPersonalData bool `json:"processes_personal_data"`
ProcessesSpecialCategories bool `json:"processes_special_categories"` // Art. 9 DSGVO
ProcessesMinorData bool `json:"processes_minor_data"`
ProcessesCriminalData bool `json:"processes_criminal_data"` // Art. 10 DSGVO
// Controller/Processor role
IsController bool `json:"is_controller"` // Acts as controller
IsProcessor bool `json:"is_processor"` // Acts as processor for others
// Territorial scope (Art. 3)
OffersToEU bool `json:"offers_to_eu"` // Offers goods/services to EU
MonitorsEUIndividuals bool `json:"monitors_eu_individuals"` // Monitors behavior of EU individuals
// Scale of processing
LargeScaleProcessing bool `json:"large_scale_processing"`
SystematicMonitoring bool `json:"systematic_monitoring"`
Profiling bool `json:"profiling"`
AutomatedDecisionMaking bool `json:"automated_decision_making"` // Art. 22 DSGVO
AutomatedDecisions bool `json:"automated_decisions"` // Alias for automated_decision_making
LegalEffects bool `json:"legal_effects"` // Automated decisions with legal effects
// Special categories (Art. 9) - detailed
SpecialCategories []string `json:"special_categories,omitempty"` // racial_ethnic_origin, political_opinions, etc.
// High-risk activities (Art. 35)
HighRiskActivities []string `json:"high_risk_activities,omitempty"` // systematic_monitoring, automated_decisions, etc.
// Data subjects
DataSubjectCount int `json:"data_subject_count"` // Approximate number
DataSubjectCountRange string `json:"data_subject_count_range,omitempty"` // "< 1000", "1000-10000", "> 10000", "> 100000"
// Data transfers
TransfersToThirdCountries bool `json:"transfers_to_third_countries"`
CrossBorderProcessing bool `json:"cross_border_processing"` // Processing across EU borders
SCCsInPlace bool `json:"sccs_in_place"`
BindingCorporateRules bool `json:"binding_corporate_rules"`
// External processing
UsesExternalProcessor bool `json:"uses_external_processor"`
// DSB requirement triggers
RequiresDSBByLaw bool `json:"requires_dsb_by_law"`
HasAppointedDSB bool `json:"has_appointed_dsb"`
DSBIsInternal bool `json:"dsb_is_internal"`
// Extended data categories (v2)
ProcessesEmployeeData bool `json:"processes_employee_data"`
ProcessesFinancialData bool `json:"processes_financial_data"`
ProcessesHealthData bool `json:"processes_health_data"`
ProcessesBiometricData bool `json:"processes_biometric_data"`
// Online / Platform processing (v2)
UsesCookies bool `json:"uses_cookies"`
UsesTracking bool `json:"uses_tracking"`
UsesVideoSurveillance bool `json:"uses_video_surveillance"`
OperatesPlatform bool `json:"operates_platform"`
PlatformUserCount int `json:"platform_user_count,omitempty"`
}
// AIUsageFacts contains AI Act relevant information
type AIUsageFacts struct {
// Basic AI usage
UsesAI bool `json:"uses_ai"`
AIApplications []string `json:"ai_applications,omitempty"`
// AI Act role
IsAIProvider bool `json:"is_ai_provider"` // Develops/provides AI systems
IsAIDeployer bool `json:"is_ai_deployer"` // Uses AI systems
IsAIDistributor bool `json:"is_ai_distributor"`
IsAIImporter bool `json:"is_ai_importer"`
// Risk categories (pre-classification)
HasHighRiskAI bool `json:"has_high_risk_ai"`
HasLimitedRiskAI bool `json:"has_limited_risk_ai"`
HasMinimalRiskAI bool `json:"has_minimal_risk_ai"`
// Specific high-risk categories (Annex III)
BiometricIdentification bool `json:"biometric_identification"` // Real-time, remote
CriticalInfrastructure bool `json:"critical_infrastructure"` // AI in CI
EducationAccess bool `json:"education_access"` // Admission, assessment
EmploymentDecisions bool `json:"employment_decisions"` // Recruitment, evaluation
EssentialServices bool `json:"essential_services"` // Credit, benefits
LawEnforcement bool `json:"law_enforcement"`
MigrationAsylum bool `json:"migration_asylum"`
JusticeAdministration bool `json:"justice_administration"`
// Prohibited practices (Art. 5)
SocialScoring bool `json:"social_scoring"`
EmotionRecognition bool `json:"emotion_recognition"` // Workplace/education
PredictivePolicingIndividual bool `json:"predictive_policing_individual"`
// GPAI (General Purpose AI)
UsesGPAI bool `json:"uses_gpai"`
GPAIWithSystemicRisk bool `json:"gpai_with_systemic_risk"`
// Transparency obligations
AIInteractsWithNaturalPersons bool `json:"ai_interacts_with_natural_persons"`
GeneratesDeepfakes bool `json:"generates_deepfakes"`
}
// FinancialFacts contains financial regulation specific information
type FinancialFacts struct {
// Entity type (DORA scope)
EntityType string `json:"entity_type,omitempty"` // Credit institution, payment service provider, etc.
IsRegulated bool `json:"is_regulated"`
// DORA specific
DORAApplies bool `json:"dora_applies"`
HasCriticalICT bool `json:"has_critical_ict"`
ICTOutsourced bool `json:"ict_outsourced"`
ICTProviderLocation string `json:"ict_provider_location,omitempty"` // "EU", "EEA", "third_country"
ConcentrationRisk bool `json:"concentration_risk"`
// MaRisk/BAIT specific (Germany)
MaRiskApplies bool `json:"marisk_applies"`
BAITApplies bool `json:"bait_applies"`
// AI in financial services
AIAffectsCustomers bool `json:"ai_affects_customers"`
AlgorithmicTrading bool `json:"algorithmic_trading"`
AIRiskAssessment bool `json:"ai_risk_assessment"`
AIAMLKYC bool `json:"ai_aml_kyc"`
}
// ITSecurityFacts contains IT security posture information
type ITSecurityFacts struct {
// ISMS status
HasISMS bool `json:"has_isms"`
ISO27001Certified bool `json:"iso27001_certified"`
ISO27001CertExpiry string `json:"iso27001_cert_expiry,omitempty"`
// Security processes
HasIncidentProcess bool `json:"has_incident_process"`
HasVulnerabilityMgmt bool `json:"has_vulnerability_mgmt"`
HasPatchMgmt bool `json:"has_patch_mgmt"`
HasAccessControl bool `json:"has_access_control"`
HasMFA bool `json:"has_mfa"`
HasEncryption bool `json:"has_encryption"`
HasBackup bool `json:"has_backup"`
HasDisasterRecovery bool `json:"has_disaster_recovery"`
// BCM
HasBCM bool `json:"has_bcm"`
BCMTested bool `json:"bcm_tested"`
// Network security
HasNetworkSegmentation bool `json:"has_network_segmentation"`
HasFirewall bool `json:"has_firewall"`
HasIDS bool `json:"has_ids"`
// Monitoring
HasSecurityMonitoring bool `json:"has_security_monitoring"`
Has24x7SOC bool `json:"has_24x7_soc"`
// Awareness
SecurityAwarenessTraining bool `json:"security_awareness_training"`
RegularSecurityTraining bool `json:"regular_security_training"`
// Certifications
OtherCertifications []string `json:"other_certifications,omitempty"` // SOC2, BSI C5, etc.
}
// SupplyChainFacts contains supply chain security information
type SupplyChainFacts struct {
// Supply chain basics
HasSupplyChainRiskMgmt bool `json:"has_supply_chain_risk_mgmt"`
SupplierCount int `json:"supplier_count,omitempty"`
CriticalSupplierCount int `json:"critical_supplier_count,omitempty"`
// Third party risk
ThirdPartyAudits bool `json:"third_party_audits"`
SupplierSecurityReqs bool `json:"supplier_security_reqs"`
// ICT supply chain (NIS2)
HasICTSupplyChainPolicy bool `json:"has_ict_supply_chain_policy"`
ICTSupplierDiversity bool `json:"ict_supplier_diversity"`
}
// PersonnelFacts contains workforce-related information
type PersonnelFacts struct {
// Security personnel
HasCISO bool `json:"has_ciso"`
HasDedicatedSecurityTeam bool `json:"has_dedicated_security_team"`
SecurityTeamSize int `json:"security_team_size,omitempty"`
// Compliance personnel
HasComplianceOfficer bool `json:"has_compliance_officer"`
HasDPO bool `json:"has_dpo"`
DPOIsExternal bool `json:"dpo_is_external"`
// AI personnel (AI Act)
HasAICompetence bool `json:"has_ai_competence"`
HasAIGovernance bool `json:"has_ai_governance"`
}
// ============================================================================
// Helper Methods
// ============================================================================
// CalculateSizeCategory determines the organization size based on EU SME criteria
func (o *OrganizationFacts) CalculateSizeCategory() string {
// Use group figures if part of a group
employees := o.EmployeeCount
revenue := o.AnnualRevenue
balance := o.BalanceSheetTotal
if o.IsPartOfGroup && o.GroupEmployees > 0 {
employees = o.GroupEmployees
}
if o.IsPartOfGroup && o.GroupRevenue > 0 {
revenue = o.GroupRevenue
}
// EU SME Criteria (Recommendation 2003/361/EC)
// Micro: <10 employees AND (revenue OR balance) <= €2m
// Small: <50 employees AND (revenue OR balance) <= €10m
// Medium: <250 employees AND revenue <= €50m OR balance <= €43m
// Large: everything else
if employees < 10 && (revenue <= 2_000_000 || balance <= 2_000_000) {
return "micro"
}
if employees < 50 && (revenue <= 10_000_000 || balance <= 10_000_000) {
return "small"
}
if employees < 250 && (revenue <= 50_000_000 || balance <= 43_000_000) {
return "medium"
}
return "large"
}
// IsSME returns true if the organization qualifies as an SME
func (o *OrganizationFacts) IsSME() bool {
category := o.CalculateSizeCategory()
return category == "micro" || category == "small" || category == "medium"
}
// MeetsNIS2SizeThreshold checks if organization meets NIS2 size threshold
// (>= 50 employees OR >= €10m revenue AND >= €10m balance)
func (o *OrganizationFacts) MeetsNIS2SizeThreshold() bool {
employees := o.EmployeeCount
revenue := o.AnnualRevenue
balance := o.BalanceSheetTotal
if o.IsPartOfGroup && o.GroupEmployees > 0 {
employees = o.GroupEmployees
}
if o.IsPartOfGroup && o.GroupRevenue > 0 {
revenue = o.GroupRevenue
}
// NIS2 size threshold: medium+ enterprises
// >= 50 employees OR (>= €10m revenue AND >= €10m balance)
if employees >= 50 {
return true
}
if revenue >= 10_000_000 && balance >= 10_000_000 {
return true
}
return false
}
// MeetsNIS2LargeThreshold checks if organization meets NIS2 "large" threshold
// (>= 250 employees OR >= €50m revenue)
func (o *OrganizationFacts) MeetsNIS2LargeThreshold() bool {
employees := o.EmployeeCount
revenue := o.AnnualRevenue
if o.IsPartOfGroup && o.GroupEmployees > 0 {
employees = o.GroupEmployees
}
if o.IsPartOfGroup && o.GroupRevenue > 0 {
revenue = o.GroupRevenue
}
return employees >= 250 || revenue >= 50_000_000
}
// NewUnifiedFacts creates a new UnifiedFacts with default values
func NewUnifiedFacts() *UnifiedFacts {
return &UnifiedFacts{
Organization: OrganizationFacts{Country: "DE", EUMember: true},
Sector: SectorFacts{},
DataProtection: DataProtectionFacts{},
AIUsage: AIUsageFacts{},
Financial: FinancialFacts{},
ITSecurity: ITSecurityFacts{},
SupplyChain: SupplyChainFacts{},
Personnel: PersonnelFacts{},
}
}
// FromUseCaseIntake creates UnifiedFacts from an existing UseCaseIntake
func (f *UnifiedFacts) FromUseCaseIntake(intake *UseCaseIntake) {
f.UCCAFacts = intake
// Map data types
f.DataProtection.ProcessesPersonalData = intake.DataTypes.PersonalData
f.DataProtection.ProcessesSpecialCategories = intake.DataTypes.Article9Data
f.DataProtection.ProcessesMinorData = intake.DataTypes.MinorData
f.DataProtection.Profiling = intake.Purpose.Profiling
f.DataProtection.AutomatedDecisionMaking = intake.Purpose.DecisionMaking
// Map AI usage
if intake.ModelUsage.RAG || intake.ModelUsage.Training || intake.ModelUsage.Finetune || intake.ModelUsage.Inference {
f.AIUsage.UsesAI = true
f.AIUsage.IsAIDeployer = true
}
// Map sector from domain
f.MapDomainToSector(string(intake.Domain))
}
// MapDomainToSector maps a UCCA domain to sector facts
func (f *UnifiedFacts) MapDomainToSector(domain string) {
// Map common domains to NIS2 sectors
sectorMap := map[string]string{
"energy": "energy",
"utilities": "energy",
"oil_gas": "energy",
"banking": "banking_financial",
"finance": "banking_financial",
"insurance": "banking_financial",
"investment": "banking_financial",
"healthcare": "health",
"pharma": "health",
"medical_devices": "health",
"logistics": "transport",
"telecom": "digital_infrastructure",
"it_services": "ict_service_mgmt",
"cybersecurity": "ict_service_mgmt",
"public_sector": "public_administration",
"defense": "public_administration",
"food_beverage": "food",
"chemicals": "chemicals",
"research": "research",
"education": "education",
"higher_education": "education",
}
if sector, ok := sectorMap[domain]; ok {
f.Sector.PrimarySector = sector
} else {
f.Sector.PrimarySector = "other"
}
// Set financial flags
if domain == "banking" || domain == "finance" || domain == "insurance" || domain == "investment" {
f.Sector.IsFinancialInstitution = true
f.Financial.IsRegulated = true
f.Financial.DORAApplies = true
}
}