PD-32 — Synthèse d'implémentation¶
Produit par l'orchestrateur Claude à l'étape 6c.
Résumé¶
| Critère | Statut |
|---|---|
| Tâches complétées | 5/5 |
| Code contracts respectés | ✅ |
| Tests implémentés | ✅ |
| Review sécurité | ✅ CONFORME |
Livrables produits¶
Tâche 1 : Migration + Entity¶
| Fichier | Description |
|---|---|
src/database/migrations/1738200000000-AddUserProfileFields.ts | Migration TypeORM ajoutant name, avatar_url, preferences |
src/modules/auth/entities/user.entity.ts | Extension avec nouvelles colonnes + @Exclude() sur champs sensibles |
Invariants respectés : - Colonnes nullable ou avec défaut pour compatibilité - Migration réversible (down) - @Exclude() sur srpSalt, passwordHash, validationToken
Tâche 2 : DTOs¶
| Fichier | Description |
|---|---|
src/modules/user/dto/user-preferences.dto.ts | Schéma strict pour preferences (locale, timezone, security, notifications) |
src/modules/user/dto/update-user-profile.dto.ts | Validation PUT (name, avatarUrl, preferences uniquement) |
src/modules/user/dto/user-profile-response.dto.ts | Réponse GET (name, email, avatarUrl, preferences) |
Invariants respectés : - INV-32-05 : UpdateUserProfileDto n'accepte que name, avatar_url, preferences - INV-32-06 : Champs protégés rejetés via whitelist/forbidNonWhitelisted - INV-32-07 : UserPreferencesDto valide strictement le schéma
Tâche 3 : Service + Controller¶
| Fichier | Description |
|---|---|
src/modules/user/services/user-profile.service.ts | getProfile/updateProfile avec RLS |
src/modules/user/controllers/user-profile.controller.ts | GET/PUT /user/profile avec JwtAuthGuard |
src/modules/user/user.module.ts | Module NestJS |
src/modules/user/index.ts | Barrel exports |
src/app.module.ts | Import UserModule ajouté |
Invariants respectés : - INV-32-01 : @UseGuards(JwtAuthGuard) sur le controller - INV-32-02 : Opérations via RlsQueryService + SET LOCAL - INV-32-08 : GET retourne UserProfileResponseDto - INV-32-10 : UPDATE dans transaction
Tâche 4 : Tests¶
| Fichier | Type | Couverture |
|---|---|---|
src/modules/user/dto/update-user-profile.dto.spec.ts | Unit | DTOs validation |
src/modules/user/services/user-profile.service.spec.ts | Unit | Service (mocked) |
test/user-profile.e2e-spec.ts | E2E | TC-NOM-, TC-ERR-, TC-INV-* |
Scénarios couverts : - ✅ TC-NOM-01 : GET profil réussi - ✅ TC-NOM-02 : PUT profil réussi - ✅ TC-INV-32-03/04 : Champs sensibles exclus - ✅ TC-INV-32-06 : Champs protégés rejetés - ✅ TC-ERR-01 : Auth required (401) - ✅ TC-ERR-02 : Validation errors (400) - ✅ TC-ERR-03/04 : Cross-access RLS
Tâche 5 : Review sécurité¶
| Fichier | Verdict |
|---|---|
docs/epics/auth-identity/PD-32-user-settings/PD-32-security-review.md | ✅ CONFORME |
Points audités : - Forbidden patterns : aucune violation - Injection SQL : non vulnérable (ORM paramétré) - Cross-access RLS : protégé - Champs sensibles : @Exclude() appliqué
Structure finale du module¶
src/modules/user/
├── controllers/
│ └── user-profile.controller.ts
├── dto/
│ ├── update-user-profile.dto.ts
│ ├── update-user-profile.dto.spec.ts
│ ├── user-preferences.dto.ts
│ └── user-profile-response.dto.ts
├── services/
│ ├── user-profile.service.ts
│ └── user-profile.service.spec.ts
├── index.ts
└── user.module.ts
test/
└── user-profile.e2e-spec.ts
src/database/migrations/
└── 1738200000000-AddUserProfileFields.ts
Endpoints exposés¶
| Méthode | Route | Auth | Description |
|---|---|---|---|
| GET | /user/profile | JWT | Récupère le profil courant |
| PUT | /user/profile | JWT | Met à jour le profil courant |
Exemple GET /user/profile¶
{
"name": "Jean Dupont",
"email": "jean@example.com",
"avatarUrl": "https://cdn.example.com/avatar.png",
"preferences": {
"locale": "fr",
"timezone": "Europe/Paris",
"security": { "loginNotifications": true },
"notifications": { "email": true, "push": false }
}
}
Exemple PUT /user/profile¶
// Request
{
"name": "Jean Dupont Updated",
"preferences": { "locale": "en" }
}
// Response (200 OK)
{
"name": "Jean Dupont Updated",
"email": "jean@example.com",
"avatarUrl": "https://cdn.example.com/avatar.png",
"preferences": {
"locale": "en",
"timezone": "Europe/Paris"
}
}
Prochaines étapes¶
- Étape 7 : Acceptabilité (ChatGPT)
- Étape 8 : Gate CLOSURE
- Étape 9 : Retour d'expérience
Synthèse produite le 2026-02-05 par l'orchestrateur Claude