Aller au contenu

PD-32 — Confrontation Gate AMBIGUITY (Step 5) — v2

1. Contexte

  • Story ID : PD-32
  • Gate : AMBIGUITY (Review Plan d'implementation)
  • Date : 2026-02-05
  • Version : 2 (après corrections)
  • Corrections par : Claude (orchestrateur)

2. Rappel des écarts v1

ID Gravité Description
DIV-01 BLOQUANT Champ plan exposé dans GET
DIV-02 BLOQUANT Mécanisme test accès croisé non décrit
DIV-03 MAJEUR Mapping ERR-32-* non contractualisé
DIV-04 MAJEUR Seuil rate limiting non documenté
DIV-08 MAJEUR Invariant supplémentaire user-module
DIV-09 MAJEUR Code contract INV-32-08 incomplet
DIV-06 MINEUR Serialisation non contractualisée
DIV-07 MINEUR AppModule non contractualisé

3. Vérification des corrections

DIV-01 : Champ plan exposé dans GET — ✅ CORRIGÉ

Avant : - §2.1 step 6.1 : SELECT name, email, plan, avatar_url, preferences - §2.1 step 8 : { name, email, plan, avatar_url, preferences }

Après : - §2.1 step 6.1 : SELECT name, email, avatar_url, preferences - §2.1 step 8 : { name, email, avatar_url, preferences } - §2.2 step 9 : { name, email, avatar_url, preferences }

Verdict : Conforme à CA-32-04 (pas de champ protégé en sortie)


DIV-02 : Mécanisme test accès croisé — ✅ CORRIGÉ

Avant : Aucune description du mécanisme de test

Après : Note ajoutée après §5 :

"Les tests TC-ERR-03/04 vérifient l'isolation RLS en créant deux utilisateurs U1 et U2 en base, puis en exécutant une requête avec le contexte RLS de U1 tout en vérifiant que les données de U2 ne sont jamais exposées ni modifiées. Le test contrôle l'état de U2 avant/après via SELECT direct."

Verdict : Mécanisme explicite et testable


DIV-03 : Mapping ERR-32-* — ✅ CORRIGÉ

Avant : "Si le filter global ne produit pas le format attendu, créer..."

Après (§6.3) : "Un ExceptionFilter (global ou dédié UserProfileExceptionFilter) DOIT mapper les exceptions vers le format contractuel {error: ERR-32-*, message}. La vérification de ce mapping fait partie des tests TC-INV-02."

Verdict : Formulation contractuelle affirmative


DIV-04 : Seuil rate limiting — ✅ CORRIGÉ

Avant : "RateLimitGuard | Rate limiting global"

Après (§1.3) : "RateLimitGuard | Rate limiting global (configuration globale existante : src/config/rate-limit.config.ts. Pour les tests TC-ERR-08, utiliser l'environnement de test avec seuil réduit configurable.)"

Verdict : Référence config et testabilité documentées


DIV-08 : Invariant supplémentaire user-module — ✅ CORRIGÉ

Avant : invariants: ["Le module DOIT exporter UserProfileService..."]

Après : invariants: []

Verdict : Invariant non-spec retiré


DIV-09 : Code contract INV-32-08 — ✅ CORRIGÉ

Avant : "GET DOIT retourner UserProfileResponseDto (name, email, avatar_url)"

Après : "GET DOIT retourner UserProfileResponseDto (name, email, avatar_url, preferences)"

Verdict : Aligné avec spec §5 F-32-01 step 4


DIV-06 : Serialisation — ✅ CORRIGÉ

Après (§9.3) : "Oublier de vérifier que ClassSerializerInterceptor est appliqué globalement"

Verdict : Piège documenté


DIV-07 : AppModule — ✅ CORRIGÉ

Après (code-contracts.yaml header) : "# Note technique: AppModule est exclu des code contracts (modification triviale d'import de module)."

Verdict : Exclusion explicite documentée


4. Écart identifié en review v2

DIV-10 : Incohérence terminologique §2.2 étape 3.1 — ✅ CORRIGÉ

Source : Review ChatGPT v2 Description : Le flux §2.2 indiquait "whitelist: true rejecte" alors que le mécanisme correct est forbidNonWhitelisted: true.

Correction appliquée : - Avant : 3.1 Si champ protégé présent (whitelist: true rejecte) - Après : 3.1 Si champ protégé présent (forbidNonWhitelisted: true rejecte)

Verdict : Aligné avec INV-32-06 et le mapping §3/§4.

5. Bilan v2

Gravité v1 v2
BLOQUANT 2 0
MAJEUR 4 0
MINEUR 2 0

6. Verdict confrontation v2

Tous les écarts identifiés en v1 ont été corrigés. Le plan d'implémentation et les code contracts sont maintenant conformes à la spécification.

Statut : ✅ CONFORME