Compare commits
No commits in common. "e69fa95463feb5aeed958fc779c00e07b0d6c177" and "7e46e1d99275c504df32720acf66b49aa926ecd2" have entirely different histories.
e69fa95463
...
7e46e1d992
75
CHANGELOG.md
75
CHANGELOG.md
@ -1,74 +1,7 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 0.1.0 - Version initiale complète
|
## 0.1.0 - Initialisation
|
||||||
|
|
||||||
### ✨ Fonctionnalités principales
|
- Scaffold Vite React+TS
|
||||||
|
- Outillage Node 22.12, ESLint, Prettier, markdownlint
|
||||||
- **Interface notariale complète** : Application front-end pour l'analyse de documents notariaux
|
- Vitest et Testing Library
|
||||||
- **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,237 +1,75 @@
|
|||||||
# 4NK IA Front Notarial
|
# React + TypeScript + Vite
|
||||||
|
|
||||||
Application front-end pour l'analyse intelligente de documents notariaux avec IA.
|
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||||
|
|
||||||
## 🎯 Fonctionnalités
|
Currently, two official plugins are available:
|
||||||
|
|
||||||
### 📄 Gestion de documents
|
- [@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
|
||||||
|
|
||||||
- **Upload multiple** : Glisser-déposer de documents (PDF, images)
|
## Expanding the ESLint configuration
|
||||||
- **Prévisualisation** : Affichage des documents uploadés
|
|
||||||
- **Types supportés** : PDF, PNG, JPG, JPEG
|
|
||||||
|
|
||||||
### 🔍 Extraction et analyse
|
If you are developing a production application, we recommend updating the configuration to enable type-aware
|
||||||
|
lint rules:
|
||||||
|
|
||||||
- **OCR automatique** : Extraction du texte des documents
|
```js
|
||||||
- **Détection de type** : Identification automatique du type de document
|
export default tseslint.config([
|
||||||
- **Objets standardisés** : Extraction d'identités, adresses, biens, contrats
|
globalIgnores(['dist']),
|
||||||
- **Détection de langue** : Identification automatique de la langue
|
{
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
extends: [
|
||||||
|
// Other configs...
|
||||||
|
|
||||||
### 📊 Analyse intelligente
|
// 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,
|
||||||
|
|
||||||
- **Score de vraisemblance** : Évaluation de la crédibilité du document
|
// Other configs...
|
||||||
- **Recommandations** : Suggestions d'actions à effectuer
|
],
|
||||||
- **Synthèse** : Résumé automatique du document
|
languageOptions: {
|
||||||
|
parserOptions: {
|
||||||
### 🌐 Données contextuelles
|
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
||||||
|
tsconfigRootDir: import.meta.dirname,
|
||||||
- **Cadastre** : Vérification des références cadastrales
|
},
|
||||||
- **Géorisques** : Analyse des risques géologiques
|
// other options...
|
||||||
- **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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Configuration des environnements
|
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:
|
||||||
|
|
||||||
Créer un fichier `.env` :
|
```js
|
||||||
|
// eslint.config.js
|
||||||
|
import reactX from 'eslint-plugin-react-x'
|
||||||
|
import reactDom from 'eslint-plugin-react-dom'
|
||||||
|
|
||||||
```env
|
export default tseslint.config([
|
||||||
VITE_API_URL=http://localhost:8000
|
globalIgnores(['dist']),
|
||||||
VITE_CADASTRE_API_URL=https://api.cadastre.gouv.fr
|
{
|
||||||
VITE_GEORISQUES_API_URL=https://www.georisques.gouv.fr/api
|
files: ['**/*.{ts,tsx}'],
|
||||||
VITE_GEOFONCIER_API_URL=https://api.geofoncier.fr
|
extends: [
|
||||||
VITE_BODACC_API_URL=https://api.bodacc.fr
|
// Other configs...
|
||||||
VITE_INFOGREFFE_API_URL=https://api.infogreffe.fr
|
// 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...
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🛠️ 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
355
docs/API.md
@ -1,355 +0,0 @@
|
|||||||
# 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
|
|
@ -1,282 +0,0 @@
|
|||||||
# 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
|
|
@ -1,517 +0,0 @@
|
|||||||
# 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
627
docs/TESTING.md
@ -1,627 +0,0 @@
|
|||||||
# 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