Aller au contenu

PD-15 — Rétrospective

1. Contexte

Champ Valeur
Story ID PD-15
Titre Schéma vault_secure.users
Domaine backend-core
Projet backend
Date complétion 2025-12-XX
Verdict ACCEPTÉ AVEC RÉSERVES

2. Métriques

Métrique Valeur
Écarts MAJEURS 2
Points fluides 10
Champs table id, email, srp_salt, password_hash, plan, timestamps

3. Learnings clés

  • RLS SELECT complexe : Les policies SELECT s'appliquent à TOUTES les lectures, y compris le login SRP. Le subscriber TypeORM ne peut pas intercepter avant un SELECT.

  • USING(false) bloque tout : Une policy DELETE avec USING(false) ne permet aucune exception, même pour admin. Nécessite soit une policy conditionnelle, soit un rôle BYPASSRLS.

  • Normalisation email applicative : class-validator @IsEmail valide le format mais ne transforme pas. Sans @Transform, "User@X.com" et "user@x.com" sont différents.

  • INSERT sans RLS user : L'utilisateur n'existe pas encore lors de l'inscription. Un rôle serveur dédié est requis.

4. Patterns applicables

Nouveau pattern : RLS et login

Pour les opérations de login/inscription qui doivent lire/écrire AVANT que le contexte utilisateur existe : 1. Utiliser un rôle PostgreSQL avec BYPASSRLS pour l'authentification 2. Ou créer une policy conditionnelle avec current_setting('app.is_auth_flow')::boolean

Nouveau pattern : TypeORM RLS Middleware

Le RlsSubscriber ne couvre pas les SELECT. Pour RLS complet, utiliser un middleware NestJS qui exécute SET LOCAL app.current_user_id = ... AVANT chaque query.

5. Signal CLAUDE.md

Priorité haute : Documenter les limites de TypeORM subscribers avec RLS.

### RLS et TypeORM — Limites subscribers (2026-02-XX)

Le `RlsSubscriber` TypeORM intercepte les opérations `repository.save()` / `repository.remove()` mais PAS les SELECT via `repository.find()` ou `createQueryBuilder().getMany()`.

**Solution** : Middleware NestJS exécutant `SET LOCAL app.current_user_id` AVANT la query.

6. Conclusion

PD-15 a créé la table users avec RLS mais a révélé des incompatibilités fondamentales entre le modèle RLS PostgreSQL et les patterns TypeORM. Le cas du login (SELECT sans contexte utilisateur) et de la suppression admin (DELETE bloqué) nécessitent des rôles PostgreSQL spécifiques non prévus initialement.


Rétrospective générée 2026-02-19 (Étape 10 batch backend-core)