SPB Git

spb/lou-ka

Public

Lou·Ka — tous les logements à louer du Québec, un seul endroit.

History of frontend/src/pages/Listing.tsx Clear filter
page 1
  1. Fri, Sep 4, 2026 1

    1. feat(fiche): refonte premium mobile-first de la fiche logement (2026-09-04)
      …
      Frontend (frontend/src/fiche/, nouvelle arborescence) : héro prix → adresse →
      résumé → galerie → actions ; Lou-Ka Score (60 % KA Score emplacement + 40 %
      prix vs juste valeur, partiel si une composante manque) ; « En bref »
      déterministe (prix, accessibilité, air, inondation, coûts, TAL, chaleur,
      baisse de prix) ; navigation sticky par sections (scroll-spy) ; Prix et marché
      (juste valeur + histogramme) ; Le logement (grille icône/valeur) ; description
      tronquée + texte original ; inclusions dédoublonnées FR/EN ; grande carte 3D
      Ka Maps avec filtres de lieux (transport, épiceries, pharmacies, commerces,
      écoles, parcs, essence) ; À proximité / Transport en carrousels + bottom sheet ;
      Quartier en KPI compacts + accessibilité en lignes ; KA Scores compacts ;
      Registre des loyers orienté décision (jauge p10–p90, médianes par chambres,
      3 comparables + sheet filtrable) ; coût réel + Hydro ; risque d'inondation
      (statut clair, juridique en accordéon) ; qualité de l'air en tuiles ; essence
      (3 stats, 3 stations, sheet) ; Dossier de l'immeuble en accordéons (historique,
      passeport, gestionnaire, TAL, hiver) ; Sources et méthodologie + fin de fiche.
      Primitives : SectionCard, Accordion, BottomSheet (modale ≥ 900 px), StatTile,
      StatusBadge, Skeleton, états vides/erreur, toast. Données : useFicheData
      (groupe critique au montage, groupe différé à l'approche de la carte).
      Tokens --lk-* scopés (.lk-fiche) : fond #F7F7F5, cartes blanches bord 1 px,
      ombres légères, rayons 10/14/18/22, orange réservé CTA/prix/score. Desktop
      ≥ 1024 : aside sticky (prix, CTA, score, constats, Demander à Ka). CTA sticky
      compact affiché seulement après le héro ; bouton « ✦ Demander à Ka » discret
      branché sur le widget KA Agent existant (contexte de la fiche transmis).
      Header compact sur la fiche (56 px, ticker masqué, favoris + partage,
      connexion en icône sur mobile). Aucun `order` CSS ; scrollIntoView banni de la
      barre de sections (faisait ouvrir la page à 434 px). Anciennes classes
      .fiche/.f-* intactes pour la fiche court terme. 16 anciens composants de fiche
      supprimés (remplacés). check-order.mjs mis à jour + shots.mjs / interactions.mjs.
      
      Backend (additif, rétrocompatible) : poi.py conserve lat/lng des POI (carte) ;
      gaz.py expose lat/lng des stations ; /api/gaz et /api/rdl acceptent `limit`
      (sheets « Voir les N »). vite.config : proxy /api paramétrable (LOUKA_API).
      
      Validé : tsc + vite build, check-order OK (scrollY 0, ordre croissant, sans
      overflow 375→1440), captures Playwright 6 largeurs, sheets/carte/Ka/404,
      fiche sans KA Score. node_modules frontend réinstallés (typescript/esbuild
      tronqués par ka2 le 2026-08-31 pour ENOSPC).
      Simon-Pierre Boucher · 1 file +159 −550
  2. Tue, Aug 25, 2026 1

    1. Fiche logement : refonte editoriale v2 — icones contextuelles, sections sans boites
      …
      - Nouveau composant AmenityIco (~34 pictos maison, trait 1.8) : chaque
        inclusion/caracteristique est appariee par mots-cles (accents neutralises)
        a SON icone — lave-vaisselle, chauffage, balcon, stationnement, animaux,
        piscine, foyer… — fini le meme ✓ repete dix fois
      - Inclusions : grille en filets (tuile icone 32px accent-soft, libelle,
        ✓ discret a droite pour le confirme ; neutre pour les mentions libres)
      - Chips cles du hero : hairline + icone contextuelle (3½ → porte, dispo →
        calendrier, pi² → regle…) au lieu d aplats marine
      - Colonne editoriale (gauche) de-boxee : description, inclusions, details
        pratiques respirent sans carte — les modules de donnees (droite) restent
        en cartes ; titres avec tiret accent net (sans bordure/ombre heritees)
      - Details pratiques : rangees en filets, cles en micro-mono, fini les tuiles
      - Prix 38-54px, ancres en onglets textes, en-bref en filet accent,
        galerie au cadre allege (hairline, rayon 10)
      - Mobile : le CTA sticky prend le bas d ecran, la tabbar s efface sur la
        fiche (body:has(.cta-sticky)) — plus de chevauchement
      Simon-Pierre Boucher · 1 file +16 −4
  3. Mon, Aug 24, 2026 2

    1. Simon-Pierre Boucher · 1 file +15
    2. feat(tal): historique du Tribunal administratif du logement par adresse
      …
      Décisions publiques du TAL (diffusées par SOQUIJ) croisées avec l'adresse
      de chaque annonce : recherche « no civique + rue » via Scrapfly (le site
      exige rendu JS + IP résidentielle ; pas de phrases entre guillemets),
      puis vérification de l'adresse exacte dans le texte intégral et
      classification (non-paiement, résiliation, expulsion, reprise/éviction,
      insalubrité…, demande du locateur vs du locataire, verdict). Cache par
      adresse dans data/tal.db, backfill borné dans la boucle watch + file
      prioritaire alimentée par les fiches consultées (/api/tal), bloc
      « Historique au TAL » sur la fiche (aucun nom de partie affiché —
      référence neutre + lien SOQUIJ).
      
      Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +3
  4. Sun, Aug 23, 2026 6

    1. hydro : cache par uid + dérivation du code postal via lat/lng (Mapbox)
      …
      - cache indexé aussi par uid (clé stable annonce) : affichage cache-only sur
        la fiche sans code postal ni appel Mapbox
      - code postal dérivé du lat/lng par géocodage inverse Mapbox quand l adresse
        n en porte pas (cas Immo-Ka) — au moment du calcul seulement
      - estimate(uid, lat, lng) ; endpoint et fiche passent uid+lat+lng ;
        cache-only renvoie en_attente (bouton) si un calcul est faisable
      - precompute sélectionne lat/lng/uid, saute ce qui est déjà en cache par uid
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +1 −1
    2. Fiche : estimation du coût d electricite Hydro-Quebec (a la demande)
      …
      - louka/hydro.py : parcours PUBLIC rétro-conçu de l outil « Estimer les coûts
        d électricité à une résidence » — 2 étapes (lieu-consommation -> estimation)
        sur services-cl.solutions.hydroquebec.com, jeton reCAPTCHA v2 via solveur
        enfichable (2captcha/CapSolver, clé HQ_CAPTCHA_KEY), sortie par proxy
        résidentiel CA (Oxylabs/Bright Data), cache 6 mois data/hydro.db ; sans clé
        captcha -> {disponible:false} et bloc masqué (jamais d estimation inventée)
      - GET /api/hydro?adresse= ; bloc fiche à la demande (bouton, 1 captcha/appel)
        affichant le coût mensuel et annuel estimés
      
      Activation : définir HQ_CAPTCHA_KEY (+ HQ_CAPTCHA_PROVIDER) dans .env.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +3
    3. Fiche : bloc Commerces et transport (Mapbox Search Box + cache POI/OSM)
      …
      - louka/commerces.py : point de vente le plus proche de 14 grandes bannières
        (Costco, Walmart, Metro, IGA, Maxi, Super C, Provigo, Canadian Tire,
        Dollarama, SAQ, Pharmaprix, Jean Coutu, Home Depot, RONA) via l API Mapbox
        Search Box (jeton public kamaps, validation du nom retourné, anti
        « Station Métro »), cache par cellule ~1 km TTL 30 j ; station de métro et
        arrêt de bus les plus proches repris du cache POI du projet (repli
        Overpass) ; GET /api/commerces
      - bloc fiche : pastilles SVG monogrammes aux couleurs des bannières,
        nom du point de vente et distance — métro/bus en tête
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +3
    4. Fiche : qualité de l air (RSQAQ/PST) + essence à proximité (gazquebec.ca)
      …
      - louka/air.py : agrégats annuels par station du RSQAQ (MELCCFP) — horaires
        2024-2025 (PM2.5, NO2, O3, SO2, CO) + séquentielles PST/PM10 (<LD -> LD/2),
        data/air.db minuscule, station la plus proche ≤ 60 km ; bloc fiche avec
        badge global et barres vs repères OMS 2021 / norme RAA (PST 60 µg/m³)
      - louka/gaz.py : copie locale des ~2 450 stations de gazquebec.ca (prix
        Régulier/Super/Diesel, TTL 4 h, auto-refresh au lookup) ; bloc fiche avec
        KPI (stations, médiane du secteur, meilleur prix) et tableau des stations
        les plus proches, la moins chère mise en évidence
      - run.py air-refresh / gaz-refresh, GET /api/air et /api/gaz
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +6
    5. Risque d inondation (BDZI) + Registre des loyers v2 (visuel)
      …
      - louka/inondation.py : base locale data/inondation.db construite du GeoPackage
        BDZI officiel (25 k polygones éclatés + R*Tree, couverture Carto_ZI_S),
        lookup point-dans-polygone shapely (0-40 ms), statuts en_zone / a_proximite
        (≤100 m) / hors_zone / non_cartographie ; run.py inondation-build,
        GET /api/inondation — bloc fiche avec badge de sévérité (grand courant
        0-20 ans = élevé, faible courant 20-100 ans = modéré) et rappel que la
        cartographie officielle fait foi (CMM non couverte par la BDZI)
      - Registre des loyers v2 : tuiles KPI (volume, médiane secteur, médiane même
        nombre de chambres), bande de position p10-p90/boîte p25-p75/médiane vs le
        loyer demandé, barres des médianes par chambres (celle de l annonce
        surlignée + étiquette), date de la valeur = année du loyer (mois seulement
        si le bail débute la même année), quartiles côté API
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +3
    6. Registre des loyers : extraction pancanadienne (57 433 déclarations géocodées) + bloc fiche
      …
      - louka/rdl.py : balayage par boîtes de l API publique de registre-des-loyers.ca
        (subdivision récursive sur erreur ou volume suspect), base séparée data/rdl.db,
        requête de proximité (bbox + haversine) avec médianes globale/récente/par chambres
      - run.py rdl + GET /api/rdl?lat&lng&radius
      - fiche : bloc « Registre des loyers » sous l analyse de prix — médiane du secteur,
        écart du loyer demandé vs les déclarations du même nombre de chambres,
        8 déclarations les plus proches avec la date de la valeur (année du loyer,
        mois si le bail débute la même année), crédit Vivre en ville
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +3
  5. Wed, Aug 19, 2026 1

    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 · 1 file +59 −55
  6. Tue, Aug 18, 2026 3

    1. 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 · 1 file +3
    2. 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 · 1 file +2
    3. 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 · 1 file +127 −11
  7. Sat, Aug 15, 2026 1

  8. Thu, Aug 13, 2026 2

    1. 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 · 1 file +8 −3
  9. Sun, Aug 9, 2026 1

    1. 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 · 1 file +4
  10. Sat, Aug 8, 2026 5

    1. 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 · 1 file +4 −2
    2. 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 · 1 file +272 −130
    3. 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 · 1 file +2
    4. 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 · 1 file +41 −1
    5. simon-pierre boucher · 1 file +58 −6
  11. Thu, Aug 6, 2026 1

    1. Lou-Ka — agrégateur de logements à louer (Québec, Lévis, Grand Montréal)
      …
      Plateforme complète : 68 connecteurs de gestionnaires immobiliers, schéma
      standardisé avec détection de changements (hash), API FastAPI, frontend
      React/Vite PWA (design éditorial sharp, thème clair), déployée sur
      www.lou-ka.com avec resynchronisation horaire.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +146
Menu

Theme