---
suivi: 1478
date: 2026-09-07
sujet: Tableau de bord compta — indicateurs du comptable
chantier: comptabilite / synthese
type: feature
statut: poussé
hash: b4da0118
fichiers:
  - app/Support/Compta/ComptaTableauBordAcces.php
  - app/Services/Compta/ComptaTableauBordService.php
  - app/Http/Controllers/ComptaTableauBordController.php
  - app/Http/Middleware/HandleInertiaRequests.php
  - routes/web.php
  - resources/js/Layouts/AppShell.vue
  - resources/js/Pages/Factures/TableauBord.vue
  - public/build/
  - tests/Unit/ComptaTableauBord1478SourceTest.php
  - tests/Unit/ComptaTableauBord1478Test.php
  - tests/Feature/ComptaTableauBord1478FeatureTest.php
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - docs/suivi/SUIVI_1478_tableau_bord_compta.md
---

# SUIVI #1478 — Tableau de bord compta (indicateurs du comptable)

## PROMPT ENVOYÉ

Page « Tableau de bord compta » dans le menu COMPTABILITÉ (pas un widget).
Quatre blocs : pipeline, blocages nommés, échues non payées, montant à payer
par compte bancaire (nature × origine × échéance). Accès GS_COMPTABILITE,
GS_DIRECTION_GENERALE, GS_ADMIN_ERP. Lecture seule. Mesure avant écriture.

## BASE GIT

```
git log --oneline -1 origin/main
c1b8fefa chore(suivi): hash fiche #1477
```

MySQL agent : refusé. Aucun chiffre de production inventé.

## FICHES LUES

- **#1477** (LEÇON) — `JuridiqueAcces` constante + `m365GroupNames()` brut ;
  flag nav Inertia aligné menu/route ; pas de permission feature si pas de
  garde amont.
- **#1468** (LEÇON) — props KPI omises hors droit (`$groupesM365` dédié) ;
  `Carbon::setTestNow` pour l’âge.
- **#1465** (LEÇON) — garde amont `feature.permission` peut 403 avant le
  contrôleur ; menu et route alignés ; pas `hasAnyM365Group` / `is_admin_erp`.
- **#1460** (LEÇON) — `WidgetDataService` reste pour le dashboard perso ;
  prune widgets interdit ; ne pas réutiliser pour une synthèse globale.
- **#1374** (LEÇON) — `paiement_fonds_propres` colonne nullable sur
  `depot_factures` (suggestion vs choix saisi).
- **#1442** — ne pas réassigner une variable payload Inertia avec
  `m365GroupNames()`.

Impact : helper type `JuridiqueAcces` (pas de permission dédiée — nouvelle
route, aucune garde `feature.permission` en amont). Totaux globaux car les
trois groupes sont dans `FactureVisibility::SOCLE_TOTAL_GROUPS`. Clics vers
écrans accessibles aux trois groupes (pas `/factures/comptabilisation` : DG
403). Graphique ApexCharts déjà présent (`vue3-apexcharts`).

## SYNTHÈSE

Route `GET /factures/tableau-de-bord`, service SQL dédié (6 requêtes), page
Inertia lecture seule, entrée de menu conditionnée par
`nav.compta_tableau_bord_visible`. Contrôleur `abort_unless` **avant**
`agregats()`. Pas de widget, pas de prune, écrans existants inchangés.

## DÉPLOIEMENT OVH

1. git pull origin main
2. find app/ config/ database/ -name "*.php" -exec touch {} +
3. php artisan optimize:clear && php artisan view:clear && php artisan route:clear
4. php artisan journal:sync

Pas de migrate. Pas de npm/composer/optimize/config:cache sur OVH.

## TESTS MANUEL ROBIN

Sabrina BARTOLI (24) ou Rudy BENOR → GS_COMPTABILITE : menu + page.
Anne PORTALES (37) ou Laury PORTALES (18) → DG : menu + page.
Un compte GS_HECTARE ou GS_COMMERCIAL → pas de menu, 403 sur l’URL.
Robin (admin) ne sert pas au test de refus.

Recouper chaque chiffre avec les listes filtrées (URL sous chaque carte).

## LEÇON

Synthèse compta ≠ widget dashboard : totaux socle total, pas `applyScope`.
Cible de clic = intersection des écrans accessibles aux trois groupes
(liste factures + MEP), jamais l’écran comptabilisation (DG exclu).
« À payer » = `PaiementLignesPayablesService::eligibleFacturesQuery`
(comptabilisée + `paiement_effectif` en_attente), distinct du virement
préparé (`etat_paiement_sage`).
