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:
parent
7e46e1d992
commit
afb58ef4b1
75
CHANGELOG.md
75
CHANGELOG.md
@ -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
286
README.md
@ -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
355
docs/API.md
Normal 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
282
docs/ARCHITECTURE.md
Normal 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
517
docs/DEPLOYMENT.md
Normal 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
627
docs/TESTING.md
Normal 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
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user