Services: Admin-Compliance, Backend-Compliance, AI-Compliance-SDK, Consent-SDK, Developer-Portal, PCA-Platform, DSMS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
287 lines
12 KiB
Go
287 lines
12 KiB
Go
package ucca
|
|
|
|
// ============================================================================
|
|
// Didactic Examples - Real-world scenarios for learning
|
|
// ============================================================================
|
|
|
|
// Example represents a didactic example case
|
|
type Example struct {
|
|
ID string `json:"id"`
|
|
Title string `json:"title"`
|
|
TitleDE string `json:"title_de"`
|
|
Description string `json:"description"`
|
|
DescriptionDE string `json:"description_de"`
|
|
Domain Domain `json:"domain"`
|
|
Outcome Feasibility `json:"outcome"`
|
|
OutcomeDE string `json:"outcome_de"`
|
|
Lessons string `json:"lessons"`
|
|
LessonsDE string `json:"lessons_de"`
|
|
|
|
// Matching criteria
|
|
MatchCriteria MatchCriteria `json:"-"`
|
|
}
|
|
|
|
// MatchCriteria defines when an example matches an intake
|
|
type MatchCriteria struct {
|
|
Domains []Domain
|
|
HasPersonalData *bool
|
|
HasArticle9Data *bool
|
|
HasMinorData *bool
|
|
AutomationLevels []AutomationLevel
|
|
HasScoring *bool
|
|
HasLegalEffects *bool
|
|
ModelUsageRAG *bool
|
|
ModelUsageTraining *bool
|
|
}
|
|
|
|
// boolPtr helper for creating bool pointers
|
|
func boolPtr(b bool) *bool {
|
|
return &b
|
|
}
|
|
|
|
// ExampleLibrary contains all didactic examples
|
|
var ExampleLibrary = []Example{
|
|
// =========================================================================
|
|
// Example 1: Parkhaus (CONDITIONAL)
|
|
// =========================================================================
|
|
{
|
|
ID: "EX-PARKHAUS",
|
|
Title: "Parking Garage License Plate Recognition",
|
|
TitleDE: "Parkhaus mit Kennzeichenerkennung",
|
|
Description: "A parking garage operator wants to use AI-based license plate recognition for automated entry/exit and billing. Cameras capture license plates, AI recognizes them, and matches to customer database.",
|
|
DescriptionDE: "Ein Parkhaus-Betreiber möchte KI-basierte Kennzeichenerkennung für automatisierte Ein-/Ausfahrt und Abrechnung nutzen. Kameras erfassen Kennzeichen, KI erkennt sie und gleicht mit Kundendatenbank ab.",
|
|
Domain: DomainGeneral,
|
|
Outcome: FeasibilityCONDITIONAL,
|
|
OutcomeDE: "BEDINGT MÖGLICH - Mit Auflagen umsetzbar",
|
|
Lessons: "License plates are personal data (linkable to vehicle owners). Requires: legal basis (contract performance), retention limits, access controls, deletion on request capability.",
|
|
LessonsDE: "Kennzeichen sind personenbezogene Daten (verknüpfbar mit Haltern). Erfordert: Rechtsgrundlage (Vertragserfüllung), Aufbewahrungsfristen, Zugriffskontrollen, Löschbarkeit auf Anfrage.",
|
|
MatchCriteria: MatchCriteria{
|
|
Domains: []Domain{DomainGeneral, DomainPublic},
|
|
HasPersonalData: boolPtr(true),
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// Example 2: CFO-Gehalt (NO)
|
|
// =========================================================================
|
|
{
|
|
ID: "EX-CFO-GEHALT",
|
|
Title: "Executive Salary Prediction AI",
|
|
TitleDE: "KI zur CFO-Gehaltsvorhersage",
|
|
Description: "A company wants to train an AI model on historical CFO salary data to predict appropriate compensation for new executives. The training data includes names, companies, exact salaries, and performance metrics.",
|
|
DescriptionDE: "Ein Unternehmen möchte ein KI-Modell mit historischen CFO-Gehaltsdaten trainieren, um angemessene Vergütung für neue Führungskräfte vorherzusagen. Die Trainingsdaten umfassen Namen, Unternehmen, exakte Gehälter und Leistungskennzahlen.",
|
|
Domain: DomainFinance,
|
|
Outcome: FeasibilityNO,
|
|
OutcomeDE: "NICHT ZULÄSSIG - Erhebliche DSGVO-Verstöße",
|
|
Lessons: "Training with identifiable salary data of individuals violates purpose limitation, data minimization, and likely lacks legal basis. Alternative: Use aggregated, anonymized market studies.",
|
|
LessonsDE: "Training mit identifizierbaren Gehaltsdaten einzelner Personen verstößt gegen Zweckbindung, Datenminimierung und hat wahrscheinlich keine Rechtsgrundlage. Alternative: Aggregierte, anonymisierte Marktstudien nutzen.",
|
|
MatchCriteria: MatchCriteria{
|
|
Domains: []Domain{DomainFinance, DomainHR},
|
|
HasPersonalData: boolPtr(true),
|
|
ModelUsageTraining: boolPtr(true),
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// Example 3: Stadtwerke-Chatbot (YES)
|
|
// =========================================================================
|
|
{
|
|
ID: "EX-STADTWERKE",
|
|
Title: "Utility Company Customer Service Chatbot",
|
|
TitleDE: "Stadtwerke-Chatbot für Kundenservice",
|
|
Description: "A municipal utility company wants to deploy an AI chatbot to answer customer questions about tariffs, bills, and services. The chatbot uses RAG with FAQ documents and does not store personal customer data.",
|
|
DescriptionDE: "Ein Stadtwerk möchte einen KI-Chatbot einsetzen, um Kundenfragen zu Tarifen, Rechnungen und Services zu beantworten. Der Chatbot nutzt RAG mit FAQ-Dokumenten und speichert keine personenbezogenen Kundendaten.",
|
|
Domain: DomainUtilities,
|
|
Outcome: FeasibilityYES,
|
|
OutcomeDE: "ZULÄSSIG - Niedriges Risiko",
|
|
Lessons: "RAG-only with public FAQ documents, no personal data storage, customer support purpose = low risk. Best practice: log only anonymized metrics, offer human escalation.",
|
|
LessonsDE: "Nur-RAG mit öffentlichen FAQ-Dokumenten, keine Speicherung personenbezogener Daten, Kundenservice-Zweck = geringes Risiko. Best Practice: Nur anonymisierte Metriken loggen, Eskalation zu Menschen anbieten.",
|
|
MatchCriteria: MatchCriteria{
|
|
Domains: []Domain{DomainUtilities, DomainPublic, DomainGeneral},
|
|
HasPersonalData: boolPtr(false),
|
|
ModelUsageRAG: boolPtr(true),
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// Example 4: Schülerdaten (NO)
|
|
// =========================================================================
|
|
{
|
|
ID: "EX-SCHUELER",
|
|
Title: "Student Performance Scoring AI",
|
|
TitleDE: "KI-Bewertung von Schülerleistungen",
|
|
Description: "A school wants to use AI to automatically score and rank students based on their homework, test results, and classroom behavior. The scores would influence grade recommendations.",
|
|
DescriptionDE: "Eine Schule möchte KI nutzen, um Schüler automatisch basierend auf Hausaufgaben, Testergebnissen und Unterrichtsverhalten zu bewerten und zu ranken. Die Scores würden Notenempfehlungen beeinflussen.",
|
|
Domain: DomainEducation,
|
|
Outcome: FeasibilityNO,
|
|
OutcomeDE: "NICHT ZULÄSSIG - Schutz Minderjähriger",
|
|
Lessons: "Automated profiling and scoring of minors is prohibited. Children require special protection. Grades must remain human decisions. Alternative: AI for teacher suggestions, never automatic scoring.",
|
|
LessonsDE: "Automatisiertes Profiling und Scoring von Minderjährigen ist verboten. Kinder erfordern besonderen Schutz. Noten müssen menschliche Entscheidungen bleiben. Alternative: KI für Lehrervorschläge, niemals automatisches Scoring.",
|
|
MatchCriteria: MatchCriteria{
|
|
Domains: []Domain{DomainEducation},
|
|
HasMinorData: boolPtr(true),
|
|
HasScoring: boolPtr(true),
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// Example 5: HR-Bewertung (NO)
|
|
// =========================================================================
|
|
{
|
|
ID: "EX-HR-BEWERTUNG",
|
|
Title: "Automated Employee Performance Evaluation",
|
|
TitleDE: "Automatisierte Mitarbeiterbewertung",
|
|
Description: "An HR department wants to fully automate quarterly performance reviews using AI. The system would analyze emails, meeting participation, and task completion to generate scores that directly determine bonuses and promotions.",
|
|
DescriptionDE: "Eine Personalabteilung möchte Quartalsbewertungen mit KI vollständig automatisieren. Das System würde E-Mails, Meeting-Teilnahme und Aufgabenerfüllung analysieren, um Scores zu generieren, die direkt Boni und Beförderungen bestimmen.",
|
|
Domain: DomainHR,
|
|
Outcome: FeasibilityNO,
|
|
OutcomeDE: "NICHT ZULÄSSIG - Art. 22 DSGVO Verstoß",
|
|
Lessons: "Fully automated decisions with legal/significant effects on employees violate Art. 22 GDPR. Requires human review. Also: email surveillance raises additional issues. Alternative: AI-assisted (not automated) evaluations with mandatory human decision.",
|
|
LessonsDE: "Vollautomatisierte Entscheidungen mit rechtlichen/erheblichen Auswirkungen auf Mitarbeiter verstoßen gegen Art. 22 DSGVO. Erfordert menschliche Überprüfung. Außerdem: E-Mail-Überwachung wirft zusätzliche Fragen auf. Alternative: KI-unterstützte (nicht automatisierte) Bewertungen mit verpflichtender menschlicher Entscheidung.",
|
|
MatchCriteria: MatchCriteria{
|
|
Domains: []Domain{DomainHR},
|
|
HasPersonalData: boolPtr(true),
|
|
HasScoring: boolPtr(true),
|
|
HasLegalEffects: boolPtr(true),
|
|
AutomationLevels: []AutomationLevel{AutomationFullyAutomated},
|
|
},
|
|
},
|
|
}
|
|
|
|
// MatchExamples calculates relevance of examples to the given intake
|
|
func MatchExamples(intake *UseCaseIntake) []ExampleMatch {
|
|
var matches []ExampleMatch
|
|
|
|
for _, ex := range ExampleLibrary {
|
|
similarity := calculateSimilarity(intake, ex.MatchCriteria)
|
|
if similarity > 0.3 { // Threshold for relevance
|
|
matches = append(matches, ExampleMatch{
|
|
ExampleID: ex.ID,
|
|
Title: ex.TitleDE,
|
|
Description: ex.DescriptionDE,
|
|
Similarity: similarity,
|
|
Outcome: ex.OutcomeDE,
|
|
Lessons: ex.LessonsDE,
|
|
})
|
|
}
|
|
}
|
|
|
|
// Sort by similarity (highest first)
|
|
for i := 0; i < len(matches)-1; i++ {
|
|
for j := i + 1; j < len(matches); j++ {
|
|
if matches[j].Similarity > matches[i].Similarity {
|
|
matches[i], matches[j] = matches[j], matches[i]
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return top 3
|
|
if len(matches) > 3 {
|
|
matches = matches[:3]
|
|
}
|
|
|
|
return matches
|
|
}
|
|
|
|
// calculateSimilarity calculates how similar an intake is to example criteria
|
|
func calculateSimilarity(intake *UseCaseIntake, criteria MatchCriteria) float64 {
|
|
var score float64
|
|
var maxScore float64
|
|
|
|
// Domain match (weight: 3)
|
|
if len(criteria.Domains) > 0 {
|
|
maxScore += 3
|
|
for _, d := range criteria.Domains {
|
|
if intake.Domain == d {
|
|
score += 3
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// Personal data match (weight: 2)
|
|
if criteria.HasPersonalData != nil {
|
|
maxScore += 2
|
|
if *criteria.HasPersonalData == intake.DataTypes.PersonalData {
|
|
score += 2
|
|
}
|
|
}
|
|
|
|
// Article 9 data match (weight: 2)
|
|
if criteria.HasArticle9Data != nil {
|
|
maxScore += 2
|
|
if *criteria.HasArticle9Data == intake.DataTypes.Article9Data {
|
|
score += 2
|
|
}
|
|
}
|
|
|
|
// Minor data match (weight: 3)
|
|
if criteria.HasMinorData != nil {
|
|
maxScore += 3
|
|
if *criteria.HasMinorData == intake.DataTypes.MinorData {
|
|
score += 3
|
|
}
|
|
}
|
|
|
|
// Automation level match (weight: 2)
|
|
if len(criteria.AutomationLevels) > 0 {
|
|
maxScore += 2
|
|
for _, a := range criteria.AutomationLevels {
|
|
if intake.Automation == a {
|
|
score += 2
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// Scoring match (weight: 2)
|
|
if criteria.HasScoring != nil {
|
|
maxScore += 2
|
|
hasScoring := intake.Purpose.EvaluationScoring || intake.Outputs.RankingsOrScores
|
|
if *criteria.HasScoring == hasScoring {
|
|
score += 2
|
|
}
|
|
}
|
|
|
|
// Legal effects match (weight: 2)
|
|
if criteria.HasLegalEffects != nil {
|
|
maxScore += 2
|
|
if *criteria.HasLegalEffects == intake.Outputs.LegalEffects {
|
|
score += 2
|
|
}
|
|
}
|
|
|
|
// RAG usage match (weight: 1)
|
|
if criteria.ModelUsageRAG != nil {
|
|
maxScore += 1
|
|
if *criteria.ModelUsageRAG == intake.ModelUsage.RAG {
|
|
score += 1
|
|
}
|
|
}
|
|
|
|
// Training usage match (weight: 2)
|
|
if criteria.ModelUsageTraining != nil {
|
|
maxScore += 2
|
|
if *criteria.ModelUsageTraining == intake.ModelUsage.Training {
|
|
score += 2
|
|
}
|
|
}
|
|
|
|
if maxScore == 0 {
|
|
return 0
|
|
}
|
|
|
|
return score / maxScore
|
|
}
|
|
|
|
// GetExampleByID returns an example by its ID
|
|
func GetExampleByID(id string) *Example {
|
|
for _, ex := range ExampleLibrary {
|
|
if ex.ID == id {
|
|
return &ex
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetAllExamples returns all available examples
|
|
func GetAllExamples() []Example {
|
|
return ExampleLibrary
|
|
}
|