Rapport de validation sync liste↔carte + KA Scores (25/25 E2E) + chrome mobile
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8 changed files +76 −0
modified
frontend/src/styles.css
+3 −0
@@ -1836,3 +1836,6 @@ html { scroll-padding-top: 76px; } /* header sticky au-dessus des ancres */ | ||
| 1836 | 1836 | .ka-poids-row b { text-align: right; font-variant-numeric: tabular-nums; } |
| 1837 | 1837 | |
| 1838 | 1838 | .ms-car-price .ka-badge { margin-left: 2px; } |
| 1839 | +@media (max-width: 780px) { | |
| 1840 | + .ms .ka-3d { top: 148px; right: 10px; } | |
| 1841 | +} | |
modified
reports/sync-validation/01-carte-desktop.png
+0 −0
Binary file not shown.
modified
reports/sync-validation/03-filtre-tri.png
+0 −0
Binary file not shown.
modified
reports/sync-validation/04-polygone.png
+0 −0
Binary file not shown.
modified
reports/sync-validation/07-mobile-carrousel.png
+0 −0
Binary file not shown.
modified
reports/sync-validation/08-mobile-carte.png
+0 −0
Binary file not shown.
modified
reports/sync-validation/09-geolocalisation.png
+0 −0
Binary file not shown.
added
reports/sync-validation/RAPPORT.md
+73 −0
@@ -0,0 +1,73 @@ | ||
| 1 | +# Lou-Ka — Rapport de validation : synchronisation liste ↔ carte + KA Scores | |
| 2 | + | |
| 3 | +Date : 2026-08-18 · Nœud : M3U96b (`~/apps/lou-ka`) · Prod : www.lou-ka.com | |
| 4 | +Suite E2E : `scripts/test-sync.mjs` (Playwright/Chromium) — **25/25 réussis**. | |
| 5 | +Tests API : `tests/test_search.py` (9/9) · Barème : `tests/test_kascores.py` (8/8) | |
| 6 | +· Framework : `ka-maps` vitest (36/36, dont `drawGeo.test.ts`). | |
| 7 | + | |
| 8 | +## Architecture livrée | |
| 9 | + | |
| 10 | +Une seule vérité partagée : `filtres + zone (bbox visible ou polygone) + tri | |
| 11 | ++ page` → **une requête** `/api/search` → **une réponse** contenant la page de | |
| 12 | +liste ET tous les points carte, triés pareil. Le compteur de liste est par | |
| 13 | +construction égal au nombre de marqueurs ; l'index d'un point donne sa page. | |
| 14 | + | |
| 15 | +## Critères d'acceptation | |
| 16 | + | |
| 17 | +| # | Critère | Verdict | Preuve | | |
| 18 | +|---|---|---|---| | |
| 19 | +| 1 | Compteur liste = points carte (filtres seuls, carte seule, combinés, polygone) | ✅ structurel | E2E : 44 744=44 744 · 2 902=2 902 (≤900 $) · 369=369 (polygone) · 0=0 (zone vide) ; `test_search.py` | | |
| 20 | +| 2 | Filtre → carte < 300 ms perçues ; carte → liste en fin de geste | ✅ | API 82-98 ms (bbox/polygone), 364 ms province entière (45 k points, une fois puis cache client) ; debounce 280 ms fin de geste | | |
| 21 | +| 3 | Survol miroir < 100 ms, deux sens | ✅ | feature-state GPU sans re-rendu ; E2E vérifie l'état à 90 ms dans les deux sens | | |
| 22 | +| 4 | Clic marqueur → liste défile (page ajustée au besoin) ; clic annonce → recentrage + mini-fiche | ✅ | E2E « visible » + mini-fiche ; l'index des points garantit le « toujours » | | |
| 23 | +| 5 | Aucune requête périmée n'écrase une récente | ✅ | numéro de séquence + AbortController ; E2E rafale de 4 drags rapides | | |
| 24 | +| 6 | 2 000+ résultats fluides, mobile compris | ✅* | 45 k points en clustering natif Mapbox GL (aucun marqueur DOM), liste paginée (20/page), images lazy ; *fps non instrumenté en headless — architecture 60 fps (couches GPU) | | |
| 25 | +| 7 | URL partagée = recherche reproduite (filtres+zone+tri) | ✅ | E2E : caméra+tri+zone+move restaurés, 236 résultats identiques | | |
| 26 | +| 8 | Bascule mobile sans perte + carrousel synchronisé 2 sens | ✅ | E2E : marqueur→carrousel et carrousel→marqueur, URL stable à la bascule | | |
| 27 | +| 9 | États vides & dégradés propres | ✅ | « Aucun logement dans cette zone » + Élargir la zone ; +N sans position affiché honnêtement | | |
| 28 | +| 10 | Rapport + captures | ✅ | ce fichier + 11 captures dans ce dossier | | |
| 29 | + | |
| 30 | +## Captures | |
| 31 | + | |
| 32 | +01 carte desktop (compteur partagé + « sans position ») · 02 sélection miroir | |
| 33 | +(mini-fiche + carte surlignée) · 03 filtre+tri partagé · 04 polygone dessiné | |
| 34 | +(puce retirable, 369=369) · 05 zéro résultat · 06 URL partagée · 07 carrousel | |
| 35 | +mobile synchronisé · 08 bascule mobile · 09 géolocalisation d'accueil · | |
| 36 | +10 fiche KA Scores · 11 page méthodologie /ka-scores. | |
| 37 | + | |
| 38 | +## Fonctionnalités au-delà des critères | |
| 39 | + | |
| 40 | +- **Géolocalisation d'accueil** : à l'arrivée (URL nue, 1×/session), demande de | |
| 41 | + position → vue carte centrée sur l'utilisateur (garde-fou hors-Québec, refus | |
| 42 | + silencieux, liens partagés respectés) + bouton « Me localiser ». | |
| 43 | +- **Respect de l'intention** : `moveend.byUser` (framework) distingue geste et | |
| 44 | + mouvement programmé — recadrage auto seulement si l'utilisateur n'a pas la | |
| 45 | + main, sinon « Recadrer sur les résultats ». | |
| 46 | +- Marqueurs « déjà vus » atténués, fourchette de prix des clusters au survol, | |
| 47 | + écartement discret des unités d'un même immeuble (toutes cliquables à z max). | |
| 48 | + | |
| 49 | +## KA Scores (v1, barème 2026.08-v1) | |
| 50 | + | |
| 51 | +- 5 scores 0-100 par immeuble + global pondéré (pondérations personnalisables | |
| 52 | + côté client, /ka-scores). Sources : OSM (Overpass par tuiles, cache 3 mois, | |
| 53 | + table env_tiles) + percentile transport PMD StatCan 2021 (quartier.db). | |
| 54 | +- Honnêteté : « Données insuffisantes » / « Non desservi » au lieu de 0 ; | |
| 55 | + détail par score sur la fiche ; distances vol d'oiseau ×1,3 documentées ; | |
| 56 | + date + version affichées ; méthodologie publique. | |
| 57 | +- Perf : ~7 900 immeubles calculés en 8 s (incrémental) ; distribution | |
| 58 | + (déciles global, zone urbaine) : 18 · 53 · 63 · 69 · 74 · 78 · 81 · 84 · | |
| 59 | + 87 · 90 · 98. | |
| 60 | +- Intégration : pastille sur les cartes d'annonces, section fiche, tri | |
| 61 | + « Meilleur KA Score », filtre « KA Score minimal », /api/kascores/stats, | |
| 62 | + recalcul incrémental à chaque cycle de sync (watch). | |
| 63 | +- Couverture : ~90 tuiles OSM à télécharger (en cours au moment du rapport ; | |
| 64 | + la boucle watch complète 4 tuiles/heure et le calcul suit automatiquement). | |
| 65 | + | |
| 66 | +## Restes à faire (documentés, non bloquants) | |
| 67 | + | |
| 68 | +- Fréquences GTFS réelles (v1 : proximité des arrêts × PMD) ; dénivelé du | |
| 69 | + Bike Score ; numérotation optionnelle des marqueurs selon le tri ; | |
| 70 | + précédent/suivant navigateur sur les filtres (l'URL est complète, la | |
| 71 | + restauration ne réagit pas encore à popstate) ; « Mon point » / isochrones / | |
| 72 | + heatmap des loyers / alertes par polygone (PARTIES 2-5 du chantier KA | |
| 73 | + géographique) ; recalibrage du barème une fois le parc complet scoré. | |
| 74 | ||