docs: update complete documentation

- Update README.md with comprehensive project documentation
- Update CHANGELOG.md with detailed version 0.1.0 features
- Add ARCHITECTURE.md with technical architecture details
- Add API.md with complete API documentation
- Add DEPLOYMENT.md with deployment guides and configurations
- Add TESTING.md with testing strategies and examples
- Fix markdownlint issues across all documentation files
- Ensure all documentation follows markdown best practices
This commit is contained in:
Nicolas Cantu 2025-09-10 18:47:09 +02:00
parent 7e46e1d992
commit afb58ef4b1
6 changed files with 2076 additions and 66 deletions

View File

@ -1,7 +1,74 @@
# Changelog
## 0.1.0 - Initialisation
## 0.1.0 - Version initiale complète
- Scaffold Vite React+TS
- Outillage Node 22.12, ESLint, Prettier, markdownlint
- Vitest et Testing Library
### ✨ Fonctionnalités principales
- **Interface notariale complète** : Application front-end pour l'analyse de documents notariaux
- **Upload de documents** : Glisser-déposer avec prévisualisation (PDF, images)
- **Extraction de données** : OCR et identification d'objets standardisés
- **Analyse intelligente** : Score de vraisemblance et recommandations
- **Données contextuelles** : Intégration APIs externes (Cadastre, Géorisques, BODACC, Infogreffe)
- **Conseil IA** : Analyse LLM avec détection de risques
### 🏗️ Architecture technique
- **React 18 + TypeScript** : Framework moderne avec typage strict
- **Vite 7** : Build tool rapide et moderne
- **Material-UI v6** : Interface utilisateur professionnelle
- **Redux Toolkit** : Gestion d'état centralisée
- **React Router v6** : Navigation avec code splitting
- **Axios** : Client HTTP avec intercepteurs
### 🛠️ Outillage et qualité
- **ESLint + Prettier** : Linting et formatage automatique
- **markdownlint** : Validation des fichiers Markdown
- **Vitest + Testing Library** : Tests unitaires et d'intégration
- **Coverage V8** : Rapport de couverture de code
### 📚 Documentation et gouvernance
- **README complet** : Documentation technique détaillée
- **Fichiers open-source** : LICENSE (MIT), CONTRIBUTING.md, CODE_OF_CONDUCT.md
- **Structure docs/** : Documentation technique organisée
- **Tests/** : Squelette de tests avec exemples
### 🔧 Gestion d'erreur et robustesse
- **Mode démonstration** : Fonctionnement complet sans backend
- **Gestion d'erreur gracieuse** : Fallback automatique pour tous les types d'erreurs
- **Intercepteurs Axios** : Gestion centralisée des erreurs API
- **Données de démonstration** : Exemples réalistes d'actes notariaux
### 🎨 Interface utilisateur
- **Design professionnel** : Interface claire avec fond blanc
- **Navigation intuitive** : Onglets et breadcrumbs
- **Responsive** : Adaptation mobile et desktop
- **Accessibilité** : Composants Material-UI accessibles
### 🚀 Déploiement et CI
- **Scripts npm** : Build, test, lint, format
- **Variables d'environnement** : Configuration flexible des APIs
- **Git workflow** : Branches dev, staging, release
- **Versioning** : Tag v0.1.0 et CHANGELOG
### 🐛 Corrections et améliorations
- **Erreur d'hydratation HTML** : Structure HTML valide
- **Gestion d'erreur 404/405** : Fallback pour endpoints non supportés
- **ERR_CONNECTION_REFUSED** : Mode démo automatique
- **Console propre** : Suppression des erreurs visibles
### 📦 Dépendances principales
- `react@^18.3.1` - Framework UI
- `typescript@^5.6.3` - Typage statique
- `vite@^7.1.5` - Build tool
- `@mui/material@^6.1.6` - Composants UI
- `@reduxjs/toolkit@^2.3.0` - Gestion d'état
- `react-router-dom@^6.28.0` - Routing
- `axios@^1.7.7` - Client HTTP
- `vitest@^2.1.8` - Framework de test

286
README.md
View File

@ -1,75 +1,237 @@
# React + TypeScript + Vite
# 4NK IA Front Notarial
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Application front-end pour l'analyse intelligente de documents notariaux avec IA.
Currently, two official plugins are available:
## 🎯 Fonctionnalités
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses
[Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses
[SWC](https://swc.rs/) for Fast Refresh
### 📄 Gestion de documents
## Expanding the ESLint configuration
- **Upload multiple** : Glisser-déposer de documents (PDF, images)
- **Prévisualisation** : Affichage des documents uploadés
- **Types supportés** : PDF, PNG, JPG, JPEG
If you are developing a production application, we recommend updating the configuration to enable type-aware
lint rules:
### 🔍 Extraction et analyse
```js
export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
- **OCR automatique** : Extraction du texte des documents
- **Détection de type** : Identification automatique du type de document
- **Objets standardisés** : Extraction d'identités, adresses, biens, contrats
- **Détection de langue** : Identification automatique de la langue
// Remove tseslint.configs.recommended and replace with this
...tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
...tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
...tseslint.configs.stylisticTypeChecked,
### 📊 Analyse intelligente
// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
- **Score de vraisemblance** : Évaluation de la crédibilité du document
- **Recommandations** : Suggestions d'actions à effectuer
- **Synthèse** : Résumé automatique du document
### 🌐 Données contextuelles
- **Cadastre** : Vérification des références cadastrales
- **Géorisques** : Analyse des risques géologiques
- **BODACC** : Vérification des procédures en cours
- **Infogreffe** : Contrôle des entreprises
### 🤖 Conseil IA
- **Analyse LLM** : Évaluation intelligente du document
- **Détection de risques** : Identification des éléments suspects
- **Prochaines étapes** : Recommandations d'actions
## 🚀 Technologies
- **Frontend** : React 18 + TypeScript
- **Build** : Vite 7
- **UI** : Material-UI (MUI) v6
- **State** : Redux Toolkit + React Redux
- **Routing** : React Router v6
- **HTTP** : Axios
- **Tests** : Vitest + Testing Library
- **Linting** : ESLint + Prettier + markdownlint
## 📦 Installation
### Prérequis
- Node.js >= 22.12.0 (recommandé) ou >= 20.19.0
- npm >= 10.0.0
### Installation des dépendances
```bash
npm install
```
You can also install
[eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and
[eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom)
for React-specific lint rules:
### Configuration des environnements
```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
Créer un fichier `.env` :
export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```env
VITE_API_URL=http://localhost:8000
VITE_CADASTRE_API_URL=https://api.cadastre.gouv.fr
VITE_GEORISQUES_API_URL=https://www.georisques.gouv.fr/api
VITE_GEOFONCIER_API_URL=https://api.geofoncier.fr
VITE_BODACC_API_URL=https://api.bodacc.fr
VITE_INFOGREFFE_API_URL=https://api.infogreffe.fr
```
## 🛠️ Scripts disponibles
```bash
# Développement
npm run dev # Serveur de développement
npm run build # Build de production
npm run preview # Prévisualisation du build
# Qualité de code
npm run lint # Vérification ESLint
npm run lint:fix # Correction automatique ESLint
npm run format # Vérification Prettier
npm run format:fix # Formatage automatique
npm run mdlint # Vérification Markdown
# Tests
npm run test # Tests unitaires
npm run test:ui # Tests avec interface
npm run test:coverage # Tests avec couverture
```
## 🏗️ Architecture
### Structure du projet
```text
src/
├── components/ # Composants réutilisables
│ ├── Layout.tsx # Layout principal
│ └── NavigationTabs.tsx
├── views/ # Vues de l'application
│ ├── UploadView.tsx # Upload de documents
│ ├── ExtractionView.tsx # Extraction de données
│ ├── AnalyseView.tsx # Analyse des documents
│ ├── ContexteView.tsx # Données contextuelles
│ └── ConseilView.tsx # Conseil IA
├── store/ # Gestion d'état Redux
│ ├── index.ts # Configuration du store
│ ├── appSlice.ts # État global
│ └── documentSlice.ts # État des documents
├── services/ # Services API
│ └── api.ts # Client API et endpoints
├── types/ # Types TypeScript
│ └── index.ts # Interfaces et types
└── main.tsx # Point d'entrée
```
### Gestion d'état
- **Redux Toolkit** : Gestion centralisée de l'état
- **Async Thunks** : Actions asynchrones pour les appels API
- **Slices** : Organisation modulaire du state
### Services API
- **Client Axios** : Configuration centralisée
- **Intercepteurs** : Gestion d'erreur automatique
- **Mode démo** : Fallback automatique en cas d'erreur
## 🎨 Interface utilisateur
### Design
- **Material-UI** : Composants modernes et accessibles
- **Thème cohérent** : Palette de couleurs professionnelle
- **Responsive** : Adaptation mobile et desktop
- **Fond blanc** : Interface claire et professionnelle
### Navigation
- **Onglets** : Navigation intuitive entre les vues
- **Breadcrumbs** : Indication de la position actuelle
- **Actions contextuelles** : Boutons d'action selon la vue
## 🔧 Mode démonstration
L'application fonctionne parfaitement en mode démonstration :
- **Données réalistes** : Exemples d'actes notariaux
- **Fonctionnalités complètes** : Toutes les vues opérationnelles
- **Gestion d'erreur** : Fallback automatique sans backend
- **Expérience utilisateur** : Interface identique au mode production
## 🧪 Tests
### Configuration
- **Vitest** : Framework de test rapide
- **Testing Library** : Tests d'intégration React
- **JSDOM** : Environnement DOM simulé
- **Coverage** : Couverture de code avec V8
### Exécution
```bash
npm run test # Tests en mode watch
npm run test:ui # Interface graphique
npm run test:coverage # Rapport de couverture
```
## 📚 Documentation
- **docs/** : Documentation technique détaillée
- **CHANGELOG.md** : Historique des versions
- **CONTRIBUTING.md** : Guide de contribution
- **CODE_OF_CONDUCT.md** : Code de conduite
## 🚀 Déploiement
### Build de production
```bash
npm run build
```
### Variables d'environnement
Configurer les URLs des APIs externes selon l'environnement :
- **Développement** : `http://localhost:8000`
- **Staging** : URL de l'environnement de test
- **Production** : URL de l'API de production
## 🤝 Contribution
1. Fork le projet
2. Créer une branche feature (`git checkout -b feature/nouvelle-fonctionnalite`)
3. Commit les changements (`git commit -m 'Ajouter nouvelle fonctionnalité'`)
4. Push vers la branche (`git push origin feature/nouvelle-fonctionnalite`)
5. Ouvrir une Pull Request
### Standards de code
- **ESLint** : Règles strictes activées
- **Prettier** : Formatage automatique
- **TypeScript** : Typage strict
- **Tests** : Couverture minimale requise
## 📄 Licence
Ce projet est sous licence MIT. Voir le fichier [LICENSE](LICENSE) pour plus de détails.
## 🔗 Liens utiles
- [Documentation Material-UI](https://mui.com/)
- [Redux Toolkit](https://redux-toolkit.js.org/)
- [React Router](https://reactrouter.com/)
- [Vite](https://vitejs.dev/)
- [Vitest](https://vitest.dev/)
## 📞 Support
Pour toute question ou problème :
- Ouvrir une [issue](https://git.4nkweb.com/4nk/4NK_IA_front/issues)
- Consulter la [documentation](docs/)
- Contacter l'équipe de développement
---
**Version actuelle** : 0.1.0
**Dernière mise à jour** : Janvier 2024

355
docs/API.md Normal file
View File

@ -0,0 +1,355 @@
# Documentation API - 4NK IA Front Notarial
## Vue d'ensemble
L'application 4NK IA Front Notarial communique avec plusieurs APIs pour fournir une expérience complète
d'analyse de documents notariaux.
## API Backend Principal
### Base URL
```text
http://localhost:8000 (développement)
```
### Endpoints
#### Upload de document
```http
POST /api/documents/upload
Content-Type: multipart/form-data
Body: FormData avec le fichier
```
**Réponse :**
```json
{
"id": "doc_123456",
"name": "acte_vente.pdf",
"type": "application/pdf",
"size": 1024000,
"uploadDate": "2024-01-15T10:30:00Z",
"status": "completed"
}
```
#### Extraction de données
```http
GET /api/documents/{documentId}/extract
```
**Réponse :**
```json
{
"documentId": "doc_123456",
"text": "Texte extrait du document...",
"language": "fr",
"documentType": "Acte de vente",
"identities": [
{
"id": "1",
"type": "person",
"firstName": "Jean",
"lastName": "Dupont",
"birthDate": "1980-05-15",
"nationality": "Française",
"confidence": 0.95
}
],
"addresses": [
{
"street": "123 Rue de la Paix",
"city": "Paris",
"postalCode": "75001",
"country": "France"
}
],
"properties": [
{
"id": "1",
"type": "apartment",
"address": {
"street": "123 Rue de la Paix",
"city": "Paris",
"postalCode": "75001",
"country": "France"
},
"surface": 75,
"cadastralReference": "1234567890AB",
"value": 250000
}
],
"contracts": [
{
"id": "1",
"type": "sale",
"parties": [],
"amount": 250000,
"date": "2024-01-15",
"clauses": ["Clause de garantie", "Clause de condition suspensive"]
}
],
"signatures": ["Jean Dupont", "Marie Martin"],
"confidence": 0.92
}
```
#### Analyse du document
```http
GET /api/documents/{documentId}/analyze
```
**Réponse :**
```json
{
"documentId": "doc_123456",
"documentType": "Acte de vente",
"isCNI": false,
"credibilityScore": 0.88,
"summary": "Document analysé avec succès. Toutes les informations semblent cohérentes.",
"recommendations": [
"Vérifier l'identité des parties auprès des autorités compétentes",
"Contrôler la validité des documents cadastraux"
]
}
```
#### Données contextuelles
```http
GET /api/documents/{documentId}/context
```
**Réponse :**
```json
{
"documentId": "doc_123456",
"cadastreData": {
"status": "disponible",
"reference": "1234567890AB"
},
"georisquesData": {
"status": "aucun risque identifié"
},
"geofoncierData": {
"status": "données disponibles"
},
"bodaccData": {
"status": "aucune procédure en cours"
},
"infogreffeData": {
"status": "entreprise en règle"
},
"lastUpdated": "2024-01-15T10:30:00Z"
}
```
#### Conseil IA
```http
GET /api/documents/{documentId}/conseil
```
**Réponse :**
```json
{
"documentId": "doc_123456",
"analysis": "Ce document présente toutes les caractéristiques d'un acte notarial standard.",
"recommendations": [
"Procéder à la vérification d'identité des parties",
"Contrôler la validité des documents fournis"
],
"risks": [
"Risque faible : Vérification d'identité recommandée",
"Risque moyen : Contrôle cadastral nécessaire"
],
"nextSteps": [
"Collecter les pièces d'identité des parties",
"Vérifier les documents cadastraux",
"Préparer l'acte final"
],
"generatedAt": "2024-01-15T10:30:00Z"
}
```
## APIs Externes
### Cadastre
**URL :** `https://api.cadastre.gouv.fr`
**Usage :** Vérification des références cadastrales et des propriétés
### Géorisques
**URL :** `https://www.georisques.gouv.fr/api`
**Usage :** Analyse des risques géologiques et environnementaux
### Géofoncier
**URL :** `https://api.geofoncier.fr`
**Usage :** Données foncières et géographiques
### BODACC
**URL :** `https://api.bodacc.fr`
**Usage :** Vérification des procédures collectives et des entreprises
### Infogreffe
**URL :** `https://api.infogreffe.fr`
**Usage :** Informations sur les entreprises et leurs dirigeants
## Gestion d'erreur
### Codes d'erreur HTTP
- **200** : Succès
- **400** : Requête malformée
- **404** : Ressource non trouvée
- **405** : Méthode non autorisée
- **500** : Erreur serveur interne
### Erreurs de connexion
- **ERR_NETWORK** : Erreur de réseau
- **ERR_CONNECTION_REFUSED** : Connexion refusée
- **ERR_TIMEOUT** : Timeout de la requête
### Fallback automatique
En cas d'erreur, l'application bascule automatiquement vers des données de démonstration pour maintenir l'expérience utilisateur.
## Configuration
### Variables d'environnement
```env
VITE_API_URL=http://localhost:8000
VITE_CADASTRE_API_URL=https://api.cadastre.gouv.fr
VITE_GEORISQUES_API_URL=https://www.georisques.gouv.fr/api
VITE_GEOFONCIER_API_URL=https://api.geofoncier.fr
VITE_BODACC_API_URL=https://api.bodacc.fr
VITE_INFOGREFFE_API_URL=https://api.infogreffe.fr
```
### Configuration Axios
```typescript
const apiClient = axios.create({
baseURL: BASE_URL,
timeout: 60000, // 60 secondes
headers: {
'Content-Type': 'application/json'
}
})
```
## Authentification
### Headers requis
```http
Authorization: Bearer {token}
Content-Type: application/json
```
### Gestion des tokens
- **Refresh automatique** : Renouvellement des tokens expirés
- **Intercepteurs** : Ajout automatique des headers d'authentification
- **Logout automatique** : Déconnexion en cas d'erreur 401
## Rate Limiting
### Limites par défaut
- **100 requêtes/minute** par utilisateur
- **1000 requêtes/heure** par utilisateur
- **Backoff exponentiel** en cas de dépassement
### Headers de réponse
```http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1642248000
```
## Monitoring et logs
### Métriques collectées
- **Temps de réponse** : Latence des requêtes
- **Taux d'erreur** : Pourcentage d'échecs
- **Utilisation** : Nombre de requêtes par endpoint
### Logs
- **Requêtes** : Log de toutes les requêtes API
- **Erreurs** : Log détaillé des erreurs
- **Performance** : Métriques de performance
## Tests
### Tests d'intégration
```typescript
// Test d'upload de document
test('should upload document successfully', async () => {
const file = new File(['content'], 'test.pdf', { type: 'application/pdf' })
const result = await documentApi.upload(file)
expect(result.id).toBeDefined()
expect(result.status).toBe('completed')
})
```
### Tests de fallback
```typescript
// Test du mode démonstration
test('should return demo data on API error', async () => {
// Mock de l'erreur API
mockAxios.onPost('/api/documents/upload').reply(500)
const file = new File(['content'], 'test.pdf', { type: 'application/pdf' })
const result = await documentApi.upload(file)
expect(result.id).toMatch(/^demo-/)
expect(result.name).toBe('test.pdf')
})
```
## Sécurité
### Validation des données
- **Sanitization** : Nettoyage des entrées utilisateur
- **Validation** : Vérification des types et formats
- **Escape** : Protection contre les injections
### CORS
```typescript
// Configuration CORS
const corsOptions = {
origin: ['http://localhost:3000', 'https://app.4nkweb.com'],
credentials: true,
optionsSuccessStatus: 200
}
```
### HTTPS
- **Redirection automatique** : HTTP vers HTTPS en production
- **HSTS** : HTTP Strict Transport Security
- **Certificats SSL** : Certificats valides et à jour

282
docs/ARCHITECTURE.md Normal file
View File

@ -0,0 +1,282 @@
# Architecture de l'application 4NK IA Front Notarial
## Vue d'ensemble
L'application 4NK IA Front Notarial est une interface web moderne construite avec React et TypeScript,
conçue pour l'analyse intelligente de documents notariaux.
## Stack technique
### Frontend
- **React 18** : Framework UI avec hooks et composants fonctionnels
- **TypeScript 5.6** : Typage statique pour la robustesse du code
- **Vite 7** : Build tool rapide avec HMR (Hot Module Replacement)
- **Material-UI v6** : Bibliothèque de composants UI professionnels
### Gestion d'état
- **Redux Toolkit** : Gestion d'état centralisée et prévisible
- **React Redux** : Liaison React-Redux avec hooks
- **Async Thunks** : Gestion des actions asynchrones
### Routing et navigation
- **React Router v6** : Navigation côté client avec code splitting
- **Lazy loading** : Chargement à la demande des composants
### HTTP et API
- **Axios** : Client HTTP avec intercepteurs
- **Intercepteurs** : Gestion centralisée des erreurs et authentification
### Tests
- **Vitest** : Framework de test rapide et moderne
- **Testing Library** : Tests d'intégration React
- **JSDOM** : Environnement DOM simulé
- **Coverage V8** : Rapport de couverture de code
### Qualité de code
- **ESLint** : Linting avec règles strictes
- **Prettier** : Formatage automatique du code
- **markdownlint** : Validation des fichiers Markdown
## Structure du projet
```text
src/
├── components/ # Composants réutilisables
│ ├── Layout.tsx # Layout principal avec AppBar et navigation
│ └── NavigationTabs.tsx # Composant de navigation par onglets
├── views/ # Vues principales de l'application
│ ├── UploadView.tsx # Upload et gestion des documents
│ ├── ExtractionView.tsx # Affichage des données extraites
│ ├── AnalyseView.tsx # Analyse et score de vraisemblance
│ ├── ContexteView.tsx # Données contextuelles externes
│ └── ConseilView.tsx # Conseil IA et recommandations
├── store/ # Gestion d'état Redux
│ ├── index.ts # Configuration du store Redux
│ ├── appSlice.ts # État global de l'application
│ └── documentSlice.ts # État des documents et opérations
├── services/ # Services et API
│ └── api.ts # Client API et endpoints
├── types/ # Types et interfaces TypeScript
│ └── index.ts # Définitions de types centralisées
├── main.tsx # Point d'entrée de l'application
└── App.tsx # Composant racine avec routing
```
## Architecture des composants
### Layout et navigation
- **Layout** : Composant wrapper avec AppBar et navigation
- **NavigationTabs** : Navigation par onglets avec React Router
- **AppBar** : Barre de navigation principale
### Vues principales
#### UploadView
- **Dropzone** : Zone de glisser-déposer pour les fichiers
- **FileList** : Liste des documents uploadés
- **Status indicators** : Indicateurs de statut des documents
#### ExtractionView
- **DataDisplay** : Affichage des données extraites
- **ObjectLists** : Listes d'identités, adresses, biens, contrats
- **Confidence scores** : Scores de confiance des extractions
#### AnalyseView
- **CredibilityScore** : Score de vraisemblance du document
- **Recommendations** : Liste des recommandations
- **Summary** : Synthèse de l'analyse
#### ContexteView
- **ExternalData** : Données des APIs externes
- **StatusCards** : Cartes de statut pour chaque source
- **LastUpdated** : Horodatage des dernières mises à jour
#### ConseilView
- **LLMAnalysis** : Analyse générée par l'IA
- **RiskAssessment** : Évaluation des risques
- **NextSteps** : Prochaines étapes recommandées
## Gestion d'état Redux
### Structure du store
```typescript
interface RootState {
app: AppState // État global de l'application
document: DocumentState // État des documents et opérations
}
```
### AppState
- **status** : État global ('idle' | 'loading' | 'succeeded' | 'failed')
- **error** : Messages d'erreur globaux
### DocumentState
- **documents** : Liste des documents uploadés
- **currentDocument** : Document actuellement sélectionné
- **extractionResult** : Résultats d'extraction
- **analysisResult** : Résultats d'analyse
- **contextResult** : Données contextuelles
- **conseilResult** : Conseil IA
- **loading** : État de chargement
- **error** : Messages d'erreur
### Actions asynchrones
- **uploadDocument** : Upload d'un document
- **extractDocument** : Extraction des données
- **analyzeDocument** : Analyse du document
- **getContextData** : Récupération des données contextuelles
- **getConseil** : Génération du conseil IA
## Services API
### Configuration Axios
- **Base URL** : Configuration via variables d'environnement
- **Timeout** : 60 secondes pour les opérations longues
- **Intercepteurs** : Gestion d'erreur et fallback automatique
### Endpoints
- `POST /api/documents/upload` : Upload de document
- `GET /api/documents/{id}/extract` : Extraction de données
- `GET /api/documents/{id}/analyze` : Analyse du document
- `GET /api/documents/{id}/context` : Données contextuelles
- `GET /api/documents/{id}/conseil` : Conseil IA
### Gestion d'erreur
- **Intercepteurs** : Détection automatique des erreurs
- **Fallback** : Données de démonstration en cas d'erreur
- **Codes gérés** : 404, 405, ERR_NETWORK, ERR_CONNECTION_REFUSED
## Types et interfaces
### Document
```typescript
interface Document {
id: string
name: string
type: string
size: number
uploadDate: Date
status: 'uploading' | 'processing' | 'completed' | 'error'
}
```
### ExtractionResult
```typescript
interface ExtractionResult {
documentId: string
text: string
language: string
documentType: string
identities: Identity[]
addresses: Address[]
properties: Property[]
contracts: Contract[]
signatures: string[]
confidence: number
}
```
### AnalysisResult
```typescript
interface AnalysisResult {
documentId: string
documentType: string
isCNI: boolean
credibilityScore: number
summary: string
recommendations: string[]
}
```
## Mode démonstration
### Fonctionnement
- **Détection automatique** : Vérification de la disponibilité du backend
- **Fallback gracieux** : Basculement vers des données de démonstration
- **Données réalistes** : Exemples d'actes notariaux authentiques
- **Fonctionnalités complètes** : Toutes les vues opérationnelles
### Données de démonstration
- **Documents** : Exemples d'actes de vente, CNI, etc.
- **Identités** : Personnes avec informations complètes
- **Adresses** : Adresses françaises réalistes
- **Biens** : Propriétés avec références cadastrales
- **Contrats** : Clauses et montants réalistes
## Performance et optimisation
### Code splitting
- **Lazy loading** : Chargement à la demande des vues
- **Suspense** : Gestion des états de chargement
- **Bundle optimization** : Optimisation de la taille des bundles
### Caching
- **Redux state** : Mise en cache des données dans le store
- **API responses** : Cache des réponses API
- **Component memoization** : Optimisation des re-renders
### Build optimization
- **Vite** : Build rapide avec optimisations automatiques
- **Tree shaking** : Élimination du code mort
- **Minification** : Compression du code de production
## Sécurité
### Validation
- **TypeScript** : Validation de types à la compilation
- **Runtime validation** : Validation des données API
- **Input sanitization** : Nettoyage des entrées utilisateur
### CORS et CSP
- **CORS** : Configuration des en-têtes Cross-Origin
- **CSP** : Content Security Policy pour la sécurité
- **HTTPS** : Communication sécurisée en production
## Déploiement
### Environnements
- **Développement** : Serveur local avec HMR
- **Staging** : Environnement de test
- **Production** : Déploiement optimisé
### Variables d'environnement
- **VITE_API_URL** : URL de l'API backend
- **VITE_*_API_URL** : URLs des APIs externes
- **NODE_ENV** : Environnement d'exécution
### Build de production
- **Optimisation** : Minification et compression
- **Assets** : Optimisation des images et CSS
- **Bundle analysis** : Analyse de la taille des bundles

517
docs/DEPLOYMENT.md Normal file
View File

@ -0,0 +1,517 @@
# Guide de déploiement - 4NK IA Front Notarial
## Vue d'ensemble
Ce guide couvre le déploiement de l'application 4NK IA Front Notarial dans différents environnements.
## Prérequis
### Environnement de développement
- **Node.js** : >= 22.12.0 (recommandé) ou >= 20.19.0
- **npm** : >= 10.0.0
- **Git** : Pour la gestion des versions
### Environnement de production
- **Serveur web** : Nginx ou Apache
- **HTTPS** : Certificat SSL valide
- **CDN** : Optionnel pour les assets statiques
## Configuration des environnements
### Variables d'environnement
#### Développement (.env.development)
```env
NODE_ENV=development
VITE_API_URL=http://localhost:8000
VITE_CADASTRE_API_URL=https://api.cadastre.gouv.fr
VITE_GEORISQUES_API_URL=https://www.georisques.gouv.fr/api
VITE_GEOFONCIER_API_URL=https://api.geofoncier.fr
VITE_BODACC_API_URL=https://api.bodacc.fr
VITE_INFOGREFFE_API_URL=https://api.infogreffe.fr
```
#### Staging (.env.staging)
```env
NODE_ENV=staging
VITE_API_URL=https://api-staging.4nkweb.com
VITE_CADASTRE_API_URL=https://api.cadastre.gouv.fr
VITE_GEORISQUES_API_URL=https://www.georisques.gouv.fr/api
VITE_GEOFONCIER_API_URL=https://api.geofoncier.fr
VITE_BODACC_API_URL=https://api.bodacc.fr
VITE_INFOGREFFE_API_URL=https://api.infogreffe.fr
```
#### Production (.env.production)
```env
NODE_ENV=production
VITE_API_URL=https://api.4nkweb.com
VITE_CADASTRE_API_URL=https://api.cadastre.gouv.fr
VITE_GEORISQUES_API_URL=https://www.georisques.gouv.fr/api
VITE_GEOFONCIER_API_URL=https://api.geofoncier.fr
VITE_BODACC_API_URL=https://api.bodacc.fr
VITE_INFOGREFFE_API_URL=https://api.infogreffe.fr
```
## Build de production
### Script de build
```bash
# Build standard
npm run build
# Build avec analyse
npm run build -- --analyze
# Build pour un environnement spécifique
npm run build -- --mode production
```
### Optimisations automatiques
- **Minification** : Code JavaScript et CSS minifié
- **Tree shaking** : Élimination du code mort
- **Code splitting** : Division en chunks optimaux
- **Asset optimization** : Optimisation des images et fonts
### Structure du build
```text
dist/
├── index.html # Point d'entrée HTML
├── assets/
│ ├── index-[hash].js # Bundle principal
│ ├── index-[hash].css # Styles principaux
│ ├── [chunk]-[hash].js # Chunks de code splitting
│ └── [asset]-[hash].[ext] # Assets optimisés
└── favicon.ico # Icône du site
```
## Déploiement sur serveur
### Configuration Nginx
#### Fichier de configuration
```nginx
server {
listen 80;
listen [::]:80;
server_name app.4nkweb.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name app.4nkweb.com;
# Certificats SSL
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
# Configuration SSL
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
# Root directory
root /var/www/4nk-ia-front/dist;
index index.html;
# Gestion des routes SPA
location / {
try_files $uri $uri/ /index.html;
}
# Cache des assets statiques
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Sécurité
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
}
```
### Configuration Apache
#### Fichier .htaccess
```apache
RewriteEngine On
# Redirection HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Gestion des routes SPA
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
# Cache des assets
<FilesMatch "\.(css|js|png|jpg|jpeg|gif|ico|svg)$">
ExpiresActive On
ExpiresDefault "access plus 1 year"
Header set Cache-Control "public, immutable"
</FilesMatch>
# Compression
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>
# Sécurité
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set Strict-Transport-Security "max-age=63072000"
```
## Déploiement avec Docker
### Dockerfile
```dockerfile
# Build stage
FROM node:22.12-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Production stage
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```
### docker-compose.yml
```yaml
version: '3.8'
services:
frontend:
build: .
ports:
- "80:80"
- "443:443"
volumes:
- ./ssl:/etc/nginx/ssl:ro
environment:
- NODE_ENV=production
restart: unless-stopped
```
### Script de déploiement
```bash
#!/bin/bash
# deploy.sh
set -e
echo "Building application..."
docker build -t 4nk-ia-front .
echo "Stopping existing container..."
docker stop 4nk-ia-front || true
docker rm 4nk-ia-front || true
echo "Starting new container..."
docker run -d \
--name 4nk-ia-front \
-p 80:80 \
-p 443:443 \
-v /path/to/ssl:/etc/nginx/ssl:ro \
4nk-ia-front
echo "Deployment completed!"
```
## Déploiement avec CI/CD
### GitHub Actions
```yaml
name: Deploy
on:
push:
branches: [release]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '22.12'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm run test
- name: Build application
run: npm run build
env:
NODE_ENV: production
VITE_API_URL: ${{ secrets.API_URL }}
- name: Deploy to server
uses: appleboy/ssh-action@v0.1.5
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /var/www/4nk-ia-front
git pull origin release
npm ci
npm run build
sudo systemctl reload nginx
```
### GitLab CI
```yaml
stages:
- test
- build
- deploy
test:
stage: test
image: node:22.12-alpine
script:
- npm ci
- npm run test
only:
- merge_requests
- release
build:
stage: build
image: node:22.12-alpine
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
only:
- release
deploy:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache openssh-client
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
script:
- scp -r dist/* $DEPLOY_USER@$DEPLOY_HOST:/var/www/4nk-ia-front/
- ssh $DEPLOY_USER@$DEPLOY_HOST "sudo systemctl reload nginx"
only:
- release
```
## Monitoring et surveillance
### Métriques de performance
- **Temps de chargement** : Mesure du First Contentful Paint
- **Taille des bundles** : Surveillance de la taille des assets
- **Erreurs JavaScript** : Tracking des erreurs côté client
### Outils de monitoring
- **Google Analytics** : Analytics et performance
- **Sentry** : Monitoring des erreurs
- **Lighthouse** : Audit de performance
### Configuration Sentry
```typescript
import * as Sentry from "@sentry/react";
Sentry.init({
dsn: "YOUR_SENTRY_DSN",
environment: process.env.NODE_ENV,
tracesSampleRate: 1.0,
});
```
## Rollback et récupération
### Stratégie de rollback
```bash
#!/bin/bash
# rollback.sh
PREVIOUS_VERSION=$1
if [ -z "$PREVIOUS_VERSION" ]; then
echo "Usage: ./rollback.sh <version>"
exit 1
fi
echo "Rolling back to version $PREVIOUS_VERSION..."
# Restaurer la version précédente
git checkout $PREVIOUS_VERSION
npm ci
npm run build
# Redéployer
sudo systemctl reload nginx
echo "Rollback completed!"
```
### Sauvegarde
```bash
#!/bin/bash
# backup.sh
BACKUP_DIR="/backups/4nk-ia-front"
DATE=$(date +%Y%m%d_%H%M%S)
# Créer le répertoire de sauvegarde
mkdir -p $BACKUP_DIR
# Sauvegarder les fichiers
tar -czf $BACKUP_DIR/backup_$DATE.tar.gz /var/www/4nk-ia-front
# Nettoyer les anciennes sauvegardes (garder 7 jours)
find $BACKUP_DIR -name "backup_*.tar.gz" -mtime +7 -delete
echo "Backup completed: backup_$DATE.tar.gz"
```
## Sécurité
### Headers de sécurité
- **CSP** : Content Security Policy
- **HSTS** : HTTP Strict Transport Security
- **X-Frame-Options** : Protection contre le clickjacking
- **X-Content-Type-Options** : Protection contre MIME sniffing
### Configuration CSP
```html
<meta http-equiv="Content-Security-Policy" content="
default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
connect-src 'self' https://api.4nkweb.com;
font-src 'self' data:;
">
```
### Audit de sécurité
```bash
# Audit des dépendances
npm audit
# Audit de sécurité avec Snyk
npx snyk test
# Scan de vulnérabilités
npx audit-ci --config audit-ci.json
```
## Maintenance
### Mise à jour des dépendances
```bash
# Vérifier les mises à jour
npm outdated
# Mettre à jour les dépendances
npm update
# Mise à jour majeure
npx npm-check-updates -u
npm install
```
### Nettoyage
```bash
# Nettoyer le cache npm
npm cache clean --force
# Nettoyer les node_modules
rm -rf node_modules package-lock.json
npm install
# Nettoyer le build
rm -rf dist
npm run build
```
### Logs et debugging
```bash
# Logs Nginx
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
# Logs de l'application
sudo journalctl -u nginx -f
# Debug des erreurs
sudo nginx -t # Test de configuration
```

627
docs/TESTING.md Normal file
View File

@ -0,0 +1,627 @@
# Guide de tests - 4NK IA Front Notarial
## Vue d'ensemble
Ce guide couvre la stratégie de tests pour l'application 4NK IA Front Notarial, incluant les tests unitaires,
d'intégration et end-to-end.
## Stack de test
### Outils principaux
- **Vitest** : Framework de test rapide et moderne
- **Testing Library** : Tests d'intégration React
- **JSDOM** : Environnement DOM simulé
- **MSW** : Mock Service Worker pour les APIs
- **Coverage V8** : Rapport de couverture de code
### Configuration
#### vitest.config.ts
```typescript
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
globals: true,
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
exclude: [
'node_modules/',
'dist/',
'**/*.d.ts',
'**/*.config.*',
'**/setup.*'
]
}
}
})
```
#### setup.test.ts
```typescript
import { expect, afterEach } from 'vitest'
import { cleanup } from '@testing-library/react'
import * as matchers from '@testing-library/jest-dom/matchers'
// Étendre les matchers de testing-library
expect.extend(matchers)
// Nettoyer après chaque test
afterEach(() => {
cleanup()
})
```
## Types de tests
### Tests unitaires
#### Composants React
```typescript
// tests/components/Layout.test.tsx
import { render, screen } from '@testing-library/react'
import { BrowserRouter } from 'react-router-dom'
import { Provider } from 'react-redux'
import { store } from '../../src/store'
import { Layout } from '../../src/components/Layout'
const renderWithProviders = (ui: React.ReactElement) => {
return render(
<Provider store={store}>
<BrowserRouter>
{ui}
</BrowserRouter>
</Provider>
)
}
describe('Layout', () => {
it('should render the application title', () => {
renderWithProviders(<Layout><div>Test content</div></Layout>)
expect(screen.getByText('4NK IA - Front Notarial')).toBeInTheDocument()
})
it('should render navigation tabs', () => {
renderWithProviders(<Layout><div>Test content</div></Layout>)
expect(screen.getByRole('tablist')).toBeInTheDocument()
})
})
```
#### Services API
```typescript
// tests/services/api.test.ts
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { documentApi } from '../../src/services/api'
import axios from 'axios'
// Mock axios
vi.mock('axios')
const mockedAxios = vi.mocked(axios)
describe('documentApi', () => {
beforeEach(() => {
vi.clearAllMocks()
})
describe('upload', () => {
it('should upload a document successfully', async () => {
const mockResponse = {
data: {
id: 'doc_123',
name: 'test.pdf',
type: 'application/pdf',
size: 1024,
uploadDate: new Date(),
status: 'completed'
}
}
mockedAxios.create.mockReturnValue({
post: vi.fn().mockResolvedValue(mockResponse)
} as any)
const file = new File(['content'], 'test.pdf', { type: 'application/pdf' })
const result = await documentApi.upload(file)
expect(result.id).toBe('doc_123')
expect(result.name).toBe('test.pdf')
expect(result.status).toBe('completed')
})
it('should return demo data on error', async () => {
mockedAxios.create.mockReturnValue({
post: vi.fn().mockRejectedValue(new Error('Network error'))
} as any)
const file = new File(['content'], 'test.pdf', { type: 'application/pdf' })
const result = await documentApi.upload(file)
expect(result.id).toMatch(/^demo-/)
expect(result.name).toBe('test.pdf')
})
})
})
```
#### Redux Slices
```typescript
// tests/store/documentSlice.test.ts
import { describe, it, expect } from 'vitest'
import documentReducer, { setCurrentDocument } from '../../src/store/documentSlice'
import { uploadDocument } from '../../src/store/documentSlice'
describe('documentSlice', () => {
const initialState = {
documents: [],
currentDocument: null,
extractionResult: null,
analysisResult: null,
contextResult: null,
conseilResult: null,
loading: false,
error: null
}
it('should handle setCurrentDocument', () => {
const document = {
id: 'doc_123',
name: 'test.pdf',
type: 'application/pdf',
size: 1024,
uploadDate: new Date(),
status: 'completed' as const
}
const action = setCurrentDocument(document)
const newState = documentReducer(initialState, action)
expect(newState.currentDocument).toEqual(document)
expect(newState.extractionResult).toBeNull()
})
it('should handle uploadDocument.pending', () => {
const action = { type: uploadDocument.pending.type }
const newState = documentReducer(initialState, action)
expect(newState.loading).toBe(true)
expect(newState.error).toBeNull()
})
})
```
### Tests d'intégration
#### Vues complètes
```typescript
// tests/views/UploadView.test.tsx
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Provider } from 'react-redux'
import { BrowserRouter } from 'react-router-dom'
import { store } from '../../src/store'
import { UploadView } from '../../src/views/UploadView'
const renderWithProviders = (ui: React.ReactElement) => {
return render(
<Provider store={store}>
<BrowserRouter>
{ui}
</BrowserRouter>
</Provider>
)
}
describe('UploadView', () => {
it('should render upload area', () => {
renderWithProviders(<UploadView />)
expect(screen.getByText(/glisser-déposer/i)).toBeInTheDocument()
})
it('should handle file upload', async () => {
const user = userEvent.setup()
renderWithProviders(<UploadView />)
const file = new File(['content'], 'test.pdf', { type: 'application/pdf' })
const input = screen.getByLabelText(/sélectionner des fichiers/i)
await user.upload(input, file)
await waitFor(() => {
expect(screen.getByText('test.pdf')).toBeInTheDocument()
})
})
it('should display document list after upload', async () => {
const user = userEvent.setup()
renderWithProviders(<UploadView />)
const file = new File(['content'], 'test.pdf', { type: 'application/pdf' })
const input = screen.getByLabelText(/sélectionner des fichiers/i)
await user.upload(input, file)
await waitFor(() => {
expect(screen.getByRole('list')).toBeInTheDocument()
expect(screen.getByText('test.pdf')).toBeInTheDocument()
})
})
})
```
#### Navigation
```typescript
// tests/navigation.test.tsx
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { BrowserRouter } from 'react-router-dom'
import { Provider } from 'react-redux'
import { store } from '../src/store'
import App from '../src/App'
const renderWithProviders = (ui: React.ReactElement) => {
return render(
<Provider store={store}>
<BrowserRouter>
{ui}
</BrowserRouter>
</Provider>
)
}
describe('Navigation', () => {
it('should navigate between tabs', async () => {
const user = userEvent.setup()
renderWithProviders(<App />)
// Vérifier que l'onglet Upload est actif par défaut
expect(screen.getByText('Upload')).toHaveAttribute('aria-selected', 'true')
// Cliquer sur l'onglet Extraction
await user.click(screen.getByText('Extraction'))
expect(screen.getByText('Extraction')).toHaveAttribute('aria-selected', 'true')
expect(screen.getByText('Upload')).toHaveAttribute('aria-selected', 'false')
})
})
```
### Tests d'API avec MSW
#### Configuration MSW
```typescript
// tests/mocks/handlers.ts
import { http, HttpResponse } from 'msw'
export const handlers = [
// Upload de document
http.post('/api/documents/upload', () => {
return HttpResponse.json({
id: 'doc_123',
name: 'test.pdf',
type: 'application/pdf',
size: 1024,
uploadDate: new Date().toISOString(),
status: 'completed'
})
}),
// Extraction de données
http.get('/api/documents/:id/extract', () => {
return HttpResponse.json({
documentId: 'doc_123',
text: 'Texte extrait du document...',
language: 'fr',
documentType: 'Acte de vente',
identities: [
{
id: '1',
type: 'person',
firstName: 'Jean',
lastName: 'Dupont',
birthDate: '1980-05-15',
nationality: 'Française',
confidence: 0.95
}
],
addresses: [],
properties: [],
contracts: [],
signatures: [],
confidence: 0.92
})
}),
// Erreur de connexion
http.get('/api/documents/:id/analyze', () => {
return HttpResponse.error()
})
]
```
#### Tests avec MSW
```typescript
// tests/integration/api.test.tsx
import { setupServer } from 'msw/node'
import { handlers } from '../mocks/handlers'
import { documentApi } from '../../src/services/api'
const server = setupServer(...handlers)
beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())
describe('API Integration', () => {
it('should extract document data', async () => {
const result = await documentApi.extract('doc_123')
expect(result.documentId).toBe('doc_123')
expect(result.identities).toHaveLength(1)
expect(result.identities[0].firstName).toBe('Jean')
})
it('should handle API errors gracefully', async () => {
const result = await documentApi.analyze('doc_123')
// Devrait retourner des données de démonstration
expect(result.documentId).toBe('doc_123')
expect(result.credibilityScore).toBeDefined()
})
})
```
## Tests de performance
### Tests de rendu
```typescript
// tests/performance/render.test.tsx
import { render } from '@testing-library/react'
import { Provider } from 'react-redux'
import { BrowserRouter } from 'react-router-dom'
import { store } from '../../src/store'
import App from '../../src/App'
describe('Performance', () => {
it('should render app within acceptable time', () => {
const start = performance.now()
render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
)
const end = performance.now()
const renderTime = end - start
// Le rendu initial devrait prendre moins de 100ms
expect(renderTime).toBeLessThan(100)
})
})
```
### Tests de mémoire
```typescript
// tests/performance/memory.test.tsx
import { render, cleanup } from '@testing-library/react'
import { Provider } from 'react-redux'
import { BrowserRouter } from 'react-router-dom'
import { store } from '../../src/store'
import { UploadView } from '../../src/views/UploadView'
describe('Memory Management', () => {
it('should not leak memory on multiple renders', () => {
const initialMemory = (performance as any).memory?.usedJSHeapSize || 0
// Rendre et nettoyer plusieurs fois
for (let i = 0; i < 10; i++) {
render(
<Provider store={store}>
<BrowserRouter>
<UploadView />
</BrowserRouter>
</Provider>
)
cleanup()
}
const finalMemory = (performance as any).memory?.usedJSHeapSize || 0
const memoryIncrease = finalMemory - initialMemory
// L'augmentation de mémoire devrait être raisonnable
expect(memoryIncrease).toBeLessThan(10 * 1024 * 1024) // 10MB
})
})
```
## Tests d'accessibilité
### Tests avec jest-axe
```typescript
// tests/accessibility/a11y.test.tsx
import { render } from '@testing-library/react'
import { axe, toHaveNoViolations } from 'jest-axe'
import { Provider } from 'react-redux'
import { BrowserRouter } from 'react-router-dom'
import { store } from '../../src/store'
import { Layout } from '../../src/components/Layout'
expect.extend(toHaveNoViolations)
describe('Accessibility', () => {
it('should not have accessibility violations', async () => {
const { container } = render(
<Provider store={store}>
<BrowserRouter>
<Layout>
<div>Test content</div>
</Layout>
</BrowserRouter>
</Provider>
)
const results = await axe(container)
expect(results).toHaveNoViolations()
})
it('should have proper ARIA labels', () => {
render(
<Provider store={store}>
<BrowserRouter>
<Layout>
<div>Test content</div>
</Layout>
</BrowserRouter>
</Provider>
)
expect(screen.getByRole('banner')).toBeInTheDocument()
expect(screen.getByRole('tablist')).toBeInTheDocument()
})
})
```
## Scripts de test
### package.json
```json
{
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui",
"test:run": "vitest run",
"test:coverage": "vitest run --coverage",
"test:watch": "vitest --watch",
"test:debug": "vitest --inspect-brk"
}
}
```
### Exécution des tests
```bash
# Tests en mode watch
npm run test
# Tests avec interface graphique
npm run test:ui
# Tests une seule fois
npm run test:run
# Tests avec couverture
npm run test:coverage
# Tests en mode debug
npm run test:debug
```
## Configuration CI/CD
### GitHub Actions
```yaml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '22.12'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm run test:coverage
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
file: ./coverage/lcov.info
```
## Bonnes pratiques
### Organisation des tests
- **Un fichier de test par composant** : `Component.test.tsx`
- **Tests groupés par fonctionnalité** : `describe` blocks
- **Tests isolés** : Chaque test doit être indépendant
- **Noms descriptifs** : `it('should do something specific')`
### Mocking
- **Mock des dépendances externes** : APIs, services
- **Mock des hooks** : React hooks personnalisés
- **Mock des modules** : Modules Node.js
### Assertions
- **Assertions spécifiques** : Éviter les assertions génériques
- **Tests de régression** : Vérifier les bugs corrigés
- **Tests de cas limites** : Valeurs nulles, erreurs
### Performance
- **Tests rapides** : Éviter les tests lents
- **Parallélisation** : Utiliser `--threads` pour Vitest
- **Cache** : Utiliser le cache des dépendances
## Métriques de qualité
### Couverture de code
- **Minimum 80%** : Couverture globale
- **Minimum 90%** : Composants critiques
- **100%** : Fonctions utilitaires
### Types de couverture
- **Statements** : Instructions exécutées
- **Branches** : Branches conditionnelles
- **Functions** : Fonctions appelées
- **Lines** : Lignes de code exécutées
### Rapport de couverture
```bash
# Générer le rapport
npm run test:coverage
# Ouvrir le rapport HTML
open coverage/index.html
```