---
suivi: 1413
date: 2026-09-02
sujet: facture_doublon_controle_humain
chantier: factures
type: feature
statut: poussé
hash: 67454fc5
fichiers:
  - database/migrations/2026_09_02_141300_add_doublon_controle_to_factures_and_depot_factures.php
  - app/Support/FactureDoublonControle.php
  - app/Support/DepotFactureDoublonPayload.php
  - app/Models/Facture.php
  - app/Models/DepotFacture.php
  - app/Http/Controllers/DepotFactureController.php
  - app/Http/Controllers/FactureController.php
  - app/Services/DepotFactureEngagerWorkflowService.php
  - app/Services/DepotFactureValiderDejaValideService.php
  - routes/web.php
  - resources/js/Pages/Factures/Show.vue
  - resources/js/Pages/DepotFactures/DepotFactureSaisieForm.vue
  - tests/Unit/FactureDoublonControle1413SourceTest.php
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - public/build/
  - docs/suivi/SUIVI_1413_doublon_controle_humain.md
---

## PROMPT ENVOYÉ

SUIVI #1413 — marquer un doublon détecté comme « vérifié, ce n’est pas un doublon », trace auteur/date, bandeau qui reste mais change d’apparence, deux écrans (saisie + fiche facture), réversibilité journalisée.

## FICHES LUES

- #1410 — verrou : SoT facture + miroir dépôt, Historisable, canEditDepot / GROUPES_RETRAIT.
- #1412 — point d’entrée fiche facture via routes dépôt + latestOfMany.

## ÉTAPE 0 (mesures)

- Détection : `DepotFactureDuplicateDetector` (SOCLE n°+montant ±0,01 ; FILET ≥3 critères). Flag stocké `doublon_detecte` / `doublon_de_id` à l’OCR ; liste matches recalculée à la volée via `DepotFactureDoublonPayload`.
- SHOW COLUMNS : **base locale inaccessible** — requêtes fournies dans le livrable.
- Deux bandeaux = **même source** `DepotFactureDoublonPayload` (pas d’arrêt).

## SYNTHÈSE

### Portée retenue
**DÉPÔT** comme source de vérité (où vit `doublon_detecte` ; saisie sans facture), miroir `factures` + sync tous dépôts liés — même mécanique d’écriture que le verrou, SoT inverse tant qu’il n’y a pas de facture.

### Nouveau doublon après contrôle
Empreinte SHA-256 des matches (`type:id`) stockée dans `doublon_controle_empreinte`. Si un nouveau match apparaît, empreinte diverge → contrôle non actif → bandeau alerte se réarme.

### UI
Case « J’ai vérifié : ce n’est pas un doublon » + confirmation. Après : bandeau info « Doublon vérifié par {NOM} le {DATE} — ce n’est pas un doublon. » Comparer / Ouvrir le doublon restent.

### Droits
Marquer : `canEditDepot`. Annuler : auteur OU `FactureVerrou::GROUPES_RETRAIT` (m365 brut). Routes POST dépôt.

## DÉPLOIEMENT-TEST

```bash
git pull origin main
php artisan migrate --force
php artisan optimize:clear
php artisan view:clear
php artisan route:clear
php artisan journal:sync
```

## LEÇON

Le flag de détection est sur le dépôt et la liste est recalculée : un contrôle humain doit mémoriser **quelle paire/ensemble** a été validé (empreinte), sinon un 3ᵉ doublon ne réarmerait jamais l’alerte.
