Lou·Ka — tous les logements à louer du Québec, un seul endroit.
- 264commits
- 1branches
- 0releases
- 180.7 MBon disk
- maindefault branch
- 5 days agolast push
-
Tue, Nov 3, 2026 1
-
Thu, Oct 8, 2026 1
-
retrait: connecteur Ubee supprimé et 466 inscriptions effacées (plainte de Ubee, 2026-10-08)
…
- louka/connectors/ubee.py + docs/connecteurs/ubee.md supprimés, ligne INDEX retirée - data/sources.json : ubee → retiré (ne pas réactiver sans accord écrit) - louka/web.py : les statuts inactif/retiré sont aussi déclarés disabled_sources à api-ka - base : listings (466), price_log (505), fairvalue (375), listing_events (319), recycled_cache (77), managers (1), sync_log (372), image_checks (12 701 URL Cloudinary ubee-media) effacés ; dédup inter-sources recalculée - sauvegarde à froid hors dépôt : ~/ubee-retrait-20261008/ Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
-
-
Fri, Sep 4, 2026 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).
-
-
Fri, Aug 28, 2026 1
-
Wed, Aug 26, 2026 1
-
feat(ka-id v2): personnalisation Groupe KA — louka/kaid.py (canonique ka-ui.git/kaid), journal serveur (search/detail_view/favorite), reranking personnalisé du tri par défaut (blend 0,35, session > long terme, masqués exclus), enrichisseur ka_id (session legacy sans ka_id), routeur /api/kaid, SDK ka-id.js, badge « Recommandé pour vous » sur ListingCard
…
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
-
-
Mon, Aug 24, 2026 4
-
Annuaire des déménageurs du Québec : page /demenageurs (565 entreprises, 17 régions)
…
- data/demenageurs.json : dataset canonique (balayage Google Places via Serper, 188 villes, dédoublonnage CID/téléphone) — partagé avec Immo-Ka - louka/demenageurs.py : API /api/demenageurs (filtres région + texte) - frontend : page Demenageurs.tsx (recherche, filtre par région, tel:/site web), liens nav + menu mobile + prefooter - seo.py : SSR /demenageurs (liste complète par région, JSON-LD MovingCompany ItemList) + entrée sitemap-pages - scripts/build_demenageurs.py : régénération du dataset Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
-
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>
-
feat(doc): page documentation /doc (guide + captures) + lien footer + PDF téléchargeable
…
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
-
-
Sun, Aug 23, 2026 9
-
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>
-
hydro : pré-calcul des 100 annonces récentes + auto pour les nouvelles
…
- hydro.precompute(limit, budget) : calcule l estimation des annonces les plus récentes non encore en cache, plafond de résolutions captcha par appel (coût borné) ; run.py hydro-precompute [N] [budget] - watch : precompute(100, budget=30) à chaque cycle -> nouvelles annonces estimées automatiquement ; le cache data/hydro.db persiste entre releases - estimate(solve=False) = lecture cache seule (aucun captcha) ; GET /api/hydro cache-only par défaut, solve=1 pour forcer - fiche : le bloc s affiche AUTOMATIQUEMENT quand l estimation est en cache, sinon bouton de calcul à la demande Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
-
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> -
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>
-
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>
-
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>
-
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>
-
tri_logis : réécriture pour le nouveau site trilogis.ca (Next.js/Supabase) + fenêtre syncs_since_h sur /api/stats
…
- tri_logis : l ancien site statique tri-logis.ca a migré vers trilogis.ca (Next.js App Router + Supabase) — 23 synchros à found=0. Le connecteur lit désormais le payload RSC rendu serveur de /a-louer (tableau "units" JSON complet : prix, statut, date de dispo, notation n½, secteur, GPS, inclusions) et la galerie signée de chaque fiche /a-louer/<slug> (bucket privé property-media, tokens ~7 j re-signés à chaque sync). Périmètre : résidentiel longue durée seulement (commercial exclu). Sync de test : found=51, added=51. - web.py /api/stats : paramètre optionnel syncs_since_h (fenêtre en heures pour recent_syncs, LIMIT 4000, repli sur les 20 dernières si <20 dans la fenêtre) — le moniteur central api-ka voit enfin toute la fenêtre de 2 h au lieu de 20 entrées (~11 min), fin des fausses alertes stale. Sans paramètre : comportement inchangé. - Diagnostics sans changement de code : courtemanche, place_florimay et atlas_immo retournent 0 annonce parce que les sites n affichent réellement aucune disponibilité (vérifié en live) — connecteurs sains. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
-
-
Sat, Aug 22, 2026 2
-
court terme : nouvelle section « Location court terme » isolée (backend louka/shortterm + API /api/ct + page /court-terme) — 1er connecteur Airbnb
…
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
-
tri par défaut : annonces les plus récentes d'abord (liste, carte, geojson) au lieu du prix croissant
…
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
-
-
Wed, Aug 19, 2026 1
-
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>
-
-
Tue, Aug 18, 2026 3
-
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>
-
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>
-
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>
-
-
Mon, Aug 17, 2026 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>
-
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>
-
Nouvelles sources + déduplication inter-sources
…
8 connecteurs (208 → 212), testés en live : - logisquebec — portail (~9 800 fiches) : sitemaps + JSON-LD, expiration HTTP 410 - duproprio — location par particuliers (~4 200, 0 % chevauchement) : sitemaps gz + JSON-LD, retrait = 302 - louer_ca — réseau Rentals.ca (~1 700) : API GraphQL interne (JWT), 1 annonce par plan d'étage - roomies — chambres/colocation : JSON-LD Room - groupe_maurice — 37 résidences pour aînés (RPA) : API REST + grilles de prix - bons_locataires — agence Montréal : carte MapListPro + fiches WordPress - omhm — logements abordables ENHARMONIE - fb_marketplace — Scrapfly ASP, pagination par tranches de prix (scroll bloqué hors login) Déduplication inter-sources (louka/dedup.py) : - colonnes dup_of / dup_sources (migration db.py), recalcul idempotent dans ingest.watch() après géocodage - blocage par clé d'adresse (civique + rue normalisée FR/EN + ville), confirmation type + prix ±4 % - contrainte « ≤1 annonce par source par groupe » (évite de fusionner des unités distinctes d'un immeuble) - canonique = source la plus autoritaire (gestionnaire direct > portail > petites annonces) - web.py n'affiche que les annonces canoniques (dup_of IS NULL) ; dup_sources exposé pour le badge « aussi publiée sur » - résultat : 147 groupes, 154 doublons masqués sur 18 536 annonces Utilitaire _detailutil.TtlDetailCache : cache de pages détail avec TTL + budget par sync. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
-
-
Thu, Aug 13, 2026 6
-
SEO — SSR léger FastAPI (louka/seo.py) : HTML complet dès la première requête ; pages programmatiques /villes et /ville/{ville}[/{type}] ; fiches avec title/description uniques + JSON-LD RealEstateListing ; robots.txt ; sitemaps dynamiques (index + villes + annonces) ; 410 annonces retirées, 404 réels (fin des soft-404) ; GZip
…
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
-
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>
-
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) -
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 -
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)
-
-
Tue, Aug 11, 2026 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>
-
-
Sun, Aug 9, 2026 2
-
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>
-
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>
-
-
Sat, Aug 8, 2026 4
-
Stats : compte « ailleurs au Québec » distinct du Grand Montréal (expansion provinciale)
…
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
-
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>
-
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>
-
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>
-