feat(api): alignement back/front + support functionalType/mimeType + modes simple/complete (VITE_BACKEND_MODE)
This commit is contained in:
parent
013a6dda0a
commit
6600308d61
161
docs/API.md
161
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": "<date locale>",
|
||||
"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
|
||||
|
@ -59,7 +59,7 @@ export const FilePreview: React.FC<FilePreviewProps> = ({ 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<FilePreviewProps> = ({ document, onClose }) =
|
||||
</IconButton>
|
||||
</Box>
|
||||
<Alert severity="info">
|
||||
Aperçu non disponible pour ce type de fichier ({document.type})
|
||||
Aperçu non disponible pour ce type de fichier ({document.functionalType || document.mimeType})
|
||||
</Alert>
|
||||
</Paper>
|
||||
)
|
||||
|
@ -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<AnalysisResult> => {
|
||||
try {
|
||||
if (BACKEND_MODE === 'complete') {
|
||||
const { data } = await apiClient.get<AnalysisResult>(`/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<ContextResult> => {
|
||||
try {
|
||||
if (BACKEND_MODE === 'complete') {
|
||||
const { data } = await apiClient.get<ContextResult>(`/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<ConseilResult> => {
|
||||
try {
|
||||
if (BACKEND_MODE === 'complete') {
|
||||
const { data } = await apiClient.get<ConseilResult>(`/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 {
|
||||
|
@ -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'
|
||||
|
@ -136,7 +136,7 @@ export default function UploadView() {
|
||||
|
||||
<Box display="flex" gap={1} flexWrap="wrap">
|
||||
<Chip
|
||||
label={doc.type}
|
||||
label={doc.functionalType || doc.mimeType}
|
||||
size="small"
|
||||
variant="outlined"
|
||||
/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user