Aller au contenu

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/profile requiert 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 RateLimitGuard existant).

Techniques

  • Cohérence avec PD-106 : le contrat d'API doit être compatible avec ce que le client mobile attend (GET /user/profile retournant name, email, avatar_url?).
  • Cohérence avec l'architecture existante : NestJS, TypeORM, DTOs avec class-validator, Swagger, guards existants.

Organisationnelles

  • L'entité User existante devra potentiellement être étendue (ajout de champs name, 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, srpSalt ou 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, id ou 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 champ name doit être ajouté à l'entité User. PD-106 l'attend dans la réponse GET /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 si avatar_url est 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 avec whitelist: 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.