PD-240 — Retour d'expérience (REX)¶
Story : PD-240 — Suppression de compte utilisateur Date : 2026-02-07 Auteur : Claude (Opus 4.5)
1. Résumé exécutif¶
| Métrique | Valeur |
|---|---|
| Durée totale | 1 jour |
| Nombre de gates | 3 |
| Itérations Gate 3 (CONFORMITY_CHECK) | 3 (GO v3) |
| Itérations Gate 5 (AMBIGUITY) | 2 (GO v2) |
| Itérations Gate 8 (CLOSURE) | 2 (GO v2) |
| Écarts corrigés | 4 (ECT-240-02, 04, 06, 07) |
| Écarts acceptés (dette technique) | 5 (ECT-240-01, 03, 05, 08, 09) |
Verdict final : GO avec réserves techniques documentées.
2. Objectifs vs. Réalisé¶
| Objectif spécifié | Réalisé | Commentaire |
|---|---|---|
| Suppression compte irréversible | ✅ | Flux sessions → purge → Keycloak |
| Purge RGPD Article 17 | ✅ | Tables user, device_trust, key_envelopes |
| Re-authentification obligatoire | ✅ | Guard avec X-Reauth-Token JWT |
| Protection anti-replay | ⚠️ | Blacklist Redis (fail-open) |
| Rate limiting endpoint | ⚠️ | Guard dédié (fail-open) |
| Format erreur | ✅ | DeleteAccountExceptionFilter |
| Endpoint admin audit | ✅ | GET /admin/audit/user/:userId |
3. Difficultés rencontrées¶
3.1 Gate 8 v1 : NON_CONFORME¶
Cause : 4 écarts bloquants identifiés par les reviews ChatGPT : 1. ECT-240-02 : Purge RGPD limitée à la table User (device_trust, key_envelopes non purgées) 2. ECT-240-04 : Tests E2E n'injectaient pas d'erreurs déterministes pour ERR-240-DELETE-FAILED 3. ECT-240-06 : Reauth token réutilisable (pas de one-time token) 4. ECT-240-07 : Absence de rate limiting sur l'endpoint critique
Impact : Boucle de correction + cycle d'acceptabilité v2 complet.
3.2 Zones d'ombre Gate 8 v2¶
Cause : Le PMO a exigé la résolution des 3 zones d'ombre avant GO : - ZO-01 : Monitoring Redis - ZO-02 : X-Forwarded-For - ZO-03 : Contraintes DB
Résolution : Analyse code source pour clarifier chaque point (patterns existants, comportement intentionnel).
4. Enseignements techniques¶
4.1 Pattern fail-open Redis¶
Constat : Les protections Redis (blacklist, rate limit) dégradent gracieusement si Redis est indisponible.
Décision : Compromis de disponibilité accepté. L'alternative (fail-closed) bloquerait l'endpoint en cas de panne Redis.
Règle : Pour les endpoints critiques dépendant de Redis, documenter explicitement le comportement fail-open/fail-closed.
4.2 Purge RGPD transactionnelle¶
Constat : La purge doit couvrir toutes les tables liées à l'utilisateur, pas seulement la table principale.
Tables identifiées : user, device_trust, key_envelopes.
Règle : Avant d'implémenter une purge RGPD, lister exhaustivement les tables avec FK vers userId.
4.3 One-time token via Redis blacklist¶
Constat : L'invalidation d'un token JWT après usage nécessite un état serveur (blacklist).
Implémentation : SHA-256 du token comme clé Redis, TTL = durée de vie du token.
Règle : Pour les tokens one-time, utiliser une blacklist Redis avec TTL aligné sur l'expiration du token.
4.4 Buffer.alloc(0) pour champs bytea NOT NULL¶
Constat : Mettre un champ bytea à "vide" sans violer NOT NULL est possible avec Buffer.alloc(0).
Comportement : Un verifier SRP vide empêche toute authentification (design intentionnel).
Règle : Pour anonymiser des champs bytea NOT NULL, utiliser Buffer.alloc(0) plutôt que null.
5. Enseignements processus¶
5.1 Reviews LLM après corrections¶
Constat : La règle de validation croisée impose des reviews ChatGPT même après corrections Claude.
Bénéfice : Les reviews v2 ont identifié des points résiduels (fail-open) que Claude n'avait pas documentés.
Règle : Toujours exécuter les 3 reviews LLM (code, tests, sécurité) après toute modification significative.
5.2 Résolution des zones d'ombre¶
Constat : Le PMO peut exiger zéro zone d'ombre avant GO.
Méthode : Analyse du code source pour clarifier chaque point avec références précises (fichier:ligne).
Règle : Anticiper les zones d'ombre en documentant les choix techniques dès l'implémentation.
6. Dette technique acceptée¶
| Écart | Description | Justification |
|---|---|---|
| ECT-240-01 | Erreurs métier non typées (Error générique) | Refactoring hors scope, pas d'impact fonctionnel |
| ECT-240-03 | Mapping Keycloak userId = user.sub supposé | Conforme à l'architecture OIDC existante |
| ECT-240-05 | Token admin forgé dans tests | Tests E2E, authz réelle testée en staging |
| ECT-240-08 | PII potentiels dans logs | À auditer séparément (PD-security) |
| ECT-240-09 | Coverage 76.27% < 80% | Dû aux services hors scope, pas à PD-240 |
7. Recommandations futures¶
| ID | Recommandation | Priorité |
|---|---|---|
| REC-01 | Ajouter alerting spécifique "protection PD-240 inactive" si Redis down | Moyenne |
| REC-02 | Auditer les logs des services blacklist/rate limit pour PII | Haute |
| REC-03 | Documenter les tables à purger dans un registre RGPD centralisé | Haute |
| REC-04 | Créer un RateLimitService générique réutilisable (éviter duplication) | Faible |
8. Métriques de qualité¶
| Métrique | Valeur | Seuil | Statut |
|---|---|---|---|
| ESLint errors | 0 | 0 | ✅ |
| Prettier | OK | OK | ✅ |
| TypeScript | OK | OK | ✅ |
| Tests passés | 218 | 218 | ✅ |
| Coverage branches | 76.27% | 80% | ⚠️ |
| Reviews LLM | 3/3 APPROUVÉ | 3/3 | ✅ |
9. Artefacts produits¶
| Artefact | Version | Statut |
|---|---|---|
| PD-240-besoin.md | v1 | Final |
| PD-240-specification.md | v4 | Final |
| PD-240-tests.md | v1 | Final |
| PD-240-plan.md | v1 | Final |
| PD-240-code-contracts.yaml | v2 | Final |
| PD-240-decomposition.md | v1 | Final |
| PD-240-acceptability.md | v2 | Final |
| PD-240-verdict-step8-v2.yaml | v2 | GO |
Document généré le 2026-02-07 Orchestrateur : Claude (Opus 4.5)