---
suivi: 1533
date: 2026-09-14
sujet: Refonte du tableau des parcelles (Prospection)
chantier: foncier / prospection / liste
type: feature
statut: poussé
hash: 7893a849
fichiers:
  - app/Http/Controllers/Foncier/ProspectionController.php
  - app/Services/Foncier/ParcelleProspectionQuery.php
  - resources/js/Pages/Foncier/Prospection/Index.vue
  - resources/js/Components/Foncier/Prospection/ProspectionParcellesSublist.vue
  - tests/Unit/TableauParcelles1533SourceTest.php
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - public/build/
  - docs/suivi/SUIVI_1533_tableau_parcelles.md
---

# SUIVI #1533 — Tableau des parcelles (Prospection)

## PROMPT ENVOYÉ

Refonte du tableau liste parcelles : pleine largeur, 11 colonnes dans
l’ordre mockup (Commune, Référence, Propriétaire(s), Surface, État,
Zonage, Constr., Occup., Acte, Valorisation, Référent), ligne cliquable,
lignes détenues en vert clair, totaux SQL en pied sur l’ensemble filtré.
Pas de N+1 (withCount + sous-requêtes). Aucune migration. Visibilité,
filtres, pastilles état, orphelins, mention « Détenue par le groupe »
(#1530) et filtre « mon secteur » inchangés. Zone commune : rebase
origin/main avant Vite.

## FICHES LUES

- **#1530 LEÇON** — mention groupe = `societe_detentrice_id` /
  `detenue_par_le_groupe` ; ne pas mélanger `societe_detentrice_libelle`.
- **#1208 LEÇON** — N+1 ; select partiel BelongsToMany sans nom = libellé
  vide (#1184) ; `query_count` en pied de page.
- **#1463 / #1449 LEÇON** — paliers 860 / 1280 ; pas de classe Tailwind
  min-largeur inventée dans les docs ; `width: 1280px; max-width: 100%`.
- **#1271 LEÇON** — `overflow-x-hidden` interdit (récidive #1444).
- **#1199 LEÇON** — deux lectures + orphelins explicites.
- **ParcellePanel.vue** n’est importé nulle part : non modifié (filtre
  « Occupée » du panel reste pour les tests #1119).

## SYNTHÈSE

Grille mode parcelle à 11 colonnes, 100 % de la largeur disponible
(coque `pp-page` alignée sur le palier fiche). Secteur n’est plus une
colonne ; le filtre confort `mon_secteur` reste. Occup. = présence d’une
ligne `parcelle_occupations` (le filtre `occupee` reste sur les
occupations courantes). Acte = `withCount(actesFonciers)`. Valorisation =
sous-requête la plus récente + « +N autres ». Référent = créateur
(`createur_id` nullable → tiret). Ligne cliquable, `@click.stop` sur les
liens parcelle et propriétaires. Pied SQL sur le résultat filtré complet,
mention « ce n’est pas une évaluation du patrimoine ». Résolution
secteur / responsables dossier uniquement si « grouper par chargé »
(évite le N+1 par commune).

## DÉPLOIEMENT-TEST

1. `git pull origin main`
2. `php artisan optimize:clear` + `view:clear` + `journal:sync`
3. AB 0571 → ligne verte, Acte = 2
4. AP 0076 → ligne normale, Acte vide si aucun
5. Clic ligne → fiche parcelle ; clic propriétaire → fiche propriétaire
6. Parcelle sans créateur → Référent = tiret
7. Plusieurs valorisations → plus récente + « +N autres »
8. Pied cohérent ; filtre commune → totaux recalculés
9. 1280 / 1100 / 800 px — patron 860/1280
10. Mode sombre OS → vert lisible

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

## LEÇON

Les 32 requêtes pour 7 lignes venaient surtout de
`resolveParCodeInsee` par commune (colonne Secteur), pas des relations
métier. Retirer la colonne sans conditionner ce batch laisse le N+1.
`with('valorisations')->limit(1)` limite la relation globale, pas par
parent : sous-requête corrélée + `withCount`. Totaux pied = clone SQL
avant `with()`, jamais un reduce JS sur la page. Liens internes d’une
ligne cliquable : `closest('a, button')` **et** `@click.stop`.
`overflow-x-hidden` reste interdit ; `overflow-hidden` sans `-x` reste
légitime (#1471).
