---
suivi: 1331
date: 2026-08-13
sujet: dashboard_widgets_contenu_factures_a_valider
chantier: dashboard
type: feature
statut: poussé
hash: fbcac070
fichiers:
  - config/dashboard_widgets.php
  - app/Services/Dashboard/WidgetDataService.php
  - app/Services/Dashboard/DashboardDefaultLayoutService.php
  - app/Services/Dashboard/UserDashboardLayoutService.php
  - app/Console/Commands/DashboardPruneObsoleteWidgetsCommand.php
  - resources/js/Components/Dashboard/WidgetBody.vue
  - resources/js/Pages/Dashboard/Index.vue
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - public/build/
  - tools/diag/diag_widget_factures_1331.php
  - docs/suivi/SUIVI_1331_dashboard_widget_factures_a_valider.md
---

## PROMPT ENVOYÉ

LOT #1331 — retirer les 11 widgets du catalogue (mécanique conservée), recréer
uniquement « Mes factures à valider » (lignes lisibles + clic fiche), filtrer via
FactureVisibility, corriger seed côte-à-côte, empty state accueillant. Pas de
migration ; prune commande explicite. Ne pas toucher transport #1329 ni SIWI /
Marches / AppShell / useFormatters / journal concurrent (entrée #1331 ajoutée
après #1330).

## SYNTHÈSE

### Fiches lues
- `#1327` : Ziggy, seed `position_x=0`, triangle resizer.
- `#1329` : URLs en dur, états error/retry, Log::error + HTTP 500 — **non touchés**.
- `#1330` : `public_groupes` tableau — entrée #1331 conforme `['tous']`.

### OBJET 1 — Retrait catalogue
Catalogue réduit à `factures_a_valider`. Layout orphelin : `getLayoutForUser`
filtre `meta === null` → **ignoré silencieusement** (pas d’erreur, pas de case
muette). Compte local `user_dashboard_widgets` = 0 (stub) ; prod à mesurer via
`php artisan dashboard:prune-obsolete-widgets --dry-run` / diag.
Commande `dashboard:prune-obsolete-widgets` (--force) pour nettoyage explicite —
pas de migration.

### Code mort
`WidgetDataService` n’est appelé que par `WidgetController` (+ outils diag). Les
méthodes des 10 autres widgets ont été **retirées** du service (devenaient mortes).

### OBJET 2 — Widget factures
Périmètre = factures `en_validation_nv1|en_validation_nv2` avec workflow
`en_attente` où l’utilisateur est **éligible** (validateur désigné / rôle
programme / juriste / PDG NV2) — aligné `ValidationController::buildFacturesForUser`
(hors `mise_paiement` comptable). Rejetées hors périmètre. Puis
`FactureVisibility::canViewFacture`. Lien : `GET /factures/fiche/{id}`
(`factures.fiche.show`). Montants anormaux prod : **pas un agrégat** — ancien UI
affichait `fournisseur ?? numero_facture_fournisseur` + `montant_ttc` unitaire
(« 6 » / « 44282 » = n° fournisseur, pas id interne).

### OBJET 3 — Droits
Catalogue ouvert (`required_permissions => []`). Données filtrées
FactureVisibility uniquement.

### OBJET 4 — Layout
Seed / addWidget placent côte à côte (grille 12). Triangle = poignée resize
`grid-layout-plus` (`is-resizable="editMode"`) — normal en mode édition.

### Chantier ouvert — 10 widgets NON recréés
1. appels_de_fonds_en_retard
2. leads_marketing_recents
3. meta_health
4. synthese_chantier
5. tresorerie_consolidee
6. synthese_commerciale
7. demandes_fournisseurs
8. synchros_intacct
9. calendrier
10. documents_recents
(Décision à prendre : refaire contenu ou abandonner.)

### Vérification écran
**NON faite** en navigation privée / compte non-admin prod depuis cet
environnement. Lot **non validé écran** tant que tests 1–14 prod non joués.

## DÉPLOIEMENT-TEST

```bash
git pull origin main
php artisan optimize:clear
php artisan view:clear
php artisan journal:sync
php artisan dashboard:prune-obsolete-widgets --dry-run
```

Pas de migration. Ensuite tests prod listés dans le prompt #1331.

## LEÇON

Un widget « lisible » exige fournisseur / programme / référence humaine / HT — jamais
`numero ?? id` nu. Contenu périmé ≠ mécanique cassée. Clés hors catalogue = ignore
à l’affichage + prune commande, jamais migration DELETE silencieuse.
