---
suivi: 1938
date: 2026-10-16
sujet: Pagination liste parcelles 50/100/200/500
chantier: module-foncier
type: evolution
statut: poussé
hash: 9da5828db
fichiers:
  - app/Http/Controllers/Foncier/ProspectionController.php
  - resources/js/Pages/Foncier/Prospection/Index.vue
  - tests/Unit/ParcelleParPage1938Test.php
  - tests/Unit/ParcelleExportPagination1731SourceTest.php
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - public/build/manifest.json
  - docs/suivi/SUIVI_1938_parcelles_par_page_500.md
---

# SUIVI #1938 — pagination 50 / 100 / 200 / 500

## Fiches lues

- **#1731 LEÇON** — page et export partagent `requeteListe()` ; pagination déjà 50/100/200 mémorisée dans `users.preferences` (`foncier_parcelles_par_page`).
- **#1208 / #1533 LEÇON** — eager liste (`with` + `withCount`) : pas de N+1 ; `query_count` déjà mesuré dans `payloadParcelle`.
- **#1918 / #1922 / #1925** — ne pas toucher édition en ligne, filtre Statut défaut, vue complète.

Réutilisation : `User::preference` / `setPreference` + clé `PREF_FONCIER_PARCELLES_PAR_PAGE` (#1731). Aucun nouveau mécanisme.

## PROMPT ENVOYÉ

Sélecteur « par page » 50 / 100 / 200 / 500 sur Foncier > Parcelles. Mémorisation par utilisateur côté serveur. Première ouverture : 50. Whitelist stricte ; valeur invalide → 50. Perf à 500 sans N+1. Ne pas toucher export, carte, édition (#1918), vue (#1925), filtre statut (#1922).

## SYNTHÈSE

`ProspectionController::TAILLE_PAGE` passe à `[50, 100, 200, 500]`. `resolveParPage` : sans `per_page` → préférence (défaut 50) ; valeur whitelist → appliquée et mémorisée si différente ; toute autre valeur (`9999`, `abc`) → **50** (plus le repli sur la préférence stockée). Front : mêmes options, changement → reload sans `page` (= page 1). Export Excel inchangé (toutes les lignes filtrées).

| Libellé affiché | Valeur postée (`per_page`) | Valeur relue / mémorisée (`users.preferences.foncier_parcelles_par_page`) |
| --- | --- | --- |
| 50 | 50 | 50 |
| 100 | 100 | 100 |
| 200 | 200 | 200 |
| 500 | 500 | 500 |

### Perf

Eager inchangé (`appliquerEagerListe`) : commune, propriétaires (+ responsable), responsable, natures + `withCount` / `withExists` — nombre de requêtes SQL **indépendant** du nombre de lignes de la page. MySQL local absent ; migrate sqlite échoue (DDL MySQL). Pas de durée inventée. Preuve : source + `query_count` déjà exposé par `payloadParcelle` (#1208).

## DÉPLOIEMENT-TEST

git pull origin main
php artisan optimize:clear
php artisan view:clear
php artisan journal:sync

Pas de migration. Pas de route nouvelle.

1. Liste : sélecteur 50 / 100 / 200 / 500 ; défaut 50 sans préférence.
2. Passer à 500 : page 1, compteur cohérent (ex. 822 → 2 pages).
3. Recharger / se reconnecter : 500 conservé ; autre utilisateur indépendant.
4. URL `per_page=9999` ou `abc` → 50 lignes.
5. Regroupement commune + sélection groupée à 500 : OK.

## LEÇON

Une valeur `per_page` hors whitelist ne doit pas renvoyer la préférence stockée : sinon une URL forcée (`9999`) affiche 200 si l’utilisateur avait 200. Repli fixe à 50. Réutiliser `users.preferences` plutôt qu’un localStorage (PC/Mac).
