package ucca // ============================================================================ // Architecture Patterns - Hardcoded recommendations // ============================================================================ // Pattern represents an architecture pattern recommendation type Pattern struct { ID string `json:"id"` Title string `json:"title"` TitleDE string `json:"title_de"` Description string `json:"description"` DescriptionDE string `json:"description_de"` Benefits []string `json:"benefits"` Requirements []string `json:"requirements"` ApplicableWhen func(intake *UseCaseIntake) bool `json:"-"` } // PatternLibrary contains all available architecture patterns var PatternLibrary = []Pattern{ { ID: "P-RAG-ONLY", Title: "RAG-Only Architecture", TitleDE: "Nur-RAG-Architektur", Description: "Use Retrieval-Augmented Generation without storing or training on personal data. The LLM only receives anonymized context from a vector database, never raw personal data.", DescriptionDE: "Nutzen Sie Retrieval-Augmented Generation ohne Speicherung oder Training mit personenbezogenen Daten. Das LLM erhält nur anonymisierten Kontext aus einer Vektor-Datenbank, niemals Rohdaten.", Benefits: []string{ "No personal data in model weights", "Easy to delete/update information", "Audit trail for all retrievals", "Minimal GDPR compliance burden", }, Requirements: []string{ "Vector database with access controls", "Pre-anonymization pipeline", "Query logging for audit", }, ApplicableWhen: func(intake *UseCaseIntake) bool { // Applicable when using RAG and dealing with personal data return intake.ModelUsage.RAG && (intake.DataTypes.PersonalData || intake.DataTypes.CustomerData) }, }, { ID: "P-PRE-ANON", Title: "Pre-Anonymization Pipeline", TitleDE: "Vor-Anonymisierungs-Pipeline", Description: "Implement mandatory anonymization/pseudonymization before any data reaches the AI system. Personal identifiers are replaced with tokens that can be resolved only by authorized systems.", DescriptionDE: "Implementieren Sie eine verpflichtende Anonymisierung/Pseudonymisierung bevor Daten das KI-System erreichen. Persönliche Identifikatoren werden durch Tokens ersetzt, die nur von autorisierten Systemen aufgelöst werden können.", Benefits: []string{ "Personal data never reaches AI", "Reversible for authorized access", "Compliant with Art. 32 GDPR", "Reduces data breach impact", }, Requirements: []string{ "PII detection system", "Token mapping database (secured)", "Re-identification access controls", "Audit logging for re-identification", }, ApplicableWhen: func(intake *UseCaseIntake) bool { // Applicable when handling personal data and not public data only return intake.DataTypes.PersonalData && !intake.DataTypes.PublicData }, }, { ID: "P-NAMESPACE-ISOLATION", Title: "Namespace Isolation", TitleDE: "Namespace-Isolation", Description: "Strict separation of data and models per tenant/department. Each namespace has its own vector store, model context, and access controls. No data leakage between tenants.", DescriptionDE: "Strikte Trennung von Daten und Modellen pro Mandant/Abteilung. Jeder Namespace hat eigenen Vektor-Speicher, Modellkontext und Zugriffskontrollen. Keine Datenlecks zwischen Mandanten.", Benefits: []string{ "Multi-tenant compliance", "Clear data ownership", "Easy audit per namespace", "Deletion per namespace", }, Requirements: []string{ "Multi-tenant architecture", "Namespace-aware APIs", "Access control per namespace", "Separate encryption keys", }, ApplicableWhen: func(intake *UseCaseIntake) bool { // Applicable for multi-tenant scenarios or when handling different data types return intake.DataTypes.CustomerData || intake.DataTypes.EmployeeData }, }, { ID: "P-HITL-ENFORCED", Title: "Human-in-the-Loop Enforcement", TitleDE: "Verpflichtende menschliche Kontrolle", Description: "Mandatory human review before any AI output affects individuals. The AI provides suggestions, but final decisions require human approval. Audit trail for all decisions.", DescriptionDE: "Verpflichtende menschliche Überprüfung bevor KI-Ausgaben Personen betreffen. Die KI liefert Vorschläge, aber finale Entscheidungen erfordern menschliche Genehmigung. Prüfpfad für alle Entscheidungen.", Benefits: []string{ "Art. 22 GDPR compliance", "Accountability clear", "Error correction possible", "Human judgment preserved", }, Requirements: []string{ "Review workflow system", "Decision audit logging", "Clear escalation paths", "Training for reviewers", }, ApplicableWhen: func(intake *UseCaseIntake) bool { // Applicable when outputs have legal effects or involve scoring/decisions return intake.Outputs.LegalEffects || intake.Outputs.RankingsOrScores || intake.Outputs.AccessDecisions || intake.Purpose.EvaluationScoring || intake.Purpose.DecisionMaking }, }, { ID: "P-LOG-MINIMIZATION", Title: "Log Minimization", TitleDE: "Log-Minimierung", Description: "Minimize logging of personal data in AI interactions. Store only anonymized metrics, not raw prompts/responses. Implement automatic log rotation and deletion.", DescriptionDE: "Minimieren Sie die Protokollierung personenbezogener Daten in KI-Interaktionen. Speichern Sie nur anonymisierte Metriken, keine Roh-Prompts/Antworten. Implementieren Sie automatische Log-Rotation und Löschung.", Benefits: []string{ "Data minimization (Art. 5c GDPR)", "Reduced storage costs", "Simplified deletion requests", "Lower breach impact", }, Requirements: []string{ "Log anonymization pipeline", "Automatic log rotation", "Metrics without PII", "Retention policy enforcement", }, ApplicableWhen: func(intake *UseCaseIntake) bool { // Applicable when storing prompts/responses return intake.Retention.StorePrompts || intake.Retention.StoreResponses }, }, } // GetApplicablePatterns returns patterns applicable for the given intake func GetApplicablePatterns(intake *UseCaseIntake) []Pattern { var applicable []Pattern for _, p := range PatternLibrary { if p.ApplicableWhen(intake) { applicable = append(applicable, p) } } return applicable } // GetPatternByID returns a pattern by its ID func GetPatternByID(id string) *Pattern { for _, p := range PatternLibrary { if p.ID == id { return &p } } return nil } // GetAllPatterns returns all available patterns func GetAllPatterns() []Pattern { return PatternLibrary } // PatternToRecommendation converts a Pattern to a PatternRecommendation func PatternToRecommendation(p Pattern, rationale string, priority int) PatternRecommendation { return PatternRecommendation{ PatternID: p.ID, Title: p.TitleDE, Description: p.DescriptionDE, Rationale: rationale, Priority: priority, } } // ============================================================================ // Forbidden Pattern Definitions // ============================================================================ // ForbiddenPatternDef defines patterns that should NOT be used type ForbiddenPatternDef struct { ID string Title string TitleDE string Description string DescriptionDE string Reason string ReasonDE string GDPRRef string ForbiddenWhen func(intake *UseCaseIntake) bool } // ForbiddenPatternLibrary contains all forbidden pattern definitions var ForbiddenPatternLibrary = []ForbiddenPatternDef{ { ID: "FP-DIRECT-PII-TRAINING", Title: "Direct PII Training", TitleDE: "Direktes Training mit personenbezogenen Daten", Description: "Training AI models directly on personal data without proper legal basis or consent.", DescriptionDE: "Training von KI-Modellen direkt mit personenbezogenen Daten ohne ausreichende Rechtsgrundlage oder Einwilligung.", Reason: "Violates GDPR purpose limitation and data minimization principles.", ReasonDE: "Verstößt gegen DSGVO-Grundsätze der Zweckbindung und Datenminimierung.", GDPRRef: "Art. 5(1)(b)(c) DSGVO", ForbiddenWhen: func(intake *UseCaseIntake) bool { return intake.ModelUsage.Training && intake.DataTypes.PersonalData }, }, { ID: "FP-ART9-WITHOUT-CONSENT", Title: "Special Category Data Without Explicit Consent", TitleDE: "Besondere Kategorien ohne ausdrückliche Einwilligung", Description: "Processing special category data (health, religion, etc.) without explicit consent or legal basis.", DescriptionDE: "Verarbeitung besonderer Datenkategorien (Gesundheit, Religion, etc.) ohne ausdrückliche Einwilligung oder Rechtsgrundlage.", Reason: "Article 9 data requires explicit consent or specific legal basis.", ReasonDE: "Art. 9-Daten erfordern ausdrückliche Einwilligung oder spezifische Rechtsgrundlage.", GDPRRef: "Art. 9 DSGVO", ForbiddenWhen: func(intake *UseCaseIntake) bool { return intake.DataTypes.Article9Data }, }, { ID: "FP-AUTOMATED-LEGAL-DECISION", Title: "Fully Automated Legal Decisions", TitleDE: "Vollautomatisierte rechtliche Entscheidungen", Description: "Making fully automated decisions with legal effects without human oversight.", DescriptionDE: "Treffen vollautomatisierter Entscheidungen mit rechtlichen Auswirkungen ohne menschliche Aufsicht.", Reason: "Article 22 GDPR restricts automated individual decision-making.", ReasonDE: "Art. 22 DSGVO beschränkt automatisierte Einzelentscheidungen.", GDPRRef: "Art. 22 DSGVO", ForbiddenWhen: func(intake *UseCaseIntake) bool { return intake.Automation == AutomationFullyAutomated && intake.Outputs.LegalEffects }, }, { ID: "FP-MINOR-PROFILING", Title: "Profiling of Minors", TitleDE: "Profiling von Minderjährigen", Description: "Creating profiles or scores for children/minors.", DescriptionDE: "Erstellen von Profilen oder Scores für Kinder/Minderjährige.", Reason: "Special protection for minors under GDPR.", ReasonDE: "Besonderer Schutz für Minderjährige unter der DSGVO.", GDPRRef: "Art. 8, Erwägungsgrund 38 DSGVO", ForbiddenWhen: func(intake *UseCaseIntake) bool { return intake.DataTypes.MinorData && (intake.Purpose.Profiling || intake.Purpose.EvaluationScoring) }, }, { ID: "FP-THIRD-COUNTRY-PII", Title: "PII Transfer to Third Countries", TitleDE: "Übermittlung personenbezogener Daten in Drittländer", Description: "Transferring personal data to third countries without adequate safeguards.", DescriptionDE: "Übermittlung personenbezogener Daten in Drittländer ohne angemessene Schutzmaßnahmen.", Reason: "Requires adequacy decision or appropriate safeguards.", ReasonDE: "Erfordert Angemessenheitsbeschluss oder geeignete Garantien.", GDPRRef: "Art. 44-49 DSGVO", ForbiddenWhen: func(intake *UseCaseIntake) bool { return intake.Hosting.Region == "third_country" && intake.DataTypes.PersonalData }, }, } // GetForbiddenPatterns returns forbidden patterns for the given intake func GetForbiddenPatterns(intake *UseCaseIntake) []ForbiddenPattern { var forbidden []ForbiddenPattern for _, fp := range ForbiddenPatternLibrary { if fp.ForbiddenWhen(intake) { forbidden = append(forbidden, ForbiddenPattern{ PatternID: fp.ID, Title: fp.TitleDE, Description: fp.DescriptionDE, Reason: fp.ReasonDE, GDPRRef: fp.GDPRRef, }) } } return forbidden }