Expression de Besoin — PD-32¶
Créer endpoints gestion profil utilisateur¶
1. Contexte¶
ProbatioVault dispose d'un système d'authentification (inscription, login SRP, JWT, RLS) mais aucun endpoint ne permet à un utilisateur authentifié de consulter ou modifier ses propres informations de profil.
L'application mobile iOS (PD-106) a été spécifiée avec l'hypothèse (H-106-01) que des endpoints backend de gestion de profil existent. PD-106 consomme notamment : - GET /user/profile → {name, email, avatar_url?} - GET /user/mfa/status → {active, method}
PD-32 couvre uniquement la partie profil utilisateur (consultation et modification). Les endpoints MFA, changement de mot de passe, suppression de compte et logout relèvent d'autres user stories (PD-27, PD-28, PD-30, PD-31, etc.).
L'entité User existante contient : id, email, plan (free/premium/business), status, srpSalt, passwordHash, createdAt, updatedAt. Elle ne contient actuellement ni name, ni avatar_url, ni preferences.
2. Objectifs principaux¶
- Permettre à un utilisateur authentifié de consulter son propre profil (informations non sensibles).
- Permettre à un utilisateur authentifié de modifier certaines informations de son profil (préférences, et potentiellement d'autres champs modifiables).
- Fournir les endpoints attendus par le client mobile (PD-106) pour l'écran Settings.
- Appliquer un rate limiting sur ces endpoints pour prévenir les abus.
- Valider les données en entrée selon les contraintes métier.
3. Non-objectifs (exclusions explicites)¶
- Pas de gestion MFA dans PD-32 (couvert par PD-27).
- Pas de changement de mot de passe (couvert par une autre user story).
- Pas de suppression de compte (couvert par une autre user story).
- Pas de gestion de sessions / logout (couvert par PD-30).
- Pas de modification de l'email — l'email est l'identifiant principal, sa modification implique un flux de revalidation qui dépasse le périmètre de PD-32.
- Pas de modification du plan — le changement de plan relève d'un flux de facturation/abonnement distinct.
- Pas d'upload d'avatar — si un champ avatar existe, il s'agit d'une URL ou de données générées (initiales), pas d'un flux d'upload fichier.
4. Contraintes¶
Juridiques / réglementaires¶
- RGPD : les données de profil sont des données personnelles. L'utilisateur doit pouvoir les consulter (droit d'accès, art. 15).
- Minimisation des données : ne retourner que les champs strictement nécessaires côté client. Exclure impérativement
srpSalt,passwordHash,validationToken.
Sécurité¶
- Authentification obligatoire : tout accès aux endpoints
/user/profilerequiert un JWT valide. - RLS : le middleware RLS existant doit garantir qu'un utilisateur ne peut accéder qu'à ses propres données. Aucune route ne doit permettre de consulter ou modifier le profil d'un autre utilisateur.
- Rate limiting : les endpoints doivent être protégés contre les appels excessifs (cohérent avec le
RateLimitGuardexistant).
Techniques¶
- Cohérence avec PD-106 : le contrat d'API doit être compatible avec ce que le client mobile attend (
GET /user/profileretournantname,email,avatar_url?). - Cohérence avec l'architecture existante : NestJS, TypeORM, DTOs avec class-validator, Swagger, guards existants.
Organisationnelles¶
- L'entité
Userexistante devra potentiellement être étendue (ajout de champsname,preferences, etc.). L'impact sur les migrations doit être évalué.
5. Scénarios d'échec et résultats inacceptables¶
- Fuite de données sensibles : retourner le
passwordHash,srpSaltou tout secret cryptographique dans la réponse du profil. - Accès croisé : un utilisateur A qui consulte ou modifie le profil d'un utilisateur B.
- Modification silencieuse de champs protégés : un appel PUT qui modifierait
email,plan,status,idou tout champ non autorisé. - Absence de validation : accepter des données invalides (ex: préférences avec des valeurs hors bornes, champs injectés).
- Incohérence avec PD-106 : le client mobile reçoit un contrat d'API différent de ce qu'il attend, provoquant des erreurs silencieuses ou un affichage incorrect.
6. Tensions et conflits — résolus par alignement PD-106¶
Les tensions suivantes sont résolues par alignement avec le contrat d'API défini dans PD-106 (spécification canonique du client mobile) :
- Nommage de la route :
→GET /users/meGET /user/profile(alignement PD-106). Le endpoint PUT suit la même convention :PUT /user/profile. - Champ
name: oui, un champnamedoit être ajouté à l'entitéUser. PD-106 l'attend dans la réponseGET /user/profile→{name, email, avatar_url?}. Le champ est optionnel (nullable) — il peut être renseigné après l'inscription. avatar_url: champ optionnel dans la réponse. PD-106 gère le fallback côté client (affichage des initiales siavatar_urlest null). Pas d'upload fichier dans PD-32.
Tension resolue¶
- Champ
preferences: inclus dans le perimetre PD-32 en anticipation d'un usage futur (synchronisation multi-device des preferences de securite, preferences applicatives). Actuellement absent du contrat PD-106 et du code app — les preferences de securite (auto-lock, biometrie) sont stockees localement sur le device via SecureStore. Le backend fournira le socle de stockage serveur pour permettre une synchronisation future.
Decision technique¶
- Schema
preferences: colonne JSONB en base, validation par DTO strict cote applicatif (class-validator avecwhitelist: true). Les cles de preferences sont explicites et typees dans le DTO — ajouter une preference = modifier le DTO, pas de migration BDD. Les cles initiales seront definies en specification.
Decision technique (rate limiting)¶
- Rate limiting : utiliser la configuration globale existante (
RateLimitGuard). Pas de configuration specifique pour les endpoints profil.
Decision technique (champs modifiables)¶
- Champs modifiables via
PUT /user/profile:name,avatar_url,preferences. Tous les autres champs sont en lecture seule ou exclus de la reponse.
7. Questions ouvertes¶
Aucune — toutes les questions ont ete tranchees.