From d0827a119e362408779b7de26a8498b73a0cdb2c Mon Sep 17 00:00:00 2001 From: Julien Martin Date: Wed, 26 Nov 2025 14:33:04 +0100 Subject: [PATCH] =?UTF-8?q?docs:=20ajout=20documentation=20technique=20com?= =?UTF-8?q?pl=C3=A8te=20(configuration,=20documents=20l=C3=A9gaux,=20ticke?= =?UTF-8?q?ts,=20d=C3=A9cisions,=20backlog=20Phase=202)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/21_CONFIGURATION-SYSTEME.md | 712 +++++++++++++++++++ docs/22_DOCUMENTS-LEGAUX.md | 697 +++++++++++++++++++ docs/23_LISTE-TICKETS.md | 1108 ++++++++++++++++++++++++++++++ docs/24_DECISIONS-PROJET.md | 568 +++++++++++++++ docs/25_PHASE-2-BACKLOG.md | 433 ++++++++++++ 5 files changed, 3518 insertions(+) create mode 100644 docs/21_CONFIGURATION-SYSTEME.md create mode 100644 docs/22_DOCUMENTS-LEGAUX.md create mode 100644 docs/23_LISTE-TICKETS.md create mode 100644 docs/24_DECISIONS-PROJET.md create mode 100644 docs/25_PHASE-2-BACKLOG.md diff --git a/docs/21_CONFIGURATION-SYSTEME.md b/docs/21_CONFIGURATION-SYSTEME.md new file mode 100644 index 0000000..fc438b5 --- /dev/null +++ b/docs/21_CONFIGURATION-SYSTEME.md @@ -0,0 +1,712 @@ +# 🔧 Documentation Technique - Configuration SystĂšme On-Premise + +**Version** : 1.0 +**Date** : 25 Novembre 2025 +**Auteur** : Équipe PtitsPas +**RĂ©fĂ©rence** : Architecture On-Premise + +--- + +## 📖 Table des matiĂšres + +1. [Vue d'ensemble](#vue-densemble) +2. [Architecture de configuration](#architecture-de-configuration) +3. [Table configuration](#table-configuration) +4. [Service Configuration](#service-configuration) +5. [Workflow Setup Initial](#workflow-setup-initial) +6. [APIs Configuration](#apis-configuration) +7. [Interface Admin](#interface-admin) +8. [Exemples de configuration](#exemples-de-configuration) + +--- + +## 🎯 Vue d'ensemble + +### ProblĂ©matique + +L'application P'titsPas est dĂ©ployĂ©e **on-premise** chez diffĂ©rentes collectivitĂ©s. Chaque collectivitĂ© a : +- Son propre serveur SMTP +- Ses propres ports et configurations rĂ©seau +- Son propre nom de domaine +- Sa propre charte graphique + +**Solution** : Configuration dynamique stockĂ©e en base de donnĂ©es, modifiable via interface web. + +### Principes + +1. ✅ **Pas de hardcoding** : Aucune valeur en dur dans le code +2. ✅ **Pas de redĂ©ploiement** : Modification sans rebuild Docker +3. ✅ **SĂ©curitĂ©** : Mots de passe chiffrĂ©s en AES-256 +4. ✅ **TraçabilitĂ©** : Qui a modifiĂ© quoi et quand +5. ✅ **Setup wizard** : Configuration guidĂ©e Ă  la premiĂšre connexion +6. ✅ **Validation** : Test SMTP avant sauvegarde + +--- + +## đŸ—ïž Architecture de configuration + +### Flux de donnĂ©es + +``` +┌─────────────────────────────────────────────────────────┐ +│ Application │ +├────────────────────────────────────────────────────────── +│ │ +│ ┌──────────────┐ ┌──────────────┐ │ +│ │ Frontend │─────▶│ Backend │ │ +│ │ (Admin) │ │ ConfigAPI │ │ +│ └──────────────┘ └──────┬───────┘ │ +│ │ │ +│ â–Œ │ +│ ┌──────────────┐ │ +│ │ ConfigService│ │ +│ │ (Cache) │ │ +│ └──────┬───────┘ │ +│ │ │ +│ â–Œ │ +│ ┌──────────────┐ │ +│ │ PostgreSQL │ │ +│ │ configuration│ │ +│ └──────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────┘ +``` + +### Composants + +1. **Table `configuration`** : Stockage clĂ©/valeur en BDD +2. **ConfigService** : Cache en mĂ©moire + chiffrement +3. **ConfigAPI** : Endpoints REST pour CRUD +4. **Guard Setup** : Redirection forcĂ©e si config incomplĂšte +5. **Interface Admin** : Formulaire de configuration + +--- + +## 📊 Table configuration + +### SchĂ©ma SQL + +```sql +-- Table de configuration systĂšme (clĂ©/valeur) +CREATE TABLE configuration ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + cle VARCHAR(100) UNIQUE NOT NULL, -- ClĂ© unique (ex: 'smtp_host') + valeur TEXT, -- Valeur (peut ĂȘtre NULL) + type VARCHAR(50) NOT NULL, -- Type: 'string', 'number', 'boolean', 'json', 'encrypted' + categorie VARCHAR(50), -- CatĂ©gorie: 'email', 'app', 'security' + description TEXT, -- Description pour l'interface admin + modifie_le TIMESTAMPTZ DEFAULT now(), -- Date derniĂšre modification + modifie_par UUID REFERENCES utilisateurs(id) -- Qui a modifiĂ© (traçabilitĂ©) +); + +-- Index pour performance +CREATE INDEX idx_configuration_cle ON configuration(cle); +CREATE INDEX idx_configuration_categorie ON configuration(categorie); +``` + +### Seed initial + +```sql +INSERT INTO configuration (cle, valeur, type, categorie, description) VALUES +-- === Configuration Email (SMTP) === +('smtp_host', 'localhost', 'string', 'email', 'Serveur SMTP (ex: mail.mairie-bezons.fr, smtp.gmail.com)'), +('smtp_port', '25', 'number', 'email', 'Port SMTP (25, 465, 587)'), +('smtp_secure', 'false', 'boolean', 'email', 'Utiliser SSL/TLS (true pour port 465)'), +('smtp_auth_required', 'false', 'boolean', 'email', 'Authentification SMTP requise'), +('smtp_user', '', 'string', 'email', 'Utilisateur SMTP (si authentification requise)'), +('smtp_password', '', 'encrypted', 'email', 'Mot de passe SMTP (chiffrĂ© en AES-256)'), +('email_from_name', 'P''titsPas', 'string', 'email', 'Nom de l''expĂ©diteur affichĂ© dans les emails'), +('email_from_address', 'no-reply@ptits-pas.fr', 'string', 'email', 'Adresse email de l''expĂ©diteur'), + +-- === Configuration Application === +('app_name', 'P''titsPas', 'string', 'app', 'Nom de l''application (affichĂ© dans l''interface)'), +('app_url', 'https://app.ptits-pas.fr', 'string', 'app', 'URL publique de l''application (pour les liens dans emails)'), +('app_logo_url', '/assets/logo.png', 'string', 'app', 'URL du logo de l''application'), +('setup_completed', 'false', 'boolean', 'app', 'Configuration initiale terminĂ©e'), + +-- === Configuration SĂ©curitĂ© === +('password_reset_token_expiry_days', '7', 'number', 'security', 'DurĂ©e de validitĂ© des tokens de crĂ©ation/rĂ©initialisation de mot de passe (en jours)'), +('jwt_expiry_hours', '24', 'number', 'security', 'DurĂ©e de validitĂ© des sessions JWT (en heures)'), +('max_upload_size_mb', '5', 'number', 'security', 'Taille maximale des fichiers uploadĂ©s (en MB)'), +('bcrypt_rounds', '12', 'number', 'security', 'Nombre de rounds bcrypt pour le hachage des mots de passe'); +``` + +### Types de donnĂ©es + +| Type | Description | Exemple | +|------|-------------|---------| +| `string` | ChaĂźne de caractĂšres | `"mail.example.com"` | +| `number` | Nombre entier ou dĂ©cimal | `587` | +| `boolean` | BoolĂ©en | `true` / `false` | +| `json` | Objet JSON | `{"key": "value"}` | +| `encrypted` | ChaĂźne chiffrĂ©e AES-256 | `"a3f8b2..."` (hash) | + +--- + +## 🔧 Service Configuration + +### ResponsabilitĂ©s + +1. **Cache en mĂ©moire** : Chargement au dĂ©marrage +2. **Lecture** : `get(key, defaultValue)` +3. **Écriture** : `set(key, value, userId)` +4. **Chiffrement** : AES-256 pour type `encrypted` +5. **Conversion de types** : string → number/boolean/json +6. **Test SMTP** : Validation connexion + +### ImplĂ©mentation (TypeScript) + +```typescript +// backend/src/config/config.service.ts +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { Configuration } from './entities/configuration.entity'; +import * as crypto from 'crypto'; + +@Injectable() +export class ConfigService { + private cache: Map = new Map(); + private readonly ENCRYPTION_KEY = process.env.CONFIG_ENCRYPTION_KEY; + + constructor( + @InjectRepository(Configuration) + private configRepo: Repository, + ) { + this.loadCache(); + } + + // Chargement du cache au dĂ©marrage + async loadCache() { + const configs = await this.configRepo.find(); + configs.forEach(config => { + let value = config.valeur; + + // DĂ©chiffrement si nĂ©cessaire + if (config.type === 'encrypted' && value) { + value = this.decrypt(value); + } + + // Conversion de type + value = this.convertType(value, config.type); + + this.cache.set(config.cle, value); + }); + } + + // RĂ©cupĂ©ration d'une valeur + get(key: string, defaultValue?: any): any { + return this.cache.has(key) ? this.cache.get(key) : defaultValue; + } + + // Mise Ă  jour d'une valeur + async set(key: string, value: any, userId: string): Promise { + const config = await this.configRepo.findOne({ where: { cle: key } }); + + if (!config) { + throw new Error(`Configuration key '${key}' not found`); + } + + let valueToStore = String(value); + + // Chiffrement si nĂ©cessaire + if (config.type === 'encrypted') { + valueToStore = this.encrypt(valueToStore); + } + + config.valeur = valueToStore; + config.modifie_par = userId; + config.modifie_le = new Date(); + + await this.configRepo.save(config); + + // Mise Ă  jour du cache + this.cache.set(key, value); + } + + // RĂ©cupĂ©ration de toutes les configs par catĂ©gorie + async getByCategory(category: string): Promise { + const configs = await this.configRepo.find({ where: { categorie: category } }); + + return configs.reduce((acc, config) => { + let value = config.valeur; + + if (config.type === 'encrypted') { + value = '***********'; // Masquer les mots de passe + } else { + value = this.convertType(value, config.type); + } + + acc[config.cle] = { + value, + description: config.description, + type: config.type, + }; + + return acc; + }, {}); + } + + // Test de connexion SMTP + async testSmtpConnection(): Promise { + const nodemailer = require('nodemailer'); + + const transporter = nodemailer.createTransport({ + host: this.get('smtp_host'), + port: this.get('smtp_port'), + secure: this.get('smtp_secure'), + auth: this.get('smtp_auth_required') ? { + user: this.get('smtp_user'), + pass: this.get('smtp_password'), + } : undefined, + }); + + try { + await transporter.verify(); + return true; + } catch (error) { + console.error('SMTP test failed:', error); + return false; + } + } + + // Utilitaires + private convertType(value: string, type: string): any { + switch (type) { + case 'number': return Number(value); + case 'boolean': return value === 'true'; + case 'json': return JSON.parse(value); + default: return value; + } + } + + private encrypt(text: string): string { + const cipher = crypto.createCipher('aes-256-cbc', this.ENCRYPTION_KEY); + let encrypted = cipher.update(text, 'utf8', 'hex'); + encrypted += cipher.final('hex'); + return encrypted; + } + + private decrypt(text: string): string { + const decipher = crypto.createDecipher('aes-256-cbc', this.ENCRYPTION_KEY); + let decrypted = decipher.update(text, 'hex', 'utf8'); + decrypted += decipher.final('utf8'); + return decrypted; + } +} +``` + +--- + +## 🔄 Workflow Setup Initial + +### Diagramme de sĂ©quence + +```mermaid +sequenceDiagram + participant SA as Super Admin + participant App as Application + participant Guard as SetupGuard + participant API as ConfigAPI + participant DB as PostgreSQL + participant SMTP as Serveur SMTP + + SA->>App: PremiĂšre connexion + App->>Guard: VĂ©rifier setup_completed + Guard->>DB: SELECT valeur FROM configuration
WHERE cle='setup_completed' + DB-->>Guard: 'false' + + Guard-->>App: Redirection forcée vers
/admin/setup + + SA->>SA: Remplit formulaire config
(SMTP, app, sĂ©curitĂ©) + + SA->>App: Clic "Tester la connexion SMTP" + App->>API: POST /api/v1/configuration/test-smtp + API->>SMTP: Test connexion + + alt Test SMTP OK + SMTP-->>API: ✅ Connexion rĂ©ussie + API->>SA: Envoi email de test + API-->>App: ✅ Test rĂ©ussi + App-->>SA: Message: "Email de test envoyĂ©" + else Test SMTP KO + SMTP-->>API: ❌ Erreur connexion + API-->>App: ❌ Erreur dĂ©taillĂ©e + App-->>SA: Message: "Erreur: vĂ©rifiez les paramĂštres" + end + + SA->>App: Clic "Sauvegarder" + App->>API: PATCH /api/v1/configuration/bulk
{smtp_host, smtp_port, ...} + + API->>DB: BEGIN TRANSACTION + API->>DB: UPDATE configuration SET valeur=...
FOR EACH key + API->>DB: UPDATE configuration
SET valeur='true'
WHERE cle='setup_completed' + API->>DB: COMMIT + + API->>API: Recharger cache ConfigService + + API-->>App: ✅ Configuration sauvegardĂ©e + App-->>SA: Redirection vers /admin/dashboard + + SA->>App: AccĂšs complet Ă  l'application +``` + +### Étapes dĂ©taillĂ©es + +#### 1. DĂ©tection configuration incomplĂšte + +**Guard** : `SetupGuard` (NestJS) + +```typescript +@Injectable() +export class SetupGuard implements CanActivate { + constructor(private configService: ConfigService) {} + + canActivate(context: ExecutionContext): boolean { + const request = context.switchToHttp().getRequest(); + const setupCompleted = this.configService.get('setup_completed', false); + + // Exemptions + const exemptedRoutes = ['/auth/login', '/admin/setup', '/api/v1/configuration']; + if (exemptedRoutes.some(route => request.url.includes(route))) { + return true; + } + + // Si setup non complĂ©tĂ©, bloquer + if (!setupCompleted) { + throw new HttpException( + 'Configuration initiale requise', + HttpStatus.TEMPORARY_REDIRECT, + { location: '/admin/setup' } + ); + } + + return true; + } +} +``` + +#### 2. Formulaire Setup (Frontend) + +**3 onglets** : + +##### Onglet 1 : Configuration Email 📧 + +| Champ | Type | Valeur par dĂ©faut | Obligatoire | +|-------|------|-------------------|-------------| +| Serveur SMTP | Text | `localhost` | ✅ | +| Port SMTP | Number | `25` | ✅ | +| SĂ©curitĂ© | Select | `Aucune` / `STARTTLS` / `SSL/TLS` | ✅ | +| Authentification requise | Checkbox | `false` | - | +| Utilisateur SMTP | Text | - | Si auth | +| Mot de passe SMTP | Password | - | Si auth | +| Nom expĂ©diteur | Text | `P'titsPas` | ✅ | +| Email expĂ©diteur | Email | `no-reply@ptits-pas.fr` | ✅ | + +**Bouton** : "đŸ§Ș Tester la connexion SMTP" + +##### Onglet 2 : Personnalisation 🎹 + +| Champ | Type | Valeur par dĂ©faut | Obligatoire | +|-------|------|-------------------|-------------| +| Nom de l'application | Text | `P'titsPas` | ✅ | +| URL de l'application | URL | `https://app.ptits-pas.fr` | ✅ | +| Logo | File (PNG/JPG) | Logo par dĂ©faut | ❌ | + +##### Onglet 3 : ParamĂštres avancĂ©s ⚙ + +| Champ | Type | Valeur par dĂ©faut | Obligatoire | +|-------|------|-------------------|-------------| +| DurĂ©e validitĂ© token MDP (jours) | Number | `7` | ✅ | +| DurĂ©e session JWT (heures) | Number | `24` | ✅ | +| Taille max upload (MB) | Number | `5` | ✅ | + +**Bouton** : "đŸ’Ÿ Sauvegarder et terminer la configuration" + +--- + +## 🔌 APIs Configuration + +### Endpoint 1 : RĂ©cupĂ©rer config par catĂ©gorie + +```http +GET /api/v1/configuration/:category +Authorization: Bearer +``` + +**ParamĂštres** : +- `category` : `email` | `app` | `security` + +**RĂ©ponse 200** : +```json +{ + "smtp_host": { + "value": "localhost", + "description": "Serveur SMTP", + "type": "string" + }, + "smtp_port": { + "value": 25, + "description": "Port SMTP", + "type": "number" + }, + "smtp_password": { + "value": "***********", + "description": "Mot de passe SMTP", + "type": "encrypted" + } +} +``` + +--- + +### Endpoint 2 : Mise Ă  jour multiple + +```http +PATCH /api/v1/configuration/bulk +Authorization: Bearer +Content-Type: application/json +``` + +**Body** : +```json +{ + "smtp_host": "mail.mairie-bezons.fr", + "smtp_port": 587, + "smtp_secure": false, + "smtp_auth_required": true, + "smtp_user": "noreply@mairie-bezons.fr", + "smtp_password": "SecretPassword123", + "email_from_name": "P'titsPas - Mairie de Bezons", + "email_from_address": "noreply@mairie-bezons.fr", + "app_name": "P'titsPas Bezons", + "app_url": "https://ptitspas.mairie-bezons.fr" +} +``` + +**RĂ©ponse 200** : +```json +{ + "message": "Configuration mise Ă  jour avec succĂšs", + "updated": 10 +} +``` + +--- + +### Endpoint 3 : Test connexion SMTP + +```http +POST /api/v1/configuration/test-smtp +Authorization: Bearer +Content-Type: application/json +``` + +**Body** : +```json +{ + "smtp_host": "mail.mairie-bezons.fr", + "smtp_port": 587, + "smtp_secure": false, + "smtp_auth_required": true, + "smtp_user": "noreply@mairie-bezons.fr", + "smtp_password": "SecretPassword123", + "test_email": "admin@mairie-bezons.fr" +} +``` + +**RĂ©ponse 200** : +```json +{ + "success": true, + "message": "Connexion SMTP rĂ©ussie. Email de test envoyĂ© Ă  admin@mairie-bezons.fr" +} +``` + +**RĂ©ponse 400** : +```json +{ + "success": false, + "message": "Erreur de connexion SMTP", + "error": "ECONNREFUSED: Connection refused" +} +``` + +--- + +## đŸ’» Interface Admin + +### Écran Setup Initial + +``` +┌─────────────────────────────────────────────────────────┐ +│ 🚀 Configuration Initiale - P'titsPas │ +├────────────────────────────────────────────────────────── +│ │ +│ Bienvenue ! Configurez votre installation P'titsPas │ +│ │ +│ [ 📧 Email ] [ 🎹 Personnalisation ] [ ⚙ AvancĂ© ] │ +├────────────────────────────────────────────────────────── +│ │ +│ 📧 Configuration Email (SMTP) │ +│ │ +│ Serveur SMTP * │ +│ [_____________________________________________] │ +│ Ex: mail.mairie-bezons.fr, smtp.gmail.com │ +│ │ +│ Port SMTP * │ +│ [_____] 25 (standard), 465 (SSL), 587 (STARTTLS) │ +│ │ +│ SĂ©curitĂ© * │ +│ [ â–Œ Aucune ] STARTTLS SSL/TLS │ +│ │ +│ ☐ Authentification requise │ +│ │ +│ Utilisateur SMTP │ +│ [_____________________________________________] │ +│ │ +│ Mot de passe SMTP │ +│ [_____________________________________________] │ +│ │ +│ Nom de l'expĂ©diteur * │ +│ [_____________________________________________] │ +│ Ex: P'titsPas - Mairie de Bezons │ +│ │ +│ Email expĂ©diteur * │ +│ [_____________________________________________] │ +│ Ex: noreply@mairie-bezons.fr │ +│ │ +│ [ đŸ§Ș Tester la connexion SMTP ] │ +│ │ +│ ───────────────────────────────────────────────── │ +│ │ +│ [ ← PrĂ©cĂ©dent ] [ Suivant → ] │ +│ │ +└─────────────────────────────────────────────────────────┘ +``` + +### Écran ParamĂštres (accĂšs permanent) + +Identique au Setup Initial, mais accessible depuis le menu admin : +- Menu Admin → ParamĂštres → Configuration SystĂšme + +--- + +## 📋 Exemples de configuration + +### Configuration 1 : Mairie (serveur local) + +```json +{ + "smtp_host": "mail.mairie-bezons.fr", + "smtp_port": 25, + "smtp_secure": false, + "smtp_auth_required": false, + "email_from_name": "P'titsPas - Mairie de Bezons", + "email_from_address": "noreply@mairie-bezons.fr", + "app_name": "P'titsPas Bezons", + "app_url": "https://ptitspas.mairie-bezons.fr" +} +``` + +### Configuration 2 : Gmail (pour tests) + +```json +{ + "smtp_host": "smtp.gmail.com", + "smtp_port": 587, + "smtp_secure": false, + "smtp_auth_required": true, + "smtp_user": "contact@ptits-pas.fr", + "smtp_password": "abcd efgh ijkl mnop", + "email_from_name": "P'titsPas", + "email_from_address": "contact@ptits-pas.fr", + "app_name": "P'titsPas", + "app_url": "https://app.ptits-pas.fr" +} +``` + +**Note** : Pour Gmail, utiliser un "Mot de passe d'application" (App Password) + +### Configuration 3 : Office 365 + +```json +{ + "smtp_host": "smtp.office365.com", + "smtp_port": 587, + "smtp_secure": false, + "smtp_auth_required": true, + "smtp_user": "noreply@collectivite.fr", + "smtp_password": "MotDePasseSecurise123", + "email_from_name": "P'titsPas - CollectivitĂ©", + "email_from_address": "noreply@collectivite.fr", + "app_name": "P'titsPas", + "app_url": "https://ptitspas.collectivite.fr" +} +``` + +--- + +## 🔒 SĂ©curitĂ© + +### Chiffrement des mots de passe + +**Algorithme** : AES-256-CBC +**ClĂ©** : Variable d'environnement `CONFIG_ENCRYPTION_KEY` (32 caractĂšres) + +**GĂ©nĂ©ration de la clĂ©** : +```bash +# Linux/Mac +openssl rand -hex 32 + +# Node.js +node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" +``` + +**Fichier `.env`** : +```env +CONFIG_ENCRYPTION_KEY=a3f8b2c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2 +``` + +### Variables d'environnement critiques + +**Fichier `.env`** (Ă  crĂ©er lors de l'installation) : + +```env +# Base de donnĂ©es +DATABASE_URL=postgresql://app_user:password@ptitspas-postgres:5432/ptitpas_db + +# JWT +JWT_SECRET=VotreSecretJWTTresLongEtAleatoire123456789 +JWT_EXPIRY=24h + +# Configuration +CONFIG_ENCRYPTION_KEY=VotreCleDeChiffrementAES256TresLongue32Caracteres + +# Application +NODE_ENV=production +PORT=3000 +``` + +--- + +## 📚 RĂ©fĂ©rences + +### Documentation interne +- [01_CAHIER-DES-CHARGES.md](./01_CAHIER-DES-CHARGES.md) +- [02_ARCHITECTURE.md](./02_ARCHITECTURE.md) +- [03_DEPLOYMENT.md](./03_DEPLOYMENT.md) +- [10_DATABASE.md](./10_DATABASE.md) +- [11_API.md](./11_API.md) + +### Documentation externe +- [NestJS Configuration](https://docs.nestjs.com/techniques/configuration) +- [Nodemailer SMTP](https://nodemailer.com/smtp/) +- [Node.js Crypto](https://nodejs.org/api/crypto.html) + +--- + +**DerniĂšre mise Ă  jour** : 25 Novembre 2025 +**Version** : 1.0 +**Statut** : ✅ Document validĂ© + diff --git a/docs/22_DOCUMENTS-LEGAUX.md b/docs/22_DOCUMENTS-LEGAUX.md new file mode 100644 index 0000000..6addfbd --- /dev/null +++ b/docs/22_DOCUMENTS-LEGAUX.md @@ -0,0 +1,697 @@ +# 📄 Documentation Technique - Gestion Documents LĂ©gaux (CGU/Privacy) + +**Version** : 1.0 +**Date** : 25 Novembre 2025 +**Auteur** : Équipe PtitsPas +**RĂ©fĂ©rence** : RGPD & ConformitĂ© juridique + +--- + +## 📖 Table des matiĂšres + +1. [Vue d'ensemble](#vue-densemble) +2. [Architecture](#architecture) +3. [Tables BDD](#tables-bdd) +4. [Service Documents LĂ©gaux](#service-documents-lĂ©gaux) +5. [Workflow Upload & Activation](#workflow-upload--activation) +6. [Workflow Acceptation Utilisateur](#workflow-acceptation-utilisateur) +7. [APIs](#apis) +8. [Interface Admin](#interface-admin) +9. [ConformitĂ© RGPD](#conformitĂ©-rgpd) + +--- + +## 🎯 Vue d'ensemble + +### ProblĂ©matique + +Chaque collectivitĂ© dĂ©ployant P'titsPas on-premise doit pouvoir : +1. ✅ **Personnaliser** les CGU et la Politique de confidentialitĂ© +2. ✅ **Versionner** les documents (traçabilitĂ© juridique) +3. ✅ **Tracer** qui a acceptĂ© quelle version (RGPD) +4. ✅ **Prouver** l'acceptation (IP, User-Agent, horodatage) +5. ✅ **EmpĂȘcher** le retour en arriĂšre (sĂ©curitĂ© juridique) + +### Solution + +- **Documents gĂ©nĂ©riques v1** fournis par dĂ©faut (rĂ©digĂ©s avec juriste) +- **Upload de nouvelles versions** par l'admin (PDF uniquement) +- **Versioning automatique** (incrĂ©mentation sans retour arriĂšre) +- **Activation manuelle** (prĂ©visualisation avant mise en prod) +- **TraçabilitĂ© complĂšte** (hash SHA-256, IP, User-Agent) + +--- + +## đŸ—ïž Architecture + +### Flux de donnĂ©es + +``` +┌─────────────────────────────────────────────────────────┐ +│ Workflow Documents │ +├────────────────────────────────────────────────────────── +│ │ +│ 1. UPLOAD (Admin) │ +│ Admin ──▶ API ──▶ File System ──▶ BDD │ +│ /documents/legaux/ │ +│ cgu_v4_.pdf │ +│ │ +│ 2. ACTIVATION (Admin) │ +│ Admin ──▶ API ──▶ BDD (actif=true) │ +│ │ +│ 3. ACCEPTATION (Utilisateur) │ +│ User ──▶ Frontend ──▶ API ──▶ BDD │ +│ (inscription) (trace IP/UA) │ +│ │ +└─────────────────────────────────────────────────────────┘ +``` + +### Composants + +1. **Table `documents_legaux`** : Stockage versions + mĂ©tadonnĂ©es +2. **Table `acceptations_documents`** : TraçabilitĂ© acceptations +3. **Service `DocumentsLegauxService`** : Upload, versioning, activation +4. **API REST** : CRUD documents +5. **Interface Admin** : Upload + activation +6. **Interface Inscription** : Affichage + acceptation + +--- + +## 📊 Tables BDD + +### Table 1 : `documents_legaux` + +```sql +-- Table pour gĂ©rer les versions des documents lĂ©gaux +CREATE TABLE documents_legaux ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + type VARCHAR(50) NOT NULL, -- 'cgu' ou 'privacy' + version INTEGER NOT NULL, -- NumĂ©ro de version (auto-incrĂ©mentĂ©) + fichier_nom VARCHAR(255) NOT NULL, -- Nom original du fichier + fichier_path VARCHAR(500) NOT NULL, -- Chemin de stockage + fichier_hash VARCHAR(64) NOT NULL, -- Hash SHA-256 pour intĂ©gritĂ© + actif BOOLEAN DEFAULT false, -- Version actuellement active + televerse_par UUID REFERENCES utilisateurs(id), -- Qui a uploadĂ© + televerse_le TIMESTAMPTZ DEFAULT now(), -- Date d'upload + active_le TIMESTAMPTZ, -- Date d'activation + UNIQUE(type, version) -- Pas de doublon version +); + +-- Index pour performance +CREATE INDEX idx_documents_legaux_type_actif ON documents_legaux(type, actif); +CREATE INDEX idx_documents_legaux_version ON documents_legaux(type, version DESC); +``` + +**Contraintes** : +- ✅ Un seul document `actif=true` par type Ă  la fois +- ✅ Versioning auto-incrĂ©mentĂ© (pas de gaps) +- ✅ Hash SHA-256 pour vĂ©rifier l'intĂ©gritĂ© du fichier + +--- + +### Table 2 : `acceptations_documents` + +```sql +-- Table de traçabilitĂ© des acceptations (RGPD) +CREATE TABLE acceptations_documents ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + id_utilisateur UUID REFERENCES utilisateurs(id) ON DELETE CASCADE, + id_document UUID REFERENCES documents_legaux(id), + type_document VARCHAR(50) NOT NULL, -- 'cgu' ou 'privacy' + version_document INTEGER NOT NULL, -- Version acceptĂ©e + accepte_le TIMESTAMPTZ DEFAULT now(), -- Date d'acceptation + ip_address INET, -- IP de l'utilisateur (RGPD) + user_agent TEXT -- Navigateur (preuve) +); + +CREATE INDEX idx_acceptations_utilisateur ON acceptations_documents(id_utilisateur); +CREATE INDEX idx_acceptations_document ON acceptations_documents(id_document); +``` + +**DonnĂ©es capturĂ©es** : +- ✅ **Qui** : `id_utilisateur` +- ✅ **Quoi** : `type_document`, `version_document` +- ✅ **Quand** : `accepte_le` +- ✅ **OĂč** : `ip_address` +- ✅ **Comment** : `user_agent` + +--- + +### Modification table `utilisateurs` + +```sql +-- Ajouter colonnes pour rĂ©fĂ©rence rapide (optionnel) +ALTER TABLE utilisateurs + ADD COLUMN cgu_version_acceptee INTEGER, + ADD COLUMN cgu_acceptee_le TIMESTAMPTZ, + ADD COLUMN privacy_version_acceptee INTEGER, + ADD COLUMN privacy_acceptee_le TIMESTAMPTZ; +``` + +**Note** : Ces colonnes sont **redondantes** avec `acceptations_documents`, mais permettent un accĂšs rapide sans JOIN. + +--- + +### Seed initial + +```sql +-- Documents gĂ©nĂ©riques v1 (fournis par dĂ©faut) +INSERT INTO documents_legaux (type, version, fichier_nom, fichier_path, fichier_hash, actif, televerse_le, active_le) VALUES +('cgu', 1, 'cgu_v1_default.pdf', '/documents/legaux/cgu_v1_default.pdf', 'a3f8b2c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2', true, now(), now()), +('privacy', 1, 'privacy_v1_default.pdf', '/documents/legaux/privacy_v1_default.pdf', 'b4f9c3d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4', true, now(), now()); +``` + +**Fichiers Ă  fournir** : +- `/documents/legaux/cgu_v1_default.pdf` (rĂ©digĂ© avec juriste) +- `/documents/legaux/privacy_v1_default.pdf` (conforme RGPD) + +--- + +## 🔧 Service Documents LĂ©gaux + +### ResponsabilitĂ©s + +1. **RĂ©cupĂ©rer documents actifs** : `getDocumentsActifs()` +2. **Uploader nouvelle version** : `uploadNouvelleVersion(type, file, userId)` +3. **Activer une version** : `activerVersion(documentId)` +4. **Lister versions** : `listerVersions(type)` +5. **TĂ©lĂ©charger document** : `telechargerDocument(documentId)` + +### ImplĂ©mentation (TypeScript) + +```typescript +// backend/src/documents-legaux/documents-legaux.service.ts +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { DocumentLegal } from './entities/document-legal.entity'; +import * as crypto from 'crypto'; +import * as fs from 'fs/promises'; +import * as path from 'path'; + +@Injectable() +export class DocumentsLegauxService { + private readonly UPLOAD_DIR = '/app/documents/legaux'; + + constructor( + @InjectRepository(DocumentLegal) + private docRepo: Repository, + ) {} + + // RĂ©cupĂ©rer les documents actifs + async getDocumentsActifs(): Promise<{ cgu: DocumentLegal; privacy: DocumentLegal }> { + const cgu = await this.docRepo.findOne({ + where: { type: 'cgu', actif: true }, + }); + + const privacy = await this.docRepo.findOne({ + where: { type: 'privacy', actif: true }, + }); + + if (!cgu || !privacy) { + throw new Error('Documents lĂ©gaux manquants'); + } + + return { cgu, privacy }; + } + + // Uploader une nouvelle version + async uploadNouvelleVersion( + type: 'cgu' | 'privacy', + file: Express.Multer.File, + userId: string, + ): Promise { + // 1. Calculer la prochaine version + const lastDoc = await this.docRepo.findOne({ + where: { type }, + order: { version: 'DESC' }, + }); + const nouvelleVersion = (lastDoc?.version || 0) + 1; + + // 2. Calculer le hash du fichier + const fileBuffer = file.buffer; + const hash = crypto.createHash('sha256').update(fileBuffer).digest('hex'); + + // 3. GĂ©nĂ©rer le nom de fichier unique + const timestamp = Date.now(); + const fileName = `${type}_v${nouvelleVersion}_${timestamp}.pdf`; + const filePath = path.join(this.UPLOAD_DIR, fileName); + + // 4. Sauvegarder le fichier + await fs.mkdir(this.UPLOAD_DIR, { recursive: true }); + await fs.writeFile(filePath, fileBuffer); + + // 5. CrĂ©er l'entrĂ©e en BDD + const document = this.docRepo.create({ + type, + version: nouvelleVersion, + fichier_nom: file.originalname, + fichier_path: filePath, + fichier_hash: hash, + actif: false, // Pas actif par dĂ©faut + televerse_par: userId, + televerse_le: new Date(), + }); + + return await this.docRepo.save(document); + } + + // Activer une version + async activerVersion(documentId: string): Promise { + const document = await this.docRepo.findOne({ where: { id: documentId } }); + + if (!document) { + throw new Error('Document non trouvĂ©'); + } + + // Transaction : dĂ©sactiver l'ancienne version, activer la nouvelle + await this.docRepo.manager.transaction(async (manager) => { + // DĂ©sactiver toutes les versions de ce type + await manager.update( + DocumentLegal, + { type: document.type, actif: true }, + { actif: false }, + ); + + // Activer la nouvelle version + await manager.update( + DocumentLegal, + { id: documentId }, + { actif: true, active_le: new Date() }, + ); + }); + } + + // Lister toutes les versions (pour l'admin) + async listerVersions(type: 'cgu' | 'privacy'): Promise { + return await this.docRepo.find({ + where: { type }, + order: { version: 'DESC' }, + relations: ['televerse_par'], + }); + } + + // TĂ©lĂ©charger un document (stream) + async telechargerDocument(documentId: string): Promise<{ stream: Buffer; filename: string }> { + const document = await this.docRepo.findOne({ where: { id: documentId } }); + + if (!document) { + throw new Error('Document non trouvĂ©'); + } + + const fileBuffer = await fs.readFile(document.fichier_path); + + return { + stream: fileBuffer, + filename: document.fichier_nom, + }; + } + + // VĂ©rifier l'intĂ©gritĂ© d'un document + async verifierIntegrite(documentId: string): Promise { + const document = await this.docRepo.findOne({ where: { id: documentId } }); + + if (!document) { + throw new Error('Document non trouvĂ©'); + } + + const fileBuffer = await fs.readFile(document.fichier_path); + const hash = crypto.createHash('sha256').update(fileBuffer).digest('hex'); + + return hash === document.fichier_hash; + } +} +``` + +--- + +## 🔄 Workflow Upload & Activation + +### Diagramme de sĂ©quence + +```mermaid +sequenceDiagram + participant A as Admin + participant API as Backend API + participant FS as File System + participant DB as PostgreSQL + + A->>API: POST /api/v1/documents-legaux
{type: 'cgu', file: PDF} + + API->>API: Validation fichier
(PDF, max 10MB) + API->>API: Calcul hash SHA-256 + + API->>DB: SELECT MAX(version)
WHERE type='cgu' + DB-->>API: version = 3 + + API->>API: Nouvelle version = 4 + + API->>FS: Enregistrer fichier
/documents/legaux/cgu_v4_.pdf + FS-->>API: ✅ Fichier sauvegardĂ© + + API->>DB: INSERT INTO documents_legaux
(type, version=4, actif=false) + DB-->>API: ✅ Document créé + + API-->>A: 201 Created
{id, version: 4, actif: false} + + A->>A: Prévisualisation PDF + A->>API: PATCH /api/v1/documents-legaux/{id}/activer + + API->>DB: BEGIN TRANSACTION + API->>DB: UPDATE documents_legaux
SET actif=false WHERE type='cgu' + API->>DB: UPDATE documents_legaux
SET actif=true, active_le=now()
WHERE id={id} + API->>DB: COMMIT + + API-->>A: ✅ CGU v4 activĂ©es +``` + +--- + +## đŸ“„ Workflow Acceptation Utilisateur + +### Diagramme de sĂ©quence + +```mermaid +sequenceDiagram + participant U as Utilisateur + participant App as Frontend + participant API as Backend + participant DB as PostgreSQL + + U->>App: Inscription (Ă©tape CGU) + + App->>API: GET /api/v1/documents-legaux/actifs + API->>DB: SELECT * FROM documents_legaux
WHERE actif=true + DB-->>API: {cgu: v4, privacy: v2} + API-->>App: {cgu: {version: 4, url: '...'}, privacy: {...}} + + App->>App: Afficher liens PDF
"CGU v4" et "Privacy v2" + + U->>U: Lit les documents + U->>U: Coche "J'accepte" + + App->>API: POST /api/v1/auth/register
{..., cgu_version: 4, privacy_version: 2, ip, user_agent} + + API->>DB: BEGIN TRANSACTION + + API->>DB: INSERT INTO utilisateurs
(..., cgu_version_acceptee=4, privacy_version_acceptee=2) + DB-->>API: id_utilisateur + + API->>DB: INSERT INTO acceptations_documents
(id_utilisateur, type='cgu', version=4, ip, user_agent) + API->>DB: INSERT INTO acceptations_documents
(id_utilisateur, type='privacy', version=2, ip, user_agent) + + API->>DB: COMMIT + + API-->>App: ✅ Inscription rĂ©ussie +``` + +--- + +## 🔌 APIs + +### API 1 : RĂ©cupĂ©rer documents actifs (Public) + +```http +GET /api/v1/documents-legaux/actifs +``` + +**RĂ©ponse 200** : +```json +{ + "cgu": { + "id": "uuid-cgu-v4", + "type": "cgu", + "version": 4, + "url": "/api/v1/documents-legaux/uuid-cgu-v4/download", + "active_le": "2025-11-20T14:30:00Z" + }, + "privacy": { + "id": "uuid-privacy-v2", + "type": "privacy", + "version": 2, + "url": "/api/v1/documents-legaux/uuid-privacy-v2/download", + "active_le": "2025-10-15T09:15:00Z" + } +} +``` + +--- + +### API 2 : Lister versions (Admin) + +```http +GET /api/v1/documents-legaux/:type/versions +Authorization: Bearer +``` + +**ParamĂštres** : +- `type` : `cgu` | `privacy` + +**RĂ©ponse 200** : +```json +[ + { + "id": "uuid-cgu-v4", + "version": 4, + "fichier_nom": "CGU_Mairie_Bezons_2025.pdf", + "actif": true, + "televerse_par": { + "id": "uuid-admin", + "prenom": "Lucas", + "nom": "MOREAU" + }, + "televerse_le": "2025-11-20T14:00:00Z", + "active_le": "2025-11-20T14:30:00Z" + }, + { + "id": "uuid-cgu-v3", + "version": 3, + "fichier_nom": "CGU_v3.pdf", + "actif": false, + "televerse_par": { + "id": "uuid-admin", + "prenom": "Admin", + "nom": "SystĂšme" + }, + "televerse_le": "2025-10-15T09:00:00Z", + "active_le": "2025-10-15T09:15:00Z" + } +] +``` + +--- + +### API 3 : Upload nouvelle version (Admin) + +```http +POST /api/v1/documents-legaux +Authorization: Bearer +Content-Type: multipart/form-data +``` + +**Body** : +``` +type: cgu +file: +``` + +**RĂ©ponse 201** : +```json +{ + "id": "uuid-nouveau-doc", + "type": "cgu", + "version": 5, + "fichier_nom": "CGU_Mairie_Bezons_2025_v2.pdf", + "actif": false, + "televerse_le": "2025-11-25T10:00:00Z" +} +``` + +**Erreurs** : +- `400 Bad Request` : Fichier non PDF ou trop volumineux (>10MB) +- `401 Unauthorized` : Token manquant ou invalide +- `403 Forbidden` : RĂŽle insuffisant (pas super_admin) + +--- + +### API 4 : Activer une version (Admin) + +```http +PATCH /api/v1/documents-legaux/:id/activer +Authorization: Bearer +``` + +**RĂ©ponse 200** : +```json +{ + "message": "Document activĂ© avec succĂšs", + "documentId": "uuid-nouveau-doc", + "type": "cgu", + "version": 5 +} +``` + +--- + +### API 5 : TĂ©lĂ©charger document (Public) + +```http +GET /api/v1/documents-legaux/:id/download +``` + +**RĂ©ponse 200** : +``` +Content-Type: application/pdf +Content-Disposition: attachment; filename="CGU_v5.pdf" + + +``` + +--- + +### API 6 : Historique acceptations utilisateur (Admin) + +```http +GET /api/v1/users/:userId/acceptations +Authorization: Bearer +``` + +**RĂ©ponse 200** : +```json +[ + { + "type_document": "cgu", + "version_document": 4, + "accepte_le": "2025-11-20T15:30:00Z", + "ip_address": "192.168.1.100", + "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + }, + { + "type_document": "privacy", + "version_document": 2, + "accepte_le": "2025-11-20T15:30:00Z", + "ip_address": "192.168.1.100", + "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + } +] +``` + +--- + +## đŸ’» Interface Admin + +### Écran Gestion Documents LĂ©gaux + +``` +┌─────────────────────────────────────────────────────────┐ +│ 📄 Gestion des Documents LĂ©gaux │ +├────────────────────────────────────────────────────────── +│ [ CGU ] [ Politique de confidentialitĂ© ] │ +├────────────────────────────────────────────────────────── +│ │ +│ 📋 Conditions GĂ©nĂ©rales d'Utilisation (CGU) │ +│ │ +│ Version active : v4 │ +│ ActivĂ©e le : 20/11/2025 14:30 │ +│ TĂ©lĂ©versĂ©e par : Lucas MOREAU │ +│ │ +│ [ đŸ“„ TĂ©lĂ©charger ] [ đŸ‘ïž PrĂ©visualiser ] │ +│ │ +│ ───────────────────────────────────────────────── │ +│ │ +│ đŸ“€ Uploader une nouvelle version │ +│ │ +│ ⚠ Attention : L'upload d'une nouvelle version │ +│ crĂ©era la version v5. Vous pourrez la prĂ©visualiser│ +│ avant de l'activer. │ +│ │ +│ [ Choisir un fichier PDF ] (max 10MB) │ +│ │ +│ [ đŸ“€ Uploader ] │ +│ │ +│ ───────────────────────────────────────────────── │ +│ │ +│ 📜 Historique des versions │ +│ │ +│ ┌───────────────────────────────────────────────┐ │ +│ │ ✅ v4 (Active) │ │ +│ │ ActivĂ©e le : 20/11/2025 14:30 │ │ +│ │ Par : Lucas MOREAU │ │ +│ │ Hash : a3f8b2c4...e0f1a2 ✓ │ │ +│ │ [ đŸ“„ TĂ©lĂ©charger ] [ đŸ‘ïž Voir ] │ │ +│ └───────────────────────────────────────────────┘ │ +│ │ +│ ┌───────────────────────────────────────────────┐ │ +│ │ v3 (Inactive) │ │ +│ │ ActivĂ©e le : 15/10/2025 09:15 │ │ +│ │ Par : Admin SystĂšme │ │ +│ │ Hash : b4f9c3d6...f2a3b4 ✓ │ │ +│ │ [ đŸ“„ TĂ©lĂ©charger ] [ đŸ‘ïž Voir ] [🔄 RĂ©activer]│ │ +│ └───────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────┘ +``` + +--- + +## 🔒 ConformitĂ© RGPD + +### DonnĂ©es capturĂ©es + +| DonnĂ©e | Justification RGPD | DurĂ©e conservation | +|--------|-------------------|-------------------| +| `id_utilisateur` | TraçabilitĂ© acceptation | DurĂ©e du compte | +| `version_document` | Preuve version acceptĂ©e | DurĂ©e du compte | +| `accepte_le` | Horodatage lĂ©gal | DurĂ©e du compte | +| `ip_address` | Preuve origine acceptation | 1 an (recommandĂ©) | +| `user_agent` | Preuve navigateur/appareil | 1 an (recommandĂ©) | + +### Droits utilisateur + +#### Droit d'accĂšs (Article 15) +L'utilisateur peut demander : +- Quelles versions il a acceptĂ©es +- Quand il les a acceptĂ©es +- Depuis quelle IP + +**API** : `GET /api/v1/users/me/acceptations` + +#### Droit Ă  l'oubli (Article 17) +Lors de la suppression du compte : +- Suppression des donnĂ©es personnelles +- Conservation des acceptations anonymisĂ©es (obligation lĂ©gale) + +**ImplĂ©mentation** : +```sql +-- Anonymisation (pas suppression totale) +UPDATE acceptations_documents +SET ip_address = NULL, + user_agent = NULL +WHERE id_utilisateur = ''; + +-- Puis suppression utilisateur +DELETE FROM utilisateurs WHERE id = ''; +``` + +--- + +## 📚 RĂ©fĂ©rences + +### Documentation interne +- [01_CAHIER-DES-CHARGES.md](./01_CAHIER-DES-CHARGES.md) +- [10_DATABASE.md](./10_DATABASE.md) +- [11_API.md](./11_API.md) +- [21_CONFIGURATION-SYSTEME.md](./21_CONFIGURATION-SYSTEME.md) + +### Documentation externe +- [RGPD - Article 7 (Consentement)](https://www.cnil.fr/fr/reglement-europeen-protection-donnees/chapitre2#Article7) +- [RGPD - Article 15 (Droit d'accĂšs)](https://www.cnil.fr/fr/reglement-europeen-protection-donnees/chapitre3#Article15) +- [RGPD - Article 17 (Droit Ă  l'oubli)](https://www.cnil.fr/fr/reglement-europeen-protection-donnees/chapitre3#Article17) + +--- + +**DerniĂšre mise Ă  jour** : 25 Novembre 2025 +**Version** : 1.0 +**Statut** : ✅ Document validĂ© + + diff --git a/docs/23_LISTE-TICKETS.md b/docs/23_LISTE-TICKETS.md new file mode 100644 index 0000000..a5fc7c6 --- /dev/null +++ b/docs/23_LISTE-TICKETS.md @@ -0,0 +1,1108 @@ +# đŸŽ« Liste ComplĂšte des Tickets - Projet P'titsPas + +**Version** : 1.0 +**Date** : 25 Novembre 2025 +**Auteur** : Équipe PtitsPas +**Estimation totale** : ~173h + +--- + +## 📊 Vue d'ensemble + +### RĂ©partition par prioritĂ© + +| PrioritĂ© | Nombre | Estimation | Description | +|----------|--------|------------|-------------| +| **P0** | 7 tickets | ~5h | Amendements BDD (BLOQUANT) | +| **P1** | 7 tickets | ~22h | Configuration systĂšme (BLOQUANT) | +| **P2** | 18 tickets | ~50h | Backend mĂ©tier | +| **P3** | 17 tickets | ~52h | Frontend | +| **P4** | 4 tickets | ~24h | Tests & Documentation | +| **CRITIQUES** | 6 tickets | ~13h | Upload, Logs, Infra, CDC | +| **JURIDIQUE** | 1 ticket | ~8h | RĂ©daction CGU/Privacy | +| **TOTAL** | **61 tickets** | **~173h** | | + +--- + +## 🔮 PRIORITÉ 0 : Amendements Base de DonnĂ©es (BLOQUANT) + +### Ticket #1 : [BDD] Ajout champs manquants conformitĂ© CDC +**Estimation** : 1h +**Labels** : `bdd`, `p0-bloquant`, `cdc` + +**Description** : +Ajouter les champs manquants dans la base de donnĂ©es pour ĂȘtre conforme au Cahier des Charges v1.3. + +**TĂąches** : +- [ ] Ajouter `ville_naissance` VARCHAR(150) dans `utilisateurs` +- [ ] Ajouter `pays_naissance` VARCHAR(100) dans `utilisateurs` +- [ ] Ajouter `date_acceptation_cgu` TIMESTAMPTZ dans `utilisateurs` +- [ ] Rendre `nir_chiffre` NOT NULL dans `assistantes_maternelles` +- [ ] Ajouter `date_obtention_agrement` DATE dans `assistantes_maternelles` +- [ ] CrĂ©er migration Prisma +- [ ] Tester migration sur BDD de dev + +--- + +### Ticket #2 : [BDD] Ajout table/champ prĂ©sentation dossier parent +**Estimation** : 30min +**Labels** : `bdd`, `p0-bloquant`, `cdc` + +**Description** : +Ajouter un champ pour stocker la prĂ©sentation du dossier parent (Ă©tape 4 de l'inscription). + +**TĂąches** : +- [ ] Ajouter `presentation_dossier` TEXT dans table `parents` +- [ ] CrĂ©er migration Prisma +- [ ] Tester migration + +--- + +### Ticket #3 : [BDD] Ajout gestion tokens crĂ©ation mot de passe +**Estimation** : 30min +**Labels** : `bdd`, `p0-bloquant`, `security` + +**Description** : +Ajouter les champs nĂ©cessaires pour gĂ©rer les tokens de crĂ©ation de mot de passe (workflow sans MDP lors inscription). + +**TĂąches** : +- [ ] Ajouter `password_reset_token` UUID dans `utilisateurs` +- [ ] Ajouter `password_reset_expires` TIMESTAMPTZ dans `utilisateurs` +- [ ] CrĂ©er migration Prisma +- [ ] Tester migration + +--- + +### Ticket #4 : [BDD] Ajout champ genre obligatoire enfants +**Estimation** : 30min +**Labels** : `bdd`, `p0-bloquant`, `cdc` + +**Description** : +Ajouter le champ `genre` obligatoire (H/F) dans la table `enfants`. + +**TĂąches** : +- [ ] Ajouter `genre` ENUM('H', 'F') NOT NULL dans `enfants` +- [ ] CrĂ©er migration Prisma +- [ ] Tester migration + +--- + +### Ticket #5 : [BDD] Supprimer champs obsolĂštes +**Estimation** : 30min +**Labels** : `bdd`, `p0-bloquant`, `cleanup` + +**Description** : +Supprimer les champs obsolĂštes identifiĂ©s lors de l'audit. + +**TĂąches** : +- [ ] Supprimer `mobile` dans `utilisateurs` (remplacĂ© par `telephone`) +- [ ] Supprimer `telephone_fixe` dans `utilisateurs` +- [ ] Supprimer `annee_experience` dans `assistantes_maternelles` +- [ ] Supprimer `specialite` dans `assistantes_maternelles` +- [ ] CrĂ©er migration Prisma +- [ ] Tester migration + +--- + +### Ticket #6 : [BDD] Table configuration systĂšme +**Estimation** : 1h +**Labels** : `bdd`, `p0-bloquant`, `on-premise` + +**Description** : +CrĂ©er la table `configuration` pour stocker les paramĂštres systĂšme (SMTP, app, sĂ©curitĂ©). + +**TĂąches** : +- [ ] CrĂ©er table `configuration` (clĂ©/valeur/type/catĂ©gorie) +- [ ] CrĂ©er index sur `cle` et `categorie` +- [ ] Seed valeurs par dĂ©faut (SMTP localhost, ports, etc.) +- [ ] CrĂ©er migration Prisma +- [ ] Tester migration + +**RĂ©fĂ©rence** : [21_CONFIGURATION-SYSTEME.md](./21_CONFIGURATION-SYSTEME.md) + +--- + +### Ticket #7 : [BDD] Tables documents lĂ©gaux & acceptations +**Estimation** : 2h +**Labels** : `bdd`, `p0-bloquant`, `rgpd`, `juridique` + +**Description** : +CrĂ©er les tables pour gĂ©rer les versions des documents lĂ©gaux (CGU/Privacy) et tracer les acceptations utilisateurs. + +**TĂąches** : +- [ ] CrĂ©er table `documents_legaux` (versioning + hash SHA-256) +- [ ] CrĂ©er table `acceptations_documents` (traçabilitĂ© RGPD) +- [ ] Modifier table `utilisateurs` (colonnes version acceptĂ©e) +- [ ] CrĂ©er index +- [ ] Seed documents gĂ©nĂ©riques v1 +- [ ] CrĂ©er migration Prisma +- [ ] Tester migration + +**RĂ©fĂ©rence** : [22_DOCUMENTS-LEGAUX.md](./22_DOCUMENTS-LEGAUX.md) + +--- + +## 🟠 PRIORITÉ 1 : Configuration SystĂšme (BLOQUANT) + +### Ticket #8 : [Backend] Service Configuration +**Estimation** : 4h +**Labels** : `backend`, `p1-bloquant`, `on-premise` + +**Description** : +CrĂ©er le service de configuration avec cache en mĂ©moire et chiffrement AES-256. + +**TĂąches** : +- [ ] CrĂ©er `ConfigService` avec cache Map +- [ ] ImplĂ©menter `get(key, defaultValue)` +- [ ] ImplĂ©menter `set(key, value, userId)` +- [ ] ImplĂ©menter `getByCategory(category)` +- [ ] ImplĂ©menter chiffrement/dĂ©chiffrement AES-256 +- [ ] ImplĂ©menter conversion de types (string/number/boolean/json) +- [ ] ImplĂ©menter `loadCache()` au dĂ©marrage +- [ ] Tests unitaires (mock repository) + +**RĂ©fĂ©rence** : [21_CONFIGURATION-SYSTEME.md](./21_CONFIGURATION-SYSTEME.md#service-configuration) + +--- + +### Ticket #9 : [Backend] API Configuration +**Estimation** : 3h +**Labels** : `backend`, `p1-bloquant`, `on-premise` + +**Description** : +CrĂ©er les endpoints REST pour gĂ©rer la configuration systĂšme. + +**TĂąches** : +- [ ] `GET /api/v1/configuration/:category` (super_admin only) +- [ ] `PATCH /api/v1/configuration/bulk` (mise Ă  jour multiple) +- [ ] `POST /api/v1/configuration/test-smtp` (test connexion + envoi email) +- [ ] Guards (super_admin only) +- [ ] Validation DTO +- [ ] Tests unitaires + +**RĂ©fĂ©rence** : [21_CONFIGURATION-SYSTEME.md](./21_CONFIGURATION-SYSTEME.md#apis-configuration) + +--- + +### Ticket #10 : [Backend] Guard Configuration Initiale +**Estimation** : 2h +**Labels** : `backend`, `p1-bloquant`, `on-premise` + +**Description** : +CrĂ©er un Guard/Middleware qui dĂ©tecte si la configuration initiale est incomplĂšte et force la redirection. + +**TĂąches** : +- [ ] CrĂ©er `SetupGuard` +- [ ] VĂ©rifier `setup_completed` dans ConfigService +- [ ] Redirection forcĂ©e vers `/admin/setup` si false +- [ ] Exemption pour routes publiques (login, register) +- [ ] Exemption pour route `/admin/setup` +- [ ] Tests unitaires + +**RĂ©fĂ©rence** : [21_CONFIGURATION-SYSTEME.md](./21_CONFIGURATION-SYSTEME.md#workflow-setup-initial) + +--- + +### Ticket #11 : [Backend] Adaptation MailService pour config dynamique +**Estimation** : 3h +**Labels** : `backend`, `p1-bloquant`, `on-premise`, `email` + +**Description** : +Adapter le service email pour utiliser la configuration dynamique depuis la BDD au lieu de variables d'environnement hardcodĂ©es. + +**TĂąches** : +- [ ] Remplacer `mail.ptits-pas.fr` hardcodĂ© par `ConfigService.get('smtp_host')` +- [ ] Lecture config SMTP depuis BDD (host, port, secure, auth, user, pass) +- [ ] Lecture expĂ©diteur depuis BDD (from_name, from_address) +- [ ] RecrĂ©ation du transport Nodemailer dynamique +- [ ] Tests unitaires (mock ConfigService) + +**⚠ IMPORTANT** : Ce ticket corrige tous les hardcoding de `mail.ptits-pas.fr` dans le code. + +--- + +### Ticket #12 : [Frontend] Écran Configuration Initiale (Setup Wizard) +**Estimation** : 6h +**Labels** : `frontend`, `p1-bloquant`, `on-premise` + +**Description** : +CrĂ©er l'Ă©cran de configuration initiale (Setup Wizard) accessible Ă  la premiĂšre connexion du super admin. + +**TĂąches** : +- [ ] Page `/admin/setup` (accessible uniquement si config incomplĂšte) +- [ ] Formulaire multi-onglets (Email / Application / AvancĂ©) +- [ ] Onglet 1 : Configuration Email (SMTP, auth, expĂ©diteur) +- [ ] Onglet 2 : Personnalisation (nom app, URL, logo) +- [ ] Onglet 3 : ParamĂštres avancĂ©s (durĂ©es tokens, upload max) +- [ ] Bouton "Tester la connexion SMTP" (appel API + feedback) +- [ ] Validation cĂŽtĂ© client +- [ ] Sauvegarde (appel API `PATCH /configuration/bulk`) +- [ ] Message succĂšs + redirection dashboard + +**RĂ©fĂ©rence** : [21_CONFIGURATION-SYSTEME.md](./21_CONFIGURATION-SYSTEME.md#interface-admin) + +--- + +### Ticket #13 : [Frontend] Écran ParamĂštres (accĂšs permanent) +**Estimation** : 2h +**Labels** : `frontend`, `p1-bloquant`, `on-premise` + +**Description** : +CrĂ©er l'Ă©cran de paramĂštres accessible depuis le menu admin (mĂȘme interface que Setup Wizard). + +**TĂąches** : +- [ ] Page `/admin/parametres` (accessible depuis menu admin) +- [ ] MĂȘme interface que Setup Wizard +- [ ] Affichage valeurs actuelles +- [ ] Modification et sauvegarde + +--- + +### Ticket #14 : [Doc] Documentation configuration on-premise +**Estimation** : 2h +**Labels** : `documentation`, `p1-bloquant`, `on-premise` + +**Description** : +RĂ©diger la documentation pour aider les collectivitĂ©s Ă  configurer l'application. + +**TĂąches** : +- [ ] Guide d'installation pour collectivitĂ©s +- [ ] Liste des paramĂštres SMTP courants (Office 365, Gmail, serveurs locaux) +- [ ] Exemples de configuration +- [ ] Troubleshooting SMTP +- [ ] Variables `.env` requises +- [ ] GĂ©nĂ©ration secrets (JWT, encryption key) + +**RĂ©fĂ©rence** : [21_CONFIGURATION-SYSTEME.md](./21_CONFIGURATION-SYSTEME.md) + +--- + +## 🟱 PRIORITÉ 2 : Backend - Authentification & Gestion Comptes + +### Ticket #15 : [Backend] API CrĂ©ation gestionnaire +**Estimation** : 3h +**Labels** : `backend`, `p2`, `auth` + +**Description** : +CrĂ©er l'endpoint pour permettre au super admin de crĂ©er des gestionnaires. + +**TĂąches** : +- [ ] Endpoint `POST /api/v1/gestionnaires` +- [ ] Validation DTO +- [ ] Hash bcrypt +- [ ] Flag `changement_mdp_obligatoire = TRUE` +- [ ] Guards (super_admin only) +- [ ] Email de notification (utiliser MailService avec config dynamique) +- [ ] Tests unitaires + +**RĂ©fĂ©rence** : [20_WORKFLOW-CREATION-COMPTE.md](./20_WORKFLOW-CREATION-COMPTE.md#Ă©tape-2--crĂ©ation-dun-gestionnaire) + +--- + +### Ticket #16 : [Backend] API Inscription Parent (Ă©tape 1 - Parent 1) +**Estimation** : 4h +**Labels** : `backend`, `p2`, `auth`, `cdc` + +**Description** : +CrĂ©er l'endpoint d'inscription Parent (Ă©tape 1/6 : informations Parent 1). + +**TĂąches** : +- [ ] Endpoint `POST /api/v1/auth/register/parent` +- [ ] Validation DTO (sans mot de passe) +- [ ] GĂ©nĂ©ration token crĂ©ation MDP (UUID) +- [ ] DurĂ©e token : Lire depuis `ConfigService.get('password_reset_token_expiry_days')` +- [ ] CrĂ©ation utilisateur + entitĂ© parent +- [ ] Statut `en_attente` +- [ ] Tests unitaires + +**RĂ©fĂ©rence** : [20_WORKFLOW-CREATION-COMPTE.md](./20_WORKFLOW-CREATION-COMPTE.md#Ă©tape-3--inscription-dun-parent) + +--- + +### Ticket #17 : [Backend] API Inscription Parent (Ă©tape 2 - Parent 2) +**Estimation** : 2h +**Labels** : `backend`, `p2`, `auth`, `cdc` + +**Description** : +Ajouter la gestion du co-parent (Parent 2) dans l'endpoint d'inscription. + +**TĂąches** : +- [ ] Ajout gestion co-parent dans endpoint +- [ ] Relation `id_co_parent` dans table `parents` +- [ ] GĂ©nĂ©ration token pour Parent 2 +- [ ] Tests unitaires + +--- + +### Ticket #18 : [Backend] API Inscription Parent (Ă©tape 3 - Enfants) +**Estimation** : 4h +**Labels** : `backend`, `p2`, `auth`, `cdc`, `upload` + +**Description** : +CrĂ©er l'endpoint pour ajouter des enfants lors de l'inscription parent. + +**TĂąches** : +- [ ] Endpoint `POST /api/v1/enfants` +- [ ] Upload photo (Multer) +- [ ] Taille max : Lire depuis `ConfigService.get('max_upload_size_mb')` +- [ ] Validation genre obligatoire (H/F) +- [ ] Gestion enfant Ă  naĂźtre vs nĂ© +- [ ] Rattachement aux 2 parents (si Parent 2 existe) +- [ ] Tests unitaires + +--- + +### Ticket #19 : [Backend] API Inscription Parent (Ă©tape 4-6 - Finalisation) +**Estimation** : 2h +**Labels** : `backend`, `p2`, `auth`, `cdc` + +**Description** : +Finaliser l'inscription parent (prĂ©sentation, CGU, rĂ©capitulatif). + +**TĂąches** : +- [ ] Enregistrement prĂ©sentation dossier +- [ ] Enregistrement acceptation CGU avec horodatage +- [ ] Endpoint rĂ©capitulatif +- [ ] Tests unitaires + +--- + +### Ticket #20 : [Backend] API Inscription AM (panneau 1 - IdentitĂ©) +**Estimation** : 4h +**Labels** : `backend`, `p2`, `auth`, `cdc`, `upload` + +**Description** : +CrĂ©er l'endpoint d'inscription Assistante Maternelle (panneau 1/5 : identitĂ©). + +**TĂąches** : +- [ ] Endpoint `POST /api/v1/auth/register/am` +- [ ] Upload photo (Multer) +- [ ] Taille max : Lire depuis ConfigService +- [ ] Consentement photo avec horodatage +- [ ] GĂ©nĂ©ration token crĂ©ation MDP +- [ ] Tests unitaires + +**RĂ©fĂ©rence** : [20_WORKFLOW-CREATION-COMPTE.md](./20_WORKFLOW-CREATION-COMPTE.md#Ă©tape-3bis--inscription-dune-assistante-maternelle) + +--- + +### Ticket #21 : [Backend] API Inscription AM (panneau 2 - Infos pro) +**Estimation** : 3h +**Labels** : `backend`, `p2`, `auth`, `cdc` + +**Description** : +Ajouter les informations professionnelles de l'AM (panneau 2/5). + +**TĂąches** : +- [ ] Validation NIR (15 chiffres obligatoire) +- [ ] Date/lieu de naissance +- [ ] NumĂ©ro agrĂ©ment + date obtention +- [ ] CapacitĂ© accueil +- [ ] Tests unitaires + +--- + +### Ticket #22 : [Backend] API CrĂ©ation mot de passe +**Estimation** : 3h +**Labels** : `backend`, `p2`, `auth`, `security` + +**Description** : +CrĂ©er les endpoints pour permettre aux utilisateurs de crĂ©er leur mot de passe via le lien reçu par email. + +**TĂąches** : +- [ ] Endpoint `GET /api/v1/auth/verify-token?token=` +- [ ] Endpoint `POST /api/v1/auth/create-password` +- [ ] Validation token (existe, non expirĂ©, non utilisĂ©) +- [ ] Hash bcrypt + suppression token +- [ ] Activation compte (`statut = actif`) +- [ ] Tests unitaires + +**RĂ©fĂ©rence** : [20_WORKFLOW-CREATION-COMPTE.md](./20_WORKFLOW-CREATION-COMPTE.md#Ă©tape-7--crĂ©ation-du-mot-de-passe) + +--- + +### Ticket #23 : [Backend] API Liste comptes en attente +**Estimation** : 2h +**Labels** : `backend`, `p2`, `gestionnaire` + +**Description** : +CrĂ©er les endpoints pour lister les comptes en attente de validation. + +**TĂąches** : +- [ ] Endpoint `GET /api/v1/parents?statut=en_attente` +- [ ] Endpoint `GET /api/v1/assistantes-maternelles?statut=en_attente` +- [ ] Guards (gestionnaire/admin only) +- [ ] Filtres + pagination +- [ ] Tests unitaires + +**RĂ©fĂ©rence** : [20_WORKFLOW-CREATION-COMPTE.md](./20_WORKFLOW-CREATION-COMPTE.md#Ă©tape-4--consultation-des-demandes-par-le-gestionnaire) + +--- + +### Ticket #24 : [Backend] API Validation/Refus comptes +**Estimation** : 3h +**Labels** : `backend`, `p2`, `gestionnaire` + +**Description** : +CrĂ©er les endpoints pour valider ou refuser les comptes en attente. + +**TĂąches** : +- [ ] Endpoint `PATCH /api/v1/users/{id}/valider` +- [ ] Endpoint `PATCH /api/v1/users/{id}/suspendre` +- [ ] CrĂ©ation entrĂ©e table `validations` +- [ ] Guards (gestionnaire/admin only) +- [ ] Tests unitaires + +**RĂ©fĂ©rence** : [20_WORKFLOW-CREATION-COMPTE.md](./20_WORKFLOW-CREATION-COMPTE.md#Ă©tape-5--validation-dun-compte) + +--- + +### Ticket #25 : [Backend] Service Email - Installation Nodemailer +**Estimation** : 2h +**Labels** : `backend`, `p2`, `email` + +**Description** : +Installer et configurer Nodemailer pour l'envoi d'emails. + +**TĂąches** : +- [ ] Installation Nodemailer + types +- [ ] Configuration de base +- [ ] Service `MailService` avec mĂ©thodes de base +- [ ] Tests unitaires (mock SMTP) + +--- + +### Ticket #26 : [Backend] Templates Email - Validation +**Estimation** : 3h +**Labels** : `backend`, `p2`, `email` + +**Description** : +CrĂ©er les templates d'emails pour la validation des comptes (avec lien crĂ©ation MDP). + +**TĂąches** : +- [ ] Template Parent 1 (crĂ©ation MDP) +- [ ] URL app : Lire depuis `ConfigService.get('app_url')` +- [ ] Nom app : Lire depuis `ConfigService.get('app_name')` +- [ ] ExpĂ©diteur : Lire depuis ConfigService +- [ ] Template Parent 2 (co-parent crĂ©ation MDP) +- [ ] Template AM (crĂ©ation MDP) +- [ ] IntĂ©gration Handlebars +- [ ] Tests d'envoi + +**RĂ©fĂ©rence** : [20_WORKFLOW-CREATION-COMPTE.md](./20_WORKFLOW-CREATION-COMPTE.md#Ă©tape-6--rĂ©ception-de-la-notification) + +--- + +### Ticket #27 : [Backend] Templates Email - Refus +**Estimation** : 1h +**Labels** : `backend`, `p2`, `email` + +**Description** : +CrĂ©er le template d'email pour le refus de compte. + +**TĂąches** : +- [ ] Template refus gĂ©nĂ©rique +- [ ] Variables dynamiques : Nom app, URL, expĂ©diteur depuis ConfigService +- [ ] IntĂ©gration dans endpoint suspendre +- [ ] Tests d'envoi + +--- + +### Ticket #28 : [Backend] Connexion - VĂ©rification statut +**Estimation** : 2h +**Labels** : `backend`, `p2`, `auth` + +**Description** : +Modifier l'endpoint de connexion pour bloquer les comptes en attente ou suspendus. + +**TĂąches** : +- [ ] Modifier endpoint `POST /api/v1/auth/login` +- [ ] Bloquer si `statut = en_attente` +- [ ] Bloquer si `statut = suspendu` +- [ ] Messages d'erreur explicites +- [ ] Tests unitaires + +**RĂ©fĂ©rence** : [20_WORKFLOW-CREATION-COMPTE.md](./20_WORKFLOW-CREATION-COMPTE.md#Ă©tape-8--connexion-de-lutilisateur-validĂ©) + +--- + +### Ticket #29 : [Backend] Changement MDP obligatoire premiĂšre connexion +**Estimation** : 2h +**Labels** : `backend`, `p2`, `auth`, `security` + +**Description** : +ImplĂ©menter le changement de mot de passe obligatoire pour les gestionnaires/admins Ă  la premiĂšre connexion. + +**TĂąches** : +- [ ] Endpoint `POST /api/v1/auth/change-password-required` +- [ ] VĂ©rification flag `changement_mdp_obligatoire` +- [ ] Mise Ă  jour flag aprĂšs changement +- [ ] Tests unitaires + +--- + +### Ticket #30 : [Backend] Service Documents LĂ©gaux +**Estimation** : 4h +**Labels** : `backend`, `p2`, `juridique`, `rgpd` + +**Description** : +CrĂ©er le service de gestion des documents lĂ©gaux (CGU/Privacy) avec versioning. + +**TĂąches** : +- [ ] `DocumentsLegauxService` complet +- [ ] Upload avec versioning auto-incrĂ©mentĂ© +- [ ] Calcul hash SHA-256 +- [ ] Activation/dĂ©sactivation versions +- [ ] MĂ©thode `getDocumentsActifs()` +- [ ] MĂ©thode `uploadNouvelleVersion()` +- [ ] MĂ©thode `activerVersion()` +- [ ] MĂ©thode `listerVersions()` +- [ ] Tests unitaires + +**RĂ©fĂ©rence** : [22_DOCUMENTS-LEGAUX.md](./22_DOCUMENTS-LEGAUX.md#service-documents-lĂ©gaux) + +--- + +### Ticket #31 : [Backend] API Documents LĂ©gaux +**Estimation** : 3h +**Labels** : `backend`, `p2`, `juridique`, `rgpd` + +**Description** : +CrĂ©er les endpoints REST pour gĂ©rer les documents lĂ©gaux. + +**TĂąches** : +- [ ] `GET /api/v1/documents-legaux/actifs` (public) +- [ ] `GET /api/v1/documents-legaux/:type/versions` (admin) +- [ ] `POST /api/v1/documents-legaux` (upload, admin only) +- [ ] `PATCH /api/v1/documents-legaux/:id/activer` (admin only) +- [ ] `GET /api/v1/documents-legaux/:id/download` (public) +- [ ] Guards + validation +- [ ] Tests unitaires + +**RĂ©fĂ©rence** : [22_DOCUMENTS-LEGAUX.md](./22_DOCUMENTS-LEGAUX.md#apis) + +--- + +### Ticket #32 : [Backend] TraçabilitĂ© acceptations documents +**Estimation** : 2h +**Labels** : `backend`, `p2`, `rgpd` + +**Description** : +Enregistrer les acceptations de documents lĂ©gaux lors de l'inscription (traçabilitĂ© RGPD). + +**TĂąches** : +- [ ] Enregistrement dans `acceptations_documents` lors inscription +- [ ] Capture IP + User-Agent +- [ ] API `GET /api/v1/users/:id/acceptations` (admin) +- [ ] Tests unitaires + +**RĂ©fĂ©rence** : [22_DOCUMENTS-LEGAUX.md](./22_DOCUMENTS-LEGAUX.md#workflow-acceptation-utilisateur) + +--- + +## 🟱 PRIORITÉ 3 : Frontend - Interfaces + +### Ticket #33 : [Frontend] Écran CrĂ©ation Gestionnaire +**Estimation** : 3h +**Labels** : `frontend`, `p3`, `auth` + +**Description** : +CrĂ©er l'Ă©cran de crĂ©ation de gestionnaire (super admin uniquement). + +**TĂąches** : +- [ ] Formulaire (nom, prĂ©nom, email, MDP) +- [ ] Validation cĂŽtĂ© client +- [ ] Appel API `POST /gestionnaires` +- [ ] Messages succĂšs/erreur + +--- + +### Ticket #34 : [Frontend] Inscription Parent - Étape 1 (Parent 1) +**Estimation** : 3h +**Labels** : `frontend`, `p3`, `auth`, `cdc` + +**Description** : +CrĂ©er le formulaire d'inscription parent - Ă©tape 1/6 (informations Parent 1). + +**TĂąches** : +- [ ] Formulaire identitĂ© Parent 1 +- [ ] Validation cĂŽtĂ© client +- [ ] Pas de champ mot de passe +- [ ] Navigation vers Ă©tape 2 + +--- + +### Ticket #35 : [Frontend] Inscription Parent - Étape 2 (Parent 2) +**Estimation** : 3h +**Labels** : `frontend`, `p3`, `auth`, `cdc` + +**Description** : +CrĂ©er le formulaire d'inscription parent - Ă©tape 2/6 (informations Parent 2 optionnel). + +**TĂąches** : +- [ ] Question "Ajouter un second parent ?" +- [ ] Formulaire identitĂ© Parent 2 (conditionnel) +- [ ] Checkbox "MĂȘme adresse" +- [ ] Navigation vers Ă©tape 3 + +--- + +### Ticket #36 : [Frontend] Inscription Parent - Étape 3 (Enfants) +**Estimation** : 4h +**Labels** : `frontend`, `p3`, `auth`, `cdc`, `upload` + +**Description** : +CrĂ©er le formulaire d'inscription parent - Ă©tape 3/6 (informations enfants). + +**TĂąches** : +- [ ] Question "Enfant dĂ©jĂ  nĂ© ?" +- [ ] Formulaire enfant (prĂ©nom, date, genre H/F obligatoire) +- [ ] Upload photo (si nĂ©) +- [ ] Validation taille (5MB) +- [ ] Bouton "Ajouter un autre enfant" +- [ ] Navigation vers Ă©tape 4 + +--- + +### Ticket #37 : [Frontend] Inscription Parent - Étapes 4-6 (Finalisation) +**Estimation** : 4h +**Labels** : `frontend`, `p3`, `auth`, `cdc` + +**Description** : +CrĂ©er les Ă©tapes finales de l'inscription parent (prĂ©sentation, CGU, rĂ©capitulatif). + +**TĂąches** : +- [ ] Étape 4 : Textarea prĂ©sentation +- [ ] Étape 5 : Checkbox CGU + liens PDF +- [ ] Étape 6 : RĂ©capitulatif complet +- [ ] Bouton "Modifier" / "Valider" +- [ ] Appel API final +- [ ] Message confirmation + +--- + +### Ticket #38 : [Frontend] Inscription AM - Panneau 1 (IdentitĂ©) +**Estimation** : 3h +**Labels** : `frontend`, `p3`, `auth`, `cdc`, `upload` + +**Description** : +CrĂ©er le formulaire d'inscription AM - panneau 1/5 (identitĂ©). + +**TĂąches** : +- [ ] Formulaire identitĂ© +- [ ] Upload photo +- [ ] Checkbox consentement photo +- [ ] Pas de champ mot de passe +- [ ] Navigation vers panneau 2 + +--- + +### Ticket #39 : [Frontend] Inscription AM - Panneau 2 (Infos pro) +**Estimation** : 3h +**Labels** : `frontend`, `p3`, `auth`, `cdc` + +**Description** : +CrĂ©er le formulaire d'inscription AM - panneau 2/5 (informations professionnelles). + +**TĂąches** : +- [ ] Formulaire infos pro +- [ ] Champ NIR (15 chiffres, validation) +- [ ] Date/lieu naissance +- [ ] AgrĂ©ment + date obtention +- [ ] Navigation vers prĂ©sentation + +--- + +### Ticket #40 : [Frontend] Inscription AM - Finalisation +**Estimation** : 3h +**Labels** : `frontend`, `p3`, `auth`, `cdc` + +**Description** : +CrĂ©er les Ă©tapes finales de l'inscription AM (prĂ©sentation, CGU, rĂ©capitulatif). + +**TĂąches** : +- [ ] Textarea prĂ©sentation +- [ ] Checkbox CGU + liens PDF +- [ ] RĂ©capitulatif (NIR masquĂ©) +- [ ] Appel API final +- [ ] Message confirmation + +--- + +### Ticket #41 : [Frontend] Écran CrĂ©ation Mot de Passe +**Estimation** : 3h +**Labels** : `frontend`, `p3`, `auth` + +**Description** : +CrĂ©er l'Ă©cran de crĂ©ation de mot de passe (lien reçu par email). + +**TĂąches** : +- [ ] Page `/create-password?token=` +- [ ] VĂ©rification token (appel API) +- [ ] Formulaire MDP + confirmation +- [ ] Validation cĂŽtĂ© client (8 car, 1 maj, 1 chiffre) +- [ ] Appel API crĂ©ation MDP +- [ ] Redirection vers login + +--- + +### Ticket #42 : [Frontend] Dashboard Gestionnaire - Structure +**Estimation** : 2h +**Labels** : `frontend`, `p3`, `gestionnaire` + +**Description** : +CrĂ©er la structure du dashboard gestionnaire avec 2 onglets. + +**TĂąches** : +- [ ] Layout avec 2 onglets (Parents / AM) +- [ ] Navigation entre onglets +- [ ] État vide ("Aucune demande") + +--- + +### Ticket #43 : [Frontend] Dashboard Gestionnaire - Liste Parents +**Estimation** : 4h +**Labels** : `frontend`, `p3`, `gestionnaire` + +**Description** : +CrĂ©er la liste des parents en attente de validation. + +**TĂąches** : +- [ ] Appel API `GET /parents?statut=en_attente` +- [ ] Affichage liste avec cartes +- [ ] Boutons Valider/Refuser +- [ ] Modale confirmation +- [ ] RafraĂźchissement aprĂšs action + +--- + +### Ticket #44 : [Frontend] Dashboard Gestionnaire - Liste AM +**Estimation** : 4h +**Labels** : `frontend`, `p3`, `gestionnaire` + +**Description** : +CrĂ©er la liste des assistantes maternelles en attente de validation. + +**TĂąches** : +- [ ] Appel API `GET /assistantes-maternelles?statut=en_attente` +- [ ] Affichage liste avec cartes +- [ ] NIR masquĂ© +- [ ] Boutons Valider/Refuser +- [ ] Modale confirmation +- [ ] RafraĂźchissement aprĂšs action + +--- + +### Ticket #45 : [Frontend] Écran Changement MDP Obligatoire +**Estimation** : 2h +**Labels** : `frontend`, `p3`, `auth`, `security` + +**Description** : +CrĂ©er l'Ă©cran de changement de mot de passe obligatoire (premiĂšre connexion gestionnaire/admin). + +**TĂąches** : +- [ ] DĂ©tection flag `changement_mdp_obligatoire` +- [ ] Modale bloquante aprĂšs login +- [ ] Formulaire MDP actuel + nouveau MDP +- [ ] Appel API +- [ ] Redirection vers dashboard + +--- + +### Ticket #46 : [Frontend] Gestion Erreurs & Messages +**Estimation** : 2h +**Labels** : `frontend`, `p3`, `ux` + +**Description** : +CrĂ©er un systĂšme de gestion des erreurs et messages utilisateur. + +**TĂąches** : +- [ ] Intercepteur HTTP pour erreurs API +- [ ] Snackbars/Toasts pour succĂšs/erreurs +- [ ] Messages explicites (compte en attente, refusĂ©, etc.) + +--- + +### Ticket #47 : [Frontend] Écran Gestion Documents LĂ©gaux (Admin) +**Estimation** : 5h +**Labels** : `frontend`, `p3`, `juridique`, `admin` + +**Description** : +CrĂ©er l'Ă©cran de gestion des documents lĂ©gaux (CGU/Privacy) pour l'admin. + +**TĂąches** : +- [ ] Onglets CGU / Privacy +- [ ] Affichage version active +- [ ] Upload nouvelle version (PDF uniquement) +- [ ] PrĂ©visualisation PDF +- [ ] Activation version +- [ ] Historique versions + +**RĂ©fĂ©rence** : [22_DOCUMENTS-LEGAUX.md](./22_DOCUMENTS-LEGAUX.md#interface-admin) + +--- + +### Ticket #48 : [Frontend] Affichage dynamique CGU lors inscription +**Estimation** : 2h +**Labels** : `frontend`, `p3`, `juridique` + +**Description** : +Afficher dynamiquement les CGU/Privacy lors de l'inscription (avec numĂ©ro de version). + +**TĂąches** : +- [ ] Appel API `GET /documents-legaux/actifs` +- [ ] Liens vers PDF avec numĂ©ro de version +- [ ] Envoi version acceptĂ©e lors inscription + +--- + +## đŸ”” PRIORITÉ 4 : Tests & Documentation + +### Ticket #49 : [Tests] Tests unitaires Backend +**Estimation** : 8h +**Labels** : `tests`, `p4`, `backend` + +**Description** : +CrĂ©er les tests unitaires pour tous les services et controllers backend. + +**TĂąches** : +- [ ] Tests services (auth, user, mail, config, documents) +- [ ] Tests controllers +- [ ] Couverture > 80% +- [ ] Mocks (repository, ConfigService, MailService) + +--- + +### Ticket #50 : [Tests] Tests intĂ©gration Backend +**Estimation** : 5h +**Labels** : `tests`, `p4`, `backend` + +**Description** : +CrĂ©er les tests d'intĂ©gration pour les workflows complets. + +**TĂąches** : +- [ ] Workflow complet Parent +- [ ] Workflow complet AM +- [ ] Workflow refus +- [ ] Workflow configuration initiale + +--- + +### Ticket #51 : [Tests] Tests E2E Frontend +**Estimation** : 8h +**Labels** : `tests`, `p4`, `frontend` + +**Description** : +CrĂ©er les tests end-to-end pour les parcours utilisateurs. + +**TĂąches** : +- [ ] Workflow configuration initiale +- [ ] Workflow crĂ©ation gestionnaire +- [ ] Workflow inscription parent +- [ ] Workflow inscription AM +- [ ] Workflow dashboard gestionnaire + +--- + +### Ticket #52 : [Doc] Documentation API OpenAPI/Swagger +**Estimation** : 3h +**Labels** : `documentation`, `p4`, `api` + +**Description** : +GĂ©nĂ©rer et documenter l'API avec Swagger/OpenAPI. + +**TĂąches** : +- [ ] GĂ©nĂ©ration Swagger depuis NestJS +- [ ] Documentation tous les endpoints +- [ ] Exemples de requĂȘtes/rĂ©ponses +- [ ] SchĂ©mas DTO + +--- + +## ⚠ CRITIQUES : Upload, Emails, Infra, Doc + +### Ticket #53 : [Backend] Service Upload & Stockage fichiers +**Estimation** : 3h +**Labels** : `backend`, `critique`, `upload` + +**Description** : +CrĂ©er le service de gestion des uploads de fichiers (photos). + +**TĂąches** : +- [ ] Multer pour upload +- [ ] Validation (type MIME, taille max depuis config) +- [ ] Stockage dans `/uploads/photos/` +- [ ] Nettoyage fichiers orphelins +- [ ] Tests unitaires + +--- + +### Ticket #54 : [Backend] API TĂ©lĂ©chargement photos sĂ©curisĂ© +**Estimation** : 2h +**Labels** : `backend`, `critique`, `upload`, `security` + +**Description** : +CrĂ©er l'endpoint sĂ©curisĂ© pour tĂ©lĂ©charger les photos. + +**TĂąches** : +- [ ] Endpoint `GET /api/v1/files/:id` +- [ ] VĂ©rification droits (parent voit ses enfants, AM voit son profil, gestionnaire voit tout) +- [ ] Stream fichier +- [ ] Tests unitaires + +--- + +### Ticket #55 : [Backend] Service Logging (Winston) +**Estimation** : 3h +**Labels** : `backend`, `critique`, `monitoring` + +**Description** : +Mettre en place un systĂšme de logs centralisĂ© avec Winston pour faciliter le debugging et le monitoring. + +**TĂąches** : +- [ ] Installation Winston + transports +- [ ] Configuration (console + fichier avec rotation daily) +- [ ] Logs applicatifs (info, warn, error) +- [ ] Logs emails (succĂšs/Ă©chec SMTP avec dĂ©tails) +- [ ] Logs connexions (qui se connecte quand, IP) +- [ ] Logs validations (qui valide quoi, timestamp) +- [ ] Rotation des logs (daily, max 30 jours) +- [ ] Tests + +--- + +### Ticket #56 : [Frontend] Écran Logs Admin (optionnel v1.1) +**Estimation** : 4h +**Labels** : `frontend`, `p3`, `monitoring`, `admin` + +**Description** : +CrĂ©er un Ă©cran pour consulter les logs depuis l'interface admin (optionnel Phase 1.1). + +**TĂąches** : +- [ ] Page `/admin/logs` (super_admin only) +- [ ] Filtres (date, niveau, type) +- [ ] Pagination +- [ ] Recherche +- [ ] Export CSV + +**Note** : Peut ĂȘtre fait en Phase 1.1 si le temps le permet + +--- + +### Ticket #57 : [Infra] Volume Docker pour uploads +**Estimation** : 30min +**Labels** : `infra`, `critique`, `docker` + +**Description** : +Ajouter un volume Docker pour persister les fichiers uploadĂ©s. + +**TĂąches** : +- [ ] Ajout volume `/uploads` dans `docker-compose.yml` +- [ ] Persistance des fichiers uploadĂ©s +- [ ] Test redĂ©marrage conteneur + +--- + +### Ticket #58 : [Infra] Volume Docker pour documents lĂ©gaux +**Estimation** : 30min +**Labels** : `infra`, `critique`, `docker` + +**Description** : +Ajouter un volume Docker pour persister les documents lĂ©gaux (CGU/Privacy). + +**TĂąches** : +- [ ] Ajout volume `/documents/legaux` dans `docker-compose.yml` +- [ ] Persistance des PDF +- [ ] Test redĂ©marrage conteneur + +--- + +### Ticket #59 : [Doc] Guide installation & configuration +**Estimation** : 3h +**Labels** : `documentation`, `critique`, `on-premise` + +**Description** : +RĂ©diger le guide complet d'installation et de configuration pour les collectivitĂ©s. + +**TĂąches** : +- [ ] Variables `.env` requises +- [ ] GĂ©nĂ©ration secrets (JWT, encryption) +- [ ] Configuration SMTP courante +- [ ] Troubleshooting +- [ ] Commandes Docker Compose +- [ ] Backup/Restauration + +--- + +## 📚 JURIDIQUE & CDC + +### Ticket #60 : [Doc] Amendement CDC v1.4 - Suppression SMS +**Estimation** : 30min +**Labels** : `documentation`, `cdc` + +**Description** : +Amender le Cahier des Charges pour supprimer la mention des notifications SMS (pas de plus-value identifiĂ©e). + +**TĂąches** : +- [ ] Modifier CDC Section 3.1.6 (Notifications parent) +- [ ] Modifier CDC Section 3.2.5 (Notifications AM) +- [ ] Remplacer "Email OU SMS" par "Email" +- [ ] Supprimer toute mention de SMS +- [ ] IncrĂ©menter version → v1.4 +- [ ] Ajouter changelog : "Suppression notifications SMS (Email uniquement)" + +--- + +### Ticket #61 : [Doc] RĂ©daction CGU/Privacy gĂ©nĂ©riques v1 +**Estimation** : 8h +**Labels** : `documentation`, `juridique`, `rgpd` + +**Description** : +RĂ©diger les documents lĂ©gaux gĂ©nĂ©riques (CGU et Politique de confidentialitĂ©) conformes RGPD. + +**TĂąches** : +- [ ] RĂ©daction CGU gĂ©nĂ©riques (avec aide juriste) +- [ ] RĂ©daction Privacy gĂ©nĂ©riques (RGPD compliant) +- [ ] Conversion en PDF +- [ ] Placement dans `/documents/legaux/` +- [ ] Calcul hash SHA-256 + +**⚠ IMPORTANT** : NĂ©cessite l'intervention d'un juriste. + +--- + +## 📊 RĂ©sumĂ© final + +**Total** : 61 tickets +**Estimation** : ~173h de dĂ©veloppement + +### Par prioritĂ© +- **P0 (Bloquant BDD)** : 7 tickets (~5h) +- **P1 (Bloquant Config)** : 7 tickets (~22h) +- **P2 (Backend)** : 18 tickets (~50h) +- **P3 (Frontend)** : 17 tickets (~52h) ← +1 ticket logs admin +- **P4 (Tests/Doc)** : 4 tickets (~24h) +- **Critiques** : 6 tickets (~13h) ← -2 email, +1 logs, +1 CDC +- **Juridique** : 1 ticket (~8h) + +### Par domaine +- **BDD** : 7 tickets +- **Backend** : 23 tickets ← +1 logs +- **Frontend** : 17 tickets ← +1 logs admin +- **Tests** : 3 tickets +- **Documentation** : 5 tickets ← +1 amendement CDC +- **Infra** : 2 tickets +- **Juridique** : 1 ticket + +### Modifications par rapport Ă  la version initiale +- ❌ **SupprimĂ©** : Tickets "Renvoyer email validation" (backend + frontend) - Pas prioritaire +- ✅ **AjoutĂ©** : Ticket #55 "Service Logging Winston" - Monitoring essentiel +- ✅ **AjoutĂ©** : Ticket #56 "Écran Logs Admin" - Optionnel Phase 1.1 +- ✅ **AjoutĂ©** : Ticket #60 "Amendement CDC v1.4 - Suppression SMS" - Simplification + +--- + +**DerniĂšre mise Ă  jour** : 25 Novembre 2025 +**Version** : 1.0 +**Statut** : ✅ PrĂȘt pour crĂ©ation dans Gitea + diff --git a/docs/24_DECISIONS-PROJET.md b/docs/24_DECISIONS-PROJET.md new file mode 100644 index 0000000..21b6f33 --- /dev/null +++ b/docs/24_DECISIONS-PROJET.md @@ -0,0 +1,568 @@ +# 📋 DĂ©cisions Projet - P'titsPas + +**Version** : 1.0 +**Date** : 25 Novembre 2025 +**Auteur** : Équipe PtitsPas + +--- + +## 🎯 Objectif de ce document + +Ce document trace toutes les **dĂ©cisions importantes** prises lors de la conception du projet P'titsPas. Il sert de rĂ©fĂ©rence pour comprendre les choix techniques et fonctionnels. + +--- + +## 📊 DĂ©cisions Architecture + +### 1. Mono-repo vs Multi-repo + +**DĂ©cision** : ✅ **Mono-repo** + +**Justification** : +- Code cohĂ©rent dans un seul dĂ©pĂŽt Git +- Commits atomiques (frontend + backend + BDD en mĂȘme temps) +- CI/CD simplifiĂ© (un seul webhook) +- Facilite le travail collaboratif + +**Structure** : +``` +ptitspas-app/ +├── frontend/ # Application Flutter +├── backend/ # API NestJS +├── database/ # Migrations SQL/Prisma +├── api-contracts/ # Contrats OpenAPI + Prisma +├── docs/ # Documentation +└── docker-compose.yml # Orchestration +``` + +--- + +### 2. DĂ©ploiement On-Premise + +**DĂ©cision** : ✅ **Application on-premise avec configuration dynamique** + +**Justification** : +- Chaque collectivitĂ© a son infrastructure (SMTP, domaines, ports) +- Autonomie totale (pas de dĂ©pendance Ă  notre infra) +- ConformitĂ© aux politiques IT locales +- SĂ©curitĂ© (donnĂ©es restent dans le SI de la collectivitĂ©) + +**Solution technique** : +- Table `configuration` en BDD (clĂ©/valeur) +- Setup Wizard Ă  la premiĂšre connexion +- Configuration SMTP dynamique +- Personnalisation (nom app, logo, URL) + +**RĂ©fĂ©rence** : [21_CONFIGURATION-SYSTEME.md](./21_CONFIGURATION-SYSTEME.md) + +--- + +### 3. Gestion des fichiers uploadĂ©s + +**DĂ©cision** : ✅ **SystĂšme de fichiers local avec volume Docker** + +**Justification** : +- SimplicitĂ© (pas de S3/MinIO pour on-premise) +- Performance (accĂšs direct au disque) +- CoĂ»t (pas de service externe) + +**Solution technique** : +- Stockage dans `/uploads/photos/` +- Volume Docker persistant +- Service Upload avec Multer +- Validation taille (depuis config) + +**Alternatives rejetĂ©es** : +- ❌ Base de donnĂ©es (BYTEA) : Mauvaise performance +- ❌ S3/MinIO : Overkill pour on-premise + +--- + +### 4. Documents lĂ©gaux (CGU/Privacy) + +**DĂ©cision** : ✅ **Versioning automatique avec traçabilitĂ© RGPD** + +**Justification** : +- ConformitĂ© juridique (preuve d'acceptation) +- FlexibilitĂ© (chaque collectivitĂ© adapte ses CGU) +- TraçabilitĂ© (hash SHA-256, IP, User-Agent) +- SĂ©curitĂ© juridique (pas de retour en arriĂšre) + +**Solution technique** : +- Table `documents_legaux` (versioning auto-incrĂ©mentĂ©) +- Table `acceptations_documents` (traçabilitĂ© RGPD) +- Upload PDF par l'admin +- Activation manuelle aprĂšs prĂ©visualisation +- Documents gĂ©nĂ©riques v1 fournis par dĂ©faut + +**RĂ©fĂ©rence** : [22_DOCUMENTS-LEGAUX.md](./22_DOCUMENTS-LEGAUX.md) + +--- + +## 🔧 DĂ©cisions Fonctionnelles + +### 5. Workflow inscription sans mot de passe + +**DĂ©cision** : ✅ **Pas de mot de passe lors de l'inscription, lien email aprĂšs validation** + +**Justification** : +- Simplifie l'inscription (moins de friction) +- AdaptĂ© aux parents sĂ©parĂ©s/divorcĂ©s (communication difficile) +- SĂ©curitĂ© (token UUID avec expiration) +- Validation gestionnaire avant activation + +**Workflow** : +1. Parent/AM s'inscrit (sans MDP) +2. Gestionnaire valide +3. Email envoyĂ© avec lien crĂ©ation MDP (valable 7 jours) +4. Utilisateur crĂ©e son MDP +5. Compte activĂ© + +**RĂ©fĂ©rence** : [20_WORKFLOW-CREATION-COMPTE.md](./20_WORKFLOW-CREATION-COMPTE.md) + +--- + +### 6. Genre enfant obligatoire (H/F) + +**DĂ©cision** : ✅ **Genre obligatoire (H/F uniquement)** + +**Justification** : +- Contexte mĂ©tier : Enfants Ă  garder (pas de genre neutre) +- ConformitĂ© CDC +- SimplicitĂ© + +**ImplĂ©mentation** : +- Champ `genre` ENUM('H', 'F') NOT NULL dans table `enfants` + +--- + +### 7. Suppression champs tĂ©lĂ©phone + +**DĂ©cision** : ✅ **Un seul champ "TĂ©lĂ©phone" (mobile privilĂ©giĂ©)** + +**Justification** : +- Simplification (plus besoin de "Mobile" et "TĂ©lĂ©phone fixe") +- RĂ©alitĂ© terrain : Tout le monde a un mobile +- Note dans l'interface : "(mobile privilĂ©giĂ©)" + +**ImplĂ©mentation** : +- Supprimer `mobile` et `telephone_fixe` +- Garder uniquement `telephone` + +--- + +### 8. NIR obligatoire pour Assistantes Maternelles + +**DĂ©cision** : ✅ **NIR (NumĂ©ro de SĂ©curitĂ© sociale) obligatoire** + +**Justification** : +- ConformitĂ© CDC +- NĂ©cessaire pour gĂ©nĂ©ration automatique du contrat +- Stockage sĂ©curisĂ© (chiffrement recommandĂ©) + +**ImplĂ©mentation** : +- Champ `nir_chiffre` VARCHAR(15) NOT NULL dans `assistantes_maternelles` +- Validation : 15 chiffres exactement +- Affichage masquĂ© dans l'interface (XXX XX XX XX XXX 123) + +--- + +### 9. Suppression notifications SMS + +**DĂ©cision** : ✅ **Supprimer les notifications SMS, garder uniquement Email** + +**Justification** : +- Pas de plus-value identifiĂ©e +- CoĂ»t supplĂ©mentaire (service SMS) +- ComplexitĂ© (intĂ©gration Twilio/OVH) +- Email suffit largement + +**Action** : +- Amender le CDC v1.4 +- Remplacer "Email OU SMS" par "Email" +- Supprimer toute mention de SMS + +**RĂ©fĂ©rence** : Ticket #57 + +--- + +## đŸš« DĂ©cisions Phase 2 (reportĂ©es) + +### 10. Gestion erreurs SMTP (renvoyer email) + +**DĂ©cision** : ⏞ **Phase 2 ou cas par cas** + +**Justification** : +- Pas prioritaire pour MVP +- Downtime SMTP rare (< 24h) +- RecrĂ©ation dossier acceptable en phase de test +- Peut ĂȘtre ajoutĂ© plus tard si besoin terrain + +--- + +### 11. Sauvegarde & Restauration automatique + +**DĂ©cision** : ⏞ **Phase finale (quand tout fonctionne)** + +**Justification** : +- Pas bloquant pour dĂ©veloppement +- NĂ©cessite application stable +- Script `pg_dump` simple Ă  ajouter +- Documentation pour admins sys + +**À faire** : +- Script `backup.sh` avec cron +- Guide sauvegarde/restauration +- Test restauration + +--- + +### 12. RGPD avancĂ© (droit Ă  l'oubli, export donnĂ©es) + +**DĂ©cision** : ⏞ **Phase 2** + +**Justification** : +- ConformitĂ© de base assurĂ©e (consentement, traçabilitĂ©) +- Droit Ă  l'oubli : Peu de demandes en phase test +- Export donnĂ©es : Peut ĂȘtre fait manuellement en phase test + +**À faire** : +- API suppression compte (soft delete) +- API export donnĂ©es personnelles (JSON) +- Anonymisation comptes inactifs + +--- + +### 13. Statistiques dashboard + +**DĂ©cision** : ⏞ **Phase 2 (besoin d'utilisateurs d'abord)** + +**Justification** : +- Pas de donnĂ©es = pas de statistiques +- FonctionnalitĂ© importante pour vente +- NĂ©cessite application en production + +**À faire** : +- API statistiques (comptes, enfants, AM, validations) +- Widgets dashboard (graphiques) +- Export rapports + +--- + +### 14. Migration de donnĂ©es + +**DĂ©cision** : ❌ **Pas de migration prĂ©vue** + +**Justification** : +- Pas de systĂšme existant Ă  migrer +- Application nouvelle +- Import CSV peut ĂȘtre ajoutĂ© cas par cas si besoin + +--- + +### 15. Documentation utilisateur + +**DĂ©cision** : ⏞ **Phase 2 (formation prĂ©sentiel prioritaire)** + +**Justification** : +- Premiers utilisateurs : Formation directe par l'Ă©quipe +- Documentation nĂ©cessaire pour scalabilitĂ© +- VidĂ©os tutoriels utiles mais pas bloquant + +**À faire** : +- Guide utilisateur gestionnaire +- Guide utilisateur parent/AM +- FAQ +- VidĂ©os tutoriels + +--- + +## 🔐 DĂ©cisions SĂ©curitĂ© + +### 16. Chiffrement mots de passe configuration + +**DĂ©cision** : ✅ **AES-256-CBC pour mots de passe SMTP** + +**Justification** : +- SĂ©curitĂ© (mots de passe SMTP en clair = risque) +- ConformitĂ© sĂ©curitĂ© +- DĂ©chiffrement uniquement en mĂ©moire + +**ImplĂ©mentation** : +- Type `encrypted` dans table `configuration` +- ClĂ© de chiffrement dans `.env` (32 caractĂšres) +- Service ConfigService gĂšre chiffrement/dĂ©chiffrement + +--- + +### 17. Hash mots de passe utilisateurs + +**DĂ©cision** : ✅ **Bcrypt avec 12 rounds** + +**Justification** : +- Standard industrie +- RĂ©sistant aux attaques brute-force +- Configurable (rounds dans config) + +--- + +### 18. Tokens crĂ©ation mot de passe + +**DĂ©cision** : ✅ **UUID avec expiration 7 jours** + +**Justification** : +- SĂ©curitĂ© (UUID impossible Ă  deviner) +- Expiration (limite fenĂȘtre d'attaque) +- DurĂ©e configurable (dans table `configuration`) + +--- + +### 19. JWT sessions + +**DĂ©cision** : ✅ **JWT avec expiration 24h** + +**Justification** : +- Stateless (pas de session en BDD) +- Performance (pas de lookup BDD Ă  chaque requĂȘte) +- DurĂ©e configurable + +--- + +## 📊 DĂ©cisions Base de DonnĂ©es + +### 20. PostgreSQL vs autres SGBD + +**DĂ©cision** : ✅ **PostgreSQL 17** + +**Justification** : +- Open-source +- Robuste et performant +- Support JSON (flexibilitĂ©) +- Support UUID natif +- CommunautĂ© active + +--- + +### 21. ORM : Prisma vs TypeORM + +**DĂ©cision** : ✅ **Prisma** (mais TypeORM dĂ©jĂ  en place) + +**Justification Prisma** : +- Type-safety +- Migrations claires +- GĂ©nĂ©ration client automatique + +**Note** : Le projet YNOV utilise TypeORM. À Ă©valuer si migration vers Prisma nĂ©cessaire. + +--- + +### 22. Migrations versionnĂ©es + +**DĂ©cision** : ✅ **Migrations SQL versionnĂ©es** + +**Justification** : +- TraçabilitĂ© des changements schĂ©ma +- Rollback possible +- DĂ©ploiement automatisĂ© + +**ImplĂ©mentation** : +- Fichiers `XX_nom_migration.sql` +- ExĂ©cution via `prisma migrate deploy` +- User `app_admin` pour DDL +- User `app_user` pour DML (runtime) + +--- + +## đŸ§Ș DĂ©cisions Tests + +### 23. StratĂ©gie de tests + +**DĂ©cision** : ✅ **Tests unitaires + intĂ©gration + E2E** + +**Justification** : +- QualitĂ© code +- Confiance dĂ©ploiement +- DĂ©tection rĂ©gression + +**Couverture cible** : +- Tests unitaires : > 80% +- Tests intĂ©gration : Workflows complets +- Tests E2E : Parcours utilisateurs critiques + +--- + +## 📝 DĂ©cisions Documentation + +### 24. Structure documentation + +**DĂ©cision** : ✅ **Documentation centralisĂ©e dans `/docs/` avec numĂ©rotation** + +**Justification** : +- LisibilitĂ© (ordre logique) +- Maintenance (tout au mĂȘme endroit) +- Versioning (Git) + +**Structure** : +``` +docs/ +├── 00_INDEX.md +├── 01_CAHIER-DES-CHARGES.md +├── 02_ARCHITECTURE.md +├── 03_DEPLOYMENT.md +├── 10_DATABASE.md +├── 11_API.md +├── 20_WORKFLOW-CREATION-COMPTE.md +├── 21_CONFIGURATION-SYSTEME.md +├── 22_DOCUMENTS-LEGAUX.md +├── 23_LISTE-TICKETS.md +├── 24_DECISIONS-PROJET.md (ce document) +├── 90_AUDIT.md +└── test-data/ +``` + +--- + +## 🔄 DĂ©cisions Workflow + +### 25. Gitea + Webhook + DĂ©ploiement automatique + +**DĂ©cision** : ✅ **DĂ©ploiement automatique sur push master** + +**Justification** : +- ProductivitĂ© (pas de dĂ©ploiement manuel) +- FiabilitĂ© (script testĂ©) +- RapiditĂ© (feedback immĂ©diat) + +**Workflow** : +1. Push sur `master` +2. Webhook Gitea dĂ©clenchĂ© +3. Script `deploy-ptitspas.sh` exĂ©cutĂ© +4. Git pull + Migrations + Docker rebuild + Restart + +--- + +### 26. Branches Git + +**DĂ©cision** : ✅ **StratĂ©gie simple : master + feature branches** + +**Justification** : +- SimplicitĂ© (petite Ă©quipe) +- FlexibilitĂ© + +**Branches** : +- `master` : Production +- `archive/*` : Archives (ex: maquette initiale) +- `migration/*` : Migrations (ex: intĂ©gration YNOV) +- `feature/*` : Nouvelles fonctionnalitĂ©s + +--- + +## đŸŽ« DĂ©cisions Ticketing + +### 27. Taille des tickets + +**DĂ©cision** : ✅ **Tickets relativement petits (2-6h)** + +**Justification** : +- GranularitĂ© (suivi prĂ©cis) +- Motivation (tickets terminables rapidement) +- Revue de code facilitĂ©e + +--- + +### 28. Organisation tickets + +**DĂ©cision** : ✅ **1 ticket = 1 fonctionnalitĂ© complĂšte (Front + Back + BDD si nĂ©cessaire)** + +**Justification** : +- CohĂ©rence (toute la feature dĂ©veloppĂ©e ensemble) +- Testable (end-to-end immĂ©diatement) +- Atomique (livraison de valeur fonctionnelle) + +**Alternative rejetĂ©e** : +- ❌ 1 ticket Front + 1 ticket Back + 1 ticket BDD = DĂ©pendances complexes + +--- + +## 🚀 DĂ©cisions DĂ©ploiement + +### 29. Docker Compose vs Kubernetes + +**DĂ©cision** : ✅ **Docker Compose** + +**Justification** : +- SimplicitĂ© (on-premise petite/moyenne collectivitĂ©) +- Pas de besoin de scalabilitĂ© horizontale +- Maintenance facile + +**Alternative rejetĂ©e** : +- ❌ Kubernetes : Overkill pour on-premise mono-instance + +--- + +### 30. Traefik comme reverse proxy + +**DĂ©cision** : ✅ **Traefik** + +**Justification** : +- Configuration automatique (labels Docker) +- SSL Let's Encrypt automatique +- Dashboard intĂ©grĂ© + +--- + +## 📊 Logs & Monitoring + +### 31. SystĂšme de logs + +**DĂ©cision** : ✅ **Winston avec rotation quotidienne** + +**Justification** : +- Standard NestJS +- Rotation automatique (pas de disque plein) +- Niveaux de log (info, warn, error) +- Transports multiples (console + fichier) + +**Logs Ă  capturer** : +- Logs applicatifs (info, warn, error) +- Logs emails (succĂšs/Ă©chec SMTP) +- Logs connexions (qui se connecte quand) +- Logs validations (qui valide quoi) + +--- + +## 📋 RĂ©sumĂ© des dĂ©cisions critiques + +| # | DĂ©cision | Statut | Impact | +|---|----------|--------|--------| +| 1 | Mono-repo | ✅ Phase 1 | Architecture | +| 2 | On-premise avec config dynamique | ✅ Phase 1 | DĂ©ploiement | +| 3 | SystĂšme de fichiers pour uploads | ✅ Phase 1 | Stockage | +| 4 | Versioning documents lĂ©gaux | ✅ Phase 1 | RGPD | +| 5 | Inscription sans MDP | ✅ Phase 1 | UX | +| 6 | Genre enfant obligatoire (H/F) | ✅ Phase 1 | MĂ©tier | +| 7 | Un seul champ tĂ©lĂ©phone | ✅ Phase 1 | Simplification | +| 8 | NIR obligatoire AM | ✅ Phase 1 | ConformitĂ© | +| 9 | Suppression SMS | ✅ Phase 1 | Simplification | +| 10 | Renvoyer email | ⏞ Phase 2 | Nice-to-have | +| 11 | Sauvegarde auto | ⏞ Phase finale | Ops | +| 12 | RGPD avancĂ© | ⏞ Phase 2 | ConformitĂ© | +| 13 | Statistiques | ⏞ Phase 2 | Business | +| 14 | Migration donnĂ©es | ❌ RejetĂ© | N/A | +| 15 | Doc utilisateur | ⏞ Phase 2 | Formation | +| 31 | Logs Winston | ✅ Phase 1 | Monitoring | + +--- + +## 🔄 Historique des modifications + +| Date | Version | Modifications | +|------|---------|---------------| +| 25/11/2025 | 1.0 | CrĂ©ation du document - Toutes les dĂ©cisions initiales | + +--- + +**DerniĂšre mise Ă  jour** : 25 Novembre 2025 +**Version** : 1.0 +**Statut** : ✅ Document validĂ© + diff --git a/docs/25_PHASE-2-BACKLOG.md b/docs/25_PHASE-2-BACKLOG.md new file mode 100644 index 0000000..4ff8a6e --- /dev/null +++ b/docs/25_PHASE-2-BACKLOG.md @@ -0,0 +1,433 @@ +# 📋 Backlog Phase 2 - P'titsPas + +**Version** : 1.0 +**Date** : 25 Novembre 2025 +**Auteur** : Équipe PtitsPas + +--- + +## 🎯 Objectif de ce document + +Ce document liste toutes les **fonctionnalitĂ©s reportĂ©es en Phase 2**. Ces fonctionnalitĂ©s ne sont pas bloquantes pour le MVP (Phase 1), mais apportent de la valeur ajoutĂ©e pour la production intensive. + +--- + +## 📊 Vue d'ensemble + +| CatĂ©gorie | Nombre de tickets | Estimation | +|-----------|-------------------|------------| +| **RGPD avancĂ©** | 3 tickets | ~8h | +| **Monitoring avancĂ©** | 2 tickets | ~6h | +| **Statistiques & Reporting** | 4 tickets | ~16h | +| **Sauvegarde & Restauration** | 2 tickets | ~6h | +| **Documentation utilisateur** | 3 tickets | ~12h | +| **AmĂ©liorations UX** | 3 tickets | ~10h | +| **TOTAL** | **17 tickets** | **~58h** | + +--- + +## 🔒 RGPD avancĂ© + +### Ticket P2-01 : [Backend] API Suppression compte (soft delete) +**Estimation** : 3h +**Labels** : `backend`, `phase-2`, `rgpd` + +**Description** : +ImplĂ©menter le droit Ă  l'oubli (RGPD Article 17) avec suppression logique des comptes. + +**TĂąches** : +- [ ] Endpoint `DELETE /api/v1/users/:id` (soft delete) +- [ ] Ajout champ `supprime_le` TIMESTAMPTZ dans `utilisateurs` +- [ ] Anonymisation donnĂ©es personnelles (email, tĂ©lĂ©phone, adresse) +- [ ] Conservation donnĂ©es lĂ©gales (acceptations CGU) +- [ ] Guards (super_admin only) +- [ ] Tests unitaires + +**Justification report Phase 2** : +- Peu de demandes en phase test +- Suppression manuelle possible en attendant + +--- + +### Ticket P2-02 : [Backend] API Export donnĂ©es personnelles (RGPD) +**Estimation** : 3h +**Labels** : `backend`, `phase-2`, `rgpd` + +**Description** : +ImplĂ©menter le droit Ă  la portabilitĂ© (RGPD Article 20) avec export JSON des donnĂ©es personnelles. + +**TĂąches** : +- [ ] Endpoint `GET /api/v1/users/:id/export` (JSON) +- [ ] Export donnĂ©es utilisateur + enfants + acceptations +- [ ] Format JSON structurĂ© +- [ ] Guards (utilisateur lui-mĂȘme ou admin) +- [ ] Tests unitaires + +**Justification report Phase 2** : +- Export manuel SQL possible en phase test +- Peu de demandes attendues + +--- + +### Ticket P2-03 : [Backend] Cron anonymisation comptes inactifs +**Estimation** : 2h +**Labels** : `backend`, `phase-2`, `rgpd`, `cron` + +**Description** : +Anonymiser automatiquement les comptes inactifs aprĂšs X mois (configurable). + +**TĂąches** : +- [ ] Cron job quotidien +- [ ] DĂ©tection comptes inactifs (derniĂšre connexion > X mois) +- [ ] Anonymisation automatique +- [ ] Notification admin +- [ ] Configuration durĂ©e inactivitĂ© (table `configuration`) +- [ ] Tests + +**Justification report Phase 2** : +- Pas de comptes inactifs en phase test +- Peut ĂȘtre fait manuellement + +--- + +## 📊 Monitoring avancĂ© + +### Ticket P2-04 : [Backend] API MĂ©triques systĂšme +**Estimation** : 3h +**Labels** : `backend`, `phase-2`, `monitoring` + +**Description** : +Exposer des mĂ©triques systĂšme (CPU, RAM, disque, BDD) pour monitoring. + +**TĂąches** : +- [ ] Endpoint `GET /api/v1/metrics` (super_admin only) +- [ ] MĂ©triques systĂšme (CPU, RAM, disque) +- [ ] MĂ©triques BDD (connexions, taille, requĂȘtes lentes) +- [ ] MĂ©triques application (requĂȘtes/s, temps rĂ©ponse) +- [ ] Format Prometheus (optionnel) +- [ ] Tests + +**Justification report Phase 2** : +- Pas critique pour MVP +- Logs suffisent pour debugging initial + +--- + +### Ticket P2-05 : [Frontend] Dashboard Monitoring +**Estimation** : 3h +**Labels** : `frontend`, `phase-2`, `monitoring`, `admin` + +**Description** : +CrĂ©er un dashboard de monitoring pour le super admin. + +**TĂąches** : +- [ ] Page `/admin/monitoring` (super_admin only) +- [ ] Graphiques temps rĂ©el (CPU, RAM, disque) +- [ ] Alertes (seuils configurables) +- [ ] Historique mĂ©triques (7 jours) + +**Justification report Phase 2** : +- Pas critique pour MVP +- Monitoring serveur possible via outils systĂšme + +--- + +## 📈 Statistiques & Reporting + +### Ticket P2-06 : [Backend] API Statistiques dashboard +**Estimation** : 4h +**Labels** : `backend`, `phase-2`, `statistiques` + +**Description** : +CrĂ©er les endpoints pour rĂ©cupĂ©rer les statistiques de l'application. + +**TĂąches** : +- [ ] Endpoint `GET /api/v1/stats/overview` +- [ ] Statistiques globales (comptes, enfants, AM, validations) +- [ ] Statistiques temporelles (inscriptions par mois, validations par semaine) +- [ ] Statistiques gĂ©ographiques (par ville) +- [ ] Cache (rafraĂźchissement toutes les heures) +- [ ] Tests + +**Justification report Phase 2** : +- Pas de donnĂ©es = pas de statistiques +- NĂ©cessite application en production + +--- + +### Ticket P2-07 : [Frontend] Widgets statistiques dashboard +**Estimation** : 4h +**Labels** : `frontend`, `phase-2`, `statistiques`, `gestionnaire` + +**Description** : +Afficher les statistiques dans le dashboard gestionnaire. + +**TĂąches** : +- [ ] Widget "Comptes en attente" (nombre) +- [ ] Widget "Comptes validĂ©s ce mois" (graphique) +- [ ] Widget "Enfants inscrits" (nombre) +- [ ] Widget "AM disponibles" (nombre) +- [ ] Graphique Ă©volution inscriptions (6 derniers mois) + +**Justification report Phase 2** : +- Besoin d'utilisateurs rĂ©els pour avoir des donnĂ©es +- FonctionnalitĂ© importante pour vente, mais pas bloquante pour MVP + +--- + +### Ticket P2-08 : [Backend] API Export rapports (CSV/PDF) +**Estimation** : 4h +**Labels** : `backend`, `phase-2`, `reporting` + +**Description** : +Permettre l'export de rapports pour les gestionnaires. + +**TĂąches** : +- [ ] Endpoint `GET /api/v1/reports/users` (CSV) +- [ ] Endpoint `GET /api/v1/reports/validations` (CSV) +- [ ] Endpoint `GET /api/v1/reports/summary` (PDF) +- [ ] GĂ©nĂ©ration PDF (librairie PDFKit) +- [ ] Filtres (date, statut, rĂŽle) +- [ ] Tests + +**Justification report Phase 2** : +- Export manuel SQL possible en phase test +- NĂ©cessite donnĂ©es rĂ©elles + +--- + +### Ticket P2-09 : [Frontend] Écran Rapports +**Estimation** : 4h +**Labels** : `frontend`, `phase-2`, `reporting`, `gestionnaire` + +**Description** : +CrĂ©er un Ă©cran de gĂ©nĂ©ration de rapports pour les gestionnaires. + +**TĂąches** : +- [ ] Page `/admin/rapports` (gestionnaire/admin) +- [ ] SĂ©lection type de rapport (utilisateurs, validations, synthĂšse) +- [ ] Filtres (date, statut, rĂŽle) +- [ ] PrĂ©visualisation +- [ ] TĂ©lĂ©chargement (CSV/PDF) + +**Justification report Phase 2** : +- Pas prioritaire pour MVP +- NĂ©cessite donnĂ©es rĂ©elles + +--- + +## đŸ’Ÿ Sauvegarde & Restauration + +### Ticket P2-10 : [Infra] Script backup PostgreSQL automatique +**Estimation** : 3h +**Labels** : `infra`, `phase-2`, `backup` + +**Description** : +CrĂ©er un script de sauvegarde automatique de la base de donnĂ©es. + +**TĂąches** : +- [ ] Script `backup.sh` avec `pg_dump` +- [ ] Compression (gzip) +- [ ] Rotation (garder 30 derniers jours) +- [ ] Cron job quotidien (3h du matin) +- [ ] Notification email en cas d'Ă©chec +- [ ] Tests restauration + +**Justification report Phase 2** : +- Pas bloquant pour dĂ©veloppement +- Backup manuel possible en phase test +- À faire avant mise en production + +--- + +### Ticket P2-11 : [Doc] Guide sauvegarde & restauration +**Estimation** : 3h +**Labels** : `documentation`, `phase-2`, `backup` + +**Description** : +Documenter les procĂ©dures de sauvegarde et restauration pour les admins sys. + +**TĂąches** : +- [ ] ProcĂ©dure sauvegarde manuelle +- [ ] ProcĂ©dure restauration +- [ ] Configuration cron +- [ ] Troubleshooting +- [ ] Exemples de commandes +- [ ] Checklist prĂ©-restauration + +**Justification report Phase 2** : +- Documentation technique, pas bloquante pour MVP +- À faire avant mise en production + +--- + +## 📚 Documentation utilisateur + +### Ticket P2-12 : [Doc] Guide utilisateur Gestionnaire +**Estimation** : 4h +**Labels** : `documentation`, `phase-2`, `formation` + +**Description** : +RĂ©diger le guide utilisateur pour les gestionnaires. + +**TĂąches** : +- [ ] Connexion et premiĂšre utilisation +- [ ] Consultation des demandes +- [ ] Validation/Refus de comptes +- [ ] Gestion des paramĂštres +- [ ] FAQ gestionnaire +- [ ] Captures d'Ă©cran + +**Justification report Phase 2** : +- Formation prĂ©sentiel prioritaire pour premiers utilisateurs +- Documentation nĂ©cessaire pour scalabilitĂ© + +--- + +### Ticket P2-13 : [Doc] Guide utilisateur Parent/AM +**Estimation** : 4h +**Labels** : `documentation`, `phase-2`, `formation` + +**Description** : +RĂ©diger le guide utilisateur pour les parents et assistantes maternelles. + +**TĂąches** : +- [ ] Inscription Ă©tape par Ă©tape +- [ ] CrĂ©ation du mot de passe +- [ ] Connexion +- [ ] Utilisation de l'application +- [ ] FAQ parent/AM +- [ ] Captures d'Ă©cran + +**Justification report Phase 2** : +- Formation prĂ©sentiel prioritaire +- Documentation nĂ©cessaire pour scalabilitĂ© + +--- + +### Ticket P2-14 : [Doc] VidĂ©os tutoriels +**Estimation** : 4h +**Labels** : `documentation`, `phase-2`, `formation`, `video` + +**Description** : +CrĂ©er des vidĂ©os tutoriels pour les utilisateurs. + +**TĂąches** : +- [ ] VidĂ©o "Inscription parent" (3-5 min) +- [ ] VidĂ©o "Inscription AM" (3-5 min) +- [ ] VidĂ©o "Validation comptes gestionnaire" (3-5 min) +- [ ] VidĂ©o "Configuration initiale admin" (5-7 min) +- [ ] HĂ©bergement (YouTube privĂ© ou serveur) + +**Justification report Phase 2** : +- Pas bloquant pour MVP +- Utile pour scalabilitĂ© et autonomie utilisateurs + +--- + +## 🎹 AmĂ©liorations UX + +### Ticket P2-15 : [Frontend] Mode sombre +**Estimation** : 3h +**Labels** : `frontend`, `phase-2`, `ux` + +**Description** : +Ajouter un mode sombre Ă  l'application. + +**TĂąches** : +- [ ] ThĂšme sombre (couleurs, contrastes) +- [ ] Toggle mode clair/sombre +- [ ] Sauvegarde prĂ©fĂ©rence utilisateur +- [ ] Adaptation tous les Ă©crans + +**Justification report Phase 2** : +- Nice-to-have, pas bloquant +- AmĂ©liore confort utilisateur + +--- + +### Ticket P2-16 : [Frontend] Notifications push (optionnel) +**Estimation** : 4h +**Labels** : `frontend`, `phase-2`, `ux`, `notifications` + +**Description** : +Ajouter des notifications push pour les Ă©vĂ©nements importants. + +**TĂąches** : +- [ ] Service Worker (PWA) +- [ ] Notification "Compte validĂ©" +- [ ] Notification "Nouveau message" (si messagerie) +- [ ] Gestion permissions +- [ ] ParamĂštres notifications + +**Justification report Phase 2** : +- Nice-to-have, pas bloquant +- NĂ©cessite PWA ou app mobile + +--- + +### Ticket P2-17 : [Frontend] AccessibilitĂ© (WCAG 2.1) +**Estimation** : 3h +**Labels** : `frontend`, `phase-2`, `ux`, `a11y` + +**Description** : +AmĂ©liorer l'accessibilitĂ© de l'application (conformitĂ© WCAG 2.1). + +**TĂąches** : +- [ ] Audit accessibilitĂ© (Lighthouse, axe) +- [ ] Correction contrastes +- [ ] Attributs ARIA +- [ ] Navigation clavier +- [ ] Lecteur d'Ă©cran (test) + +**Justification report Phase 2** : +- AmĂ©lioration continue +- Pas bloquant pour MVP +- Important pour collectivitĂ©s (obligation lĂ©gale) + +--- + +## 📋 Priorisation Phase 2 + +### PrioritĂ© Haute (Ă  faire en premier) +1. **Sauvegarde & Restauration** (Tickets P2-10, P2-11) → Avant mise en production +2. **Statistiques** (Tickets P2-06, P2-07) → Argument de vente +3. **Documentation utilisateur** (Tickets P2-12, P2-13) → ScalabilitĂ© + +### PrioritĂ© Moyenne +4. **RGPD avancĂ©** (Tickets P2-01, P2-02, P2-03) → ConformitĂ© +5. **Reporting** (Tickets P2-08, P2-09) → Utile pour gestionnaires + +### PrioritĂ© Basse +6. **Monitoring avancĂ©** (Tickets P2-04, P2-05) → Nice-to-have +7. **AmĂ©liorations UX** (Tickets P2-15, P2-16, P2-17) → Confort + +--- + +## 🚀 CritĂšres de passage en Phase 2 + +La Phase 2 peut commencer quand : +- ✅ Phase 1 terminĂ©e (61 tickets) +- ✅ Application dĂ©ployĂ©e en production (au moins 1 collectivitĂ©) +- ✅ Utilisateurs rĂ©els (au moins 10 comptes validĂ©s) +- ✅ Feedback terrain collectĂ© +- ✅ Bugs critiques corrigĂ©s + +--- + +## 📊 Estimation globale Phase 2 + +**Total** : 17 tickets +**Estimation** : ~58h de dĂ©veloppement + +**Planning suggĂ©rĂ©** : +- Sprint 1 (2 semaines) : Sauvegarde + Statistiques (26h) +- Sprint 2 (2 semaines) : Documentation + RGPD (24h) +- Sprint 3 (1 semaine) : Reporting + AmĂ©liorations UX (8h) + +--- + +**DerniĂšre mise Ă  jour** : 25 Novembre 2025 +**Version** : 1.0 +**Statut** : ✅ Backlog Phase 2 dĂ©fini +