Outil standalone qui mesure la qualité d'extraction du provider OCR
courant (Mock, Mistral, ou autre futur) sur un set de factures avec
ground truth, séparé de la suite Playwright (qui reste sur OCR mock
pour la rapidité CI).
Pourquoi : permet de valider qu'un changement de provider (Mistral
upgrade, ajout Document AI, custom prompt) maintient la précision sur
les factures réelles avant de l'activer en prod.
Architecture :
- Lit `e2e/fixtures/invoices/<name>.pdf` (ou .png/.jpg)
- À côté, `<name>.expected.json` avec la ground truth
- Pour chaque facture : upload temporaire vers le storage courant
(MinIO en dev), appelle provider.extract(), compare field-by-field
- Cleanup du fichier temp après extraction
- Sommaire : accuracy globale, par champ, latence moyenne, exit 1
si une fixture a échoué (utile CI)
Tolérances par champ :
- amountTtcCents : exact (la précision financière compte)
- issueDate / dueDate : jour exact
- numero : exact (trim, case-insensitive)
- clientName : Jaccard similarity ≥ 85 % sur les tokens
(tolère "SARL" final manquant, espaces, etc.)
- clientEmail : exact (lowercased) ou null
Usage :
pnpm ocr:validate # provider courant (.env)
OCR_PROVIDER=mistral MISTRAL_API_KEY=... pnpm ocr:validate
node ace ocr:validate --fixtures-dir=./other --out=report.json
Sécurité :
- `.gitignore` exclut tous les fichiers de e2e/fixtures/invoices/
sauf README + .gitignore eux-mêmes — les vraies factures ne fuitent
pas dans le repo public
À faire par Arthur :
1. Dépose 10-20 vraies factures (anonymisées si possible) dans
e2e/fixtures/invoices/
2. Pour chaque, écrit le .expected.json (5 min par facture)
3. Lance `OCR_PROVIDER=mistral pnpm ocr:validate` → ajuste prompt ou
post-process si l'accuracy descend sous le seuil
Format ground truth + seuils cibles documentés dans le README du dossier.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
49 lines
1.7 KiB
JSON
49 lines
1.7 KiB
JSON
{
|
|
"name": "rubis",
|
|
"version": "0.1.0",
|
|
"private": true,
|
|
"description": "Rubis Sur l'Ongle — SaaS de relance de factures impayées pour TPE-PME françaises",
|
|
"packageManager": "pnpm@10.0.0",
|
|
"engines": {
|
|
"node": ">=22"
|
|
},
|
|
"scripts": {
|
|
"dev": "turbo run dev --parallel",
|
|
"dev:web": "turbo run dev --filter=@rubis/web",
|
|
"dev:api": "turbo run dev --filter=@rubis/api",
|
|
"dev:up": "docker compose -f docker-compose.dev.yml up -d",
|
|
"dev:down": "docker compose -f docker-compose.dev.yml down",
|
|
"dev:logs": "docker compose -f docker-compose.dev.yml logs -f",
|
|
"dev:reset": "docker compose -f docker-compose.dev.yml down -v",
|
|
"build": "turbo run build",
|
|
"lint": "turbo run lint",
|
|
"typecheck": "turbo run typecheck",
|
|
"test": "turbo run test",
|
|
"e2e": "playwright test --config e2e/playwright.config.ts",
|
|
"e2e:ui": "playwright test --config e2e/playwright.config.ts --ui",
|
|
"e2e:headed": "playwright test --config e2e/playwright.config.ts --headed",
|
|
"e2e:setup": "bash e2e/setup-db.sh",
|
|
"ocr:validate": "pnpm --filter @rubis/api exec node ace ocr:validate",
|
|
"format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md,css}\" --ignore-path .prettierignore",
|
|
"format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md,css}\" --ignore-path .prettierignore",
|
|
"prepare": "husky || true"
|
|
},
|
|
"devDependencies": {
|
|
"@playwright/test": "^1.60.0",
|
|
"@types/node": "^22.10.0",
|
|
"eslint": "^9.18.0",
|
|
"husky": "^9.1.7",
|
|
"lint-staged": "^15.3.0",
|
|
"prettier": "^3.4.2",
|
|
"turbo": "^2.3.3",
|
|
"typescript": "^5.7.3"
|
|
},
|
|
"pnpm": {
|
|
"onlyBuiltDependencies": [
|
|
"esbuild",
|
|
"msw",
|
|
"better-sqlite3"
|
|
]
|
|
}
|
|
}
|