From d91caef0c569229c1af80a13eac632c2204ed202 Mon Sep 17 00:00:00 2001 From: Julien Martin Date: Fri, 17 Apr 2026 17:33:47 +0200 Subject: [PATCH] =?UTF-8?q?merge(master):=20int=C3=A9gration=20develop=20?= =?UTF-8?q?=E2=80=94=20ticket=20#50,=20documents=20l=C3=A9gaux=20et=20vali?= =?UTF-8?q?dation=20CGU?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squash merge de la branche develop dans master : un seul commit sur master pour regrouper la livraison liée au ticket #50 (affichage dynamique des CGU et de la politique de confidentialité à l'inscription) ainsi que la documentation et les ajustements associés. Frontend (P'titsPas) : modale de validation bloquante avec onglets CGU / confidentialité, chargement des PDF depuis l'API des documents légaux actifs, affichage via pdfx (PdfViewPinch et barre de progression latérale sur le web, repli PdfView sous Windows). Branchement dans le flux d'inscription (écran de présentation), enrichissement du UserService et correction des chemins média pour les URL absolues. Documentation: jeux de fichiers juridiques (markdown et PDF de référence), réorganisation (dossier docs/juridique, archives, renommage du briefing), mises à jour index, liste de tickets et décisions projet. Scripts et métadonnées mineures (Gitea, pubspec, index web). Made-with: Cursor --- backend/scripts/close-gitea-issue-120.js | 7 +- .../scripts/create-gitea-issue-parent-api.js | 12 +- backend/scripts/list-gitea-issues.js | 7 +- .../update-gitea-issue-119-dossiers.js | 7 +- docs/00_INDEX.md | 26 +- docs/22_DOCUMENTS-LEGAUX.md | 700 +----------------- docs/23_LISTE-TICKETS.md | 14 +- docs/24_DECISIONS-PROJET.md | 15 +- ...NG-FRONTEND.md => 27_BRIEFING-FRONTEND.md} | 0 docs/PROCEDURE-API-GITEA.md | 178 +---- docs/archive/README.md | 30 + .../obsolete}/ARCHITECTURE_TECHNIQUE.md | 5 + docs/archive/obsolete/PROCEDURE-API-GITEA.md | 180 +++++ docs/archive/obsolete/README.md | 14 + .../obsolete}/STATUS-APPLICATION.md | 7 +- .../temporaires}/POINT_TICKETS_FRONT_API.txt | 1 + docs/archive/temporaires/README.md | 10 + .../temporaires}/TEMP_FRONT_alignement_AM.md | 4 +- docs/juridique/22_DOCUMENTS-LEGAUX.md | 698 +++++++++++++++++ docs/juridique/README.md | 41 + docs/juridique/cgc.md | 116 +++ docs/juridique/cgu.md | 119 +++ docs/juridique/cgu.pdf | Bin 0 -> 59965 bytes docs/juridique/politique-confidentialite.md | 188 +++++ docs/juridique/politique-confidentialite.pdf | Bin 0 -> 73533 bytes frontend/assets/documents/cgu_ptitspas.pdf | Bin 0 -> 52116 bytes frontend/lib/services/api/api_config.dart | 6 + frontend/lib/services/user_service.dart | 73 ++ .../cgu_privacy_validation_dialog.dart | 449 +++++++++++ .../lib/widgets/presentation_form_screen.dart | 99 ++- frontend/pubspec.lock | 56 ++ frontend/pubspec.yaml | 3 + frontend/web/index.html | 10 + scripts/gitea-close-issue-with-comment.sh | 6 +- 34 files changed, 2169 insertions(+), 912 deletions(-) rename docs/{BRIEFING-FRONTEND.md => 27_BRIEFING-FRONTEND.md} (100%) create mode 100644 docs/archive/README.md rename docs/{ => archive/obsolete}/ARCHITECTURE_TECHNIQUE.md (98%) create mode 100644 docs/archive/obsolete/PROCEDURE-API-GITEA.md create mode 100644 docs/archive/obsolete/README.md rename docs/{ => archive/obsolete}/STATUS-APPLICATION.md (92%) rename docs/{ => archive/temporaires}/POINT_TICKETS_FRONT_API.txt (95%) create mode 100644 docs/archive/temporaires/README.md rename docs/{ => archive/temporaires}/TEMP_FRONT_alignement_AM.md (92%) create mode 100644 docs/juridique/22_DOCUMENTS-LEGAUX.md create mode 100644 docs/juridique/README.md create mode 100644 docs/juridique/cgc.md create mode 100644 docs/juridique/cgu.md create mode 100644 docs/juridique/cgu.pdf create mode 100644 docs/juridique/politique-confidentialite.md create mode 100644 docs/juridique/politique-confidentialite.pdf create mode 100644 frontend/assets/documents/cgu_ptitspas.pdf create mode 100644 frontend/lib/widgets/cgu_privacy_validation_dialog.dart diff --git a/backend/scripts/close-gitea-issue-120.js b/backend/scripts/close-gitea-issue-120.js index fbdc75a..dae726e 100644 --- a/backend/scripts/close-gitea-issue-120.js +++ b/backend/scripts/close-gitea-issue-120.js @@ -1,7 +1,7 @@ /** * Commentaire de clôture + fermeture issue Gitea #120. * Usage: node backend/scripts/close-gitea-issue-120.js - * Token : .gitea-token (racine), GITEA_TOKEN, ou docs/BRIEFING-FRONTEND.md + * Token : .gitea-token (racine), GITEA_TOKEN, ou docs/27_BRIEFING-FRONTEND.md */ const https = require('https'); const fs = require('fs'); @@ -45,7 +45,10 @@ if (!token) { } if (!token) { try { - const briefing = fs.readFileSync(path.join(repoRoot, 'docs/BRIEFING-FRONTEND.md'), 'utf8'); + const briefing = fs.readFileSync( + path.join(repoRoot, 'docs/27_BRIEFING-FRONTEND.md'), + 'utf8', + ); const m = briefing.match(/Token:\s*(giteabu_[a-f0-9]+)/); if (m) token = m[1].trim(); } catch (_) {} diff --git a/backend/scripts/create-gitea-issue-parent-api.js b/backend/scripts/create-gitea-issue-parent-api.js index 68f2541..7d457fa 100644 --- a/backend/scripts/create-gitea-issue-parent-api.js +++ b/backend/scripts/create-gitea-issue-parent-api.js @@ -1,7 +1,8 @@ /** * Crée l'issue Gitea "[Frontend] Inscription Parent – Branchement soumission formulaire à l'API" * Usage: node backend/scripts/create-gitea-issue-parent-api.js - * Token : .gitea-token (racine du dépôt), sinon GITEA_TOKEN, sinon docs/BRIEFING-FRONTEND.md (voir PROCEDURE-API-GITEA.md) + * Token : .gitea-token (racine du dépôt), sinon GITEA_TOKEN, sinon + * docs/27_BRIEFING-FRONTEND.md (voir docs/26_GITEA-API.md) */ const https = require('https'); const fs = require('fs'); @@ -19,13 +20,18 @@ if (!token) { } if (!token) { try { - const briefing = fs.readFileSync(path.join(repoRoot, 'docs/BRIEFING-FRONTEND.md'), 'utf8'); + const briefing = fs.readFileSync( + path.join(repoRoot, 'docs/27_BRIEFING-FRONTEND.md'), + 'utf8', + ); const m = briefing.match(/Token:\s*(giteabu_[a-f0-9]+)/); if (m) token = m[1].trim(); } catch (_) {} } if (!token) { - console.error('Token non trouvé : créer .gitea-token à la racine ou export GITEA_TOKEN (voir docs/PROCEDURE-API-GITEA.md)'); + console.error( + 'Token non trouvé : créer .gitea-token à la racine ou export GITEA_TOKEN (voir docs/26_GITEA-API.md)', + ); process.exit(1); } diff --git a/backend/scripts/list-gitea-issues.js b/backend/scripts/list-gitea-issues.js index 57742c8..599b738 100644 --- a/backend/scripts/list-gitea-issues.js +++ b/backend/scripts/list-gitea-issues.js @@ -1,6 +1,6 @@ /** * Liste toutes les issues Gitea (ouvertes + fermées) pour jmartin/petitspas. - * Token : .gitea-token (racine), GITEA_TOKEN, ou docs/BRIEFING-FRONTEND.md + * Token : .gitea-token (racine), GITEA_TOKEN, ou docs/27_BRIEFING-FRONTEND.md */ const https = require('https'); const fs = require('fs'); @@ -16,7 +16,10 @@ if (!token) { } if (!token) { try { - const briefing = fs.readFileSync(path.join(repoRoot, 'docs/BRIEFING-FRONTEND.md'), 'utf8'); + const briefing = fs.readFileSync( + path.join(repoRoot, 'docs/27_BRIEFING-FRONTEND.md'), + 'utf8', + ); const m = briefing.match(/Token:\s*(giteabu_[a-f0-9]+)/); if (m) token = m[1].trim(); } catch (_) {} diff --git a/backend/scripts/update-gitea-issue-119-dossiers.js b/backend/scripts/update-gitea-issue-119-dossiers.js index 225dbcb..81257b2 100644 --- a/backend/scripts/update-gitea-issue-119-dossiers.js +++ b/backend/scripts/update-gitea-issue-119-dossiers.js @@ -1,7 +1,7 @@ /** * Met à jour l'issue Gitea #119 : endpoint unifié GET /dossiers/:numeroDossier (option A) * Usage: node backend/scripts/update-gitea-issue-119-dossiers.js - * Token : .gitea-token (racine), GITEA_TOKEN, ou docs/BRIEFING-FRONTEND.md + * Token : .gitea-token (racine), GITEA_TOKEN, ou docs/27_BRIEFING-FRONTEND.md */ const https = require('https'); const fs = require('fs'); @@ -17,7 +17,10 @@ if (!token) { } if (!token) { try { - const briefing = fs.readFileSync(path.join(repoRoot, 'docs/BRIEFING-FRONTEND.md'), 'utf8'); + const briefing = fs.readFileSync( + path.join(repoRoot, 'docs/27_BRIEFING-FRONTEND.md'), + 'utf8', + ); const m = briefing.match(/Token:\s*(giteabu_[a-f0-9]+)/); if (m) token = m[1].trim(); } catch (_) {} diff --git a/docs/00_INDEX.md b/docs/00_INDEX.md index df689ca..2f8a601 100644 --- a/docs/00_INDEX.md +++ b/docs/00_INDEX.md @@ -19,15 +19,39 @@ Ce fichier sert d'index pour naviguer dans toute la documentation du projet. ### Développement - [**10 - Database Schema**](./10_DATABASE.md) - Schéma de la base de données et modèles - [**11 - API Documentation**](./11_API.md) - Documentation complète des endpoints REST +- [**14 - Note backend config setup**](./14_NOTE-BACKEND-CONFIG-SETUP.md) - Setup configuration +- [**92 - Note backend gestionnaires**](./92_NOTE-BACKEND-GESTIONNAIRES.md) - Gestionnaires +- [**99 - Règles de codage**](./99_REGLES-CODAGE.md) - Conventions de code ### Workflows Fonctionnels - [**20 - Workflow Création de Compte**](./20_WORKFLOW-CREATION-COMPTE.md) - Workflow complet de création et validation des comptes utilisateurs - [**21 - Configuration Système**](./21_CONFIGURATION-SYSTEME.md) - Configuration on-premise dynamique -- [**22 - Documents Légaux**](./22_DOCUMENTS-LEGAUX.md) - Gestion CGU/Privacy avec versioning +- [**22 - Documents Légaux**](./juridique/22_DOCUMENTS-LEGAUX.md) - Gestion CGU/Privacy avec versioning + +### Juridique (sources & technique) +- [**Dossier juridique**](./juridique/README.md) - Index : CGU/CGC en Markdown, + export PDF, lien vers la doc technique n°22 + +### Projet & suivi (Gitea / tickets) - [**23 - Liste des Tickets**](./23_LISTE-TICKETS.md) - 61 tickets Phase 1 détaillés - [**24 - Décisions Projet**](./24_DECISIONS-PROJET.md) - Décisions architecturales et fonctionnelles - [**25 - Backlog Phase 2**](./25_PHASE-2-BACKLOG.md) - Fonctionnalités techniques reportées - [**26 - API Gitea**](./26_GITEA-API.md) - Procédure d'utilisation de l'API Gitea (issues, PR, branches, labels) +- [**27 - Briefing frontend**](./27_BRIEFING-FRONTEND.md) - Accès Git, priorités, scripts Gitea (token) + +### Archive & convention de nommage +- [**Dossier archive**](./archive/README.md) - Fichiers **sans** `NN_` déplacés + (temporaires, obsolètes) ; règles de rangement et suppression +- Pointeur : [PROCEDURE-API-GITEA.md](./PROCEDURE-API-GITEA.md) → voir **26** + +### Exceptions de nommage (racine `docs/`) +Fichiers **sans préfixe numérique** encore à la racine par **héritage** ou +références outils (`.cursorrules`, etc.) — **à renommer** en `NN_` quand +possible : +- `CHARTE_GRAPHIQUE.md` +- `EVOLUTIONS_CDC.md` +- `SuperNounou_Cahier_Des_Charges_Complet_V1.1.md` +- `SuperNounou_SSS-001.md` ### Administration (À créer) - [**30 - Guide d'administration**](./30_ADMIN.md) - Gestion des utilisateurs, accès PgAdmin, logs diff --git a/docs/22_DOCUMENTS-LEGAUX.md b/docs/22_DOCUMENTS-LEGAUX.md index 4bd5bc5..c213372 100644 --- a/docs/22_DOCUMENTS-LEGAUX.md +++ b/docs/22_DOCUMENTS-LEGAUX.md @@ -1,698 +1,8 @@ -# 📄 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é +# Fichier déplacé +La documentation **Documents légaux** a été déplacée vers : +**[juridique/22_DOCUMENTS-LEGAUX.md](./juridique/22_DOCUMENTS-LEGAUX.md)** +Voir aussi le dossier **[juridique/](./juridique/)** pour les sources **CGU** +et **CGC** en Markdown. diff --git a/docs/23_LISTE-TICKETS.md b/docs/23_LISTE-TICKETS.md index fdebf49..eee299d 100644 --- a/docs/23_LISTE-TICKETS.md +++ b/docs/23_LISTE-TICKETS.md @@ -55,7 +55,7 @@ | 44 | [Frontend] Dashboard Gestionnaire - Structure | ✅ Terminé | | 45 | [Frontend] Dashboard Gestionnaire - Liste Parents | ✅ Fermé (obsolète, couvert #103-#111) | | 46 | [Frontend] Dashboard Gestionnaire - Liste AM | ✅ Fermé (obsolète, couvert #103-#111) | -| 47 | [Frontend] Écran Changement MDP Obligatoire | Ouvert | +| 47 | [Frontend] Écran Changement MDP Obligatoire | ✅ Fermé | | 48 | [Frontend] Gestion Erreurs & Messages | Ouvert | | 49 | [Frontend] Écran Gestion Documents Légaux (Admin) | Ouvert | | 50 | [Frontend] Affichage dynamique CGU lors inscription | Ouvert | @@ -243,7 +243,7 @@ Créer les tables pour gérer les versions des documents légaux (CGU/Privacy) e - [ ] Créer migration Prisma - [ ] Tester migration -**Référence** : [22_DOCUMENTS-LEGAUX.md](./22_DOCUMENTS-LEGAUX.md) +**Référence** : [22_DOCUMENTS-LEGAUX.md](./juridique/22_DOCUMENTS-LEGAUX.md) --- @@ -679,7 +679,7 @@ Créer le service de gestion des documents légaux (CGU/Privacy) avec versioning - [ ] Méthode `listerVersions()` - [ ] Tests unitaires -**Référence** : [22_DOCUMENTS-LEGAUX.md](./22_DOCUMENTS-LEGAUX.md#service-documents-légaux) +**Référence** : [22_DOCUMENTS-LEGAUX.md](./juridique/22_DOCUMENTS-LEGAUX.md#service-documents-légaux) --- @@ -699,7 +699,7 @@ Créer les endpoints REST pour gérer les documents légaux. - [ ] Guards + validation - [ ] Tests unitaires -**Référence** : [22_DOCUMENTS-LEGAUX.md](./22_DOCUMENTS-LEGAUX.md#apis) +**Référence** : [22_DOCUMENTS-LEGAUX.md](./juridique/22_DOCUMENTS-LEGAUX.md#apis) --- @@ -716,7 +716,7 @@ Enregistrer les acceptations de documents légaux lors de l'inscription (traçab - [ ] API `GET /api/v1/users/:id/acceptations` (admin) - [ ] Tests unitaires -**Référence** : [22_DOCUMENTS-LEGAUX.md](./22_DOCUMENTS-LEGAUX.md#workflow-acceptation-utilisateur) +**Référence** : [22_DOCUMENTS-LEGAUX.md](./juridique/22_DOCUMENTS-LEGAUX.md#workflow-acceptation-utilisateur) --- @@ -1005,7 +1005,7 @@ Créer l'écran de gestion des documents légaux (CGU/Privacy) pour l'admin. - [ ] Activation version - [ ] Historique versions -**Référence** : [22_DOCUMENTS-LEGAUX.md](./22_DOCUMENTS-LEGAUX.md#interface-admin) +**Référence** : [22_DOCUMENTS-LEGAUX.md](./juridique/22_DOCUMENTS-LEGAUX.md#interface-admin) --- @@ -1165,7 +1165,7 @@ Branchement du formulaire d'inscription parent (étape 5, récapitulatif) à l'e **Référence** : [20_WORKFLOW-CREATION-COMPTE.md](./20_WORKFLOW-CREATION-COMPTE.md#étape-3--inscription-dun-parent), backend #18 (refonte API inscription parent). -**Création** : issue Gitea #101 créée. Pour recréer ou script : `node backend/scripts/create-gitea-issue-parent-api.js` (token dans `.gitea-token` ou voir [PROCEDURE-API-GITEA.md](./PROCEDURE-API-GITEA.md)). +**Création** : issue Gitea #101 créée. Pour recréer ou script : `node backend/scripts/create-gitea-issue-parent-api.js` (token dans `.gitea-token` ou voir [26_GITEA-API.md](./26_GITEA-API.md)). --- diff --git a/docs/24_DECISIONS-PROJET.md b/docs/24_DECISIONS-PROJET.md index fd8a72d..62bcbe5 100644 --- a/docs/24_DECISIONS-PROJET.md +++ b/docs/24_DECISIONS-PROJET.md @@ -95,7 +95,7 @@ ptitspas-app/ - 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) +**Référence** : [22_DOCUMENTS-LEGAUX.md](./juridique/22_DOCUMENTS-LEGAUX.md) --- @@ -413,7 +413,18 @@ docs/ ├── 11_API.md ├── 20_WORKFLOW-CREATION-COMPTE.md ├── 21_CONFIGURATION-SYSTEME.md -├── 22_DOCUMENTS-LEGAUX.md +├── 22_DOCUMENTS-LEGAUX.md # pointeur → juridique/ +├── 27_BRIEFING-FRONTEND.md +├── PROCEDURE-API-GITEA.md # pointeur → 26_GITEA-API.md +├── juridique/ +│ ├── README.md +│ ├── cgu.md +│ ├── cgc.md +│ └── 22_DOCUMENTS-LEGAUX.md +├── archive/ +│ ├── README.md +│ ├── temporaires/ +│ └── obsolete/ ├── 23_LISTE-TICKETS.md ├── 24_DECISIONS-PROJET.md (ce document) ├── 90_AUDIT.md diff --git a/docs/BRIEFING-FRONTEND.md b/docs/27_BRIEFING-FRONTEND.md similarity index 100% rename from docs/BRIEFING-FRONTEND.md rename to docs/27_BRIEFING-FRONTEND.md diff --git a/docs/PROCEDURE-API-GITEA.md b/docs/PROCEDURE-API-GITEA.md index 6a41046..fcae5a0 100644 --- a/docs/PROCEDURE-API-GITEA.md +++ b/docs/PROCEDURE-API-GITEA.md @@ -1,176 +1,8 @@ -# Procédure – Utilisation de l’API Gitea +# Fichier déplacé / fusionné -## 1. Contexte +La procédure **API Gitea** est désormais documentée sous : -- **Instance** : https://git.ptits-pas.fr -- **API de base** : `https://git.ptits-pas.fr/api/v1` -- **Projet P'titsPas** : dépôt `jmartin/petitspas` (owner = `jmartin`, repo = `petitspas`) +**[26_GITEA-API.md](./26_GITEA-API.md)** -## 2. Authentification - -### 2.1 Token - -Le token est défini dans l’environnement (ex. `~/.bashrc`) : - -```bash -export GITEA_TOKEN="" -``` - -Pour l’utiliser dans les commandes : - -```bash -source ~/.bashrc # ou : . ~/.bashrc -# Puis utiliser $GITEA_TOKEN dans les curl -``` - -### 2.2 En-tête HTTP - -Toutes les requêtes API doivent envoyer le token : - -```bash --H "Authorization: token $GITEA_TOKEN" -``` - -Exemple : - -```bash -curl -s -H "Authorization: token $GITEA_TOKEN" \ - "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas" -``` - -## 3. Endpoints utiles - -### 3.1 Dépôt (repository) - -| Action | Méthode | URL | -|---------------|---------|-----| -| Infos dépôt | GET | `/repos/{owner}/{repo}` | -| Liste dépôts | GET | `/repos/search?q=petitspas` | - -Exemple – infos du dépôt : - -```bash -curl -s -H "Authorization: token $GITEA_TOKEN" \ - "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas" | jq . -``` - -### 3.2 Issues (tickets) - -| Action | Méthode | URL | -|------------------|---------|-----| -| Liste des issues | GET | `/repos/{owner}/{repo}/issues` | -| Détail d’une issue | GET | `/repos/{owner}/{repo}/issues/{index}` | -| Créer une issue | POST | `/repos/{owner}/{repo}/issues` | -| Modifier une issue | PATCH | `/repos/{owner}/{repo}/issues/{index}` | -| Fermer une issue | PATCH | (même URL, `state: "closed"`) | - -**Paramètres GET utiles pour la liste :** - -- `state` : `open` ou `closed` -- `labels` : filtre par label (ex. `frontend`) -- `page`, `limit` : pagination - -Exemples : - -```bash -# Toutes les issues ouvertes -curl -s -H "Authorization: token $GITEA_TOKEN" \ - "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues?state=open" | jq . - -# Issues ouvertes avec label "frontend" -curl -s -H "Authorization: token $GITEA_TOKEN" \ - "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues?state=open" | \ - jq '.[] | select(.labels[].name == "frontend") | {number, title, state}' - -# Détail de l’issue #47 -curl -s -H "Authorization: token $GITEA_TOKEN" \ - "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues/47" | jq . - -# Fermer l’issue #31 -curl -s -X PATCH -H "Authorization: token $GITEA_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"state":"closed"}' \ - "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues/31" - -# Créer une issue -curl -s -X POST -H "Authorization: token $GITEA_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"title":"Titre du ticket","body":"Description","labels":[1]}' \ - "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues" -``` - -### 3.3 Pull requests - -| Action | Méthode | URL | -|---------------|---------|-----| -| Liste des PR | GET | `/repos/{owner}/{repo}/pulls` | -| Détail d’une PR | GET | `/repos/{owner}/{repo}/pulls/{index}` | -| Créer une PR | POST | `/repos/{owner}/{repo}/pulls` | -| Fusionner une PR | POST | `/repos/{owner}/{repo}/pulls/{index}/merge` | - -Exemples : - -```bash -# Liste des PR ouvertes -curl -s -H "Authorization: token $GITEA_TOKEN" \ - "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/pulls?state=open" | jq . - -# Créer une PR (head = branche source, base = branche cible) -curl -s -X POST -H "Authorization: token $GITEA_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"head":"develop","base":"master","title":"Titre de la PR"}' \ - "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/pulls" -``` - -### 3.4 Branches - -| Action | Méthode | URL | -|---------------|---------|-----| -| Liste des branches | GET | `/repos/{owner}/{repo}/branches` | - -```bash -curl -s -H "Authorization: token $GITEA_TOKEN" \ - "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/branches" | jq '.[].name' -``` - -### 3.5 Webhooks - -| Action | Méthode | URL | -|---------------|---------|-----| -| Liste webhooks | GET | `/repos/{owner}/{repo}/hooks` | -| Créer webhook | POST | `/repos/{owner}/{repo}/hooks` | - -### 3.6 Labels - -| Action | Méthode | URL | -|---------------|---------|-----| -| Liste des labels | GET | `/repos/{owner}/{repo}/labels` | - -```bash -curl -s -H "Authorization: token $GITEA_TOKEN" \ - "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/labels" | jq '.[] | {id, name}' -``` - -## 4. Résumé des URLs pour P'titsPas - -Remplacer `{owner}` par `jmartin` et `{repo}` par `petitspas` : - -| Ressource | URL | -|------------------|-----| -| Dépôt | `https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas` | -| Issues | `https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues` | -| Issue #n | `https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues/{n}` | -| Pull requests | `https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/pulls` | -| Branches | `https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/branches` | -| Labels | `https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/labels` | - -## 5. Documentation officielle - -- Swagger / OpenAPI : https://docs.gitea.com/api -- Référence selon la version de Gitea installée (ex. 1.21, 1.25). - -## 6. Dépannage - -- **401 Unauthorized** : vérifier le token et l’en-tête `Authorization: token `. -- **404** : vérifier owner/repo et l’URL (sensible à la casse). -- **422 / body invalide** : pour POST/PATCH, envoyer `Content-Type: application/json` et un JSON valide. +L’ancienne copie `PROCEDURE-API-GITEA.md` est archivée dans +`docs/archive/obsolete/` (doublon). diff --git a/docs/archive/README.md b/docs/archive/README.md new file mode 100644 index 0000000..794b038 --- /dev/null +++ b/docs/archive/README.md @@ -0,0 +1,30 @@ +# Archive documentation · P'titsPas + +Ce dossier regroupe les fichiers **sans préfixe numérique** à la racine de +`docs/` qui ne sont plus des **références actives**, ou qui sont des +**brouillons / temporaires**. + +## Règle de nommage (racine `docs/`) + +- Les documents **normatifs** à la racine portent un préfixe **`NN_`** + (deux chiffres), ex. `23_LISTE-TICKETS.md`. +- **Exceptions** (héritage ou outillage) listées dans + [**00_INDEX.md**](../00_INDEX.md#exceptions-de-nommage) : charte, CDC + historique, évolutions — **cible** : les renommer progressivement en `NN_` + et mettre à jour `.cursorrules` / liens. + +## Sous-dossiers ici + +| Dossier | Usage | +|---------|--------| +| [**temporaires/**](./temporaires/) | Notes jetables, exports de travail. + **Supprimables** quand la tâche associée est close. | +| [**obsolete/**](./obsolete/) | Ancienne doc **remplacée** ou **doublon** + (conservée un temps pour historique). **Supprimer** après bascule confirmée + si plus aucune référence. | + +## Hors `docs/` racine + +Les dossiers thématiques (**`juridique/`**, **`test-data/`**, etc.) peuvent +contenir des fichiers sans `NN_` : la règle `NN_` s’applique surtout aux +fichiers **directement** sous `docs/`. diff --git a/docs/ARCHITECTURE_TECHNIQUE.md b/docs/archive/obsolete/ARCHITECTURE_TECHNIQUE.md similarity index 98% rename from docs/ARCHITECTURE_TECHNIQUE.md rename to docs/archive/obsolete/ARCHITECTURE_TECHNIQUE.md index 5fead37..d7b245b 100644 --- a/docs/ARCHITECTURE_TECHNIQUE.md +++ b/docs/archive/obsolete/ARCHITECTURE_TECHNIQUE.md @@ -1,4 +1,9 @@ # Architecture Technique - P'titsPas + +> **Archivé** (`docs/archive/obsolete/`) — non maintenu à la racine `docs/`. +> Voir [`02_ARCHITECTURE.md`](../../02_ARCHITECTURE.md) pour la référence +> courante. + ## Guide d'Infrastructure et de Déploiement --- diff --git a/docs/archive/obsolete/PROCEDURE-API-GITEA.md b/docs/archive/obsolete/PROCEDURE-API-GITEA.md new file mode 100644 index 0000000..5d68f27 --- /dev/null +++ b/docs/archive/obsolete/PROCEDURE-API-GITEA.md @@ -0,0 +1,180 @@ +# Procédure – Utilisation de l’API Gitea + +> **Archivé** (`docs/archive/obsolete/`) — **doublon** de +> [`26_GITEA-API.md`](../../26_GITEA-API.md). Ne pas modifier ici ; éditer le +> fichier numéroté. + +## 1. Contexte + +- **Instance** : https://git.ptits-pas.fr +- **API de base** : `https://git.ptits-pas.fr/api/v1` +- **Projet P'titsPas** : dépôt `jmartin/petitspas` (owner = `jmartin`, repo = `petitspas`) + +## 2. Authentification + +### 2.1 Token + +Le token est défini dans l’environnement (ex. `~/.bashrc`) : + +```bash +export GITEA_TOKEN="" +``` + +Pour l’utiliser dans les commandes : + +```bash +source ~/.bashrc # ou : . ~/.bashrc +# Puis utiliser $GITEA_TOKEN dans les curl +``` + +### 2.2 En-tête HTTP + +Toutes les requêtes API doivent envoyer le token : + +```bash +-H "Authorization: token $GITEA_TOKEN" +``` + +Exemple : + +```bash +curl -s -H "Authorization: token $GITEA_TOKEN" \ + "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas" +``` + +## 3. Endpoints utiles + +### 3.1 Dépôt (repository) + +| Action | Méthode | URL | +|---------------|---------|-----| +| Infos dépôt | GET | `/repos/{owner}/{repo}` | +| Liste dépôts | GET | `/repos/search?q=petitspas` | + +Exemple – infos du dépôt : + +```bash +curl -s -H "Authorization: token $GITEA_TOKEN" \ + "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas" | jq . +``` + +### 3.2 Issues (tickets) + +| Action | Méthode | URL | +|------------------|---------|-----| +| Liste des issues | GET | `/repos/{owner}/{repo}/issues` | +| Détail d’une issue | GET | `/repos/{owner}/{repo}/issues/{index}` | +| Créer une issue | POST | `/repos/{owner}/{repo}/issues` | +| Modifier une issue | PATCH | `/repos/{owner}/{repo}/issues/{index}` | +| Fermer une issue | PATCH | (même URL, `state: "closed"`) | + +**Paramètres GET utiles pour la liste :** + +- `state` : `open` ou `closed` +- `labels` : filtre par label (ex. `frontend`) +- `page`, `limit` : pagination + +Exemples : + +```bash +# Toutes les issues ouvertes +curl -s -H "Authorization: token $GITEA_TOKEN" \ + "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues?state=open" | jq . + +# Issues ouvertes avec label "frontend" +curl -s -H "Authorization: token $GITEA_TOKEN" \ + "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues?state=open" | \ + jq '.[] | select(.labels[].name == "frontend") | {number, title, state}' + +# Détail de l’issue #47 +curl -s -H "Authorization: token $GITEA_TOKEN" \ + "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues/47" | jq . + +# Fermer l’issue #31 +curl -s -X PATCH -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"state":"closed"}' \ + "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues/31" + +# Créer une issue +curl -s -X POST -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"title":"Titre du ticket","body":"Description","labels":[1]}' \ + "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues" +``` + +### 3.3 Pull requests + +| Action | Méthode | URL | +|---------------|---------|-----| +| Liste des PR | GET | `/repos/{owner}/{repo}/pulls` | +| Détail d’une PR | GET | `/repos/{owner}/{repo}/pulls/{index}` | +| Créer une PR | POST | `/repos/{owner}/{repo}/pulls` | +| Fusionner une PR | POST | `/repos/{owner}/{repo}/pulls/{index}/merge` | + +Exemples : + +```bash +# Liste des PR ouvertes +curl -s -H "Authorization: token $GITEA_TOKEN" \ + "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/pulls?state=open" | jq . + +# Créer une PR (head = branche source, base = branche cible) +curl -s -X POST -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"head":"develop","base":"master","title":"Titre de la PR"}' \ + "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/pulls" +``` + +### 3.4 Branches + +| Action | Méthode | URL | +|---------------|---------|-----| +| Liste des branches | GET | `/repos/{owner}/{repo}/branches` | + +```bash +curl -s -H "Authorization: token $GITEA_TOKEN" \ + "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/branches" | jq '.[].name' +``` + +### 3.5 Webhooks + +| Action | Méthode | URL | +|---------------|---------|-----| +| Liste webhooks | GET | `/repos/{owner}/{repo}/hooks` | +| Créer webhook | POST | `/repos/{owner}/{repo}/hooks` | + +### 3.6 Labels + +| Action | Méthode | URL | +|---------------|---------|-----| +| Liste des labels | GET | `/repos/{owner}/{repo}/labels` | + +```bash +curl -s -H "Authorization: token $GITEA_TOKEN" \ + "https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/labels" | jq '.[] | {id, name}' +``` + +## 4. Résumé des URLs pour P'titsPas + +Remplacer `{owner}` par `jmartin` et `{repo}` par `petitspas` : + +| Ressource | URL | +|------------------|-----| +| Dépôt | `https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas` | +| Issues | `https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues` | +| Issue #n | `https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues/{n}` | +| Pull requests | `https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/pulls` | +| Branches | `https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/branches` | +| Labels | `https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/labels` | + +## 5. Documentation officielle + +- Swagger / OpenAPI : https://docs.gitea.com/api +- Référence selon la version de Gitea installée (ex. 1.21, 1.25). + +## 6. Dépannage + +- **401 Unauthorized** : vérifier le token et l’en-tête `Authorization: token `. +- **404** : vérifier owner/repo et l’URL (sensible à la casse). +- **422 / body invalide** : pour POST/PATCH, envoyer `Content-Type: application/json` et un JSON valide. diff --git a/docs/archive/obsolete/README.md b/docs/archive/obsolete/README.md new file mode 100644 index 0000000..ade8bb1 --- /dev/null +++ b/docs/archive/obsolete/README.md @@ -0,0 +1,14 @@ +# Obsolete + +Ancienne documentation **déplacée** depuis `docs/` : + +| Fichier | Motif | +|---------|--------| +| `PROCEDURE-API-GITEA.md` | Doublon fonctionnel de + [**26_GITEA-API.md**](../../26_GITEA-API.md). | +| `ARCHITECTURE_TECHNIQUE.md` | Non référencé ; la vue d’ensemble est dans + [**02_ARCHITECTURE.md**](../../02_ARCHITECTURE.md). | +| `STATUS-APPLICATION.md` | Instantané daté ; non tenu comme doc vivante. | + +Après vérification qu’aucun lien externe ne pointe encore vers ces chemins, on +peut **supprimer** ce sous-dossier ou ne garder que des pointeurs minimalistes. diff --git a/docs/STATUS-APPLICATION.md b/docs/archive/obsolete/STATUS-APPLICATION.md similarity index 92% rename from docs/STATUS-APPLICATION.md rename to docs/archive/obsolete/STATUS-APPLICATION.md index 83461d0..fb25f26 100644 --- a/docs/STATUS-APPLICATION.md +++ b/docs/archive/obsolete/STATUS-APPLICATION.md @@ -1,5 +1,8 @@ # Statut de l'application P'titsPas +> **Archivé** (`docs/archive/obsolete/`) — instantané du **8 février 2026**, non +> maintenu comme référence courante. Voir `docs/00_INDEX.md` pour la doc à jour. + **Date du point** : 8 février 2026 --- @@ -99,8 +102,8 @@ Un seul déploiement à la fois (verrou) ; plus d’étape Prisma dans le script | `11_API.md` | Endpoints API | | `20_WORKFLOW-CREATION-COMPTE.md` | Workflow création compte | | `23_LISTE-TICKETS.md` | Liste des tickets | -| `BRIEFING-FRONTEND.md` | Brief frontend, accès Git, tickets prioritaires | -| `PROCEDURE-API-GITEA.md` | Utilisation API Gitea (issues, PR, token) | +| `27_BRIEFING-FRONTEND.md` | Brief frontend, accès Git, tickets prioritaires | +| `26_GITEA-API.md` | Utilisation API Gitea (issues, PR, token) | --- diff --git a/docs/POINT_TICKETS_FRONT_API.txt b/docs/archive/temporaires/POINT_TICKETS_FRONT_API.txt similarity index 95% rename from docs/POINT_TICKETS_FRONT_API.txt rename to docs/archive/temporaires/POINT_TICKETS_FRONT_API.txt index 7f32219..fac0b2d 100644 --- a/docs/POINT_TICKETS_FRONT_API.txt +++ b/docs/archive/temporaires/POINT_TICKETS_FRONT_API.txt @@ -1,3 +1,4 @@ +# Archivé docs/archive/temporaires/ — export jetable, supprimer si inutile. Point tickets frontend (API Gitea) - 27/01/2026 ================================================ diff --git a/docs/archive/temporaires/README.md b/docs/archive/temporaires/README.md new file mode 100644 index 0000000..bde6fa3 --- /dev/null +++ b/docs/archive/temporaires/README.md @@ -0,0 +1,10 @@ +# Temporaires + +Fichiers **non numérotés** de travail (brouillons, listes de tickets exportées, +alignements UI en cours, etc.). + +- Préfixe conseillé pour les nouveaux fichiers jetables : **`TEMP_`** ou + **`WIP_`** dans ce dossier. +- **Suppression** : dès que la fonctionnalité est livrée ou le sujet clos, + supprimer le fichier (ou le déplacer vers `obsolete/` si une trace utile + reste nécessaire). diff --git a/docs/TEMP_FRONT_alignement_AM.md b/docs/archive/temporaires/TEMP_FRONT_alignement_AM.md similarity index 92% rename from docs/TEMP_FRONT_alignement_AM.md rename to docs/archive/temporaires/TEMP_FRONT_alignement_AM.md index 6a53adc..21f2eed 100644 --- a/docs/TEMP_FRONT_alignement_AM.md +++ b/docs/archive/temporaires/TEMP_FRONT_alignement_AM.md @@ -1,6 +1,8 @@ # TEMP — Alignement front / API (inscription AM & validation gestionnaire) -> **Fichier temporaire** : à supprimer ou renommer une fois le front livré. +> **Archivé** (`docs/archive/temporaires/`) — **fichier temporaire** ; à +> **supprimer** une fois le front livré ou le sujet clos (voir +> `docs/archive/temporaires/README.md`). Ce document décrit les changements **côté API** et ce que **Flutter** doit faire pour rester aligné. Aucune modification front n’a été faite dans le chantier backend associé. diff --git a/docs/juridique/22_DOCUMENTS-LEGAUX.md b/docs/juridique/22_DOCUMENTS-LEGAUX.md new file mode 100644 index 0000000..89e3f4e --- /dev/null +++ b/docs/juridique/22_DOCUMENTS-LEGAUX.md @@ -0,0 +1,698 @@ +# 📄 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/juridique/README.md b/docs/juridique/README.md new file mode 100644 index 0000000..6cc5728 --- /dev/null +++ b/docs/juridique/README.md @@ -0,0 +1,41 @@ +# Juridique · P'titsPas + +Ce dossier regroupe la **documentation juridique** et les **sources Markdown** +destinées à être publiées (souvent en **PDF**) dans l’application : notamment +l’écran d’**acceptation à l’inscription** (CGU + politique de confidentialité). + +## Documents « application » (à exporter en PDF) + +| Fichier | Rôle | +|--------|------| +| [**cgu.md**](./cgu.md) | **Conditions générales d’utilisation** du service | +| [**politique-confidentialite.md**](./politique-confidentialite.md) | **Politique de confidentialité** (RGPD, droits, finalités) | + +Ces deux fichiers correspondent aux types **`cgu`** et **`privacy`** côté API +documents légaux (voir doc technique ci-dessous). + +## Document complémentaire (optionnel) + +| Fichier | Rôle | +|--------|------| +| [**cgc.md**](./cgc.md) | **Conditions générales contractuelles** (cadre + d’engagement des parties) — distinct de la politique de confidentialité | + +## Documentation technique + +| Fichier | Rôle | +|--------|------| +| [**22_DOCUMENTS-LEGAUX.md**](./22_DOCUMENTS-LEGAUX.md) | API, BDD, versioning, + traçabilité des acceptations | + +> Tous les textes ci-dessus sont des **brouillons** à valider par un **juriste** +> ou la **DPD/DPO** avant diffusion en production. + +## Export PDF (local) + +1. Ouvrir le `.md` dans Cursor. +2. `Ctrl+Shift+P` → **Markdown PDF: Export (pdf)** (extension *Markdown PDF*, + auteur yzane). + +Les PDF déployés côté API sont décrits dans +[22_DOCUMENTS-LEGAUX.md](./22_DOCUMENTS-LEGAUX.md). diff --git a/docs/juridique/cgc.md b/docs/juridique/cgc.md new file mode 100644 index 0000000..97ee909 --- /dev/null +++ b/docs/juridique/cgc.md @@ -0,0 +1,116 @@ +# Conditions générales contractuelles (CGC) + +**Produit** : P'titsPas +**Version document** : 0.1 (brouillon) +**Date** : avril 2026 +**Statut** : à valider juridiquement avant publication + +> **Ce document n’est pas** la **politique de confidentialité** (données +> personnelles / RGPD) : voir +> [**politique-confidentialite.md**](./politique-confidentialite.md). + +--- + +## 1. Objet + +Les présentes **conditions générales contractuelles** (« CGC ») définissent le +**cadre contractuel** entre les **parties** impliquées dans l’usage de la +plateforme **P'titsPas** pour la gestion de la garde d’enfants au sein des +**collectivités** ou structures habilitées. + +Elles complètent les [**conditions générales d’utilisation**](./cgu.md) (CGU), +qui régissent l’usage du **Service numérique** lui-même. + +--- + +## 2. Parties + +Selon les cas d’usage du déploiement, peuvent notamment être parties : + +- la **collectivité** ou l’**employeur public** porteur du dispositif ; +- l’**Éditeur** ou l’**opérateur** assurant l’hébergement et la maintenance du + Service ; +- les **Utilisateurs** (parents, assistantes maternelles, relais d’assistantes + maternelles, gestionnaires, etc.). + +[À compléter : identification précise des personnes morales signataires et +rôles (maîtrise d’ouvrage, maîtrise d’œuvre, délégation).] + +--- + +## 3. Objet du contrat + +Le contrat a pour objet de préciser : + +- les **missions** et **responsabilités** de chaque catégorie d’acteur ; +- les **conditions d’inscription**, de **validation** des dossiers et de + **clôture** des comptes ; +- les **obligations** en matière de **sincérité** des informations et de + **coopération** avec les services compétents. + +--- + +## 4. Obligations des Utilisateurs + +Les Utilisateurs s’engagent à : + +- respecter le **cadre légal** applicable à la garde d’enfants et à la + protection de l’enfance ; +- ne fournir que des **documents** et **informations** licites et, le cas échéant, + conformes aux demandes des gestionnaires ; +- respecter la **charte d’usage** et les consignes communiquées par la + collectivité ou l’Éditeur. + +--- + +## 5. Obligations de la collectivité / de l’Éditeur + +[À compléter : disponibilité cible, support, sauvegardes, sous-traitance, +sous-traitants, transferts hors UE, etc.] + +--- + +## 6. Durée et résiliation + +Le présent cadre contractuel est conclu pour la **durée** d’utilisation du +Service par les Utilisateurs concernés, sous réserve des **résiliations** +prévues par la réglementation ou par décision légitime de l’Éditeur / de la +collectivité. + +La **résiliation** d’un compte Utilisateur n’implique pas nécessairement la +**suppression immédiate** de toutes les données ; les **archives** et délais +peuvent être imposés par la loi. + +--- + +## 7. Modification + +Les CGC peuvent être **adaptées** (évolution réglementaire, organisation du +dispositif). Les Utilisateurs en sont informés par un **moyen approprié** et, +lorsque la loi ou la pratique l’exige, une **nouvelle acceptation** est +enregistrée. + +--- + +## 8. Responsabilité et assurance + +[À compléter : plafonds, exclusions, co-traitance, garanties, assurance +responsabilité civile, etc.] + +--- + +## 9. Litiges + +[À compléter : médiation, compétence territoriale, droit applicable.] + +--- + +## 10. Dispositions finales + +[À compléter : intégralité de l’accord, nullité partielle, langue de référence, +date d’effet.] + +--- + +*Document généré comme base de travail pour le projet P'titsPas. Il ne +constitue pas un conseil juridique.* diff --git a/docs/juridique/cgu.md b/docs/juridique/cgu.md new file mode 100644 index 0000000..609e607 --- /dev/null +++ b/docs/juridique/cgu.md @@ -0,0 +1,119 @@ +# Conditions générales d’utilisation (CGU) + +**Produit** : P'titsPas +**Version document** : 0.2 (brouillon) +**Date** : avril 2026 +**Statut** : à valider juridiquement avant publication + +--- + +## 1. Objet et champ d’application + +Les présentes **conditions générales d’utilisation** (« CGU ») encadrent +l’accès et l’usage de la **plateforme logicielle P'titsPas** (ci-après le +« **Service** »), dédiée à l’organisation de la **garde d’enfants de 0 à 3 ans** +dans le cadre des **collectivités locales** ou structures habilitées. + +Toute **création de compte** ou **utilisation** du Service vaut acceptation des +CGU en vigueur au moment de l’utilisation. + +--- + +## 2. Définitions + +- **Éditeur** : la personne morale ou la collectivité responsable du + déploiement et de l’administration du Service. +- **Utilisateur** : toute personne disposant d’un compte (parent, assistante + maternelle, relais, gestionnaire, administrateur, etc.). +- **Données** : informations saisies ou générées dans le Service. + +--- + +## 3. Accès au Service + +Le Service est accessible selon les **modalités techniques** définies par +l’Éditeur (URL, authentification, pare-feu, etc.). + +L’Éditeur peut **suspendre** ou **restreindre** l’accès pour maintenance, +sécurité ou obligation légale, dans la mesure du possible en informant les +Utilisateurs par un moyen adapté. + +--- + +## 4. Comptes et sécurité + +Chaque Utilisateur s’engage à : + +- fournir des **informations exactes** et les mettre à jour ; +- **garder confidentiels** ses identifiants et mots de passe ; +- signaler sans délai toute **utilisation non autorisée** de son compte. + +L’Éditeur peut **désactiver** un compte en cas de manquement grave aux présentes +CGU ou à la réglementation applicable. + +--- + +## 5. Usage loyal du Service + +Il est notamment interdit d’utiliser le Service pour : + +- porter atteinte aux **droits des tiers** ou à l’**ordre public** ; +- tenter d’**accéder** de manière frauduleuse à des données ou des fonctions non + autorisées ; +- **perturber** le fonctionnement du Service (attaques, surcharge, etc.). + +--- + +## 6. Propriété intellectuelle + +Les **éléments** du Service (logiciel, charte graphique, documentation interne +non publique, etc.) restent la propriété de leurs titulaires respectifs, sauf +mention contraire. + +Les **contenus** saisis par les Utilisateurs (textes, pièces jointes autorisées) +restent sous leur responsabilité ; ils concèdent à l’Éditeur les droits +**strictement nécessaires** à l’hébergement et au fonctionnement du Service. + +--- + +## 7. Données personnelles + +Le traitement des données personnelles est décrit dans la [**politique de +confidentialité**](./politique-confidentialite.md) et les documents affichés +dans le Service, conformément au **RGPD** et aux obligations locales. + +--- + +## 8. Responsabilité + +Le Service est fourni **en l’état**, dans les limites de l’état de l’art et des +moyens raisonnables de l’Éditeur. + +L’Éditeur ne saurait être tenu responsable des **dommages indirects** ou des +**indisponibilités** indépendantes de sa volonté, dans les limites autorisées par +la loi. + +--- + +## 9. Évolution des CGU + +Les CGU peuvent être **modifiées**. Les Utilisateurs sont informés selon les +moyens prévus (notification, ré-affichage à la connexion, etc.). La **version** +acceptée est **tracée** dans le Service lorsque la fonctionnalité est activée. + +--- + +## 10. Droit applicable et litiges + +[À compléter : droit applicable, juridiction compétente, médiation éventuelle.] + +--- + +## 11. Contact + +[À compléter : coordonnées du DPO ou du service utilisateurs.] + +--- + +*Document généré comme base de travail pour le projet P'titsPas. Il ne +constitue pas un conseil juridique.* diff --git a/docs/juridique/cgu.pdf b/docs/juridique/cgu.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0ee1b6885a224d7dd5040f13576e9b88438c7023 GIT binary patch literal 59965 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

9)u-pN)M+p_<~DM;o~gBK>Al6N}nKfIrf1Zu<4b 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

#F6)s9HCaL? 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 literal 0 HcmV?d00001 diff --git a/frontend/lib/services/api/api_config.dart b/frontend/lib/services/api/api_config.dart index 5e32ef4..b3fe61d 100644 --- a/frontend/lib/services/api/api_config.dart +++ b/frontend/lib/services/api/api_config.dart @@ -27,6 +27,12 @@ class ApiConfig { return u; } final base = baseUrl.replaceAll(RegExp(r'/+$'), ''); + // Le back renvoie parfois des chemins déjà préfixés `/api/v1/...` (ex. documents + // légaux). Ne pas les coller à [baseUrl] sous peine de doubler `/api/v1`. + if (u.startsWith('/api/')) { + final origin = apiOrigin.replaceAll(RegExp(r'/+$'), ''); + return '$origin$u'; + } return u.startsWith('/') ? '$base$u' : '$base/$u'; } diff --git a/frontend/lib/services/user_service.dart b/frontend/lib/services/user_service.dart index 425e4bf..4db19ed 100644 --- a/frontend/lib/services/user_service.dart +++ b/frontend/lib/services/user_service.dart @@ -8,6 +8,39 @@ import 'package:p_tits_pas/models/dossier_unifie.dart'; import 'package:p_tits_pas/services/api/api_config.dart'; import 'package:p_tits_pas/services/api/tokenService.dart'; +class DocumentActifInfo { + final String id; + final String type; + final int version; + final String url; + + const DocumentActifInfo({ + required this.id, + required this.type, + required this.version, + required this.url, + }); + + factory DocumentActifInfo.fromJson(Map json) { + return DocumentActifInfo( + id: (json['id'] ?? '').toString(), + type: (json['type'] ?? '').toString(), + version: int.tryParse((json['version'] ?? '').toString()) ?? 0, + url: (json['url'] ?? '').toString(), + ); + } +} + +class DocumentsActifsInfo { + final DocumentActifInfo cgu; + final DocumentActifInfo privacy; + + const DocumentsActifsInfo({ + required this.cgu, + required this.privacy, + }); +} + class UserService { static Future> _headers() async { final token = await TokenService.getToken(); @@ -34,6 +67,46 @@ class UserService { return _toStr(err) ?? 'Erreur inconnue'; } + /// Documents légaux actifs (CGU + privacy). GET /documents-legaux/actifs. + static Future getDocumentsLegauxActifs() async { + final response = await http.get( + Uri.parse('${ApiConfig.baseUrl}/documents-legaux/actifs'), + headers: ApiConfig.headers, + ); + if (response.statusCode != 200) { + try { + final err = jsonDecode(response.body); + throw Exception(_errMessage(err is Map ? err['message'] : err)); + } catch (e) { + if (e is Exception) rethrow; + throw Exception( + 'Erreur chargement documents légaux (${response.statusCode})', + ); + } + } + + try { + final decoded = jsonDecode(response.body); + if (decoded is! Map) { + throw const FormatException('Réponse invalide'); + } + final cgu = decoded['cgu']; + final privacy = decoded['privacy']; + if (cgu is! Map || privacy is! Map) { + throw const FormatException('Documents actifs manquants'); + } + return DocumentsActifsInfo( + cgu: DocumentActifInfo.fromJson(Map.from(cgu)), + privacy: DocumentActifInfo.fromJson(Map.from(privacy)), + ); + } catch (e) { + if (e is FormatException) rethrow; + throw Exception( + 'Réponse invalide (documents légaux): ${e is Exception ? e.toString() : "format inattendu"}', + ); + } + } + /// Utilisateurs en attente de validation (GET /users/pending). Ticket #107. static Future> getPendingUsers({String? role}) async { final query = role != null ? '?role=$role' : ''; diff --git a/frontend/lib/widgets/cgu_privacy_validation_dialog.dart b/frontend/lib/widgets/cgu_privacy_validation_dialog.dart new file mode 100644 index 0000000..73b9ac2 --- /dev/null +++ b/frontend/lib/widgets/cgu_privacy_validation_dialog.dart @@ -0,0 +1,449 @@ +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:http/http.dart' as http; +import 'package:pdfx/pdfx.dart'; +import 'package:universal_platform/universal_platform.dart'; + +import '../services/api/api_config.dart'; +import '../services/user_service.dart'; + +/// Tons **turquoise / menthe** (charte : `#8AD0C8`) — plus doux que le vert +/// Material « gazon ». +abstract final class _ModaleCouleur { + static const Color turquoise = Color(0xFF8AD0C8); + static const Color turquoiseFonce = Color(0xFF5A9D94); + static const Color mentheTresClair = Color(0xFFF3FAF8); + static const Color mentheClair = Color(0xFFE2F3EF); + static const Color ivoire = Color(0xFFFFFEF9); + static const Color encre = Color(0xFF2F2F2F); +} + +enum LegalDocType { + cgu, + privacy, +} + +class CguPrivacyValidationDialog extends StatefulWidget { + const CguPrivacyValidationDialog({super.key}); + + @override + State createState() => + _CguPrivacyValidationDialogState(); +} + +class _CguPrivacyValidationDialogState extends State { + bool _loadingLegalDocs = false; + DocumentActifInfo? _cguDoc; + DocumentActifInfo? _privacyDoc; + LegalDocType _selectedDocType = LegalDocType.cgu; + + static const double _cornerRadius = 16; + + @override + void initState() { + super.initState(); + _loadActiveLegalDocs(); + } + + Future _loadActiveLegalDocs() async { + setState(() => _loadingLegalDocs = true); + try { + final docs = await UserService.getDocumentsLegauxActifs(); + if (!mounted) return; + setState(() { + _cguDoc = docs.cgu; + _privacyDoc = docs.privacy; + }); + } catch (_) { + // Silencieux : message dans la zone PDF si besoin. + } finally { + if (mounted) setState(() => _loadingLegalDocs = false); + } + } + + /// Sur le web, [PdfDocument.openFile] n’est pas implémenté : on charge les + /// octets puis [PdfDocument.openData]. + Future _fetchPdfBytes(String pathOrUrl) async { + final absolute = ApiConfig.absoluteMediaUrl(pathOrUrl); + final response = await http.get(Uri.parse(absolute)); + if (response.statusCode != 200) { + throw StateError('PDF indisponible (HTTP ${response.statusCode})'); + } + return response.bodyBytes; + } + + Future? get _currentPdfDocumentFuture { + switch (_selectedDocType) { + case LegalDocType.cgu: + if (_cguDoc == null) return null; + return PdfDocument.openData(_fetchPdfBytes(_cguDoc!.url)); + case LegalDocType.privacy: + if (_privacyDoc == null) return null; + return PdfDocument.openData(_fetchPdfBytes(_privacyDoc!.url)); + } + } + + String get _dialogTitle { + switch (_selectedDocType) { + case LegalDocType.cgu: + return 'Conditions Générales d’Utilisation'; + case LegalDocType.privacy: + return 'Politique de Confidentialité'; + } + } + + bool get _canValidate { + return (_cguDoc != null && _privacyDoc != null) || + (_cguDoc != null && + _privacyDoc == null && + _selectedDocType == LegalDocType.cgu) || + (_privacyDoc != null && + _cguDoc == null && + _selectedDocType == LegalDocType.privacy); + } + + /// [PdfViewPinch] n’est pas supporté sur Windows (pdfx) : repli [PdfView]. + Widget _buildPdfBody() { + final doc = _currentPdfDocumentFuture!; + final key = ValueKey(_selectedDocType); + if (UniversalPlatform.isWindows) { + return PdfView( + key: key, + scrollDirection: Axis.vertical, + controller: PdfController(document: doc), + backgroundDecoration: const BoxDecoration(color: Colors.white), + ); + } + return _PdfPaneWithScrollbar( + key: key, + documentFuture: doc, + ); + } + + @override + Widget build(BuildContext context) { + final size = MediaQuery.sizeOf(context); + final dialogW = size.width * 0.92; + final dialogH = size.height * 0.88; + + return Dialog( + insetPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 20), + backgroundColor: Colors.transparent, + elevation: 0, + child: ClipRRect( + borderRadius: BorderRadius.circular(_cornerRadius), + child: Material( + color: _ModaleCouleur.ivoire, + elevation: 6, + shadowColor: _ModaleCouleur.encre.withValues(alpha: 0.12), + child: SizedBox( + width: dialogW, + height: dialogH, + child: Column( + children: [ + _buildHeader(context), + Padding( + padding: const EdgeInsets.fromLTRB(12, 8, 12, 4), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _tabButton( + context, + label: 'CGU', + selected: _selectedDocType == LegalDocType.cgu, + enabled: !_loadingLegalDocs && _cguDoc != null, + onTap: () => setState( + () => _selectedDocType = LegalDocType.cgu, + ), + ), + const SizedBox(width: 10), + _tabButton( + context, + label: 'Confidentialité', + selected: _selectedDocType == LegalDocType.privacy, + enabled: !_loadingLegalDocs && _privacyDoc != null, + onTap: () => setState( + () => _selectedDocType = LegalDocType.privacy, + ), + ), + ], + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.fromLTRB(12, 4, 12, 8), + child: DecoratedBox( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: _ModaleCouleur.turquoiseFonce.withValues( + alpha: 0.35, + ), + ), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(12), + child: _loadingLegalDocs + ? const Center( + child: CircularProgressIndicator( + color: _ModaleCouleur.turquoiseFonce, + strokeWidth: 3, + ), + ) + : _currentPdfDocumentFuture != null + ? _buildPdfBody() + : Center( + child: Text( + 'Document non disponible.', + style: GoogleFonts.merienda( + color: _ModaleCouleur.encre + .withValues(alpha: 0.75), + ), + ), + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(16, 8, 16, 16), + child: Center( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 520), + child: FilledButton( + onPressed: _canValidate + ? () => Navigator.of(context).pop(true) + : null, + style: FilledButton.styleFrom( + backgroundColor: _ModaleCouleur.turquoiseFonce, + foregroundColor: Colors.white, + disabledBackgroundColor: + _ModaleCouleur.mentheClair.withValues(alpha: 0.7), + disabledForegroundColor: + _ModaleCouleur.encre.withValues(alpha: 0.45), + padding: const EdgeInsets.symmetric( + horizontal: 20, + vertical: 14, + ), + ), + child: Text( + 'Valider les CGU et la Politique ' + 'de Confidentialité', + textAlign: TextAlign.center, + style: GoogleFonts.merienda( + fontSize: 14, + fontWeight: FontWeight.w600, + ), + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), + ); + } + + Widget _buildHeader(BuildContext context) { + return DecoratedBox( + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + _ModaleCouleur.mentheTresClair, + _ModaleCouleur.mentheClair, + ], + ), + ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2), + child: Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 8), + child: Text( + _dialogTitle, + style: GoogleFonts.merienda( + fontSize: 17, + fontWeight: FontWeight.w600, + color: _ModaleCouleur.encre, + height: 1.25, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ), + ), + IconButton( + tooltip: 'Fermer', + icon: Icon( + Icons.close, + color: _ModaleCouleur.encre.withValues(alpha: 0.55), + ), + onPressed: () => Navigator.of(context).pop(false), + ), + ], + ), + ), + ); + } + + Widget _tabButton( + BuildContext context, { + required String label, + required bool selected, + required bool enabled, + required VoidCallback onTap, + }) { + return OutlinedButton( + onPressed: enabled ? onTap : null, + style: OutlinedButton.styleFrom( + foregroundColor: _ModaleCouleur.encre, + backgroundColor: selected + ? _ModaleCouleur.turquoise + : _ModaleCouleur.mentheTresClair, + side: BorderSide( + color: _ModaleCouleur.turquoiseFonce.withValues(alpha: 0.55), + width: 1.5, + ), + padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 10), + ), + child: Text( + label, + style: GoogleFonts.merienda( + fontSize: 13, + fontWeight: selected ? FontWeight.w600 : FontWeight.w500, + ), + ), + ); + } +} + +/// [PdfViewPinch] s’appuie sur un [InteractiveViewer], sans vrai [Scrollable] : +/// barre verticale reliée à [PdfControllerPinch.documentProgress] pour que le +/// « chariot » reste visible (surtout sur le web où la barre OS est souvent +/// masquée). +class _PdfPaneWithScrollbar extends StatefulWidget { + const _PdfPaneWithScrollbar({ + super.key, + required this.documentFuture, + }); + + final Future documentFuture; + + @override + State<_PdfPaneWithScrollbar> createState() => _PdfPaneWithScrollbarState(); +} + +class _PdfPaneWithScrollbarState extends State<_PdfPaneWithScrollbar> { + static const double _barW = 14; + static const double _thumbW = 9; + static const double _minThumbH = 44; + + late final PdfControllerPinch _ctrl; + + @override + void initState() { + super.initState(); + _ctrl = PdfControllerPinch(document: widget.documentFuture); + _ctrl.addListener(_onCtrl); + } + + void _onCtrl() { + // [PdfViewPinch] met à jour documentProgress dans son propre listener : + // replanifier pour lire la valeur après ce tour de notifications. + Future.microtask(() { + if (mounted) setState(() {}); + }); + } + + @override + void dispose() { + _ctrl.removeListener(_onCtrl); + _ctrl.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final raw = _ctrl.documentProgress; + final safeP = (!raw.isFinite || raw.isNaN) ? 0.0 : raw.clamp(0.0, 1.0); + + return Stack( + clipBehavior: Clip.hardEdge, + fit: StackFit.expand, + children: [ + Padding( + padding: const EdgeInsets.only(right: _barW), + child: PdfViewPinch( + padding: 10, + scrollDirection: Axis.vertical, + minScale: 1, + maxScale: 4, + controller: _ctrl, + backgroundDecoration: const BoxDecoration(color: Colors.white), + ), + ), + Positioned( + top: 6, + right: 1, + bottom: 6, + width: _barW, + child: LayoutBuilder( + builder: (context, c) { + final trackH = c.maxHeight; + final thumbH = (trackH * 0.2).clamp(_minThumbH, trackH * 0.5); + final maxTop = (trackH - thumbH).clamp(0.0, double.infinity); + final top = safeP * maxTop; + + return Semantics( + label: 'Position dans le document', + child: Stack( + children: [ + Positioned.fill( + child: DecoratedBox( + decoration: BoxDecoration( + color: _ModaleCouleur.turquoise.withValues( + alpha: 0.35, + ), + borderRadius: BorderRadius.circular(8), + ), + ), + ), + Positioned( + top: top, + left: (_barW - _thumbW) / 2, + child: Container( + width: _thumbW, + height: thumbH, + decoration: BoxDecoration( + color: _ModaleCouleur.turquoiseFonce, + borderRadius: BorderRadius.circular(_thumbW / 2), + boxShadow: const [ + BoxShadow( + color: Color(0x40000000), + blurRadius: 3, + offset: Offset(0, 1), + ), + ], + ), + ), + ), + ], + ), + ); + }, + ), + ), + ], + ); + } +} diff --git a/frontend/lib/widgets/presentation_form_screen.dart b/frontend/lib/widgets/presentation_form_screen.dart index ace8df1..fd2d310 100644 --- a/frontend/lib/widgets/presentation_form_screen.dart +++ b/frontend/lib/widgets/presentation_form_screen.dart @@ -1,7 +1,8 @@ +import 'dart:math' as math; + import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:go_router/go_router.dart'; -import 'dart:math' as math; import 'custom_decorated_text_field.dart'; import 'app_custom_checkbox.dart'; @@ -9,6 +10,7 @@ import 'custom_navigation_button.dart'; import 'hover_relief_widget.dart'; import '../models/card_assets.dart'; import '../config/display_config.dart'; +import 'cgu_privacy_validation_dialog.dart'; /// Widget générique pour le formulaire de présentation avec texte libre + CGU /// Supporte mode éditable et readonly, responsive mobile/desktop @@ -75,6 +77,52 @@ class _PresentationFormScreenState extends State { widget.onSubmit(_textController.text, _cguAccepted); } + Future _openCguValidationDialog() async { + final validated = await showDialog( + context: context, + builder: (context) => const CguPrivacyValidationDialog(), + ); + + if (validated == true && mounted) { + setState(() => _cguAccepted = true); + } + } + + Widget _buildCguValidationControl({ + required double fontSize, + bool compact = false, + }) { + final label = compact + ? 'J’ai validé les CGU et la\nPolitique de confidentialité' + : 'J’ai validé les Conditions Générales\nd’Utilisation et la Politique de confidentialité'; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Checkbox( + value: _cguAccepted, + onChanged: null, + ), + Flexible( + child: Text( + label, + style: GoogleFonts.merienda(fontSize: fontSize), + ), + ), + ], + ), + const SizedBox(height: 6), + TextButton.icon( + onPressed: _openCguValidationDialog, + icon: const Icon(Icons.open_in_new, size: 18), + label: const Text('Consulter et valider les CGU'), + ), + ], + ); + } + @override Widget build(BuildContext context) { final screenSize = MediaQuery.of(context).size; @@ -451,11 +499,13 @@ class _PresentationFormScreenState extends State { ), ), const SizedBox(height: 20), - AppCustomCheckbox( - label: 'J\'accepte les Conditions Générales\nd\'Utilisation et la Politique de confidentialité', - value: _cguAccepted, - onChanged: config.isReadonly ? (v) {} : (value) => setState(() => _cguAccepted = value ?? false), - ), + config.isReadonly + ? AppCustomCheckbox( + label: 'J\'accepte les Conditions Générales\nd\'Utilisation et la Politique de confidentialité', + value: _cguAccepted, + onChanged: (v) {}, + ) + : _buildCguValidationControl(fontSize: 16), ], ), ), @@ -507,12 +557,17 @@ class _PresentationFormScreenState extends State { const SizedBox(height: 16), // Checkbox en bas Transform.scale( - scale: 0.85, - child: AppCustomCheckbox( - label: 'J\'accepte les CGU et la\nPolitique de confidentialité', - value: _cguAccepted, - onChanged: config.isReadonly ? (v) {} : (value) => setState(() => _cguAccepted = value ?? false), - ), + scale: 0.95, + child: config.isReadonly + ? AppCustomCheckbox( + label: 'J\'accepte les CGU et la\nPolitique de confidentialité', + value: _cguAccepted, + onChanged: (v) {}, + ) + : _buildCguValidationControl( + fontSize: 14, + compact: true, + ), ), ], ), @@ -549,13 +604,19 @@ class _PresentationFormScreenState extends State { const SizedBox(width: 16), Expanded( child: HoverReliefWidget( - child: CustomNavigationButton( - text: 'Suivant', - style: NavigationButtonStyle.green, - onPressed: _handleSubmit, - width: double.infinity, - height: 50, - fontSize: 16, + child: Opacity( + opacity: _cguAccepted ? 1 : 0.55, + child: AbsorbPointer( + absorbing: !_cguAccepted, + child: CustomNavigationButton( + text: 'Suivant', + style: NavigationButtonStyle.green, + onPressed: _handleSubmit, + width: double.infinity, + height: 50, + fontSize: 16, + ), + ), ), ), ), diff --git a/frontend/pubspec.lock b/frontend/pubspec.lock index 8d88817..48350ec 100644 --- a/frontend/pubspec.lock +++ b/frontend/pubspec.lock @@ -57,6 +57,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.6" + extension: + dependency: transitive + description: + name: extension + sha256: be3a6b7f8adad2f6e2e8c63c895d19811fcf203e23466c6296267941d0ff4f24 + url: "https://pub.dev" + source: hosted + version: "0.6.0" fake_async: dependency: transitive description: @@ -113,6 +121,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.9.3+4" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.dev" + source: hosted + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -397,6 +413,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" + pdfx: + dependency: "direct main" + description: + name: pdfx + sha256: "29db9b71d46bf2335e001f91693f2c3fbbf0760e4c2eb596bf4bafab211471c1" + url: "https://pub.dev" + source: hosted + version: "2.9.2" + photo_view: + dependency: transitive + description: + name: photo_view + sha256: "1fc3d970a91295fbd1364296575f854c9863f225505c28c46e0a03e48960c75e" + url: "https://pub.dev" + source: hosted + version: "0.15.0" platform: dependency: transitive description: @@ -514,6 +546,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6" + url: "https://pub.dev" + source: hosted + version: "3.3.1" term_glyph: dependency: transitive description: @@ -538,6 +578,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + universal_platform: + dependency: "direct main" + description: + name: universal_platform + sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec" + url: "https://pub.dev" + source: hosted + version: "1.1.0" url_launcher: dependency: "direct main" description: @@ -602,6 +650,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.4" + uuid: + dependency: transitive + description: + name: uuid + sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489" + url: "https://pub.dev" + source: hosted + version: "4.5.3" vector_math: dependency: transitive description: diff --git a/frontend/pubspec.yaml b/frontend/pubspec.yaml index 369295c..d9f9b57 100644 --- a/frontend/pubspec.yaml +++ b/frontend/pubspec.yaml @@ -20,6 +20,8 @@ dependencies: url_launcher: ^6.2.4 http: ^1.2.2 # flutter_secure_storage: ^9.0.0 + pdfx: ^2.5.0 + universal_platform: ^1.1.0 dev_dependencies: flutter_test: @@ -32,6 +34,7 @@ flutter: assets: - assets/images/ # Déclarer le dossier entier - assets/cards/ # Nouveau dossier de cartes + - assets/documents/ fonts: - family: Merienda diff --git a/frontend/web/index.html b/frontend/web/index.html index 9b2a41d..da896cd 100644 --- a/frontend/web/index.html +++ b/frontend/web/index.html @@ -47,6 +47,16 @@ + +

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/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