# 📋 Documentation Technique - Workflow de CrĂ©ation de Compte **Version** : 1.0 **Date** : 24 Novembre 2025 **Auteur** : Équipe PtitsPas **RĂ©fĂ©rence CDC** : Cahier des Charges P'titsPas V1.3 --- ## 📖 Table des matiĂšres 1. [Vue d'ensemble](#vue-densemble) 2. [Acteurs](#acteurs) 3. [Workflow dĂ©taillĂ©](#workflow-dĂ©taillĂ©) 4. [Diagrammes de sĂ©quence](#diagrammes-de-sĂ©quence) 5. [SpĂ©cifications techniques](#spĂ©cifications-techniques) 6. [APIs utilisĂ©es](#apis-utilisĂ©es) 7. [ModĂšles de donnĂ©es](#modĂšles-de-donnĂ©es) 8. [Templates d'emails](#templates-demails) 9. [Tests et validation](#tests-et-validation) --- ## 🎯 Vue d'ensemble ### Objectif ImplĂ©menter le workflow complet de crĂ©ation et validation des comptes utilisateurs pour l'application P'titsPas, permettant : - La crĂ©ation de gestionnaires par le super administrateur - L'inscription autonome des parents et assistantes maternelles - La validation des comptes par les gestionnaires - La notification par email des dĂ©cisions ### PĂ©rimĂštre fonctionnel Ce workflow couvre la **Phase 1** du projet, correspondant au premier use case critique : > "Permettre au super admin de crĂ©er des gestionnaires, qui pourront ensuite valider les inscriptions des parents et assistantes maternelles." ### RĂ©fĂ©rence CDC **Section 3.1** : Gestion des utilisateurs **Section 3.2** : Processus de validation **Section 4.5** : Notifications email --- ## đŸ‘„ Acteurs ### 1. Super Administrateur (`super_admin`) **RĂŽle** : Administrateur systĂšme avec tous les droits **Identifiants initiaux** : - Email : `admin@ptits-pas.fr` - Mot de passe : `4dm1n1strateur` **ResponsabilitĂ©s** : - CrĂ©er les comptes gestionnaires - AccĂ©der au panneau d'administration - GĂ©rer la configuration systĂšme **RĂ©fĂ©rence** : Table `utilisateurs` avec `role = 'super_admin'` et `statut = 'actif'` --- ### 2. Gestionnaire (`gestionnaire`) **RĂŽle** : Validateur des inscriptions **CrĂ©ation** : Par le super administrateur uniquement **ResponsabilitĂ©s** : - Consulter les demandes d'inscription en attente - Valider ou refuser les comptes parents - Valider ou refuser les comptes assistantes maternelles - Consulter les informations des demandeurs **RĂ©fĂ©rence** : Table `utilisateurs` avec `role = 'gestionnaire'` et `statut = 'actif'` --- ### 3. Parent (`parent`) **RĂŽle** : Utilisateur final cherchant une assistante maternelle **CrĂ©ation** : Inscription autonome via formulaire public **Workflow** : 1. S'inscrit via le formulaire public 2. Statut initial : `en_attente` 3. Attend la validation d'un gestionnaire 4. Reçoit un email de notification (validĂ©/refusĂ©) 5. Si validĂ© : peut se connecter et accĂ©der Ă  l'application **RĂ©fĂ©rence** : - Table `utilisateurs` avec `role = 'parent'` - Table `parents` (relation 1:1 avec `utilisateurs`) --- ### 4. Assistante Maternelle (`assistante_maternelle`) **RĂŽle** : Professionnelle proposant ses services de garde **CrĂ©ation** : Inscription autonome via formulaire public **Workflow** : Identique aux parents 1. S'inscrit via le formulaire public 2. Statut initial : `en_attente` 3. Attend la validation d'un gestionnaire 4. Reçoit un email de notification (validĂ©/refusĂ©) 5. Si validĂ©e : peut se connecter et accĂ©der Ă  l'application **RĂ©fĂ©rence** : - Table `utilisateurs` avec `role = 'assistante_maternelle'` - Table `assistantes_maternelles` (relation 1:1 avec `utilisateurs`) --- ## ⚠ Points d'attention - ConformitĂ© CDC Avant de dĂ©tailler le workflow, voici les points critiques pour assurer la conformitĂ© avec le Cahier des Charges : ### Inscription Parent (CDC 3.1) - ✅ **6 Ă©tapes obligatoires** : Parent 1, Parent 2 (opt), Enfant, PrĂ©sentation, CGU, RĂ©capitulatif - ✅ **Photo obligatoire** si enfant dĂ©jĂ  nĂ© - ✅ **Acceptation CGU** avec horodatage - ✅ **Notification** : Email **OU** SMS aprĂšs validation ### Inscription Assistante Maternelle (CDC 3.2) - ✅ **NIR obligatoire** (NumĂ©ro de SĂ©curitĂ© sociale - 15 chiffres) - ✅ **Photo obligatoire** (si option activĂ©e) - ✅ **Consentement photo** avec horodatage (RGPD) - ✅ **Date et lieu de naissance** obligatoires - ✅ **Acceptation CGU** avec horodatage - ✅ **Notification** : Email **OU** SMS aprĂšs validation ### CrĂ©ation Gestionnaire (CDC 3.3) - ✅ **Changement de mot de passe obligatoire** Ă  la premiĂšre connexion - ✅ Créé par un administrateur uniquement ### CrĂ©ation Administrateur (CDC 3.4) - ✅ **Changement de mot de passe obligatoire** Ă  la premiĂšre connexion - ✅ Créé par un administrateur existant uniquement ### Champs Base de DonnĂ©es Manquants Les champs suivants doivent ĂȘtre ajoutĂ©s Ă  la base de donnĂ©es : - `nir_chiffre` (assistantes_maternelles) - **OBLIGATOIRE** - `ville_naissance` (utilisateurs) - `pays_naissance` (utilisateurs) - `date_acceptation_cgu` (utilisateurs) - `presentation_dossier` (parents ou table dĂ©diĂ©e) - `date_consentement_photo` (utilisateurs) - **Existe dĂ©jĂ ** ✅ --- ## 🔄 Workflow dĂ©taillĂ© ### Étape 1 : Initialisation du systĂšme **PrĂ©requis** : Base de donnĂ©es initialisĂ©e avec le super admin ```sql -- Seed initial (01_init.sql) INSERT INTO utilisateurs (email, password, prenom, nom, role, statut) VALUES ( 'admin@ptits-pas.fr', '$2b$12$Fo5ly1YlTj3O6lXf.IUgoeUqEebBGpmoM5zLbzZx.CueorSE7z2E2', -- Hash de "4dm1n1strateur" 'Admin', 'SystĂšme', 'super_admin', 'actif' ); ``` **État** : ✅ ImplĂ©mentĂ© --- ### Étape 2 : CrĂ©ation d'un gestionnaire **Acteur** : Super Administrateur **Interface** : Panneau d'administration - Section "CrĂ©er un gestionnaire" #### 2.1 Interface utilisateur **Écran** : Formulaire ultra-simple avec les champs suivants : | Champ | Type | Validation | Obligatoire | |-------|------|------------|-------------| | Nom | Text | 2-100 caractĂšres | ✅ | | PrĂ©nom | Text | 2-100 caractĂšres | ✅ | | Email | Email | Format email valide | ✅ | | Mot de passe | Password | Min 8 caractĂšres, 1 majuscule, 1 chiffre | ✅ | **Bouton** : "Soumettre" **Wireframe** : ``` ┌─────────────────────────────────────────┐ │ CrĂ©er un Gestionnaire │ ├────────────────────────────────────────── │ │ │ Nom : [________________] │ │ │ │ PrĂ©nom : [________________] │ │ │ │ Email : [________________] │ │ (personnel ou collectivitĂ©)│ │ │ │ Mot de passe : [________________] │ │ │ │ [ Soumettre ] │ │ │ └─────────────────────────────────────────┘ ``` #### 2.2 Flux technique **Frontend → Backend** ```typescript // Frontend (Flutter) POST /api/v1/gestionnaires Headers: { Authorization: Bearer Content-Type: application/json } Body: { "email": "lucas.moreau@ptits-pas.fr", "password": "password", "prenom": "Lucas", "nom": "MOREAU", "telephone": "06 87 23 45 67" } ``` **Backend → Database** ```typescript // Backend (NestJS) // 1. Validation du token (AuthGuard) // 2. VĂ©rification du rĂŽle (RolesGuard - super_admin uniquement) // 3. Validation des donnĂ©es (DTO) // 4. Hash du mot de passe (bcrypt, 12 rounds) // 5. CrĂ©ation de l'utilisateur INSERT INTO utilisateurs ( email, password, prenom, nom, telephone, role, statut, changement_mdp_obligatoire, cree_le ) VALUES ( 'lucas.moreau@ptits-pas.fr', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewY5iIdYvYvOYvOy', -- Hash bcrypt de "password" 'Lucas', 'MOREAU', '06 87 23 45 67', 'gestionnaire', 'actif', -- Statut actif immĂ©diatement TRUE, -- Changement de mot de passe obligatoire Ă  la premiĂšre connexion (CDC 3.3) NOW() ); ``` **RĂ©ponse** ```json { "id": "uuid-lucas-moreau", "email": "lucas.moreau@ptits-pas.fr", "prenom": "Lucas", "nom": "MOREAU", "telephone": "06 87 23 45 67", "role": "gestionnaire", "statut": "actif", "cree_le": "2025-11-24T10:30:00Z" } ``` **État** : 🟠 Backend implĂ©mentĂ©, Frontend Ă  crĂ©er --- ### Étape 3 : Inscription d'un parent **Acteur** : Parent (non authentifiĂ©) **Interface** : Page publique d'inscription parent **RĂ©fĂ©rence CDC** : Section 3.1 Le processus d'inscription parent se dĂ©roule en **6 Ă©tapes** conformĂ©ment au cahier des charges. #### 3.1 Étape 1 : Informations Parent 1 **Écran** : Formulaire d'identitĂ© du parent principal | Champ | Type | Validation | Obligatoire | |-------|------|------------|-------------| | Nom | Text | 2-100 caractĂšres | ✅ | | PrĂ©nom | Text | 2-100 caractĂšres | ✅ | | Adresse postale | Text | Adresse complĂšte | ✅ | | Code postal | Text | 5 chiffres | ✅ | | Ville | Text | 2-150 caractĂšres | ✅ | | TĂ©lĂ©phone | Tel | Format français | ✅ | | Email | Email | Format email valide | ✅ | **Note importante** : Le Parent 1 ne dĂ©finit **pas** de mot de passe lors de l'inscription. Il recevra un email avec un lien pour crĂ©er son mot de passe aprĂšs validation du gestionnaire. **Bouton** : "Suivant" --- #### 3.2 Étape 2 : Informations Parent 2 (facultatif) **Écran** : Ajout d'un co-parent (optionnel) **Question** : "Souhaitez-vous ajouter un second parent ?" - ⭕ Oui - ⭕ Non **Si Oui** : | Champ | Type | Validation | Obligatoire | |-------|------|------------|-------------| | Nom | Text | 2-100 caractĂšres | ✅ | | PrĂ©nom | Text | 2-100 caractĂšres | ✅ | | Email | Email | Format email valide | ✅ | | TĂ©lĂ©phone | Tel | Format français | ✅ | | MĂȘme adresse que Parent 1 | Checkbox | - | - | **Si "MĂȘme adresse" non cochĂ©** : Afficher les champs adresse, code postal, ville **Note importante** : Le Parent 2 ne dĂ©finit **pas** de mot de passe lors de l'inscription. Il recevra un email avec un lien pour crĂ©er son mot de passe aprĂšs validation du gestionnaire. Cette approche est particuliĂšrement adaptĂ©e aux situations de parents sĂ©parĂ©s ou divorcĂ©s oĂč la communication peut ĂȘtre difficile. **Bouton** : "Suivant" --- #### 3.3 Étape 3 : Informations sur l'enfant **Écran** : Fiche enfant **Question** : "L'enfant est-il dĂ©jĂ  nĂ© ?" - ⭕ Oui → Afficher "Date de naissance" - ⭕ Non → Afficher "Date prĂ©visionnelle de naissance" | Champ | Type | Validation | Obligatoire | |-------|------|------------|-------------| | PrĂ©nom | Text | 2-100 caractĂšres | ❌ (si Ă  naĂźtre) | | Nom | Text | HĂ©ritĂ© des parents | Auto | | Date de naissance | Date | Format JJ/MM/AAAA | ✅ (si nĂ©) | | Date prĂ©visionnelle | Date | Format JJ/MM/AAAA | ✅ (si Ă  naĂźtre) | | Genre | Select | H / F | ✅ | | Photo | File | Image (JPEG/PNG), max 5MB | ✅ (si nĂ©) | | Grossesse multiple | Checkbox | Jumeaux, triplĂ©s, etc. | ❌ | **Bouton** : "Ajouter un autre enfant" (optionnel) **Bouton** : "Suivant" **Note** : Rattachement automatique aux deux parents si Parent 2 renseignĂ©. --- #### 3.4 Étape 4 : PrĂ©sentation du dossier **Écran** : Zone de texte libre | Champ | Type | Validation | Obligatoire | |-------|------|------------|-------------| | PrĂ©sentation | Textarea | Max 2000 caractĂšres | ⚙ Configurable | **Exemple de texte d'aide** : > "DĂ©crivez votre situation familiale, vos besoins de garde, vos contraintes horaires, etc. Cette prĂ©sentation sera visible par les assistantes maternelles et le gestionnaire." **Bouton** : "Suivant" --- #### 3.5 Étape 5 : Acceptation des CGU **Écran** : Conditions GĂ©nĂ©rales d'Utilisation | ÉlĂ©ment | Type | Obligatoire | |---------|------|-------------| | CGU | Checkbox | ✅ | **Texte** : ☐ J'ai lu et j'accepte les [Conditions GĂ©nĂ©rales d'Utilisation](./cgu.pdf) et la [Politique de confidentialitĂ©](./privacy.pdf) **Comportement** : - Les liens ouvrent les documents PDF dans un nouvel onglet - Le refus bloque la crĂ©ation de compte - La date d'acceptation est enregistrĂ©e en base **Bouton** : "Suivant" --- #### 3.6 Étape 6 : RĂ©capitulatif et validation **Écran** : RĂ©sumĂ© de toutes les informations saisies **Sections affichĂ©es** : 1. **Parent 1** : Nom, prĂ©nom, email, tĂ©lĂ©phone, adresse 2. **Parent 2** (si renseignĂ©) : Nom, prĂ©nom, email, tĂ©lĂ©phone 3. **Enfant(s)** : PrĂ©nom, date de naissance/prĂ©visionnelle, photo 4. **PrĂ©sentation** : Extrait du texte (100 premiers caractĂšres) **Boutons** : - "Modifier" (retour aux Ă©tapes prĂ©cĂ©dentes) - "Valider et envoyer ma demande" **Message de confirmation** : > "Votre demande d'inscription a Ă©tĂ© envoyĂ©e. Elle sera examinĂ©e par un gestionnaire. Vous recevrez un email ou un SMS une fois votre compte validĂ©." **Bouton** : "Terminer" #### 3.2 Flux technique **Frontend → Backend** ```typescript // Frontend (Flutter) - Route publique // Exemple : Claire MARTIN (parent avec triplĂ©s) // Note : Pas de mot de passe lors de l'inscription POST /api/v1/auth/register Headers: { Content-Type: application/json } Body: { "email": "claire.martin@ptits-pas.fr", "prenom": "Claire", "nom": "MARTIN", "telephone": "06 89 56 78 90", "role": "parent" } ``` **Backend → Database** ```typescript // Backend (NestJS) // 1. Validation des donnĂ©es (DTO) // 2. VĂ©rification que l'email n'existe pas dĂ©jĂ  // 3. GĂ©nĂ©ration d'un token de crĂ©ation de mot de passe (UUID) // 4. Transaction : CrĂ©er utilisateur + entitĂ© mĂ©tier BEGIN TRANSACTION; -- CrĂ©ation de l'utilisateur (sans mot de passe) INSERT INTO utilisateurs ( email, password, prenom, nom, telephone, role, statut, adresse, code_postal, ville, profession, situation_familiale, date_naissance, password_reset_token, password_reset_expires, cree_le ) VALUES ( 'claire.martin@ptits-pas.fr', NULL, -- Pas de mot de passe lors de l'inscription 'Claire', 'MARTIN', '06 89 56 78 90', 'parent', 'en_attente', -- Statut en attente de validation '5 Avenue du GĂ©nĂ©ral de Gaulle', '95870', 'Bezons', 'InfirmiĂšre', 'MariĂ©e', '1990-04-03', gen_random_uuid(), -- Token de crĂ©ation de mot de passe NOW() + INTERVAL '7 days', -- Expiration du token (7 jours) NOW() ) RETURNING id; -- CrĂ©ation de l'entitĂ© mĂ©tier parent -- Note : id_co_parent sera renseignĂ© plus tard si Thomas MARTIN s'inscrit INSERT INTO parents (id_utilisateur, id_co_parent) VALUES ('uuid-claire-martin', NULL); COMMIT; ``` **RĂ©ponse** ```json { "message": "Inscription rĂ©ussie. Votre compte est en attente de validation par un gestionnaire. Vous recevrez un email une fois votre compte validĂ©.", "userId": "uuid-claire-martin" } ``` **État** : 🔮 À implĂ©menter complĂštement selon CDC --- ### Étape 3bis : Inscription d'une assistante maternelle **Acteur** : Assistante Maternelle (non authentifiĂ©e) **Interface** : Page publique d'inscription assistante maternelle **RĂ©fĂ©rence CDC** : Section 3.2 Le processus d'inscription assistante maternelle se dĂ©roule en **5 Ă©tapes** avec 2 panneaux principaux. #### 3bis.1 Panneau 1 : Informations d'identitĂ© **Écran** : Formulaire d'identitĂ© | Champ | Type | Validation | Obligatoire | |-------|------|------------|-------------| | Nom | Text | 2-100 caractĂšres | ✅ | | PrĂ©nom | Text | 2-100 caractĂšres | ✅ | | Adresse postale | Text | Adresse complĂšte | ✅ | | Code postal | Text | 5 chiffres | ✅ | | Ville | Text | 2-150 caractĂšres | ✅ | | TĂ©lĂ©phone | Tel | Format français | ✅ | | Email | Email | Format email valide | ✅ | | Photo de profil | File | Image (JPEG/PNG), max 5MB | ⚙ Configurable | **Consentement photo** (si photo uploadĂ©e) : ☐ J'autorise le stockage et l'affichage de ma photo sur la plateforme (RGPD) **Note importante** : L'assistante maternelle ne dĂ©finit **pas** de mot de passe lors de l'inscription. Elle recevra un email avec un lien pour crĂ©er son mot de passe aprĂšs validation du gestionnaire. **Note** : La date du consentement est enregistrĂ©e automatiquement. **Bouton** : "Suivant" --- #### 3bis.2 Panneau 2 : Informations professionnelles **Écran** : Informations professionnelles | Champ | Type | Validation | Obligatoire | |-------|------|------------|-------------| | Date de naissance | Date | Format JJ/MM/AAAA | ✅ | | Ville de naissance | Text | 2-150 caractĂšres | ✅ | | Pays de naissance | Select | Liste des pays | ✅ | | NumĂ©ro de SĂ©curitĂ© sociale (NIR) | Text | 15 chiffres | ✅ | | NumĂ©ro d'agrĂ©ment | Text | Format libre | ✅ | | Date d'obtention de l'agrĂ©ment | Date | Format JJ/MM/AAAA | ✅ | | Nombre d'enfants pouvant ĂȘtre accueillis | Number | 1-6 | ✅ | **Note importante affichĂ©e** : > ⚠ Le numĂ©ro de SĂ©curitĂ© sociale (NIR) est saisi en clair et utilisĂ© uniquement pour la gĂ©nĂ©ration automatique du contrat. Il est stockĂ© de maniĂšre sĂ©curisĂ©e et conforme au RGPD. **Bouton** : "Suivant" --- #### 3bis.3 PrĂ©sentation **Écran** : Message au gestionnaire | Champ | Type | Validation | Obligatoire | |-------|------|------------|-------------| | PrĂ©sentation | Textarea | Max 2000 caractĂšres | ❌ | **Exemple de texte d'aide** : > "PrĂ©sentez-vous et expliquez votre dĂ©marche. Vous pouvez ajouter des prĂ©cisions sur votre expĂ©rience, votre mĂ©thode pĂ©dagogique, vos disponibilitĂ©s, etc." **Bouton** : "Suivant" --- #### 3bis.4 Acceptation des CGU **Écran** : Conditions GĂ©nĂ©rales d'Utilisation | ÉlĂ©ment | Type | Obligatoire | |---------|------|-------------| | CGU | Checkbox | ✅ | **Texte** : ☐ J'ai lu et j'accepte les [Conditions GĂ©nĂ©rales d'Utilisation](./cgu.pdf) et la [Politique de confidentialitĂ©](./privacy.pdf) **Comportement** : - Les liens ouvrent les documents PDF dans un nouvel onglet - Le refus bloque la crĂ©ation de compte - La date d'acceptation est enregistrĂ©e en base **Bouton** : "Suivant" --- #### 3bis.5 RĂ©capitulatif et validation **Écran** : RĂ©sumĂ© de toutes les informations saisies **Sections affichĂ©es** : 1. **IdentitĂ©** : Nom, prĂ©nom, email, tĂ©lĂ©phone, adresse, photo 2. **Informations professionnelles** : - Date de naissance, lieu de naissance - NIR (masquĂ© : XXX XX XX XX XXX 123) - NumĂ©ro d'agrĂ©ment - CapacitĂ© d'accueil 3. **PrĂ©sentation** : Extrait du texte (100 premiers caractĂšres) **Boutons** : - "Modifier" (retour aux Ă©tapes prĂ©cĂ©dentes) - "Valider et envoyer ma demande" **Message de confirmation** : > "Votre demande d'inscription a Ă©tĂ© envoyĂ©e. Elle sera examinĂ©e par un gestionnaire. Vous recevrez un email ou un SMS une fois votre compte validĂ©." **Bouton** : "Terminer" **État** : 🔮 À implĂ©menter complĂštement selon CDC --- ### Étape 4 : Consultation des demandes par le gestionnaire **Acteur** : Gestionnaire **Interface** : Dashboard gestionnaire avec 2 onglets #### 4.1 Interface utilisateur **Écran** : Dashboard avec navigation par onglets ``` ┌─────────────────────────────────────────────────────────┐ │ Dashboard Gestionnaire │ ├────────────────────────────────────────────────────────── │ [ Parents ] [ Assistantes Maternelles ] │ ├────────────────────────────────────────────────────────── │ │ │ 📋 Demandes en attente (3) │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ đŸ‘€ Jean MARTIN │ │ │ │ 📧 jean.martin@example.com │ │ │ │ đŸ“± 06 01 02 03 04 │ │ │ │ 📅 Inscrit le : 20/11/2025 │ │ │ │ │ │ │ │ [ ✅ Valider ] [ ❌ Refuser ] │ │ │ └─────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ đŸ‘€ Sophie DURAND │ │ │ │ ... │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ ``` #### 4.2 Flux technique - Liste des parents **Frontend → Backend** ```typescript // Frontend (Flutter) GET /api/v1/parents Headers: { Authorization: Bearer } Query params: { statut: "en_attente" // Filtrer uniquement les comptes en attente } ``` **Backend → Database** ```sql -- Backend (NestJS) SELECT u.id, u.email, u.prenom, u.nom, u.telephone, u.statut, u.cree_le, p.id_co_parent FROM utilisateurs u LEFT JOIN parents p ON u.id = p.id_utilisateur WHERE u.role = 'parent' AND u.statut = 'en_attente' ORDER BY u.cree_le DESC; ``` **RĂ©ponse** ```json [ { "id": "uuid-claire-martin", "email": "claire.martin@ptits-pas.fr", "prenom": "Claire", "nom": "MARTIN", "telephone": "06 89 56 78 90", "ville": "Bezons", "profession": "InfirmiĂšre", "situation_familiale": "MariĂ©e", "statut": "en_attente", "cree_le": "2025-11-20T14:30:00Z" }, { "id": "uuid-david-lecomte", "email": "david.lecomte@ptits-pas.fr", "prenom": "David", "nom": "LECOMTE", "telephone": "06 45 56 67 78", "ville": "Bezons", "profession": "DĂ©veloppeur web", "situation_familiale": "PĂšre cĂ©libataire", "statut": "en_attente", "cree_le": "2025-11-21T09:15:00Z" } ] ``` #### 4.3 Flux technique - Liste des assistantes maternelles **Frontend → Backend** ```typescript // Frontend (Flutter) GET /api/v1/assistantes-maternelles Headers: { Authorization: Bearer } Query params: { statut: "en_attente" } ``` **Backend → Database** ```sql -- Backend (NestJS) SELECT u.id, u.email, u.prenom, u.nom, u.telephone, u.statut, u.cree_le, am.numero_agrement, am.ville_residence FROM utilisateurs u LEFT JOIN assistantes_maternelles am ON u.id = am.id_utilisateur WHERE u.role = 'assistante_maternelle' AND u.statut = 'en_attente' ORDER BY u.cree_le DESC; ``` **RĂ©ponse** ```json [ { "id": "uuid-marie-dubois", "email": "marie.dubois@ptits-pas.fr", "prenom": "Marie", "nom": "DUBOIS", "telephone": "06 96 34 56 78", "ville": "Bezons", "statut": "en_attente", "cree_le": "2025-11-22T11:00:00Z", "numero_agrement": null, "ville_residence": "Bezons" }, { "id": "uuid-fatima-elmansouri", "email": "fatima.elmansouri@ptits-pas.fr", "prenom": "Fatima", "nom": "EL MANSOURI", "telephone": "06 75 45 67 89", "ville": "Bezons", "statut": "en_attente", "cree_le": "2025-11-22T15:30:00Z", "numero_agrement": null, "ville_residence": "Bezons" } ] ``` **État** : 🟠 Backend implĂ©mentĂ©, Frontend Ă  connecter (actuellement en mock) --- ### Étape 5 : Validation d'un compte **Acteur** : Gestionnaire **Action** : Clic sur le bouton "Valider" #### 5.1 Flux technique - Validation **Frontend → Backend** ```typescript // Frontend (Flutter) PATCH /api/v1/users/{userId}/valider Headers: { Authorization: Bearer Content-Type: application/json } Body: { "comment": "Dossier complet, compte validĂ©" // Optionnel } ``` **Backend → Database** ```sql -- Backend (NestJS) -- Exemple : Lucas MOREAU valide Marie DUBOIS BEGIN TRANSACTION; -- Mise Ă  jour du statut utilisateur UPDATE utilisateurs SET statut = 'actif', modifie_le = NOW() WHERE id = 'uuid-marie-dubois'; -- Enregistrement de la validation INSERT INTO validations ( id_utilisateur, type, statut, valide_par, commentaire, cree_le ) VALUES ( 'uuid-marie-dubois', 'validation_compte', 'valide', 'uuid-lucas-moreau', 'AgrĂ©ment vĂ©rifiĂ© - Profil complet', NOW() ); COMMIT; ``` **Backend → Service Email** ```typescript // Envoi du lien de crĂ©ation de mot de passe pour tous les utilisateurs (Parents et AM) await this.mailService.sendPasswordCreationLink({ to: user.email, prenom: user.prenom, nom: user.nom, token: user.password_reset_token, expiresAt: user.password_reset_expires, role: user.role // 'parent' ou 'assistante_maternelle' }); // Si Parent 2 existe, envoi du mĂȘme type d'email if (user.role === 'parent' && parent2) { await this.mailService.sendPasswordCreationLink({ to: parent2.email, prenom: parent2.prenom, nom: parent2.nom, token: parent2.password_reset_token, expiresAt: parent2.password_reset_expires, role: 'parent', isCoParent: true // Indique qu'il s'agit du co-parent }); } ``` **RĂ©ponse** ```json { "message": "Compte validĂ© avec succĂšs", "userId": "uuid-marie-dubois", "emailSent": true } ``` #### 5.2 Flux technique - Refus **Frontend → Backend** ```typescript // Frontend (Flutter) PATCH /api/v1/users/{userId}/suspendre Headers: { Authorization: Bearer Content-Type: application/json } Body: { "comment": "Informations incomplĂštes" // Obligatoire pour un refus } ``` **Backend → Database** ```sql -- Backend (NestJS) -- Exemple : Lucas MOREAU refuse un compte (exemple fictif) BEGIN TRANSACTION; -- Mise Ă  jour du statut utilisateur UPDATE utilisateurs SET statut = 'suspendu', modifie_le = NOW() WHERE id = 'uuid-utilisateur-refuse'; -- Enregistrement du refus INSERT INTO validations ( id_utilisateur, type, statut, valide_par, commentaire, cree_le ) VALUES ( 'uuid-utilisateur-refuse', 'validation_compte', 'refuse', 'uuid-lucas-moreau', 'Informations incomplĂštes - Documents manquants', NOW() ); COMMIT; ``` **Backend → Service Email** ```typescript // Envoi de l'email de notification await this.mailService.sendAccountRejected({ to: user.email, prenom: user.prenom, nom: user.nom, role: user.role, reason: comment }); ``` **RĂ©ponse** ```json { "message": "Compte refusĂ©", "userId": "uuid-utilisateur-refuse", "emailSent": true } ``` **État** : 🔮 Backend partiellement implĂ©mentĂ© (manque envoi email), Frontend Ă  connecter --- ### Étape 6 : RĂ©ception de la notification **Acteur** : Parent ou Assistante Maternelle **Canal** : Email **OU** SMS (conformĂ©ment au CDC 3.1.6 et 3.2.5) **Note** : Le choix du canal de notification (email/SMS) peut ĂȘtre : - ConfigurĂ© par l'administrateur (paramĂštre global) - Choisi par l'utilisateur lors de l'inscription - Les deux en parallĂšle pour plus de fiabilitĂ© #### 6.1 Email de validation - Parents (avec crĂ©ation de mot de passe) **ExpĂ©diteur** : `no-reply@ptits-pas.fr` **Destinataire** : Email du parent **Objet** : `Votre compte P'titsPas a Ă©tĂ© validĂ© - CrĂ©ez votre mot de passe ✅` **Template Parent 1** : ```html

✅ Compte validĂ©

Bonjour {{prenom}} {{nom}},

Bonne nouvelle ! Votre compte P'titsPas a été validé par notre équipe.

Pour finaliser votre inscription et accéder à votre espace parent, veuillez créer votre mot de passe en cliquant sur le bouton ci-dessous :

Créer mon mot de passe

⏰ Attention : Ce lien est valable pendant 7 jours (jusqu'au {{expires_date}}).

Votre identifiant : {{email}}

Si vous avez des questions, n'hésitez pas à nous contacter à contact@ptits-pas.fr.

À trùs bientît sur P'titsPas !

L'équipe P'titsPas

``` **Template Parent 2 (Co-parent)** : ```html

✅ Bienvenue sur P'titsPas

Bonjour {{prenom}} {{nom}},

Votre co-parent vous a ajouté sur la plateforme P'titsPas et votre compte a été validé par notre équipe.

Pour accéder à votre espace parent et consulter les informations de vos enfants, veuillez créer votre mot de passe en cliquant sur le bouton ci-dessous :

Créer mon mot de passe

⏰ Attention : Ce lien est valable pendant 7 jours (jusqu'au {{expires_date}}).

Votre identifiant : {{email}}

Si vous avez des questions ou si vous n'ĂȘtes pas Ă  l'origine de cette inscription, contactez-nous Ă  contact@ptits-pas.fr.

À trùs bientît sur P'titsPas !

L'équipe P'titsPas

``` #### 6.2 Email de validation - Assistantes Maternelles (avec crĂ©ation de mot de passe) **ExpĂ©diteur** : `no-reply@ptits-pas.fr` **Destinataire** : Email de l'assistante maternelle **Objet** : `Votre compte P'titsPas a Ă©tĂ© validĂ© - CrĂ©ez votre mot de passe ✅` **Template** : ```html

✅ Compte validĂ©

Bonjour {{prenom}} {{nom}},

Bonne nouvelle ! Votre compte P'titsPas a été validé par notre équipe.

Pour finaliser votre inscription et accéder à votre espace assistante maternelle, veuillez créer votre mot de passe en cliquant sur le bouton ci-dessous :

Créer mon mot de passe

⏰ Attention : Ce lien est valable pendant 7 jours (jusqu'au {{expires_date}}).

Votre identifiant : {{email}}

Si vous avez des questions, n'hésitez pas à nous contacter à contact@ptits-pas.fr.

À trùs bientît sur P'titsPas !

L'équipe P'titsPas

``` #### 6.3 Email de refus **Expéditeur** : `no-reply@ptits-pas.fr` **Destinataire** : Email de l'utilisateur **Objet** : `Votre demande d'inscription P'titsPas` **Template** : ```html

Votre demande d'inscription

Bonjour {{prenom}} {{nom}},

Nous avons bien reçu votre demande d'inscription sur P'titsPas.

Malheureusement, nous ne pouvons pas valider votre compte pour le moment.

Motif : {{reason}}

Si vous pensez qu'il s'agit d'une erreur ou si vous souhaitez plus d'informations, n'hésitez pas à nous contacter à contact@ptits-pas.fr.

Cordialement,

L'équipe P'titsPas

``` **État** : 🔮 À implĂ©menter --- #### 6.3 SMS de validation (optionnel) **ExpĂ©diteur** : P'titsPas (nom court configurable) **Destinataire** : NumĂ©ro de tĂ©lĂ©phone de l'utilisateur **Template SMS** : ``` P'titsPas : Votre compte a Ă©tĂ© validĂ© ! CrĂ©ez votre mot de passe : https://app.ptits-pas.fr/create-password?token={{token}} (valable 7 jours) ``` **Contraintes** : - Maximum 160 caractĂšres (SMS standard) - Lien court pour l'URL - Message clair et concis --- #### 6.4 SMS de refus (optionnel) **ExpĂ©diteur** : P'titsPas **Destinataire** : NumĂ©ro de tĂ©lĂ©phone de l'utilisateur **Template SMS** : ``` P'titsPas : Votre demande d'inscription n'a pas pu ĂȘtre validĂ©e. Motif : {{reason_court}}. Contactez-nous : contact@ptits-pas.fr ``` **Contraintes** : - Maximum 160 caractĂšres - Motif abrĂ©gĂ© si nĂ©cessaire - Contact pour plus d'informations **État** : 🔮 À implĂ©menter (Service SMS Ă  configurer : Twilio, OVH, etc.) --- ### Étape 7 : CrĂ©ation du mot de passe **Acteur** : Parent (Parent 1 ou Parent 2) ou Assistante Maternelle **Interface** : Page de crĂ©ation de mot de passe (lien reçu par email) #### 7.1 Flux technique **Frontend → Backend** ```typescript // Frontend (Flutter/Web) // L'utilisateur clique sur le lien reçu par email // URL : https://app.ptits-pas.fr/create-password?token= GET /api/v1/auth/verify-token?token= // VĂ©rification que le token est valide et non expirĂ© // Si valide, affichage du formulaire de crĂ©ation de mot de passe POST /api/v1/auth/create-password Headers: { Content-Type: application/json } Body: { "token": "", "password": "NouveauMotDePasse123!", "password_confirmation": "NouveauMotDePasse123!" } ``` **Backend → Database** ```typescript // Backend (NestJS) // 1. VĂ©rification du token (existe, non expirĂ©, non utilisĂ©) // 2. Validation du mot de passe (min 8 caractĂšres, 1 majuscule, 1 chiffre) // 3. Hash du mot de passe (bcrypt, 12 rounds) // 4. Mise Ă  jour de l'utilisateur UPDATE utilisateurs SET password = '$2b$12$...', -- Hash bcrypt du nouveau mot de passe password_reset_token = NULL, -- Suppression du token password_reset_expires = NULL, statut = 'actif', -- Activation du compte modifie_le = NOW() WHERE password_reset_token = '' AND password_reset_expires > NOW() AND password IS NULL; -- SĂ©curitĂ© : uniquement si pas de mot de passe existant ``` **RĂ©ponse** ```json { "message": "Mot de passe créé avec succĂšs. Vous pouvez maintenant vous connecter.", "userId": "uuid-claire-martin" } ``` **Frontend** : Redirection automatique vers la page de connexion avec un message de succĂšs. **État** : 🔮 À implĂ©menter (Frontend + Backend) --- ### Étape 8 : Connexion de l'utilisateur validĂ© **Acteur** : Parent ou Assistante Maternelle (compte validĂ© et mot de passe dĂ©fini) **Interface** : Page de connexion #### 7.1 Flux technique **Frontend → Backend** ```typescript // Frontend (Flutter) // Exemple : Claire MARTIN se connecte aprĂšs validation POST /api/v1/auth/login Headers: { Content-Type: application/json } Body: { "email": "claire.martin@ptits-pas.fr", "password": "Test1234!" } ``` **Backend → Database** ```sql -- Backend (NestJS) SELECT id, email, password, prenom, nom, role, statut FROM utilisateurs WHERE email = 'jean.martin@example.com'; -- VĂ©rification : -- 1. L'utilisateur existe -- 2. Le mot de passe correspond (bcrypt.compare) -- 3. Le statut est 'actif' (sinon erreur 403) ``` **RĂ©ponse - SuccĂšs** ```json { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user": { "id": "uuid-claire-martin", "email": "claire.martin@ptits-pas.fr", "role": "parent", "prenom": "Claire", "nom": "MARTIN", "statut": "actif" } } ``` **RĂ©ponse - Compte en attente** ```json { "statusCode": 403, "message": "Votre compte est en attente de validation. Vous recevrez un email une fois votre compte validĂ©.", "error": "Forbidden" } ``` **RĂ©ponse - Compte refusĂ©** ```json { "statusCode": 403, "message": "Votre compte a Ă©tĂ© refusĂ©. Contactez contact@ptits-pas.fr pour plus d'informations.", "error": "Forbidden" } ``` #### 7.2 Redirection aprĂšs connexion **Parent validĂ©** → Dashboard parent (page simple : "Vous ĂȘtes connectĂ©") **Assistante Maternelle validĂ©e** → Dashboard AM (page simple : "Vous ĂȘtes connectĂ©") **État** : ✅ Backend implĂ©mentĂ©, Frontend Ă  adapter --- ## 📊 Diagrammes de sĂ©quence ### Diagramme 1 : CrĂ©ation d'un gestionnaire ```mermaid sequenceDiagram participant SA as Super Admin
(Frontend) participant API as Backend API
(NestJS) participant Auth as AuthGuard
+ RolesGuard participant DB as PostgreSQL SA->>API: POST /gestionnaires
{nom, prenom, email, password} API->>Auth: VĂ©rifier token JWT Auth->>Auth: VĂ©rifier role = super_admin Auth-->>API: ✅ AutorisĂ© API->>API: Valider DTO (CreateGestionnaireDto) API->>API: Hash password (bcrypt, 12 rounds) API->>DB: INSERT INTO utilisateurs
(role='gestionnaire', statut='actif') DB-->>API: ✅ Utilisateur créé (id, email, ...) API-->>SA: 201 Created
{id, email, prenom, nom, role} SA->>SA: Afficher message de succĂšs ``` --- ### Diagramme 2 : Inscription d'un parent ```mermaid sequenceDiagram participant P as Parent
(Frontend) participant API as Backend API
(NestJS) participant DB as PostgreSQL P->>API: POST /auth/register
{email, password, prenom, nom, role='parent'} API->>API: Valider DTO (RegisterDto) API->>DB: SELECT * FROM utilisateurs
WHERE email = ? DB-->>API: ❌ Aucun rĂ©sultat API->>API: Hash password (bcrypt, 12 rounds) API->>DB: BEGIN TRANSACTION API->>DB: INSERT INTO utilisateurs
(role='parent', statut='en_attente') DB-->>API: ✅ id_utilisateur API->>DB: INSERT INTO parents
(id_utilisateur) DB-->>API: ✅ Parent créé API->>DB: COMMIT API-->>P: 201 Created
{message, userId} P->>P: Afficher message:
"Inscription réussie.
Votre compte est en attente
de validation." ``` --- ### Diagramme 3 : Validation d'un compte par le gestionnaire ```mermaid sequenceDiagram participant G as Gestionnaire
(Frontend) participant API as Backend API
(NestJS) participant Auth as AuthGuard
+ RolesGuard participant DB as PostgreSQL participant Mail as Service Email
(Nodemailer) participant SMTP as Serveur SMTP
(mail.ptits-pas.fr) participant U as Utilisateur
(Email) G->>API: GET /parents?statut=en_attente API->>Auth: VĂ©rifier token + role gestionnaire Auth-->>API: ✅ AutorisĂ© API->>DB: SELECT * FROM utilisateurs
WHERE role='parent' AND statut='en_attente' DB-->>API: Liste des parents en attente API-->>G: 200 OK
[{id, email, prenom, nom, ...}] G->>G: Afficher liste G->>G: Clic sur "Valider" G->>API: PATCH /users/{id}/valider
{comment: "Dossier complet"} API->>Auth: VĂ©rifier token + role gestionnaire Auth-->>API: ✅ AutorisĂ© API->>DB: BEGIN TRANSACTION API->>DB: UPDATE utilisateurs
SET statut='actif'
WHERE id=? DB-->>API: ✅ 1 row updated API->>DB: INSERT INTO validations
(type, statut, valide_par, ...) DB-->>API: ✅ Validation enregistrĂ©e API->>DB: COMMIT API->>Mail: sendAccountValidated(user) Mail->>Mail: GĂ©nĂ©rer HTML depuis template Mail->>SMTP: SMTP SEND
From: no-reply@ptits-pas.fr
To: user.email
Subject: Compte validĂ© SMTP->>U: 📧 Email de validation SMTP-->>Mail: ✅ Email envoyĂ© Mail-->>API: ✅ emailSent: true API-->>G: 200 OK
{message, userId, emailSent} G->>G: Retirer l'utilisateur de la liste
Afficher notification de succĂšs U->>U: 📧 Reçoit l'email U->>U: Clic sur "Se connecter" ``` --- ### Diagramme 4 : Connexion d'un utilisateur validĂ© ```mermaid sequenceDiagram participant U as Utilisateur
(Frontend) participant API as Backend API
(NestJS) participant DB as PostgreSQL U->>API: POST /auth/login
{email, password} API->>DB: SELECT * FROM utilisateurs
WHERE email = ? DB-->>API: Utilisateur trouvĂ© API->>API: bcrypt.compare(password, hash) API->>API: ✅ Mot de passe correct API->>API: VĂ©rifier statut alt Statut = 'actif' API->>API: GĂ©nĂ©rer JWT
(access_token + refresh_token) API-->>U: 200 OK
{access_token, refresh_token, user} U->>U: Stocker tokens U->>U: Redirection vers dashboard else Statut = 'en_attente' API-->>U: 403 Forbidden
"Compte en attente de validation" U->>U: Afficher message d'attente else Statut = 'suspendu' API-->>U: 403 Forbidden
"Compte refusĂ©" U->>U: Afficher message + contact end ``` --- ## 🔧 SpĂ©cifications techniques ### Architecture Backend **Framework** : NestJS 10.x **Langage** : TypeScript 5.x **ORM** : TypeORM 0.3.x **Validation** : class-validator + class-transformer **Authentication** : JWT (jsonwebtoken + @nestjs/jwt) **Password Hashing** : bcrypt (12 rounds) **Email** : Nodemailer (Ă  installer) ### Architecture Frontend **Framework** : Flutter 3.19.0 **Langage** : Dart 3.x **State Management** : Provider / Riverpod **HTTP Client** : Dio / http **Storage** : flutter_secure_storage (tokens) ### Architecture Database **SGBD** : PostgreSQL 17 **Schema** : Voir [DATABASE.md](./DATABASE.md) **Tables concernĂ©es** : - `utilisateurs` (table principale) - `parents` (extension pour parents) - `assistantes_maternelles` (extension pour AM) - `validations` (historique des validations) ### Configuration Email **Serveur SMTP** : `mail.ptits-pas.fr` **Port** : 25 (STARTTLS) **ExpĂ©diteur** : `no-reply@ptits-pas.fr` **Authentification** : Aucune (serveur interne) --- ## 📡 APIs utilisĂ©es ### API 1 : CrĂ©er un gestionnaire **Endpoint** : `POST /api/v1/gestionnaires` **Authentification** : Bearer Token (super_admin uniquement) **RĂ©fĂ©rence** : [API.md - Gestionnaires](./API.md#post-gestionnaires) **Request** : ```json { "email": "lucas.moreau@ptits-pas.fr", "password": "password", "prenom": "Lucas", "nom": "MOREAU" } ``` **Response 201** : ```json { "id": "uuid-lucas-moreau", "email": "lucas.moreau@ptits-pas.fr", "role": "gestionnaire", "prenom": "Lucas", "nom": "MOREAU" } ``` **Errors** : - `401 Unauthorized` : Token manquant ou invalide - `403 Forbidden` : RĂŽle insuffisant (pas super_admin) - `409 Conflict` : Email dĂ©jĂ  utilisĂ© - `400 Bad Request` : DonnĂ©es invalides --- ### API 2 : Inscription (parent ou AM) **Endpoint** : `POST /api/v1/auth/register` **Authentification** : Aucune (route publique) **RĂ©fĂ©rence** : [API.md - Authentification](./API.md#post-authregister) **Request** : ```json { "email": "claire.martin@ptits-pas.fr", "password": "password", "prenom": "Claire", "nom": "MARTIN", "telephone": "01 39 98 89 01", "role": "parent" } ``` **Response 201** : ```json { "message": "Inscription rĂ©ussie. Votre compte est en attente de validation.", "userId": "uuid-claire-martin" } ``` **Errors** : - `409 Conflict` : Email dĂ©jĂ  utilisĂ© - `400 Bad Request` : DonnĂ©es invalides --- ### API 3 : Liste des parents en attente **Endpoint** : `GET /api/v1/parents` **Authentification** : Bearer Token (gestionnaire ou super_admin) **RĂ©fĂ©rence** : [API.md - Parents](./API.md#get-parents) **Query Params** : ``` ?statut=en_attente ``` **Response 200** : ```json [ { "id": "uuid", "email": "parent@example.com", "prenom": "Jean", "nom": "Martin", "telephone": "0601020304", "statut": "en_attente", "cree_le": "2025-11-20T14:30:00Z" } ] ``` **Errors** : - `401 Unauthorized` : Token manquant ou invalide - `403 Forbidden` : RĂŽle insuffisant --- ### API 4 : Liste des assistantes maternelles en attente **Endpoint** : `GET /api/v1/assistantes-maternelles` **Authentification** : Bearer Token (gestionnaire ou super_admin) **RĂ©fĂ©rence** : [API.md - Assistantes Maternelles](./API.md#get-assistantes-maternelles) **Query Params** : ``` ?statut=en_attente ``` **Response 200** : ```json [ { "id": "uuid", "email": "am@example.com", "prenom": "Marie", "nom": "Leblanc", "telephone": "0698765432", "statut": "en_attente", "cree_le": "2025-11-22T11:00:00Z" } ] ``` --- ### API 5 : Valider un compte **Endpoint** : `PATCH /api/v1/users/{id}/valider` **Authentification** : Bearer Token (gestionnaire, administrateur ou super_admin) **RĂ©fĂ©rence** : [API.md - Utilisateurs](./API.md#patch-usersidvalider) **Request** : ```json { "comment": "Dossier complet, compte validĂ©" } ``` **Response 200** : ```json { "message": "Compte validĂ© avec succĂšs", "userId": "uuid", "emailSent": true } ``` **Errors** : - `401 Unauthorized` : Token manquant ou invalide - `403 Forbidden` : RĂŽle insuffisant - `404 Not Found` : Utilisateur introuvable - `400 Bad Request` : ID invalide --- ### API 6 : Refuser un compte **Endpoint** : `PATCH /api/v1/users/{id}/suspendre` **Authentification** : Bearer Token (gestionnaire, administrateur ou super_admin) **RĂ©fĂ©rence** : [API.md - Utilisateurs](./API.md#patch-usersidsuspendre) **Request** : ```json { "comment": "Informations incomplĂštes" } ``` **Response 200** : ```json { "message": "Compte suspendu", "userId": "uuid", "emailSent": true } ``` --- ### API 7 : Connexion **Endpoint** : `POST /api/v1/auth/login` **Authentification** : Aucune (route publique) **RĂ©fĂ©rence** : [API.md - Authentification](./API.md#post-authlogin) **Request** : ```json { "email": "parent@example.com", "password": "MotDePasse123" } ``` **Response 200** : ```json { "access_token": "eyJhbGc...", "refresh_token": "eyJhbGc...", "user": { "id": "uuid", "email": "parent@example.com", "role": "parent", "prenom": "Jean", "nom": "Martin", "statut": "actif" } } ``` **Errors** : - `401 Unauthorized` : Email ou mot de passe incorrect - `403 Forbidden` : Compte en attente ou suspendu --- ## đŸ—„ïž ModĂšles de donnĂ©es ### Utilisateur **Table** : `utilisateurs` **RĂ©fĂ©rence** : [DATABASE.md - Table utilisateurs](./DATABASE.md#1-utilisateurs) ```typescript interface Utilisateur { id: UUID; // Identifiant unique email: string; // Email (unique) password: string; // Hash bcrypt prenom: string; // PrĂ©nom nom: string; // Nom genre?: 'H' | 'F' | 'Autre'; // Genre (optionnel) role: RoleType; // RĂŽle (voir enum ci-dessous) statut: StatutUtilisateurType; // Statut (voir enum ci-dessous) telephone?: string; // TĂ©lĂ©phone adresse?: string; // Adresse complĂšte photo_url?: string; // URL photo de profil consentement_photo: boolean; // Consentement photo date_consentement_photo?: Date; // Date du consentement changement_mdp_obligatoire: boolean; // Force changement MDP cree_le: Date; // Date de crĂ©ation modifie_le: Date; // DerniĂšre modification ville?: string; // Ville code_postal?: string; // Code postal telephone?: string; // TĂ©lĂ©phone profession?: string; // Profession situation_familiale?: string; // Situation familiale date_naissance?: Date; // Date de naissance } ``` **Enums** : ```typescript enum RoleType { PARENT = 'parent', GESTIONNAIRE = 'gestionnaire', SUPER_ADMIN = 'super_admin', ASSISTANTE_MATERNELLE = 'assistante_maternelle', ADMINISTRATEUR = 'administrateur' } enum StatutUtilisateurType { EN_ATTENTE = 'en_attente', ACTIF = 'actif', SUSPENDU = 'suspendu' } ``` --- ### Parent **Table** : `parents` **RĂ©fĂ©rence** : [DATABASE.md - Table parents](./DATABASE.md#3-parents) ```typescript interface Parent { id_utilisateur: UUID; // FK → utilisateurs(id) id_co_parent?: UUID; // FK → utilisateurs(id) - Co-parent optionnel } ``` **Relation** : 1:1 avec `utilisateurs` --- ### Assistante Maternelle **Table** : `assistantes_maternelles` **RĂ©fĂ©rence** : [DATABASE.md - Table assistantes_maternelles](./DATABASE.md#2-assistantes_maternelles) ```typescript interface AssistanteMaternelle { id_utilisateur: UUID; // FK → utilisateurs(id) numero_agrement?: string; // NumĂ©ro d'agrĂ©ment nir_chiffre?: string; // NIR (15 caractĂšres) nb_max_enfants?: number; // CapacitĂ© maximale biographie?: string; // PrĂ©sentation disponible: boolean; // DisponibilitĂ© ville_residence?: string; // Ville date_agrement?: Date; // Date d'agrĂ©ment annee_experience?: number; // AnnĂ©es d'expĂ©rience specialite?: string; // SpĂ©cialitĂ©s place_disponible?: number; // Places disponibles } ``` **Relation** : 1:1 avec `utilisateurs` --- ### Validation **Table** : `validations` **RĂ©fĂ©rence** : [DATABASE.md - Table validations](./DATABASE.md#14-validations) ```typescript interface Validation { id: UUID; // Identifiant unique id_utilisateur: UUID; // FK → utilisateurs(id) type: string; // Type de validation (ex: 'validation_compte') statut: StatutValidationType; // Statut (voir enum ci-dessous) cree_le: Date; // Date de demande modifie_le: Date; // DerniĂšre modification valide_par?: UUID; // FK → utilisateurs(id) - Validateur commentaire?: string; // Commentaire du validateur } ``` **Enum** : ```typescript enum StatutValidationType { EN_ATTENTE = 'en_attente', VALIDE = 'valide', REFUSE = 'refuse' } ``` --- ## 📧 Templates d'emails ### Configuration Nodemailer **Installation** : ```bash npm install nodemailer npm install -D @types/nodemailer ``` **Configuration** (`backend/src/mail/mail.config.ts`) : ```typescript import { MailerOptions } from '@nestjs-modules/mailer'; import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter'; export const mailConfig: MailerOptions = { transport: { host: 'mail.ptits-pas.fr', port: 25, secure: false, tls: { rejectUnauthorized: false } }, defaults: { from: '"P\'titsPas" ', }, template: { dir: __dirname + '/templates', adapter: new HandlebarsAdapter(), options: { strict: true, }, }, }; ``` ### Service Email **Fichier** : `backend/src/mail/mail.service.ts` ```typescript import { Injectable } from '@nestjs/common'; import { MailerService } from '@nestjs-modules/mailer'; @Injectable() export class MailService { constructor(private mailerService: MailerService) {} async sendAccountValidated(user: { email: string; prenom: string; nom: string; role: string; }): Promise { try { const roleLabel = user.role === 'parent' ? 'Parent' : 'Assistante Maternelle'; await this.mailerService.sendMail({ to: user.email, subject: 'Votre compte P\'titsPas a Ă©tĂ© validĂ© ✅', template: './account-validated', context: { prenom: user.prenom, nom: user.nom, email: user.email, role_label: roleLabel, }, }); return true; } catch (error) { console.error('Error sending validation email:', error); return false; } } async sendAccountRejected(user: { email: string; prenom: string; nom: string; role: string; reason: string; }): Promise { try { await this.mailerService.sendMail({ to: user.email, subject: 'Votre demande d\'inscription P\'titsPas', template: './account-rejected', context: { prenom: user.prenom, nom: user.nom, reason: user.reason, }, }); return true; } catch (error) { console.error('Error sending rejection email:', error); return false; } } } ``` ### Templates Handlebars **Fichier** : `backend/src/mail/templates/account-validated.hbs` Voir le template HTML dans la section [Étape 6.1](#61-email-de-validation) **Fichier** : `backend/src/mail/templates/account-rejected.hbs` Voir le template HTML dans la section [Étape 6.2](#62-email-de-refus) --- ## ✅ Tests et validation ### Tests unitaires (Backend) **Framework** : Jest **Fichiers de test** : - `backend/src/routes/auth/auth.service.spec.ts` - `backend/src/routes/user/user.service.spec.ts` - `backend/src/mail/mail.service.spec.ts` **ScĂ©narios de test** : 1. **CrĂ©ation de gestionnaire** - ✅ CrĂ©ation rĂ©ussie avec donnĂ©es valides - ❌ Échec si email dĂ©jĂ  existant - ❌ Échec si utilisateur non super_admin - ❌ Échec si donnĂ©es invalides 2. **Inscription** - ✅ Inscription parent rĂ©ussie - ✅ Inscription AM rĂ©ussie - ✅ CrĂ©ation de l'entitĂ© mĂ©tier (parent/AM) - ❌ Échec si email dĂ©jĂ  existant - ❌ Échec si mot de passe trop faible 3. **Validation de compte** - ✅ Validation rĂ©ussie + changement statut - ✅ Email envoyĂ© - ✅ Enregistrement dans table validations - ❌ Échec si utilisateur non gestionnaire - ❌ Échec si utilisateur dĂ©jĂ  validĂ© 4. **Refus de compte** - ✅ Refus rĂ©ussi + changement statut - ✅ Email envoyĂ© avec motif - ✅ Enregistrement dans table validations - ❌ Échec si commentaire manquant 5. **Connexion** - ✅ Connexion rĂ©ussie si compte actif - ❌ Échec si compte en attente - ❌ Échec si compte suspendu - ❌ Échec si mot de passe incorrect ### Tests d'intĂ©gration (Backend) **Framework** : Supertest + Jest **ScĂ©narios de test** : 1. **Workflow complet - Parent** ```typescript it('should complete full parent workflow', async () => { // 1. Super admin crĂ©e un gestionnaire const gestionnaire = await createGestionnaire(); // 2. Parent s'inscrit const parent = await registerParent(); // 3. Gestionnaire liste les parents en attente const pendingParents = await getPendingParents(gestionnaire.token); expect(pendingParents).toContainEqual(expect.objectContaining({ email: parent.email, statut: 'en_attente' })); // 4. Gestionnaire valide le parent await validateUser(gestionnaire.token, parent.id); // 5. Parent se connecte const loginResponse = await loginUser(parent.email, parent.password); expect(loginResponse.access_token).toBeDefined(); }); ``` 2. **Workflow complet - Assistante Maternelle** - Identique au workflow parent 3. **Workflow refus** ```typescript it('should handle account rejection', async () => { const gestionnaire = await createGestionnaire(); const parent = await registerParent(); await rejectUser(gestionnaire.token, parent.id, 'Informations incomplĂštes'); const loginResponse = await loginUser(parent.email, parent.password); expect(loginResponse.statusCode).toBe(403); }); ``` ### Tests E2E (Frontend + Backend) **Framework** : Flutter Integration Tests + Mockito **ScĂ©narios de test** : 1. **CrĂ©ation gestionnaire (UI)** - Remplir le formulaire - Soumettre - VĂ©rifier le message de succĂšs - VĂ©rifier que le gestionnaire peut se connecter 2. **Inscription parent (UI)** - Remplir le formulaire d'inscription - Soumettre - VĂ©rifier le message "en attente de validation" - VĂ©rifier que la connexion est refusĂ©e 3. **Dashboard gestionnaire (UI)** - Se connecter en tant que gestionnaire - VĂ©rifier l'affichage des 2 onglets - VĂ©rifier l'affichage des comptes en attente - Cliquer sur "Valider" - VĂ©rifier que le compte disparaĂźt de la liste 4. **RĂ©ception email (Manuel)** - VĂ©rifier la rĂ©ception de l'email de validation - VĂ©rifier le contenu de l'email - Cliquer sur le lien de connexion - VĂ©rifier la redirection vers l'application ### Checklist de validation **Phase 1 : Backend** - [ ] Endpoint crĂ©ation gestionnaire fonctionne - [ ] Flag `changement_mdp_obligatoire` = TRUE pour gestionnaires/admins - [ ] Endpoint inscription parent fonctionne (6 Ă©tapes) - [ ] CrĂ©ation Parent 1 - [ ] CrĂ©ation Parent 2 (optionnel) - [ ] CrĂ©ation Enfant(s) - [ ] Enregistrement prĂ©sentation - [ ] Enregistrement acceptation CGU avec horodatage - [ ] RĂ©capitulatif - [ ] Endpoint inscription AM fonctionne (5 Ă©tapes) - [ ] Panneau 1 : IdentitĂ© + Photo + Consentement photo - [ ] Panneau 2 : NIR + AgrĂ©ment + Infos pro - [ ] PrĂ©sentation - [ ] Acceptation CGU - [ ] RĂ©capitulatif - [ ] EntitĂ© mĂ©tier créée lors de l'inscription - [ ] Endpoint validation fonctionne - [ ] Endpoint refus fonctionne - [ ] Email de validation envoyĂ© - [ ] Email de refus envoyĂ© - [ ] SMS de validation envoyĂ© (optionnel) - [ ] SMS de refus envoyĂ© (optionnel) - [ ] Connexion bloquĂ©e si compte en attente - [ ] Connexion autorisĂ©e si compte actif - [ ] Changement de mot de passe forcĂ© Ă  la premiĂšre connexion (gestionnaires/admins) **Phase 2 : Frontend** - [ ] Écran crĂ©ation gestionnaire implĂ©mentĂ© - [ ] Formulaire d'inscription parent implĂ©mentĂ© (6 Ă©tapes) - [ ] Étape 1 : Informations Parent 1 - [ ] Étape 2 : Informations Parent 2 (optionnel) - [ ] Étape 3 : Informations Enfant(s) avec upload photo - [ ] Étape 4 : PrĂ©sentation du dossier - [ ] Étape 5 : Acceptation CGU (liens PDF) - [ ] Étape 6 : RĂ©capitulatif - [ ] Formulaire d'inscription AM implĂ©mentĂ© (5 Ă©tapes) - [ ] Panneau 1 : IdentitĂ© + Upload photo + Consentement - [ ] Panneau 2 : NIR + Date/lieu naissance + AgrĂ©ment - [ ] PrĂ©sentation - [ ] Acceptation CGU (liens PDF) - [ ] RĂ©capitulatif - [ ] Dashboard gestionnaire avec 2 onglets - [ ] Liste des parents en attente affichĂ©e (avec enfants) - [ ] Liste des AM en attente affichĂ©e (avec NIR masquĂ©) - [ ] Boutons Valider/Refuser fonctionnels - [ ] Messages de feedback utilisateur - [ ] Gestion des erreurs - [ ] Écran de changement de mot de passe forcĂ© (premiĂšre connexion) **Phase 3 : IntĂ©gration** - [ ] Workflow complet parent testĂ© - [ ] Workflow complet AM testĂ© - [ ] Workflow refus testĂ© - [ ] Emails reçus et corrects - [ ] Connexion aprĂšs validation OK - [ ] Redirection vers dashboard OK --- ## 📚 RĂ©fĂ©rences ### Documentation interne - [API.md](./API.md) - Documentation complĂšte des endpoints - [DATABASE.md](./DATABASE.md) - SchĂ©ma de la base de donnĂ©es - [AUDIT.md](./AUDIT.md) - Audit du projet YNOV - [README-ARCHITECTURE.md](./README-ARCHITECTURE.md) - Architecture du projet - [README-DEPLOYMENT.md](./README-DEPLOYMENT.md) - Guide de dĂ©ploiement ### Documentation externe - [NestJS Documentation](https://docs.nestjs.com/) - [TypeORM Documentation](https://typeorm.io/) - [Flutter Documentation](https://flutter.dev/docs) - [PostgreSQL Documentation](https://www.postgresql.org/docs/) - [Nodemailer Documentation](https://nodemailer.com/) ### Cahier des Charges **Section 3.1** : Gestion des utilisateurs **Section 3.2** : Processus de validation **Section 4.5** : Notifications email --- ## 📋 RĂ©sumĂ© des modifications (ConformitĂ© CDC) Ce document a Ă©tĂ© mis Ă  jour pour ĂȘtre conforme au **Cahier des Charges v1.3** (Section 3). ### Principales modifications #### Inscription Parent - ✅ Passage de 1 formulaire simple Ă  **6 Ă©tapes complĂštes** - ✅ Ajout de la gestion du **Parent 2** (co-parent) - ✅ Ajout de la crĂ©ation des **enfants** lors de l'inscription - ✅ Ajout du champ **PrĂ©sentation du dossier** - ✅ Ajout de l'**Acceptation des CGU** avec horodatage - ✅ Ajout d'un **RĂ©capitulatif** avant validation #### Inscription Assistante Maternelle - ✅ Passage de 1 formulaire simple Ă  **5 Ă©tapes avec 2 panneaux** - ✅ Ajout du **NIR** (NumĂ©ro de SĂ©curitĂ© sociale) - **OBLIGATOIRE** - ✅ Ajout de la **Photo obligatoire** (si option activĂ©e) - ✅ Ajout du **Consentement photo** avec horodatage (RGPD) - ✅ Ajout de la **Date et lieu de naissance** - ✅ Ajout de l'**Acceptation des CGU** avec horodatage - ✅ Ajout d'un **RĂ©capitulatif** avant validation #### CrĂ©ation Gestionnaire/Administrateur - ✅ Ajout du **Changement de mot de passe obligatoire** Ă  la premiĂšre connexion #### Notifications - ✅ Ajout de la possibilitĂ© d'envoi par **SMS** en plus de l'email ### Champs Base de DonnĂ©es Ă  Ajouter ```sql -- Table utilisateurs ALTER TABLE utilisateurs ADD COLUMN ville_naissance VARCHAR(150); ALTER TABLE utilisateurs ADD COLUMN pays_naissance VARCHAR(100); ALTER TABLE utilisateurs ADD COLUMN date_acceptation_cgu TIMESTAMPTZ; -- Table assistantes_maternelles -- Le champ nir_chiffre existe dĂ©jĂ  mais doit ĂȘtre rendu OBLIGATOIRE ALTER TABLE assistantes_maternelles ALTER COLUMN nir_chiffre SET NOT NULL; -- Table parents ou nouvelle table -- Option 1 : Ajouter Ă  la table parents ALTER TABLE parents ADD COLUMN presentation_dossier TEXT; -- Option 2 : CrĂ©er une table dĂ©diĂ©e CREATE TABLE dossiers_inscription ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), id_utilisateur UUID REFERENCES utilisateurs(id) ON DELETE CASCADE, presentation TEXT, cree_le TIMESTAMPTZ DEFAULT now() ); ``` --- **DerniĂšre mise Ă  jour** : 24 Novembre 2025 **Version** : 1.0 **Statut** : ✅ Document validĂ© - Conforme CDC v1.3