diff --git a/docs/14_NOTE-BACKEND-CONFIG-SETUP.md b/docs/14_NOTE-BACKEND-CONFIG-SETUP.md new file mode 100644 index 0000000..f1716d9 --- /dev/null +++ b/docs/14_NOTE-BACKEND-CONFIG-SETUP.md @@ -0,0 +1,37 @@ +# Ticket #14 – Note pour modifications backend + +**Contexte :** Première connexion admin → panneau Paramètres, déblocage après clic sur « Sauvegarder ». Le front appelle `POST /api/v1/configuration/setup/complete` au clic sur Sauvegarder. + +## Problème + +Erreur renvoyée par le back : +`invalid input syntax for type uuid: "system"` + +- Le controller fait `const userId = req.user?.id || 'system'` puis `markSetupCompleted(userId)`. +- Le service `set()` fait `config.modifiePar = { id: userId }` ; la colonne `modifie_par` est une FK UUID vers `users`. +- La chaîne `"system"` n’est pas un UUID valide → erreur PostgreSQL. + +## Modifications à apporter au backend + +**Option A – Accepter l’absence d’utilisateur (recommandé si la route peut être appelée sans JWT)** + +1. **`config.controller.ts`** (route `completeSetup`) + - Remplacer : + `const userId = req.user?.id || 'system';` + - Par : + `const userId = req.user?.id ?? null;` + +2. **`config.service.ts`** (`markSetupCompleted`) + - Changer la signature : + `async markSetupCompleted(userId: string | null): Promise` + - Et appeler : + `await this.set('setup_completed', 'true', userId ?? undefined);` + - Dans `set()`, ne pas remplir `modifiePar` quand `userId` est absent (déjà le cas si `if (userId)`). + +**Option B – Imposer un utilisateur authentifié** + +- Activer le guard JWT (et éventuellement RolesGuard) sur `POST /configuration/setup/complete` pour que `req.user` soit toujours défini, et garder `userId = req.user.id` (plus de fallback `'system'`). + +--- + +Une fois le back modifié, le flux « Sauvegarder » → déblocage des panneaux fonctionne sans erreur. diff --git a/frontend/lib/services/configuration_service.dart b/frontend/lib/services/configuration_service.dart index 8f1c905..52cd407 100644 --- a/frontend/lib/services/configuration_service.dart +++ b/frontend/lib/services/configuration_service.dart @@ -106,8 +106,9 @@ class ConfigurationService { body: jsonEncode(body), ); if (response.statusCode != 200) { - final err = jsonDecode(response.body) as Map; - throw Exception(err['message'] ?? 'Erreur lors de la sauvegarde'); + final err = jsonDecode(response.body) as Map?; + final msg = err != null ? (err['message'] as String? ?? err['error'] as String?) : null; + throw Exception(msg ?? 'Erreur lors de la sauvegarde'); } } @@ -118,11 +119,12 @@ class ConfigurationService { headers: await _headers(), body: jsonEncode({'testEmail': testEmail}), ); - final data = jsonDecode(response.body) as Map; - if (response.statusCode == 200 && data['success'] == true) { - return data['message'] as String? ?? 'Test SMTP réussi.'; + final data = jsonDecode(response.body) as Map?; + if (response.statusCode == 200 && (data?['success'] == true)) { + return data!['message'] as String? ?? 'Test SMTP réussi.'; } - throw Exception(data['error'] ?? data['message'] ?? 'Échec du test SMTP'); + final msg = data != null ? (data['error'] as String? ?? data['message'] as String?) : null; + throw Exception(msg ?? 'Échec du test SMTP'); } /// POST /api/v1/configuration/setup/complete (après première config) @@ -132,8 +134,9 @@ class ConfigurationService { headers: await _headers(), ); if (response.statusCode != 200) { - final err = jsonDecode(response.body) as Map; - throw Exception(err['message'] ?? 'Erreur finalisation configuration'); + final err = jsonDecode(response.body) as Map?; + final msg = err != null ? (err['message'] as String? ?? err['error'] as String?) : null; + throw Exception(msg ?? 'Erreur finalisation configuration'); } } }