# Fixtures OCR — factures réelles pour bench provider Dossier de référence pour la commande `node ace ocr:validate` qui mesure la qualité d'extraction OCR (Mock, Mistral, ou autre futur provider) sur un set de factures réelles avec ground truth. ## Comment ajouter une facture 1. Dépose ton PDF dans ce dossier : `ma-facture.pdf` (ou `.png`, `.jpg`). 2. Crée à côté `ma-facture.expected.json` avec les valeurs **lisibles à l'œil sur la facture** : ```json { "expected": { "clientName": "Boulangerie Martin SARL", "clientEmail": "compta@boulangerie-martin.fr", "numero": "F-2024-0042", "amountTtcCents": 124000, "issueDate": "2024-04-15", "dueDate": "2024-05-15" }, "notes": "facture B2B classique, en-tête simple" } ``` Champs : | Champ | Format | Note | |---|---|---| | `clientName` | String | Le nom de la société/personne facturée. Variantes acceptées via similarité Jaccard ≥ 85 % (tokens) — utile si l'OCR rate un "SARL" final. | | `clientEmail` | String OR `null` | `null` si pas d'email sur la facture. | | `numero` | String | Tel qu'imprimé. Comparaison case-insensitive trim. | | `amountTtcCents` | Integer | Montant TTC en centimes. **Comparaison exacte** (la précision financière compte). | | `issueDate` | `YYYY-MM-DD` | Comparaison au jour près. | | `dueDate` | `YYYY-MM-DD` | Idem. | Le champ `notes` est libre, ignoré par la commande — pratique pour documenter "facture avec logo qui couvre 30 % du haut", "facture manuscrite scannée", etc. ## Comment lancer le bench ```bash # Avec le provider courant (.env) — par défaut "mock" pnpm --filter @rubis/api exec node ace ocr:validate # Forcer Mistral (vrai OCR — coûte des tokens API) OCR_PROVIDER=mistral MISTRAL_API_KEY=sk-... \ pnpm --filter @rubis/api exec node ace ocr:validate # Avec un dossier custom + rapport JSON node ace ocr:validate --fixtures-dir=./other-pdfs --out=report.json ``` ## Lecture du résultat La commande affiche : - Pour chaque facture : check par champ (✓/✗) avec expected vs got + confidence du provider - Sommaire : nombre de factures 100 % match, accuracy globale champs, latence moyenne - Précision par champ : pour chaque type (amount, dueDate, clientName…), le ratio de matches Exit code 1 si une facture a échoué → utile en CI pour bloquer un déploiement OCR si la qualité a chuté. ## Diversité du set Pour un bench représentatif, viser au moins : - 5 factures B2B (en-tête société, SIRET, TVA, montant rond) - 5 factures de prestation (taux horaire, jours, multilignes) - 2-3 factures avec spécificités (sous-totaux multiples, devises mixtes, scan basse qualité) - 1 facture **mauvaise** : floue, manuscrite, photo prise à la volée — pour mesurer le worst case et calibrer la confidence du provider Les vraies factures peuvent contenir des infos sensibles — **ne pas commit dans le repo public.** Le `.gitignore` exclut ce dossier par défaut (cf. `e2e/fixtures/invoices/.gitignore`). ## Cibler un seuil de qualité Calibrage suggéré V1 (à ajuster après premier run réel) : - `amountTtcCents` : ≥ 98 % d'accuracy (zéro tolérance sur l'argent) - `dueDate` / `issueDate` : ≥ 95 % - `numero` : ≥ 95 % - `clientName` : ≥ 90 % (avec fuzzy) - `clientEmail` : ≥ 80 % (souvent absent → null fréquent) En-dessous, soit améliorer le provider (prompt Mistral, post-processing), soit baisser la confiance affichée à l'user dans le SPA (badge "à vérifier" sur les drafts).