""" rgpd_model.py — Anonymisation des données personnelles (droit à l'effacement, RGPD art. 17). Bloc 1 - C10 : traçabilité, et Bloc 2 - C4 : la seule donnée personnelle stockée dans l'application est le `sub` OIDC (Keycloak) — aucune autre table ne duplique d'attribut d'identité. `sub` est référencé dans quatre tables : annonces.auteur_sub, fichiers.uploader_sub, evenements.createur_sub (toutes NOT NULL — la donnée ne peut donc pas être mise à NULL sans casser la contrainte, d'où le choix d'un pseudonyme irréversible) et audit_log.utilisateur_sub (NULLable, mais pseudonymisée elle aussi par cohérence, pour garder la traçabilité du volume d'actions sans conserver l'identité). Toutes les mises à jour sont exécutées dans UNE seule transaction InnoDB (un seul curseur `commit=True`) : soit les quatre tables sont mises à jour, soit aucune ne l'est en cas d'erreur (cohérence, pas d'anonymisation partielle). """ def anonymize(db, target_sub, anon_value): """Remplace `target_sub` par `anon_value` dans toutes les tables qui le référencent. Retourne le nombre de lignes modifiées par table. """ with db.cursor(commit=True) as cur: cur.execute( "UPDATE annonces SET auteur_sub = %s WHERE auteur_sub = %s", (anon_value, target_sub), ) annonces_rows = cur.rowcount cur.execute( "UPDATE fichiers SET uploader_sub = %s WHERE uploader_sub = %s", (anon_value, target_sub), ) fichiers_rows = cur.rowcount cur.execute( "UPDATE evenements SET createur_sub = %s WHERE createur_sub = %s", (anon_value, target_sub), ) evenements_rows = cur.rowcount cur.execute( "UPDATE audit_log SET utilisateur_sub = %s WHERE utilisateur_sub = %s", (anon_value, target_sub), ) audit_rows = cur.rowcount return { "annonces": annonces_rows, "fichiers": fichiers_rows, "evenements": evenements_rows, "audit_log": audit_rows, }