102 lines
3.7 KiB
Go
102 lines
3.7 KiB
Go
// 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"
|
||
}
|
||
}
|