diff --git a/docs/API.md b/docs/API.md index 73bc556..416721f 100644 --- a/docs/API.md +++ b/docs/API.md @@ -13,174 +13,80 @@ d'analyse de documents notariaux. http://localhost:8000 (développement) ``` +### Modes d'API pris en charge + +- **Mode simple** (`VITE_BACKEND_MODE=simple`) : endpoints sous `/api/notary/...` +- **Mode complet** (`VITE_BACKEND_MODE=complete`) : endpoints sous `/api/documents/...` + +La variable d'environnement `VITE_BACKEND_MODE` pilote dynamiquement le choix des endpoints côté front. + ### Endpoints #### Upload de document ```http -POST /api/documents/upload +POST /api/notary/upload # mode simple +POST /api/documents/upload # mode complet Content-Type: multipart/form-data Body: FormData avec le fichier ``` -**Réponse :** +**Réponse (champs attendus et utilisés par le front) :** + +```json +{ + "document_id": "doc_123456", // ou "id" + "mime_type": "application/pdf", // ou "mimeType" + "functional_type": "CNI" // ou "functionalType" (type fonctionnel métier) +} +``` + +Le front mappe en `Document`: ```json { "id": "doc_123456", "name": "acte_vente.pdf", - "type": "application/pdf", + "mimeType": "application/pdf", + "functionalType": "CNI", "size": 1024000, - "uploadDate": "2024-01-15T10:30:00Z", - "status": "completed" + "uploadDate": "", + "status": "completed", + "previewUrl": "blob:..." } ``` #### 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 -} +GET /api/notary/documents/{documentId} # mode simple (détails document + résultats) +GET /api/documents/{documentId}/extract # mode complet ``` #### Analyse du document ```http -GET /api/documents/{documentId}/analyze +GET /api/documents/{documentId}/analyze # mode complet ``` -**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" - ] -} -``` +(mode simple: synthèse construite côté front à partir de `/api/notary/documents/{documentId}`) #### Données contextuelles ```http -GET /api/documents/{documentId}/context +GET /api/documents/{documentId}/context # mode complet ``` -**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" -} -``` +(mode simple: non disponible — fallback de démonstration) #### Conseil IA ```http -GET /api/documents/{documentId}/conseil +GET /api/documents/{documentId}/conseil # mode complet ``` -**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" -} -``` +(mode simple: non disponible — fallback de démonstration) ## APIs Externes @@ -235,6 +141,7 @@ En cas d'erreur, l'application bascule automatiquement vers des données de dém ```env VITE_API_URL=http://localhost:8000 +VITE_BACKEND_MODE=simple 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 diff --git a/src/components/FilePreview.tsx b/src/components/FilePreview.tsx index 24c5982..29051a3 100644 --- a/src/components/FilePreview.tsx +++ b/src/components/FilePreview.tsx @@ -59,7 +59,7 @@ export const FilePreview: React.FC = ({ document, onClose }) = } } - const isPDF = document.type.includes('pdf') || document.name.toLowerCase().endsWith('.pdf') + const isPDF = document.mimeType.includes('pdf') || document.name.toLowerCase().endsWith('.pdf') if (!isPDF) { return ( @@ -71,7 +71,7 @@ export const FilePreview: React.FC = ({ document, onClose }) = - Aperçu non disponible pour ce type de fichier ({document.type}) + Aperçu non disponible pour ce type de fichier ({document.functionalType || document.mimeType}) ) diff --git a/src/services/api.ts b/src/services/api.ts index 1a93098..079ba73 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -2,6 +2,7 @@ import axios from 'axios' import type { Document, ExtractionResult, AnalysisResult, ContextResult, ConseilResult } from '../types' const BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000' +const BACKEND_MODE = (import.meta.env.VITE_BACKEND_MODE || 'simple').toLowerCase() as 'simple' | 'complete' export const apiClient = axios.create({ baseURL: BASE_URL, @@ -54,7 +55,8 @@ export const documentApi = { return { id: data.document_id || data.id || 'upload-' + Date.now(), name: file.name, - type: file.type || 'application/pdf', + mimeType: data.mime_type || data.mimeType || file.type || 'application/pdf', + functionalType: data.functional_type || data.functionalType || undefined, size: file.size, uploadDate: new Date(), status: 'completed', @@ -69,7 +71,8 @@ export const documentApi = { return { id: 'demo-' + Date.now(), name: file.name, - type: file.type || 'application/pdf', + mimeType: file.type || 'application/pdf', + functionalType: undefined, size: file.size, uploadDate: new Date(), status: 'completed', @@ -189,8 +192,24 @@ export const documentApi = { // Analyse du document analyze: async (documentId: string): Promise => { try { - const { data } = await apiClient.get(`/api/documents/${documentId}/analyze`) - return data + if (BACKEND_MODE === 'complete') { + const { data } = await apiClient.get(`/api/documents/${documentId}/analyze`) + return data + } + // Mode simple: pas d'endpoint d'analyse dédié -> utiliser le détail et synthétiser + const { data } = await apiClient.get(`/api/notary/documents/${documentId}`) + return { + documentId, + documentType: data?.results?.document_type || 'Document', + isCNI: (data?.results?.document_type || '').toLowerCase().includes('cni'), + credibilityScore: data?.results?.verification_score ?? 0.85, + summary: 'Analyse synthétique basée sur les métadonnées documentaires disponibles.', + recommendations: [ + "Vérifier l'identité des parties", + "Contrôler la validité des documents cadastraux", + "S'assurer de la conformité des clauses contractuelles", + ], + } } catch { // Données de démonstration return { @@ -211,8 +230,20 @@ export const documentApi = { // Données contextuelles getContext: async (documentId: string): Promise => { try { - const { data } = await apiClient.get(`/api/documents/${documentId}/context`) - return data + if (BACKEND_MODE === 'complete') { + const { data } = await apiClient.get(`/api/documents/${documentId}/context`) + return data + } + // Mode simple: pas d'endpoint context -> démo + return { + documentId, + 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: new Date() + } } catch { // Données de démonstration return { @@ -230,8 +261,30 @@ export const documentApi = { // Conseil LLM getConseil: async (documentId: string): Promise => { try { - const { data } = await apiClient.get(`/api/documents/${documentId}/conseil`) - return data + if (BACKEND_MODE === 'complete') { + const { data } = await apiClient.get(`/api/documents/${documentId}/conseil`) + return data + } + // Mode simple: pas d'endpoint conseil -> démo + return { + documentId, + analysis: "Ce document présente toutes les caractéristiques d'un acte notarial standard. Les informations sont cohérentes et les parties semblent légitimes. Aucun élément suspect n'a été détecté.", + recommendations: [ + "Procéder à la vérification d'identité des parties", + "Contrôler la validité des documents fournis", + "S'assurer de la conformité réglementaire" + ], + 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: new Date() + } } catch { // Données de démonstration return { diff --git a/src/types/index.ts b/src/types/index.ts index ba23b58..e4deeb6 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,7 +1,8 @@ export interface Document { id: string name: string - type: string + mimeType: string + functionalType?: string size: number uploadDate: Date status: 'uploading' | 'processing' | 'completed' | 'error' diff --git a/src/views/UploadView.tsx b/src/views/UploadView.tsx index ab35a5b..54a6d68 100644 --- a/src/views/UploadView.tsx +++ b/src/views/UploadView.tsx @@ -136,7 +136,7 @@ export default function UploadView() {