SPB Git

Repository Public

History of frontend Clear filter
Page 1
  1. Wed, Aug 19, 20265 commits

    1. fix(fiche): ordre des sections = ordre du DOM sur tous les breakpoints
      ···
      Sur mobile, PriceAnalysis (.f-fairvalue), la carte (.f-carte) et les KA
      Scores (.f-kascores) n avaient pas de règle order: et retombaient à
      order:0 — ils s affichaient AVANT la galerie, le prix et l adresse.
      
      - Listing.tsx : DOM restructuré en ordre logique unique (galerie → prix/
        adresse/PDF → description → inclusions → détails pratiques → analyse
        de prix → carte 3D → KA Scores → quartier → à proximité)
      - styles.css : suppression de tous les order:/display:contents — mobile
        empile les colonnes en flux naturel, desktop garde la grid 2 colonnes
      - scripts/check-order.mjs : validation Playwright (iPhone + desktop) de
        l ordre visuel, du scroll initial et de l absence d order CSS
      
      Validé Chromium + WebKit (iPhone 14) et desktop 1440px sur 2 fiches.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 3 files +110 −61
    2. Simon-Pierre Boucher 1 file +4 −1
    3. Stats v2 : dashboard ultra complet + 5 rapports PDF (module Groupe KA v2)
      ···
      - louka/statsdash.py : jauges de couverture (geo/prix/photos/publiees/completude),
        sparklines KPI, serie des retraits + loyer moyen d entree (area), multi-courbes
        loyer median par taille, barres empilees par source, distribution des loyers,
        heatmap horaire 7x24, calendrier 26 semaines, tables loyers par taille et
        baisses de loyer, records enrichis (villes chere/abordable, hausse, heure de
        pointe) - donnees reelles seulement, cache 5 min conserve
      - louka/kapdf.py + frontend/src/ka/stats/* : module canonique v2 (5 modes PDF)
      - /api/stats/report : mode=complet|synthese|tendances|repartitions|donnees,
        filename(mode) ; inconnu -> complet (retrocompatible v1)
      - pages/Stats.tsx : rendu des nouvelles sections dans l ordre du SPEC v2 +
        PdfButton menu 5 rapports
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 4 files +954 −179
    4. Mobile : backdrop du menu compte via createPortal, verrou scroll de la feuille filtres, champs ≥16 px, logo tactile, socle mobile tokens.css, ka-agent corrigé
      ···
      - frontend/src/App.tsx : .account-backdrop rendu à la racine via createPortal
        (le backdrop-filter du header re-parentait le position:fixed → voile de
        66 px) + fermeture du menu compte à Escape.
      - frontend/src/pages/Home.tsx : feuille de filtres mobile (sheetOpen) — gel du
        scroll d arrière-plan (pattern du hamburger) + fermeture à Escape.
      - frontend/src/styles.css : backdrop compte plein écran sous le header (z-40,
        le menu ancré dans le header reste au-dessus) ; champs de filtres ≥16 px sur
        mobile (f-search, f-native, f-ctl select, ms-sort) ; zone tactile ≥44 px du
        logo .brand (::after inset -8px, rendu inchangé).
      - frontend/src/ka/tokens.css : socle mobile obligatoire (z-index communs,
        --vh100, .ka-scroll-lock, .ka-bottombar, filet anti-zoom iOS 16 px).
      - frontend/public/ka-agent.js : safe-areas, textarea 16 px, plein écran
        ≤640 px + verrou, pas de focus clavier forcé.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 5 files +153 −16
  2. Tue, Aug 18, 20265 commits

    1. Rapport de validation sync liste↔carte + KA Scores (25/25 E2E) + chrome mobile
      ···
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 1 file +3
    2. KA Scores — suite géographique maison (Walk/Transit/Bike/Calme/Services)
      ···
      · environment.py : inventaire OSM par tuile (Overpass) — routes majeures,
        rails, aéroports, zones industrielles, bars, pistes cyclables (géométrie
        densifiée) et TOUS les POI par catégorie ; cache env_tiles ~3 mois.
      · kascores.py : 5 scores 0-100 par immeuble + global pondéré, barème
        versionné (2026.08-v1), détails honnêtes par score, « Données
        insuffisantes »/« Non desservi » plutôt que des 0 trompeurs ; Transit =
        proximité des arrêts × percentile PMD StatCan ; calcul incrémental
        (7 900 immeubles en ~8 s), distribution de calibration en sortie.
      · API : ks_* joints à /api/listings et /api/search (tri « ka », filtre
        kascore_min), détail complet sur la fiche, /api/kascores/stats.
      · Frontend : pastille KA sur les cartes d annonces, section KA Scores de
        la fiche (5 jauges + détail dépliable + date/version), page /ka-scores
        (méthodologie publique + pondérations personnelles en curseurs), tri
        « Meilleur KA Score » dans la vue carte, filtre « KA Score minimal ».
      · Boucle watch : env (4 tuiles max) + kascores incrémental à chaque sync.
      · Tests : test_kascores.py (barème, honnêteté, rendement décroissant,
        cohérence spatiale sur le parc réel).
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 10 files +563 −6
    3. Recherche synchronisée liste ↔ carte (une seule vérité partagée)
      ···
      · /api/search : une réponse = page de liste + tous les points carte,
        même tri — compteur liste = marqueurs par construction ; bbox, polygone
        dessiné, tris (prix/récent/affaires), include=liste, annonces sans
        position comptées honnêtement.
      · MapSearch.tsx : état unique filtres+zone+tri+page, miroirs survol/clic
        < 100 ms dans les deux sens, page ajustée au clic marqueur + pulsation,
        « Rechercher quand je déplace la carte », « Rechercher dans cette zone »,
        recadrage animé respectant l intention (byUser), « Recadrer sur les
        résultats », zone dessinée en puce retirable + URL, carrousel mobile
        synchronisé aux marqueurs, états vides propres, URL complète partageable.
      · Géolocalisation d accueil : arrivée sur le site → demande de position →
        vue carte centrée sur l utilisateur (une fois par session, lien partagé
        respecté, refus silencieux).
      · Marqueurs « déjà vu » atténués (localStorage), fourchette de prix des
        clusters au survol, spiderfy discret des unités d un même immeuble.
      · Tests : scripts/test-sync.mjs (25 vérifications E2E Playwright, critères
        1-9), tests/test_search.py (9 tests API).
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 7 files +1,129 −41
    4. Garde-fou overflow-x: clip (débordement transitoire 360 px au chargement)
      ···
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 1 file +5
    5. Qualité des données + solidité mobile + framework de juste valeur (fair value)
      ···
      Mission 1 — enrichissement des connecteurs et qualité :
      - quality.py : score de complétude 0-100 + seuil de publication (quarantaine
        des annonces sans prix plausible / localisation / contenu exploitable)
      - imgcheck.py : audit des images (liens morts 404/410, minuscules, placeholders
        multi-adresses, doublons) -> galeries nettoyées images_ok, cache image_checks,
        politesse 3 requêtes/hôte, écriture hors transaction réseau
      - 26 connecteurs enrichis (galeries complètes, descriptions, prix, adresses) :
        kangalou, royal_lepage, medway, remax_quebec, groupe_maurice, mellem, sutton,
        lespac, heafey, kijiji, fb_marketplace, zumper, equinoxe_batimo, logis_experts,
        quartier_sila, msi, summum, quartier_plus, urban_services, cosoltec, garic,
        lakle, matinale, huma, jutras, groupe_theoret, ferrovia
      - normalize : clean_city/clean_sector (rues et entités HTML retirées des menus),
        kijiji : adresses françaises « 89, rue X » correctement découpées
      - geocode : virgule après le n° civique corrigée (lot AQ), base en WAL
      - dedup : une annonce en quarantaine ne masque jamais un doublon publié
      
      Mission 2 — mobile :
      - /api/img : miniatures WebP servies à la taille de l écran (cache disque)
      - SmartImg : miniature -> original -> visuel de secours Lou-Ka (jamais d icône cassée)
      - lightbox tactile : balayage scroll-snap + pincement + double-tape
      - bannière témoins : ne recouvre plus le bouton Filtres (--consent-h)
      - cibles tactiles >= 44 px (pointer: coarse) ; KA Agent plein écran à l ouverture
      - stats : complétude moyenne, quarantaine par source
      
      Mission 3 — juste valeur locative (fairvalue.py, fv-logement-1.0) :
      - 3 niveaux : segments médians (repli en échelle) + coefficients de
        caractéristiques appris et centrés + comparables kNN géographiques (médiane
        pondérée) ; couloir de sécurité, fourchette, indice de confiance
      - prudence : pas de verdict si confiance faible, prix « à partir de »,
        prix non mensuel, écart hors plausible ; chambres/coloc = segment dédié
      - pastilles sous/dans/au-dessus du marché (cartes + fiche), bloc Analyse de
        prix avec histogramme, filtre « Sous le marché » + tri, page /juste-valeur
      - API : champs fv_* + deal/sort, /api/fairvalue/{uid} ; stats + PDF ;
        historisation fv_segments ; tests synthétiques ; docs/FAIRVALUE*.md
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 13 files +583 −26
  3. Mon, Aug 17, 20266 commits

    1. Câblage du widget KA Agent (bulle de chat IA Groupe KA)
      ···
      Balises window.KA_AGENT={site:"lou-ka"} + /ka-agent.js (defer) dans
      frontend/index.html ; le gabarit SSR de louka/seo.py reprend le shell du
      build Vite, les fiches logement héritent donc du widget sans doublon.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 2 files +235
    2. Footer/contact : Job-Ka rejoint l écosystème (ecosystem.json 13 sites)
      ···
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 1 file +175 −24
    3. Page /stats refaite en tableau de bord analytique + rapport PDF Groupe-KA
      ···
      - louka/statsdash.py : GET /api/stats/dashboard (contrat ka-stats SPEC.md) —
        KPI avec deltas vs période précédente, séries actives/nouvelles par jour
        (reconstruites de first_seen/last_seen), répartitions taille/source, top
        villes, heatmap, tableaux villes & gestionnaires, records auto-générés ;
        requêtes SQL agrégées + cache mémoire 5 min par période.
      - louka/kapdf.py (moteur PDF commun fpdf2) + GET /api/stats/report :
        rapport estampillé Groupe-KA (couverture Lou·Ka, sommaire, graphiques
        vectoriels, tableaux zébrés, records, page contact), modes complet/synthèse,
        nom de fichier normalisé groupe-ka_lou-ka_stats_<periode>_<date>.pdf.
      - frontend : pages/Stats.tsx réécrite sur le kit ka/stats/kacharts.tsx
        (KpiCard, PeriodSelector, LineChart N-1, Donut, BarChart, CalendarHeatmap,
        DataTable, RecordCard, PdfButton, Fraicheur) — responsive 360/768/1440,
        états vides propres quand la donnée n existe pas.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 5 files +1,197 −390
    4. Ajoute les assets de partage Groupe KA (og.png, favicon.svg, apple-touch-icon) et complète le head SSR
      ···
      - Nouveau favicon SVG et apple-touch-icon servis à la racine via frontend/public
      - Image Open Graph 1200×630 par défaut (og.png) : meta og:image + dimensions + twitter:card/twitter:image dans index.html
      - seo.py : og:image par défaut sur toutes les pages SSR, twitter:image, et retrait des meta statiques du gabarit pour éviter les doublons
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 4 files +12 −1
    5. Retour au design system commun Groupe KA « éditorial sharp » (accent orange conservé)
      ···
      Lou-Ka abandonne l'identité marine/bleu du 2026-08-15 et revient au socle
      partagé ka-ui (papier #f5f3ee, encre #141814, Space Grotesk/Inter/JetBrains
      Mono, bordures encre 1,5 px + ombres décalées), en gardant son accent orange
      (#ff6a00), son logo « porte entrouverte » et sa baseline.
      
      - ka-ui vendoré : frontend/src/ka/ (tokens.css, ecosystem.json, KaFooter,
        GroupeKaBadge) ; tokens.css importé AVANT styles.css dans main.tsx
      - styles.css : :root réécrit (accent orange + alias --lime, anciens jetons
        marine/bleu remappés sur les jetons communs), géométrie sharp 10/6 px,
        états sélectionnés encre+accent, couche d'harmonisation finale ; le thème
        Ka Maps passe à l'accent orange sur le chrome de la carte
      - Header : badge « Un service Groupe KA » (desktop + menu mobile ≥44 px)
      - Footer : KaFooter commun (siteId lou-ka, pages légales locales) précédé
        d'une rangée de navigation locale + « Gérer mes témoins »
      - Nouvelle page /contact (courriels + rôles d'ecosystem.json, avertissement
        agrégateur, liste des sites, lien hub) ; route ajoutée au fallback SPA
      - SEO : title « Lou-Ka — Un service Groupe KA » (index.html) ; titre SSR de
        l'accueil harmonisé + lien Groupe KA dans le corps SEO (seo.py)
      - « Créer mon compte » pointe vers https://www.groupe-ka.com/connexion
      - Polices Space Grotesk + JetBrains Mono ajoutées (Google Fonts)
      - ka-maps redéployé sur le nœud (~/apps/ka-maps) pour le build
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 12 files +726 −216
    6. État du nœud — captures README régénérées en prod + Logo.tsx ; gitignore data/uploads/
      ···
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 1 file +105
  4. Sat, Aug 15, 20263 commits

  5. Thu, Aug 13, 20268 commits

    1. Lou-Ka Maps — carte propulsée par Ka Maps (framework Groupe Ka, moteur Mapbox 3D)
      ···
      Frontend : MapView réécrit sur @groupe-ka/ka-maps (file:../../ka-maps) —
      style Mapbox Standard 3D par défaut + bouton 2D, pastilles de prix encre/
      blanc, grappes compte + loyer moyen (clamp anti-prix aberrants),
      « Rechercher dans cette zone », aperçu React (fin du popup HTML injecté),
      sync liste↔carte (sélection + survol), caméra dans l'URL, badge Lou-Ka
      Maps · Groupe Ka, jeton public Mapbox (kamaps/config.ts). Recherche
      debouncée (fin des requêtes à chaque frappe).
      Backend : /api/listings.geojson accepte bbox + limit et renvoie
      totalGeocoded/totalMatching ; index idx_listings_geo(lat,lng) ; PRAGMA
      optimize au cycle d'ingestion (le planificateur choisissait le mauvais
      index).
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 14 files +591 −432
    2. Profil enrichi — photo téléversée, bio, ville, coordonnées, réseaux sociaux
      ···
      - louka/profile.py : PUT /api/me/profile (nom affiché, bio 280, ville,
        téléphone, site web, réseaux instagram/facebook/x/linkedin/tiktok/youtube),
        POST /api/me/avatar (Pillow : EXIF, recadrage carré centré, 512 px, JPEG,
        purge des anciennes photos), DELETE /api/me/avatar (retour avatar Google)
      - /uploads/ monté (data/uploads/), colonnes users (display_name, avatar_url,
        bio, city, phone, website, socials JSON)
      - /api/me : nom et avatar « effectifs » (display_name > Google, upload >
        Google) + tous les champs ; profil public /u/{ka_id} : bio, ville, rôle,
        site, réseaux (jamais courriel/téléphone)
      - /profil : éditeur complet (photo avec téléversement, nom affiché, bio avec
        compteur, ville, téléphone, site, 6 réseaux avec icônes maison)
      - /u/{ka_id} : bio, chips ville/rôle/site, boutons réseaux sociaux
      - python-multipart ajouté (formulaires multipart FastAPI)
      Simon-Pierre Boucher 9 files +389 −30
    3. Comptes v2 — KA-ID, profil « carte de membre », rôles, favoris, pages gestionnaires
      ···
      - KA-ID : identifiant membre unique « ka- » + 10 chiffres, attribué à la
        création du compte (index unique, backfill au premier /api/me)
      - /profil : carte de membre Groupe KA (encre + lime, KA-ID en vedette, avatar,
        ancienneté, bande décorative), infos du compte, copie du KA-ID
      - Profil PUBLIC opt-in : /u/{ka_id} (nom, avatar, ancienneté — jamais le
        courriel ; 404 indistinguable si non public), toggle + lien copiable
      - Rôles à l'intégration (/bienvenue après le premier login Google) :
        · locataire — favoris (cœur sur les cartes, page /favoris, toggle optimiste)
        · gestionnaire — réclame la page de SA source (1/compte, 1 compte/source)
          et la personnalise (/gestion : accroche, description, contact, logo) ;
          page publique /g/{source} avec inventaire relié + pagination
      - louka/accounts.py (rôles, favoris, source_profiles), tables favorites +
        source_profiles + colonnes users (ka_id, public, role, org_source)
      - Contexte de compte partagé (account.tsx) : header, cartes et pages reliés
      Simon-Pierre Boucher 12 files +1,132 −7
    4. Comptes utilisateurs — connexion Google (OAuth 2.0 / OpenID Connect)
      ···
      - louka/auth.py : flux authorization-code serveur (login -> Google -> callback),
        state signé, upsert table users, session HMAC-SHA256 en cookie httpOnly 30 j
        (stdlib seulement), /api/me, /api/auth/logout, /api/auth/config
      - db.py : table users (google_sub unique, email, name, picture)
      - Frontend : bouton « Connexion » (logo Google) dans le header, avatar + menu
        compte (courriel, se déconnecter) — masqué tant que l'OAuth n'est pas configuré
      - .env : SESSION_SECRET généré ; GOOGLE_CLIENT_ID/SECRET à coller
        (redirect URI : https://www.lou-ka.com/api/auth/google/callback)
      Simon-Pierre Boucher 3 files +115 −1
    5. Web — mention Groupe KA + page Conditions d'utilisation + courriels officiels
      ···
      - Footer : « Lou-Ka est une plateforme du Groupe KA » (lien groupe-ka.com),
        © Groupe KA, contact@groupe-ka.com, lien vers /conditions
      - Nouvelle page /conditions : opérateur (info@groupe-ka.com), nature du
        service, exactitude, retrait de contenu (contact@groupe-ka.com), usage
        acceptable, volet légal (admin@groupe-ka.com) — route + menu mobile
      - Confidentialité : responsable Loi 25 admin@groupe-ka.com, retraits et
        questions contact@/info@groupe-ka.com (remplace contact@spboucher.ai)
      Simon-Pierre Boucher 4 files +120 −4
    6. Web — pagination 12 annonces/page + icônes SVG maison (fin des emojis génériques)
      ···
      - Pager.tsx : pagination éditoriale (précédent/suivant, numéros avec ellipses,
        rappel « X–Y sur N »), sous la grille ET sous la liste de la vue carte
      - Home.tsx : 12 annonces/page via limit/offset API, page dans l'URL (?page=N),
        retour page 1 au changement de filtre, défilement doux vers les résultats
      - Icons.tsx : jeu d'icônes SVG au trait « éditorial sharp » (maison, immeuble,
        caméra, patte, sofa, éclair, liste, carte, curseurs, alerte, boussole…)
      - Emojis remplacés partout (cartes, chips, bascule liste/carte, FAB filtres,
        nav mobile, onglets Stats, fiche, carrousel vide, popups carte, 404)
      Simon-Pierre Boucher 10 files +382 −43
  6. Tue, Aug 11, 20261 commit

    1. Filtres avancés — refonte du menu web + facettes par ville
      ···
      - /api/facets accepte ?city= : quartiers restreints à la ville (sélecteur dépendant)
      - Menu de filtres refait : rangée principale compacte (recherche, ville,
        quartier, loyer min–max, « Plus de filtres ») + panneau avancé repliable
        en segments (disponibilité, meublé, animaux, superficie, gestionnaire)
      - Correction du débordement horizontal (colonnes 1fr → contrôles bornés)
      - Chips rapides (dispo maintenant, animaux, meublé) + pastilles de filtres
        actifs retirables ; api.ts : price_min, pets, furnished, available_by, area_min
      - ios/ ignoré : l'app iOS native vit dans son propre dépôt (lou-ka-ios)
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 3 files +373 −68
  7. Sun, Aug 9, 20263 commits

    1. Page Stats en 5 onglets + rapport PDF enrichi (source unique marketstats.py)
      ···
      - louka/marketstats.py : tous les agrégats du marché (régions, offre,
        inclusions, prix au pi², baisses de prix 30 j, santé des sources) —
        partagés entre /api/stats/detailed et le rapport PDF
      - Onglets : Vue d'ensemble (tuiles + régions + histogramme) · Loyers
        (histogramme, par taille, prix au pi², baisses de prix cliquables) ·
        Régions & villes · L'offre (inclusions %, dispo, animaux, superficie) ·
        Gestionnaires (top 20 + santé des syncs + alertes 24 h)
      - Rapport PDF : page « Offre » ajoutée (barres d'inclusions, prix au pi²,
        baisses de prix), 4 pages, mêmes chiffres que le site
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 3 files +351 −174
    2. PDF légendaires : fiche de propriété par annonce + rapport global du marché
      ···
      - louka/pdfgen.py (reportlab) au style éditorial sharp : logo Lou·Ka dessiné
        (boîte lime tournée), tuiles à ombre décalée, chips encre/lime
      - Fiche (/api/listings/{uid}/pdf, 2 pages) : prix géant + badge « vs le
        secteur », chips clés, photos encadrées, encadré « En bref » (text mining),
        description structurée, inclusions ✓, tuiles du quartier + barres de
        proximité + badges chaleur/criminalité, à proximité avec temps de marche,
        QR code vers la fiche en ligne, attributions de licences
      - Rapport global (/api/stats/rapport.pdf, 3 pages) : grands chiffres,
        couverture par région avec barres, histogramme des loyers, par taille,
        top 20 villes et gestionnaires
      - Boutons : « Télécharger la fiche (PDF) » sur chaque annonce, « Télécharger
        le rapport global (PDF) » sur la page Stats
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 3 files +12
    3. Expansion provinciale P1 : 26 nouveaux connecteurs + 8 extensions (+1 358 annonces)
      ···
      Lot 0 extensions : girescom +Beauce, msi +Thetford, utile +Trois-Rivières/
      Rimouski, cogir/realstar/centurion/plan_a +Gatineau/Sherbrooke.
      Lot 1 plateformes maîtrisées : thrace (Livya, 181), lr_gestion (Rentsync),
      urban_services + immobilia (Building Stack).
      Lot 2 Est & Nord : immeubles_bc (Rimouski), tri_logis (Rouyn), devcore
      (Sept-Îles/Outaouais), multi_logis (Côte-Nord+Lévis), courtemanche (Saguenay).
      Lot 3 Estrie : lachance (82), gesteco (API Umbraco), savouet, laureat_richard,
      desroches. Lot 4 Mauricie/CdQ : location_di, cap_gestion (122), capital_rdr,
      gestion_tb, summum (93). Lot 5 Outaouais/Ch-App : halfred (165), heafey (245),
      brigil (Firecrawl), mellem, quartier_oree, le_st_georges, place_florimay.
      
      Enrichissement complet appliqué : géocodage provincial (+616), POI 1 756
      immeubles, quartier 1 088 annonces jointes (0 hors-zone), normalize corrigé
      (frontières de mots des mois). Registre : 114 sources, 108 connecteurs,
      ~7 350 annonces. Secrets tiers caviardés des fixtures (jetons Mapbox +
      caviardage automatique à l'enregistrement).
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 1 file +1 −1
  8. Sat, Aug 8, 20269 commits

    1. Stats : compte « ailleurs au Québec » distinct du Grand Montréal (expansion provinciale)
      ···
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 2 files +4
    2. Page /bot (transparence LouKaBot) + User-Agent pointant dessus
      ···
      Explique le robot aux gestionnaires : cadence, respect de robots.txt, aucune
      donnée personnelle, contact pour flux officiel/retrait, consigne de blocage.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher 2 files +60
    3. Passerelle de sortie vers l'annonce originale (à la Centris)
      ···
      /passerelle/:uid — Lou-Ka -> gestionnaire avec points animés, barre de
      progression (2,2 s) puis redirection ; boutons « Y aller maintenant » et
      « Rester sur Lou-Ka ». Sécurité : uid seulement, l'URL de destination vient
      de l'API (aucune redirection ouverte). CTAs de la fiche (desktop + sticky)
      rebranchés ; prefers-reduced-motion respecté.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      simon-pierre boucher 4 files +163 −2
    4. Fiche v2 mobile-first : essentiel d'abord, badge marché, CTA sticky, historique de prix
      ···
      - Ordre mobile : galerie (balayage natif + compteur) -> prix + badge
        « vs le secteur » (seuils -15 %/+10 %) -> chips clés défilantes -> ancres ->
        description -> inclusions (confirmées ✓ vs mentionnées, badge 0 $ de frais
        cachés) -> détails pratiques -> quartier -> à proximité groupé repliable
        avec temps de marche estimés
      - Desktop : 2 colonnes (logement | synthèse+quartier) via display:contents
      - CTA source sticky en bas d'écran mobile (toujours visible)
      - Criminalité reformulée (« 15 % sous la moyenne canadienne ✅ »)
      - Backend : table price_log (historique de prix aux changements), colonne
        digest (description structurée, pipeline en cours), « en ligne depuis X
        jours », plomberie schema/db/web
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      simon-pierre boucher 4 files +468 −137
    5. Quartier : scripts de construction des données + centiles PMD + correctif débordement mobile
      ···
      - scripts/build_{recensement,contexte,environnement}.py : pipelines rejouables
        (StatCan recensement 2021 + limites AD, PMD, INSPQ défavorisation, écoles
        MEQ/IMSE, îlots de chaleur INSPQ, actes criminels SPVM, IGC WDS)
      - merge_quartier.py : fusion + rangs centiles québécois des scores PMD
        (l'échelle nationale brute écrasait les valeurs urbaines)
      - data/quartier.db (51 Mo, gitignoré) : déployé par rsync, reconstruit par
        scripts — 11 317 AD, 49 791 actes SPVM 24 mois, 1 249 immeubles chaleur
      - min-width:0 sur les enfants de .detail-grid (débordement mobile)
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      simon-pierre boucher 1 file +3
    6. Stats de quartier (à la Centris) — runtime + fiche « Le quartier »
      ···
      - louka/quartier.py : jointure lat/lng -> aire de diffusion 2021 (point-dans-
        polygone local, préfiltre bbox), assemblage fiche (démographie recensement,
        scores de proximité StatCan, défavorisation INSPQ, îlot de chaleur,
        criminalité SPVM <500 m sur l'île / indice IGC ailleurs), enrichissement
        listings.dauid dans la boucle watch
      - data/quartier.db : base statique construite par scripts/ (fusion via
        scripts/merge_quartier.py), défensif si absente
      - fiche : section « Le quartier » (tuiles démographiques, barres de proximité
        0-100, badges chaleur/criminalité, attributions licences ouvertes)
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      simon-pierre boucher 4 files +182
    7. Mobile : menu déroulant animé + sélecteur de consentement témoins + page confidentialité
      ···
      - Header : hamburger animé (-> X), panneau déroulant avec liens en cascade
        (Logements, Carte, Stats, Sources, Confidentialité), backdrop flouté,
        verrouillage du défilement, fermeture à la navigation
      - CookieConsent : bandeau au premier chargement (aucun témoin tiers — honnête),
        3 choix (tout accepter / essentiels / personnaliser avec cases préférences
        et statistiques), mémorisé en localStorage, ré-ouvrable depuis le pied de
        page et la page confidentialité
      - /confidentialite : politique de confidentialité et de témoins
      - Vue carte synchronisée avec l'URL (?view=carte depuis le menu)
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      simon-pierre boucher 5 files +333 −2
    8. Commodités de proximité par immeuble (Overpass/OSM) sur chaque fiche
      ···
      - louka/poi.py : une requête Overpass par immeuble (13 catégories : épicerie,
        dépanneur, pharmacie, école, garderie, parc, bus, métro, gym, café,
        clinique, hôpital, bibliothèque), plus proche par catégorie avec distance,
        cache permanent par coordonnées arrondies (~11 m), politesse 1 req/s,
        rafraîchissement aux 3 mois
      - run.py poi [n] + intégration à la boucle watch (80 nouveaux immeubles/cycle)
      - /api/listings/{uid} : champ poi[] joint depuis le cache
      - fiche : section « À proximité » (icône, nom réel, distance formatée),
        mention données OpenStreetMap
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      simon-pierre boucher 3 files +67 −1
    9. Mission 4 — géocodage Nominatim + carte interactive MapLibre GL
      ···
      Géocodage (louka/geocode.py) :
      - Nominatim 1 req/s, User-Agent identifié, cache SQLite par immeuble
        (adresse normalisée sans n° d'unité) — une adresse n'est géocodée qu'une fois
      - nettoyages QC : préfixe d'unité « 101-2905 », « Montréal - Laval »,
        cardinales abrégées ; repli civique+rue en 2e tentative
      - validation bounding-box (Québec/Lévis resserrée, garde-fou provincial),
        flag geocode_failed, ré-essai des échecs après 30 jours
      - intégré à la boucle watch (nouvelles adresses géocodées à chaque sync)
      - finalize() rejette aussi les coordonnées invalides fournies par les sources
        (annonce de Limoilou qui pointait au Kazakhstan)
      
      Carte (frontend) :
      - /api/listings.geojson : GeoJSON filtré (mêmes filtres que /api/listings)
      - MapView MapLibre GL : chargement paresseux (254 ko gzip hors du bundle
        principal), clustering natif, marqueurs-prix, popup fiche (photo, prix,
        type, dispo, gestionnaire, lien), synchro avec les filtres, fitBounds
      - bascule Liste/Carte : côte à côte sur desktop, plein écran sur mobile
      - tuiles vectorielles OpenFreeMap (positron), style Lou-Ka (encre + lime)
      - worker MapLibre v6 copié par plugin Vite (imports relatifs préservés)
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      simon-pierre boucher 7 files +548 −8
Menu

Theme