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)