package maximizer import ( "strings" "github.com/breakpilot/ai-compliance-sdk/internal/ucca" ) // MapIntakeToDimensions converts a UseCaseIntake to a normalized DimensionConfig. // Highest sensitivity wins for multi-value fields. func MapIntakeToDimensions(intake *ucca.UseCaseIntake) *DimensionConfig { config := &DimensionConfig{ AutomationLevel: mapAutomation(intake.Automation), DecisionBinding: deriveBinding(intake), DecisionImpact: deriveImpact(intake), Domain: mapDomain(intake.Domain), DataType: deriveDataType(intake.DataTypes), HumanInLoop: deriveHIL(intake.Automation), Explainability: ExplainBasic, // default RiskClassification: RiskMinimal, // will be set by evaluator LegalBasis: LegalContract, // default TransparencyRequired: false, LoggingRequired: false, ModelType: deriveModelType(intake.ModelUsage), DeploymentScope: deriveScope(intake), } return config } // MapDimensionsToIntake converts a DimensionConfig back to a UseCaseIntake, // preserving unchanged fields from the original intake. func MapDimensionsToIntake(config *DimensionConfig, original *ucca.UseCaseIntake) *ucca.UseCaseIntake { result := *original // shallow copy // Map automation level switch config.AutomationLevel { case AutoNone: result.Automation = ucca.AutomationAssistive case AutoAssistive: result.Automation = ucca.AutomationAssistive case AutoPartial: result.Automation = ucca.AutomationSemiAutomated case AutoFull: result.Automation = ucca.AutomationFullyAutomated } // Map data type back result.DataTypes = mapDataTypeBack(config.DataType, original.DataTypes) // Map domain back result.Domain = mapDomainBack(config.Domain, original.Domain) return &result } func mapAutomation(a ucca.AutomationLevel) AutomationLevel { switch a { case ucca.AutomationAssistive: return AutoAssistive case ucca.AutomationSemiAutomated: return AutoPartial case ucca.AutomationFullyAutomated: return AutoFull default: return AutoNone } } func deriveBinding(intake *ucca.UseCaseIntake) DecisionBinding { if intake.Outputs.LegalEffects || intake.Outputs.AccessDecisions { if intake.Automation == ucca.AutomationFullyAutomated { return BindingFullyBinding } return BindingHumanReview } return BindingNonBinding } func deriveImpact(intake *ucca.UseCaseIntake) DecisionImpact { if intake.Outputs.LegalEffects || intake.Outputs.AccessDecisions { return ImpactHigh } if intake.Outputs.RankingsOrScores || intake.Purpose.EvaluationScoring || intake.Purpose.DecisionMaking { return ImpactMedium } return ImpactLow } func mapDomain(d ucca.Domain) DomainCategory { switch d { case "hr", "human_resources": return DomainHR case "finance", "banking", "insurance", "investment": return DomainFinance case "education", "school", "university": return DomainEducation case "health", "healthcare", "medical": return DomainHealth case "marketing", "advertising": return DomainMarketing default: return DomainGeneral } } func deriveDataType(dt ucca.DataTypes) DataTypeSensitivity { // Highest sensitivity wins if dt.BiometricData { return DataBiometric } if dt.Article9Data { return DataSensitive } if dt.PersonalData || dt.EmployeeData || dt.CustomerData || dt.FinancialData || dt.MinorData || dt.LocationData || dt.Images || dt.Audio { return DataPersonal } return DataNonPersonal } func deriveHIL(a ucca.AutomationLevel) HumanInLoopLevel { switch a { case ucca.AutomationAssistive: return HILRequired case ucca.AutomationSemiAutomated: return HILOptional case ucca.AutomationFullyAutomated: return HILNone default: return HILRequired } } func deriveModelType(mu ucca.ModelUsage) ModelType { if mu.RAG && !mu.Training && !mu.Finetune { return ModelRuleBased } if mu.Training || mu.Finetune { return ModelBlackboxLLM } return ModelStatistical } func deriveScope(intake *ucca.UseCaseIntake) DeploymentScope { if intake.Purpose.PublicService || intake.Outputs.DataExport { return ScopePublic } if intake.Purpose.CustomerSupport || intake.Purpose.Marketing { return ScopeExternal } return ScopeInternal } func mapDataTypeBack(dt DataTypeSensitivity, original ucca.DataTypes) ucca.DataTypes { result := original switch dt { case DataNonPersonal: result.PersonalData = false result.Article9Data = false result.BiometricData = false case DataPersonal: result.PersonalData = true result.Article9Data = false result.BiometricData = false case DataSensitive: result.PersonalData = true result.Article9Data = true result.BiometricData = false case DataBiometric: result.PersonalData = true result.Article9Data = true result.BiometricData = true } return result } // EnrichDimensionsFromProfile adjusts dimensions based on company profile data. func EnrichDimensionsFromProfile(config *DimensionConfig, profile *ucca.CompanyProfileInput) { if profile == nil { return } // Domain override from company industry (if config still generic) if config.Domain == DomainGeneral && profile.Industry != "" { lower := strings.ToLower(profile.Industry) switch { case strings.Contains(lower, "gesundheit") || strings.Contains(lower, "health"): config.Domain = DomainHealth case strings.Contains(lower, "finanz") || strings.Contains(lower, "bank") || strings.Contains(lower, "versicherung"): config.Domain = DomainFinance case strings.Contains(lower, "bildung") || strings.Contains(lower, "schule"): config.Domain = DomainEducation case strings.Contains(lower, "personal") || strings.Contains(lower, "hr"): config.Domain = DomainHR case strings.Contains(lower, "marketing"): config.Domain = DomainMarketing } } // NIS2/AI-Act regulatory flags if profile.SubjectToNIS2 { config.LoggingRequired = true } if profile.SubjectToAIAct { config.TransparencyRequired = true } } func mapDomainBack(dc DomainCategory, original ucca.Domain) ucca.Domain { switch dc { case DomainHR: return "hr" case DomainFinance: return "finance" case DomainEducation: return "education" case DomainHealth: return "health" case DomainMarketing: return "marketing" default: return original } }