// Package compliance implements the GDPR Article 30 processing registry, // EU AI Act risk classification, PDF report generation, and GDPR rights APIs. package compliance import ( "errors" "time" ) // ErrNotFound is returned when a processing entry is not found. var ErrNotFound = errors.New("compliance entry not found") // ProcessingEntry represents one record in the GDPR Article 30 processing registry. type ProcessingEntry struct { ID string `json:"id"` TenantID string `json:"tenant_id"` UseCaseName string `json:"use_case_name"` LegalBasis string `json:"legal_basis"` Purpose string `json:"purpose"` DataCategories []string `json:"data_categories"` Recipients []string `json:"recipients"` Processors []string `json:"processors"` RetentionPeriod string `json:"retention_period"` SecurityMeasures string `json:"security_measures"` ControllerName string `json:"controller_name"` // AI Act fields (E9-02) RiskLevel string `json:"risk_level"` // minimal|limited|high|forbidden|"" AiActAnswers map[string]bool `json:"ai_act_answers,omitempty"` // q1..q5 IsActive bool `json:"is_active"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // ErasureRecord is an immutable audit record for GDPR Art. 17 erasure requests. type ErasureRecord struct { ID string `json:"erasure_id"` TenantID string `json:"tenant_id"` TargetUser string `json:"user_id"` RequestedBy string `json:"requested_by"` Reason string `json:"reason"` RecordsDeleted int `json:"records_deleted"` Status string `json:"status"` CreatedAt time.Time `json:"timestamp"` } // LegalBasisLabels maps legal_basis values to human-readable French labels. var LegalBasisLabels = map[string]string{ "consent": "Consentement (Art. 6.1.a)", "contract": "Exécution d'un contrat (Art. 6.1.b)", "legal_obligation": "Obligation légale (Art. 6.1.c)", "vital_interests": "Intérêts vitaux (Art. 6.1.d)", "public_task": "Mission d'intérêt public (Art. 6.1.e)", "legitimate_interest": "Intérêt légitime (Art. 6.1.f)", } // RiskLabels maps risk_level values to human-readable labels. var RiskLabels = map[string]string{ "minimal": "Risque minimal", "limited": "Risque limité", "high": "Haut risque", "forbidden": "Interdit", } // AiActQuestions defines the 5 EU AI Act classification questions. // Keys q1..q5 correspond to the ai_act_answers JSONB field. var AiActQuestions = []struct { Key string Label string }{ {"q1", "Le système prend-il des décisions autonomes affectant des droits légaux ou des situations similaires des personnes ?"}, {"q2", "Implique-t-il une identification biométrique ou une reconnaissance des émotions ?"}, {"q3", "Est-il utilisé dans des décisions critiques (médical, justice, emploi, crédit) ?"}, {"q4", "Traite-t-il des catégories spéciales de données (santé, biométrie, origine raciale) ?"}, {"q5", "La transparence sur l'utilisation de l'IA est-elle indispensable au consentement éclairé ?"}, } // ScoreRisk computes the EU AI Act risk level from questionnaire answers. // // Scoring rules: // - 0 "yes" → minimal // - 1–2 "yes" → limited // - 3–4 "yes" → high // - 5 "yes" → forbidden func ScoreRisk(answers map[string]bool) string { yes := 0 for _, v := range answers { if v { yes++ } } switch { case yes == 5: return "forbidden" case yes >= 3: return "high" case yes >= 1: return "limited" default: return "minimal" } }