This commit is contained in:
Nicolas Cantu 2025-09-16 01:26:08 +02:00
parent 81df52b785
commit 081b33466f
11 changed files with 201 additions and 2513 deletions

View File

@ -1,139 +0,0 @@
# Documentation API - 4NK IA Lecoffre.io
## Vue d'ensemble
L'application 4NK IA Lecoffre.io communique uniquement avec le backend interne pour toutes les
fonctionnalités (upload, extraction, analyse, contexte, conseil).
## API Backend Principal
### Base URL
```text
http://localhost:8000 (développement)
```
### Endpoints
#### Upload de document
```http
POST /api/notary/upload
Content-Type: multipart/form-data
Body: FormData avec le fichier
```
Réponse attendue (champs utilisés par le front) :
```json
{
"document_id": "doc_123456",
"mime_type": "application/pdf",
"functional_type": "CNI"
}
```
Mappage front en `Document` :
```json
{
"id": "doc_123456",
"name": "acte_vente.pdf",
"mimeType": "application/pdf",
"functionalType": "CNI",
"size": 1024000,
"uploadDate": "<date locale>",
"status": "completed",
"previewUrl": "blob:..."
}
```
#### Extraction de données
```http
GET /api/notary/documents/{documentId}
```
#### Analyse du document
```http
GET /api/documents/{documentId}/analyze
```
#### Données contextuelles
```http
GET /api/documents/{documentId}/context
```
#### Conseil IA
```http
GET /api/documents/{documentId}/conseil
```
## APIs Externes
Les APIs externes (Cadastre, Géorisques, Géofoncier, BODACC, Infogreffe) sont appelées côté backend
uniquement. Aucun appel direct côté front.
## 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
## Configuration
### Variables d'environnement
```env
VITE_API_URL=http://localhost:8000
VITE_USE_OPENAI=false
VITE_OPENAI_API_KEY=
VITE_OPENAI_BASE_URL=https://api.openai.com/v1
VITE_OPENAI_MODEL=gpt-4o-mini
```
## Mode OpenAI (fallback)
Quand `VITE_USE_OPENAI=true`, le frontend bascule sur un mode de secours basé sur OpenAI:
- Upload: simulé côté client (le fichier nest pas envoyé à OpenAI)
- Extraction/Analyse/Conseil/Contexte: appels `chat.completions` sur `VITE_OPENAI_MODEL`
- Détection de type: heuristique simple côté client
Ce mode est utile pour démo/diagnostic quand le backend nest pas disponible.
### Configuration Axios
```typescript
const apiClient = axios.create({
baseURL: BASE_URL,
timeout: 60000
})
```
## Authentification
### Headers requis
```http
Authorization: Bearer {token}
Content-Type: application/json
```
## Rate Limiting
- Limites gérées par le backend

View File

@ -1,282 +0,0 @@
# Architecture de l'application 4NK IA Lecoffre.io
## Vue d'ensemble
L'application 4NK IA Lecoffre.io 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

View File

@ -1,554 +0,0 @@
# Guide de déploiement - Lecoffre.io
## Vue d'ensemble
Ce guide couvre le déploiement de l'application 4NK IALecoffre.io dans différents environnements.
## Notes de version 0.1.2
### Changements principaux
- Suppression du « mode démo » côté frontend et des fallbacks
- Routage des APIs externes exclusivement via le backend `4NK_IA_back`
- Exigence Node.js ≥ 20.19 pour la compilation
### Impact déploiement
- Variables `.env` front simplifiées (uniquement `VITE_API_URL`)
- Build requis avec Node.js ≥ 20.19
### Étapes recommandées
1. Mettre à jour lenvironnement: variables `.env.*` si nécessaire
2. Rebuilder lapplication
3. Synchroniser `dist/` vers le serveur web et recharger Nginx
Exemple de séquence côté serveur (Nginx):
```bash
cd /var/www/4nk-ia-front
git fetch --all --prune
git checkout dev
git pull --ff-only
npm ci
npm run build
sudo systemctl reload nginx
```
## Prérequis
### Environnement de développement
- **Node.js** : >= 20.19.0 (ou >= 22.12.0)
- **npm** : >= 10.0.0
- **nvm** : recommandé, le projet fournit `.nvmrc`
- **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
```
#### Staging (.env.staging)
```env
NODE_ENV=staging
VITE_API_URL=https://api-staging.4nkweb.com
```
#### Production (.env.production)
```env
NODE_ENV=production
VITE_API_URL=https://api.4nkweb.com
```
## 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
### Déploiement via Docker
#### Construction et push de l'image
```bash
# Construire l'image (tag par défaut: commit SHA court)
./scripts/docker-build.sh
# Construire avec tag explicite
IMAGE_TAG=0.1.3 ./scripts/docker-build.sh
# Pousser vers git.4nkweb.com (authentification requise)
IMAGE_TAG=0.1.3 ./scripts/docker-push.sh
```
#### Lancement de l'image
```bash
docker run -d --name 4nk-ia-front -p 8080:80 git.4nkweb.com/4nk/4nk-ia-front:0.1.3
```
#### 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
```

View File

@ -1,627 +0,0 @@
# Guide de tests - 4NK IA Lecoffre.io
## Vue d'ensemble
Ce guide couvre la stratégie de tests pour l'application 4NK IA Lecoffre.io, 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 - Lecoffre.io')).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
```

View File

@ -1,153 +0,0 @@
# Analyse du système de détection CNI - Recherche CANTU/NICOLAS
## 📋 Résumé de l'analyse
Cette analyse a été effectuée pour rechercher les informations concernant **CANTU**, **NICOLAS** et le **code de vérification de la CNI** dans le projet 4NK_IA_front.
## 🔍 Système de détection identifié
### 1. Configuration OCR spécialisée
Le système contient une configuration OCR sophistiquée spécifiquement optimisée pour détecter les noms **NICOLAS** et **CANTU** avec correction des erreurs OCR courantes.
**Fichier principal :** `/backend/server.js` (lignes 130-151)
```javascript
// Corrections pour "Nicolas"
'N1colas': 'Nicolas', 'Nicol@s': 'Nicolas', 'Nico1as': 'Nicolas',
'Nico1@s': 'Nicolas', 'N1co1as': 'Nicolas', 'N1co1@s': 'Nicolas',
// Corrections pour "Cantu"
'C@ntu': 'Cantu', 'CantU': 'Cantu', 'C@ntU': 'Cantu',
'Cant0': 'Cantu', 'C@nt0': 'Cantu', 'CantU': 'Cantu',
```
### 2. Patterns de détection spécialisés
**Fichier :** `/backend/server.js` (lignes 171-189)
Le système utilise des expressions régulières sophistiquées pour détecter "Nicolas Cantu" même avec des erreurs OCR :
```javascript
// Patterns spécifiques pour "Nicolas Cantu" avec variations OCR
/(N[il][cç][o0][l1][a@][s5]\s+[Cc][a@][n][t][u])/gi,
/(N[il][cç][o0][l1][a@][s5]\s+[Cc][a@][n][t][u])/gi,
// Recherche de "Nicolas" seul
/(N[il][cç][o0][l1][a@][s5])/gi,
// Recherche de "Cantu" seul
/([Cc][a@][n][t][u])/gi
```
### 3. Système de détection des numéros CNI
**Fichier :** `/backend/server.js` (lignes 231-234)
Le système détecte les numéros de carte d'identité avec le pattern : `([A-Z]{2}\d{6})` (2 lettres + 6 chiffres).
```javascript
const cniPattern = /([A-Z]{2}\d{6})/g
for (const match of text.matchAll(cniPattern)) {
entities.cniNumbers.push({
id: `cni-${entities.cniNumbers.length}`,
number: match[1],
confidence: 0.95
})
}
```
## 🖼️ Images de test disponibles
### Images analysées :
- `IMG_20250902_162159.jpg` (1052.7 KB)
- `IMG_20250902_162210.jpg` (980.8 KB)
**Localisation :** `/test-files/`
## 🧪 Tests effectués
### 1. Test d'extraction OCR directe
**Script créé :** `test-cni-direct.cjs`
**Résultats :**
- ✅ Images accessibles via le serveur
- ❌ Qualité OCR insuffisante sur les images test
- ❌ Aucune détection de "NICOLAS" ou "CANTU"
- ❌ Aucun numéro CNI détecté
### 2. Test avec configurations OCR multiples
**Script créé :** `test-cni-enhanced.cjs`
**Configurations testées :**
- Français + Anglais (défaut)
- Français uniquement
- Lettres et chiffres uniquement
- Mode page simple
**Résultats :**
- ❌ Toutes les configurations ont échoué à extraire du texte lisible
- ⚠️ Les images semblent être de mauvaise qualité ou corrompues
- ⚠️ Messages d'erreur : "Image too small to scale!! (2x36 vs min width of 3)"
## 🔧 Services backend disponibles
### Endpoints identifiés :
- `POST /api/extract` - Extraction OCR avec upload de fichier
- `GET /api/health` - Vérification de l'état du serveur
- `GET /api/test-files` - Accès aux fichiers de test
**Port :** 3001 (configurable via `PORT`)
## 📊 État du système
### ✅ Fonctionnalités opérationnelles :
- Serveur backend fonctionnel
- Système de correction OCR configuré
- Patterns de détection spécialisés implémentés
- Interface frontend accessible
### ❌ Problèmes identifiés :
- Qualité des images de test insuffisante pour l'OCR
- Extraction de texte corrompue
- Aucune détection réussie des noms cibles
## 🎯 Recommandations
### 1. Amélioration de la qualité des images
- Vérifier la résolution et la netteté des images
- Tester avec des images de meilleure qualité
- Ajuster les paramètres de préprocessing
### 2. Optimisation OCR
- Tester avec des paramètres OCR différents
- Implémenter un préprocessing d'image (contraste, netteté)
- Utiliser des modèles OCR spécialisés pour les documents d'identité
### 3. Tests supplémentaires
- Tester avec des images de CNI réelles de bonne qualité
- Valider les patterns de détection avec des données connues
- Implémenter des tests unitaires pour les fonctions de correction
## 📁 Fichiers créés/modifiés
### Scripts de test créés :
- `test-cni-direct.cjs` - Test d'extraction OCR directe
- `test-cni-enhanced.cjs` - Test avec configurations multiples
### Documentation :
- `docs/analyse-cni-cantu-nicolas.md` - Ce rapport d'analyse
## 🔍 Conclusion
Le système de détection CNI est **techniquement bien configuré** avec des patterns spécialisés pour détecter "NICOLAS CANTU" et les numéros de CNI. Cependant, les **images de test actuelles ne permettent pas une extraction OCR de qualité suffisante** pour valider le fonctionnement du système.
**Prochaines étapes recommandées :**
1. Obtenir des images de CNI de meilleure qualité
2. Tester avec l'interface frontend (http://localhost:5174)
3. Valider les patterns avec des données connues
4. Optimiser les paramètres OCR pour les documents d'identité
---
*Analyse effectuée le 15 septembre 2025*
*Projet : 4NK_IA_front*

View File

@ -1,322 +0,0 @@
# Architecture Backend pour le Traitement des Documents
## Vue d'ensemble
L'application utilise maintenant une architecture backend qui traite les données (OCR, NER) et renvoie du JSON au frontend. Cette approche améliore les performances et centralise le traitement des documents.
## Architecture
### 🏗️ Structure
```
4NK_IA_front/
├── backend/ # Serveur backend Express
│ ├── server.js # Serveur principal
│ ├── package.json # Dépendances backend
│ └── uploads/ # Fichiers temporaires
├── src/ # Frontend React
│ ├── services/
│ │ ├── backendApi.ts # API backend
│ │ ├── openai.ts # Fallback local
│ │ └── ruleNer.ts # Règles NER
│ └── store/
│ └── documentSlice.ts # Redux avec backend
└── test-files/ # Fichiers de test
```
### 🔄 Flux de Données
```mermaid
graph TD
A[Frontend React] --> B[Backend Express]
B --> C[Tesseract.js OCR]
B --> D[Règles NER]
C --> E[Texte extrait]
D --> F[Entités extraites]
E --> G[JSON Response]
F --> G
G --> A
```
## Backend (Express.js)
### 🚀 Serveur Principal
**Fichier**: `backend/server.js`
**Port**: 3001
**Endpoints**:
- `POST /api/extract` - Extraction de documents
- `GET /api/test-files` - Liste des fichiers de test
- `GET /api/health` - Health check
### 📄 Traitement des Documents
#### 1. Upload et Validation
```javascript
// Configuration multer
const upload = multer({
storage: multer.diskStorage({...}),
limits: { fileSize: 10 * 1024 * 1024 }, // 10MB max
fileFilter: (req, file, cb) => {
const allowedTypes = ['image/jpeg', 'image/png', 'image/tiff', 'application/pdf']
// Validation des types de fichiers
}
})
```
#### 2. Extraction OCR Optimisée
```javascript
async function extractTextFromImage(imagePath) {
const worker = await createWorker('fra+eng')
// Configuration optimisée pour cartes d'identité
const params = {
tessedit_pageseg_mode: '6',
tessedit_char_whitelist: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ...',
tessedit_ocr_engine_mode: '1', // LSTM
textord_min_xheight: '6', // Petits textes
// ... autres paramètres
}
await worker.setParameters(params)
const { data } = await worker.recognize(imagePath)
return { text: data.text, confidence: data.confidence }
}
```
#### 3. Extraction NER par Règles
```javascript
function extractEntitiesFromText(text) {
const entities = {
identities: [],
addresses: [],
cniNumbers: [],
dates: [],
documentType: 'Document'
}
// Patterns pour cartes d'identité
const namePatterns = [
/(Vendeur|Acheteur|...)\s*:\s*([A-Z][a-zà-öø-ÿ'\-]+\s+[A-Z][a-zà-öø-ÿ'\-]+)/gi,
/^([A-Z][A-ZÀ-ÖØ-öø-ÿ\s\-']{2,30})$/gm,
// ... autres patterns
]
// Extraction des entités...
return entities
}
```
### 📊 Réponse JSON
```json
{
"success": true,
"documentId": "doc-1234567890",
"fileName": "IMG_20250902_162159.jpg",
"fileSize": 1077961,
"mimeType": "image/jpeg",
"processing": {
"ocr": {
"text": "Texte extrait par OCR...",
"confidence": 85.5,
"wordCount": 25
},
"ner": {
"identities": [...],
"addresses": [...],
"cniNumbers": [...],
"dates": [...],
"documentType": "CNI"
},
"globalConfidence": 87.2
},
"extractedData": {
"documentType": "CNI",
"identities": [...],
"addresses": [...],
"cniNumbers": [...],
"dates": [...]
},
"timestamp": "2025-09-15T23:30:00.000Z"
}
```
## Frontend (React)
### 🔌 Service Backend
**Fichier**: `src/services/backendApi.ts`
```typescript
export async function extractDocumentBackend(
documentId: string,
file?: File,
hooks?: { onOcrProgress?: (progress: number) => void; onLlmProgress?: (progress: number) => void }
): Promise<ExtractionResult> {
const formData = new FormData()
formData.append('document', file)
const response = await fetch(`${BACKEND_URL}/api/extract`, {
method: 'POST',
body: formData
})
const result: BackendExtractionResult = await response.json()
// Conversion vers le format frontend
return convertBackendToFrontend(result)
}
```
### 🔄 Redux Store
**Fichier**: `src/store/documentSlice.ts`
```typescript
export const extractDocument = createAsyncThunk(
'document/extract',
async (documentId: string, thunkAPI) => {
// Vérifier si le backend est disponible
const backendAvailable = await checkBackendHealth()
if (backendAvailable) {
// Utiliser le backend
return await backendDocumentApi.extract(documentId, file, progressHooks)
} else {
// Fallback vers le mode local
return await openaiDocumentApi.extract(documentId, file, progressHooks)
}
}
)
```
## Démarrage
### 🚀 Backend
```bash
# Option 1: Script automatique
./start-backend.sh
# Option 2: Manuel
cd backend
npm install
node server.js
```
### 🌐 Frontend
```bash
npm run dev
```
### 🧪 Test de l'Architecture
```bash
node test-backend-architecture.cjs
```
## Avantages
### 🚀 Performance
- **Traitement centralisé** : OCR et NER sur le serveur
- **Optimisations** : Paramètres OCR optimisés pour les cartes d'identité
- **Cache** : Possibilité de mettre en cache les résultats
### 🔧 Maintenabilité
- **Séparation des responsabilités** : Backend pour le traitement, frontend pour l'UI
- **API REST** : Interface claire entre frontend et backend
- **Fallback** : Mode local en cas d'indisponibilité du backend
### 📊 Monitoring
- **Logs détaillés** : Traçabilité complète du traitement
- **Health check** : Vérification de l'état du backend
- **Métriques** : Confiance OCR, nombre d'entités extraites
## Configuration
### 🔧 Variables d'Environnement
**Backend**:
- `PORT=3001` - Port du serveur backend
**Frontend**:
- `VITE_BACKEND_URL=http://localhost:3001` - URL du backend
- `VITE_USE_RULE_NER=true` - Mode règles locales (fallback)
- `VITE_DISABLE_LLM=true` - Désactiver LLM
### 📁 Structure des Fichiers
```
backend/
├── server.js # Serveur Express
├── package.json # Dépendances
└── uploads/ # Fichiers temporaires (auto-créé)
src/services/
├── backendApi.ts # API backend
├── openai.ts # Fallback local
└── ruleNer.ts # Règles NER
docs/
└── architecture-backend.md # Cette documentation
```
## Dépannage
### ❌ Problèmes Courants
#### Backend non accessible
```bash
# Vérifier que le backend est démarré
curl http://localhost:3001/api/health
# Vérifier les logs
cd backend && node server.js
```
#### Erreurs OCR
- Vérifier la taille des images (minimum 3x3 pixels)
- Ajuster les paramètres `textord_min_xheight`
- Vérifier les types de fichiers supportés
#### Erreurs de communication
- Vérifier que les ports 3001 (backend) et 5176 (frontend) sont libres
- Vérifier la configuration CORS
- Vérifier les variables d'environnement
### 🔍 Logs
**Backend**:
```
🚀 Serveur backend démarré sur le port 3001
📡 API disponible sur: http://localhost:3001/api
[OCR] Début de l'extraction pour: uploads/document-123.jpg
[OCR] Extraction terminée - Confiance: 85.5%
[NER] Extraction terminée: 2 identités, 1 adresse, 1 CNI
```
**Frontend**:
```
🚀 [STORE] Utilisation du backend pour l'extraction
📊 [PROGRESS] OCR doc-123: 30%
📊 [PROGRESS] NER doc-123: 50%
🎉 [BACKEND] Extraction terminée avec succès
```
## Évolutions Futures
### 🔮 Améliorations Possibles
1. **Base de données** : Stockage des résultats d'extraction
2. **Cache Redis** : Mise en cache des résultats OCR
3. **Queue système** : Traitement asynchrone des gros volumes
4. **API GraphQL** : Interface plus flexible
5. **Microservices** : Séparation OCR et NER
6. **Docker** : Containerisation pour le déploiement
7. **Monitoring** : Métriques et alertes
8. **Tests automatisés** : Suite de tests complète

View File

@ -1,140 +0,0 @@
# Chargement Dynamique des Fichiers de Test
## Vue d'ensemble
Le système de chargement dynamique des fichiers de test permet à l'application de charger automatiquement tous les fichiers présents dans le dossier `test-files/` au lieu d'utiliser une liste de fichiers codée en dur.
## Fonctionnalités
### 🔄 Chargement Automatique
- **Détection automatique** : L'application parcourt le dossier `test-files/` au démarrage
- **Filtrage intelligent** : Seuls les fichiers supportés sont chargés
- **Logs détaillés** : Chaque étape du chargement est loggée dans la console
### 📁 Types de Fichiers Supportés
- **PDF** : `.pdf`
- **Images** : `.jpg`, `.jpeg`, `.png`, `.tiff`
- **Texte** : `.txt`, `.md`
- **Documents** : `.docx`
### 🎯 Avantages
- **Flexibilité** : Ajoutez simplement des fichiers dans `test-files/` pour les tester
- **Maintenance** : Plus besoin de modifier le code pour ajouter de nouveaux fichiers de test
- **Développement** : Facilite les tests avec différents types de documents
## Architecture
### Fichiers Modifiés
#### `src/services/testFilesApi.ts` (Nouveau)
```typescript
// API pour gérer les fichiers de test
export interface TestFileInfo {
name: string
size: number
type: string
lastModified: number
}
export async function getTestFilesList(): Promise<TestFileInfo[]>
export async function loadTestFile(fileName: string): Promise<File | null>
export function filterSupportedFiles(files: TestFileInfo[]): TestFileInfo[]
```
#### `src/views/UploadView.tsx` (Modifié)
- Remplacement de la liste codée en dur par un chargement dynamique
- Ajout de logs détaillés pour le debugging
- Gestion d'erreurs améliorée
### Flux de Chargement
```mermaid
graph TD
A[Démarrage de l'application] --> B[Vérification mode DEV]
B --> C[Appel getTestFilesList()]
C --> D[Vérification de chaque fichier]
D --> E[Filtrage des fichiers supportés]
E --> F[Chargement des fichiers valides]
F --> G[Création des objets Document]
G --> H[Ajout au store Redux]
H --> I[Déclenchement de l'extraction]
```
## Utilisation
### Ajouter de Nouveaux Fichiers de Test
1. **Placez vos fichiers** dans le dossier `test-files/`
2. **Redémarrez l'application** (ou rechargez la page)
3. **Vérifiez les logs** dans la console du navigateur
### Exemple de Logs
```
🔄 [BOOTSTRAP] Chargement des fichiers de test...
📁 [BOOTSTRAP] Fichiers trouvés: ["IMG_20250902_162159.jpg", "sample.pdf", ...]
✅ [BOOTSTRAP] Fichiers supportés: ["IMG_20250902_162159.jpg", "sample.pdf", ...]
📄 [BOOTSTRAP] Chargement de IMG_20250902_162159.jpg...
✅ [BOOTSTRAP] IMG_20250902_162159.jpg chargé (1052.7 KB)
🎉 [BOOTSTRAP] 5 fichiers chargés avec succès
🔍 [BOOTSTRAP] Déclenchement de l'extraction pour IMG_20250902_162159.jpg
```
## Configuration
### Variables d'Environnement
- `VITE_DISABLE_LLM=true` : Désactive l'utilisation des LLM
- `VITE_USE_RULE_NER=true` : Active l'extraction par règles
- `VITE_LLM_CLASSIFY_ONLY=false` : Désactive la classification LLM
### Mode Développement
Le chargement dynamique ne s'active qu'en mode développement (`import.meta.env.DEV`).
## Tests
### Script de Test
Un script de test est disponible : `test-dynamic-files.cjs`
```bash
node test-dynamic-files.cjs
```
### Vérifications Automatiques
- ✅ Existence du dossier `test-files/`
- ✅ Liste des fichiers disponibles
- ✅ Filtrage des fichiers supportés
- ✅ Accessibilité via le serveur de développement
- ✅ Chargement des fichiers individuels
## Dépannage
### Problèmes Courants
#### Aucun fichier chargé
- Vérifiez que le dossier `test-files/` existe
- Vérifiez que les fichiers ont des extensions supportées
- Consultez les logs de la console
#### Fichiers non accessibles
- Vérifiez que le serveur de développement est démarré
- Vérifiez les permissions des fichiers
- Testez l'accès direct via l'URL : `http://localhost:5174/test-files/nom-du-fichier`
#### Erreurs de chargement
- Vérifiez la taille des fichiers (limite de mémoire du navigateur)
- Vérifiez le format des fichiers
- Consultez les logs d'erreur dans la console
## Évolutions Futures
### Améliorations Possibles
- **API serveur** : Créer une vraie API pour lister les fichiers
- **Cache** : Mettre en cache la liste des fichiers
- **Filtres** : Permettre de filtrer par type de document
- **Métadonnées** : Ajouter des métadonnées aux fichiers de test
- **Interface** : Créer une interface pour gérer les fichiers de test
### Intégration CI/CD
- **Tests automatisés** : Intégrer les tests dans la pipeline CI
- **Validation** : Valider automatiquement les nouveaux fichiers de test
- **Documentation** : Générer automatiquement la documentation des fichiers de test

View File

@ -1,125 +0,0 @@
# Correction des Méthodes Dépréciées de Tesseract.js
## Problème Identifié
L'application affichait des warnings de dépréciation dans la console :
```
fileExtract.ts:113 `load` is depreciated and should be removed from code (workers now come pre-loaded)
fileExtract.ts:115 `loadLanguage` is depreciated and should be removed from code (workers now come with language pre-loaded)
fileExtract.ts:117 `initialize` is depreciated and should be removed from code (workers now come pre-initialized)
```
## Cause
Tesseract.js a été mis à jour et les méthodes suivantes sont maintenant dépréciées :
- `worker.load()` - Les workers viennent maintenant pré-chargés
- `worker.loadLanguage()` - Les workers viennent avec les langues pré-chargées
- `worker.initialize()` - Les workers viennent pré-initialisés
## Solution Appliquée
### Avant (Code Déprécié)
```typescript
const worker = await createWorker()
try {
worker.setLogger?.((m: any) => {
if (m?.progress != null) console.info('[OCR]', Math.round(m.progress * 100) + '%')
})
await worker.load() // ❌ Déprécié
await worker.loadLanguage('fra+eng') // ❌ Déprécié
await worker.initialize('fra+eng') // ❌ Déprécié
// ... reste du code
}
```
### Après (Code Corrigé)
```typescript
const worker = await createWorker('fra+eng') // ✅ Langues directement dans createWorker
try {
worker.setLogger?.((m: any) => {
if (m?.progress != null) console.info('[OCR]', Math.round(m.progress * 100) + '%')
})
// ✅ Plus besoin de load, loadLanguage, initialize
// ... reste du code
}
```
## Changements Effectués
### Fichier Modifié : `src/services/fileExtract.ts`
1. **Suppression des méthodes dépréciées** :
- `await worker.load()`
- `await worker.loadLanguage('fra+eng')`
- `await worker.initialize('fra+eng')`
2. **Modification de createWorker** :
- Avant : `createWorker()`
- Après : `createWorker('fra+eng')`
3. **Préservation des méthodes nécessaires** :
- `worker.setLogger()` - Configuration du logger
- `worker.setParameters()` - Configuration des paramètres OCR
- `worker.recognize()` - Reconnaissance du texte
- `worker.terminate()` - Nettoyage du worker
## Avantages de la Correction
### 🚀 Performance
- **Démarrage plus rapide** : Plus besoin d'attendre le chargement des langues
- **Moins d'appels API** : Réduction des appels asynchrones
- **Initialisation simplifiée** : Processus d'initialisation plus direct
### 🧹 Code Plus Propre
- **Moins de code** : Suppression de 3 lignes dépréciées
- **Moins de warnings** : Console plus propre
- **Meilleure maintenabilité** : Code aligné avec les dernières pratiques
### 🔧 Compatibilité
- **Version récente** : Compatible avec Tesseract.js v5.1.0+
- **Future-proof** : Prêt pour les futures versions
- **Standards modernes** : Suit les recommandations officielles
## Tests de Validation
### ✅ Vérifications Effectuées
1. **Compilation** : Le projet compile sans erreurs
2. **Serveur** : Le serveur de développement fonctionne
3. **Méthodes supprimées** : Aucune méthode dépréciée restante
4. **Méthodes préservées** : Toutes les méthodes nécessaires sont présentes
5. **Fonctionnalité** : L'OCR fonctionne toujours correctement
### 🧪 Script de Test
Un script de validation a été créé pour vérifier :
- Absence des méthodes dépréciées
- Présence des méthodes nécessaires
- Configuration correcte de createWorker
## Impact sur l'Utilisateur
### 🎯 Transparent
- **Aucun changement visible** : L'interface utilisateur reste identique
- **Performance améliorée** : OCR potentiellement plus rapide
- **Console plus propre** : Moins de warnings dans les logs
### 📊 Métriques
- **Réduction des warnings** : 100% des warnings de dépréciation supprimés
- **Code simplifié** : 3 lignes de code supprimées
- **Compatibilité** : 100% compatible avec Tesseract.js v5.1.0+
## Recommandations
### 🔄 Mise à Jour Continue
- **Surveiller les mises à jour** : Vérifier régulièrement les changements de Tesseract.js
- **Tests réguliers** : Tester l'OCR après chaque mise à jour
- **Documentation** : Maintenir la documentation à jour
### 🚀 Optimisations Futures
- **Configuration avancée** : Explorer les nouvelles options de configuration
- **Performance** : Optimiser les paramètres OCR pour de meilleures performances
- **Langues multiples** : Ajouter le support de langues supplémentaires si nécessaire
## Conclusion
Cette correction élimine les warnings de dépréciation tout en améliorant les performances et la maintenabilité du code. L'application est maintenant alignée avec les dernières pratiques de Tesseract.js et prête pour les futures évolutions.

196
docs/extact_model.json Normal file
View File

@ -0,0 +1,196 @@
{
"document": {
"id": "doc-1757976015681",
"fileName": "facture_4NK_08-2025_04.pdf",
"fileSize": 85819,
"mimeType": "application/pdf",
"uploadTimestamp": "2025-09-15T22:40:15.681Z"
},
"classification": {
"documentType": "Facture",
"confidence": 0.95,
"subType": "Facture de prestation",
"language": "fr",
"pageCount": 1
},
"extraction": {
"text": {
"raw": "Janin Consulting - EURL au capital de 500 Euros...",
"processed": "Janin Consulting - EURL au capital de 500 Euros...",
"wordCount": 165,
"characterCount": 1197,
"confidence": 0.95
},
"entities": {
"persons": [
{
"id": "person-1",
"type": "contact",
"firstName": "Anthony",
"lastName": "Janin",
"role": "Gérant",
"email": "ja.janin.anthony@gmail.com",
"phone": "33 (0)6 71 40 84 13",
"confidence": 0.9,
"source": "rule-based"
}
],
"companies": [
{
"id": "company-1",
"name": "Janin Consulting",
"legalForm": "EURL",
"siret": "815 322 912 00040",
"rcs": "815 322 912 NANTERRE",
"tva": "FR64 815 322 912",
"capital": "500 Euros",
"role": "Fournisseur",
"confidence": 0.95,
"source": "rule-based"
},
{
"id": "company-2",
"name": "4NK",
"tva": "FR79913422994",
"role": "Client",
"confidence": 0.9,
"source": "rule-based"
}
],
"addresses": [
{
"id": "address-1",
"type": "siège_social",
"street": "177 rue du Faubourg Poissonnière",
"city": "Paris",
"postalCode": "75009",
"country": "France",
"company": "Janin Consulting",
"confidence": 0.9,
"source": "rule-based"
},
{
"id": "address-2",
"type": "facturation",
"street": "4 SQUARE DES GOELANDS",
"city": "MONT-SAINT-AIGNAN",
"postalCode": "76130",
"country": "France",
"company": "4NK",
"confidence": 0.9,
"source": "rule-based"
}
],
"financial": {
"amounts": [
{
"id": "amount-1",
"type": "prestation",
"description": "Prestation du mois d'Août 2025",
"quantity": 10,
"unitPrice": 550.00,
"totalHT": 5500.00,
"currency": "EUR",
"confidence": 0.95
}
],
"totals": {
"totalHT": 5500.00,
"totalTVA": 1100.00,
"totalTTC": 6600.00,
"tvaRate": 0.20,
"currency": "EUR"
},
"payment": {
"terms": "30 jours après émission",
"penaltyRate": "Taux BCE + 7 points",
"bankDetails": {
"bank": "CAISSE D'EPARGNE D'ILE DE FRANCE",
"accountHolder": "Janin Anthony",
"address": "1 rue Pasteur (78800)",
"rib": "17515006000800309088884"
}
}
},
"dates": [
{
"id": "date-1",
"type": "facture",
"value": "29-août-25",
"formatted": "2025-08-29",
"confidence": 0.9,
"source": "rule-based"
},
{
"id": "date-2",
"type": "période",
"value": "août-25",
"formatted": "2025-08",
"confidence": 0.9,
"source": "rule-based"
}
],
"contractual": {
"clauses": [
{
"id": "clause-1",
"type": "paiement",
"content": "Le paiement se fera (maximum) 30 jours après l'émission de la facture.",
"confidence": 0.9
},
{
"id": "clause-2",
"type": "intérêts_retard",
"content": "Tout retard de paiement d'une quelconque facture fait courir, immédiatement et de plein droit, des intérêts de retard calculés au taux directeur de la BCE majoré de 7 points jusqu'au paiement effectif et intégral.",
"confidence": 0.9
}
],
"signatures": [
{
"id": "signature-1",
"type": "électronique",
"present": false,
"signatory": null,
"date": null,
"confidence": 0.8
}
]
},
"references": [
{
"id": "ref-1",
"type": "facture",
"number": "4NK_4",
"confidence": 0.95
}
]
}
},
"metadata": {
"processing": {
"engine": "4NK_IA_Backend",
"version": "1.0.0",
"processingTime": "2.5s",
"ocrEngine": "pdf-parse",
"nerEngine": "rule-based",
"preprocessing": {
"applied": false,
"reason": "PDF direct text extraction"
}
},
"quality": {
"globalConfidence": 0.95,
"textExtractionConfidence": 0.95,
"entityExtractionConfidence": 0.90,
"classificationConfidence": 0.95
}
},
"status": {
"success": true,
"errors": [],
"warnings": [
"Aucune signature détectée"
],
"timestamp": "2025-09-15T22:40:15.681Z"
}
}

View File

@ -1,166 +0,0 @@
# Intégration du préprocessing d'image dans le backend
## 📋 Résumé
Le préprocessing d'image a été intégré avec succès dans le backend pour améliorer considérablement la qualité de l'extraction OCR et la détection des entités dans les documents d'identité.
## 🔧 Implémentation
### 1. Module de préprocessing créé
**Fichier :** `/backend/imagePreprocessing.js`
**Fonctionnalités :**
- Redimensionnement intelligent des images
- Conversion en niveaux de gris
- Amélioration du contraste et de la luminosité
- Amélioration de la netteté avec filtres spécialisés
- Réduction du bruit avec filtre médian
- Binarisation optionnelle
### 2. Intégration dans le serveur backend
**Fichier :** `/backend/server.js`
**Modifications apportées :**
- Import du module de préprocessing
- Intégration dans la fonction `extractTextFromImage()`
- Préprocessing automatique avant l'OCR
- Nettoyage automatique des fichiers temporaires
## 📊 Résultats de l'intégration
### **Image test :** `IMG_20250902_162159.jpg`
#### **Avant le préprocessing :**
- ❌ NICOLAS : Non détecté
- ❌ CANTU : Non détecté
- ❌ Numéros CNI : 0 détecté
- ❌ Qualité OCR : Très dégradée
#### **Après le préprocessing :**
- ✅ **NICOLAS** : Détecté dans le texte
- ✅ **CANTU** : Détecté dans le texte
- ✅ **Numéros CNI** : 2 détectés (`LK093008`, `NC801211`)
- ✅ **Type de document** : CNI identifié
- ✅ **Qualité OCR** : Considérablement améliorée
### **Texte extrait avec préprocessing :**
```
RÉPUBLIQUE FRANCATSEN
CARTE NATIONALE DIDENTITE Ne : 180193155156 - es
184 JC Nom: CANTY
Fe - 0 Mele: 33 12 198
LL ee
5 IDFRACANTUCCKKLLLLKLLLLLLLLLLLK093008
4 1801931551563NICOLASSFRANC8012115M8
```
## 🎯 Améliorations apportées
### **1. Détection des noms :**
- **NICOLAS** : Détecté dans `"4 1801931551563NICOLASSFRANC8012115M8"`
- **CANTU** : Détecté dans `"JC Nom: CANTY"` et `"IDFRACANTUCCKKLLLLKLLLLLLLLLLLK093008"`
### **2. Détection des numéros CNI :**
- **LK093008** : Format 2 lettres + 6 chiffres
- **NC801211** : Format 2 lettres + 6 chiffres
### **3. Identification du type de document :**
- **Type détecté** : CNI (Carte Nationale d'Identité)
- **Confiance** : 60% globale
## 🔧 Configuration du préprocessing
### **Paramètres optimisés :**
```javascript
{
width: 2000, // Redimensionnement à 2000px
contrast: 1.5, // Augmentation du contraste
brightness: 1.1, // Légère augmentation de la luminosité
grayscale: true, // Conversion en niveaux de gris
sharpen: true, // Amélioration de la netteté
denoise: true, // Réduction du bruit
format: 'png', // Format PNG pour meilleure qualité
quality: 100 // Qualité maximale
}
```
## 🚀 API Backend
### **Endpoint :** `POST /api/extract`
**Utilisation :**
```bash
curl -X POST -F "document=@image.jpg" http://localhost:3001/api/extract
```
**Réponse JSON :**
```json
{
"success": true,
"documentId": "doc-1757975495705",
"fileName": "IMG_20250902_162159.jpg",
"processing": {
"ocr": {
"text": "RÉPUBLIQUE FRANCATSEN\nCARTE NATIONALE DIDENTITE...",
"confidence": 41,
"wordCount": 27
},
"ner": {
"identities": [...],
"cniNumbers": [
{"id": "cni-0", "number": "LK093008", "confidence": 0.95},
{"id": "cni-1", "number": "NC801211", "confidence": 0.95}
],
"documentType": "CNI"
}
}
}
```
## 📈 Performance
### **Amélioration des résultats :**
- **Détection NICOLAS** : +100% (de 0% à 100%)
- **Détection CANTU** : +100% (de 0% à 100%)
- **Détection CNI** : +100% (de 0 à 2 numéros)
- **Qualité OCR** : +300% (texte lisible vs corrompu)
### **Temps de traitement :**
- **Préprocessing** : ~2-3 secondes
- **OCR** : ~4-5 secondes
- **Total** : ~6-8 secondes par image
## 🔍 Détails techniques
### **Pipeline de traitement :**
1. **Upload** de l'image via l'API
2. **Analyse** des métadonnées de l'image
3. **Préprocessing** avec Sharp.js
4. **OCR** avec Tesseract.js (multi-stratégies)
5. **Extraction NER** avec patterns de règles
6. **Nettoyage** des fichiers temporaires
7. **Retour** des résultats JSON
### **Fichiers temporaires :**
- Création automatique d'images préprocessées
- Nettoyage automatique après traitement
- Gestion des erreurs et timeouts
## 🎉 Conclusion
L'intégration du préprocessing d'image dans le backend a été un **succès complet**. Le système peut maintenant :
**Détecter NICOLAS et CANTU** dans les images de CNI
**Extraire les numéros de CNI** au format correct
**Identifier le type de document** (CNI)
**Fournir une API robuste** pour le traitement d'images
**Gérer automatiquement** le préprocessing et le nettoyage
Le système est maintenant prêt pour la production et peut traiter efficacement les documents d'identité avec une qualité d'extraction considérablement améliorée.
---
*Documentation créée le 15 septembre 2025*
*Projet : 4NK_IA_front*
*Version : 1.0.0*