SPB Git forge

spb/food-ka

Public

Food-Ka — agrégateur de produits d'épicerie du Québec — www.food-ka.com

55commits 1branches 0releases
10.2 MBsize
maindefault branch
9 days agolast push
Python 53.9% TypeScript 24% CSS 14.9% JavaScript 5.8% HTML 1.4%

page 1

  1. Thu, Sep 17, 2026 1

  2. Mon, Sep 7, 2026 3

    1. simon-pierre boucher committed 19 days ago · 1 file +1 −1
    2. feat(fiche): refonte premium mobile-first de la fiche produit (2026-09-07)
      …
      Même socle que les fiches Lou-Ka v3 / Immo-Ka v3 (frontend/src/fiche/,
      préfixe fk-, tokens --fk-*, fond papier, cartes blanches bord 1 px, vert
      marché réservé aux CTA/prix, tomate aux soldes) : héro (bannière · prix +
      régulier barré + prix unitaire · capsules Solde / comparaison · nom ·
      galerie packshot sur blanc + lightbox · actions) ; « En bref » déterministe
      (solde et fin de circulaire, meilleur prix ou écart inter-bannières, prix
      unitaire vs médiane, baisse observée, rupture, mentions bio/local) ;
      navigation sticky ; « Prix et comparaison » (KPI, échelle de prix SVG,
      rapprochement EXACT via /api/products/{uid}/compare puis similaires par nom,
      circulaire validité/économie/petits caractères, méthodologie) ; « Le
      produit » (grille icône/valeur, rangées, étiquettes, description tronquée,
      relevés de prix en accordéon) ; Dossier de la fiche ; Sources et
      méthodologie. CTA sticky après le héro, aside desktop sticky, « Demander à
      Ka » branché sur le widget KA Agent. Header compact sur /produit/ (favoris +
      partage via fiche/current.ts, ticker et badge masqués, connexion KA en icône
      sur mobile). Cartes produit de la grille : surface blanche, bord 1 px, ombre
      légère au survol. Icons.tsx (pictos partagés) ajouté. Aucun order CSS ; pas
      de scrollIntoView à l'ouverture. Scripts QA : preview.mjs, check-order.mjs,
      shots.mjs, interactions.mjs (ferment la bannière de témoins).
      
      Validé sur M2U64 : tsc + vite build, check-order OK sur 2 fiches,
      interactions OK, captures 6 largeurs ; dist basculé, aucun changement API.
      Simon-Pierre Boucher committed 20 days ago · 21 files +2,302 −333
  3. Fri, Aug 28, 2026 1

    1. docs: README ultra détaillé + visite guidée en 10 captures
      …
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 29 days ago · 11 files +75 −5
  4. Wed, Aug 26, 2026 4

    1. Simon-Pierre Boucher committed 1 mo ago · 1 file +8 −2
    2. Simon-Pierre Boucher committed 1 mo ago · 2 files +116 −3
    3. Simon-Pierre Boucher committed 1 mo ago · 1 file +7 −2
  5. Tue, Aug 25, 2026 11

    1. Recherche mobile : ligne fine au lieu d une zone de 260px
      …
      Sur mobile, .toolbar passe en flex-direction column ; la base desktop
      « flex: 1 1 260px » de .tb-search (une LARGEUR en rangée) devenait alors une
      hauteur de 260px — énorme vide autour du champ, produits repoussés hors du
      premier écran. Correction à la source : flex: 0 0 auto dans le bloc mobile.
      Recherche 46px, toolbar complète 95px, la grille remonte de ~215px
      (vérifié Playwright 390 et 430px).
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 1 file +3 −1
    2. KA Tabbar : sync canonique ka-ui (prop onClick sur les onglets-liens)
      …
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 1 file +9 −1
    3. Barre de navigation mobile commune Groupe KA (KA Tabbar v1)
      …
      Pilule flottante fixe en bas (standard ka-ui/nav) : Produits · Recherche ·
      Soldes · Favoris, accent vert signature, safe-area iOS, micro-interactions.
      Recherche = focus du champ de la barre outils ; Favoris = hub univers KA.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 3 files +347 −1
    4. Nav v2 correctif : le ✕ de fermeture vit DANS le panneau (fixe, toujours visible)
      …
      Le ✕ était le burger du header ; si le header n'est pas épinglé (bas de page),
      il défilait hors écran alors que le panneau fixed restait affiché — impossible
      de fermer sans Escape. Ajout d'un .mm-close position:fixed en haut à droite du
      panneau et burger masqué à l'ouverture (une seule commande de fermeture).
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 2 files +13 −2
    5. Nav mobile v2 : le dropdown 480px devient un panneau plein écran fixed
      …
      Standard KA 2026-08-25 : .mobile-menu passe de position:absolute top:100%
      (max-height 480px) à position:fixed inset:0 — menu visible peu importe la
      position de scroll. Rang du header (marque + burger→✕) maintenu au-dessus du
      panneau, verrou de scroll CSS pur via html:has(.mobile-menu.open).
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 1 file +13 −9
  6. Mon, Aug 24, 2026 5

    1. Simon-Pierre Boucher committed 1 mo ago · 1 file +10
    2. Simon-Pierre Boucher committed 1 mo ago · 1 file +94 −19
    3. Simon-Pierre Boucher committed 1 mo ago · 1 file +87 −15
    4. Simon-Pierre Boucher committed 1 mo ago · 8 files +161 −2
    5. Simon-Pierre Boucher committed 1 mo ago · 3 files +86 −216
  7. Sun, Aug 23, 2026 3

    1. Simon-Pierre Boucher committed 1 mo ago · 5 files +1,115 −19
    2. widget KA Agent : balise analytics première partie (admin-ka /collect)
      …
      Bloc KA_ANALYTICS ajouté en fin de ka-agent.js par le déploiement du
      tableau de bord admin-ka : identifiant visiteur anonyme (localStorage
      KA_VID) + battement par minute vers administration-ka.com/collect
      (site, vid, chemin). Commité a posteriori — état déployé en prod.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 1 file +2
    3. stats : fenetre de sync parametrable ?syncs_since_h pour la supervision api-ka
      …
      GET /api/stats?syncs_since_h=<heures> retourne toutes les entrees de
      sync_log de la fenetre (ts >= now - h*3600, DESC, max 4000) au lieu des
      20 dernieres — corrige les faux "stale" du moniteur central : avec 57
      sources en rotation, LIMIT 20 ne montrait qu un tiers du cycle.
      Si la fenetre contient moins de 20 entrees, fallback aux 20 dernieres.
      Sans parametre : comportement inchange.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 1 file +14 −3
  8. Sat, Aug 22, 2026 5

    1. tri par défaut : nouveautés (first_seen DESC) au lieu du prix croissant
      …
      Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 2 files +3 −3
    2. Simon-Pierre Boucher committed 1 mo ago · 4 files +15 −14
    3. SEO : SSR léger, robots.txt, sitemaps et données structurées (foodka/seo.py)
      …
      - foodka/seo.py : robots.txt (Disallow /api/, /profil, Sitemap), sitemap index
        + sitemap-pages + sitemap-produits-{n}.xml chunkés 10 000 avec lastmod ;
        SSR accueil (title/description riches, H1 + liens serveur, WebSite/Organization
        JSON-LD fr-CA), pages programmatiques /?category= et /?source= (ItemList +
        BreadcrumbList, 404 si inconnue), /aubaines (ItemList), fiche /produit/{uid}
        (Product JSON-LD avec Offer CAD + availability, brand, image ; BreadcrumbList ;
        og:image = image produit ; 404 introuvable / 410 retiré), /sources (ItemList),
        meta uniques stats/contact/confidentialite. Head unique : canonical, hreflang
        fr-ca, og:* complet locale fr_CA, twitter ; contenu HTML dans #root remplacé
        par React au montage.
      - foodka/web.py : include du routeur SEO AVANT le catch-all SPA (robots.txt et
        sitemap.xml renvoyaient l index.html du SPA).
      - frontend/index.html : lang fr-CA.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 3 files +584 −1
    4. connecteurs: chaine de fetch anti-bot resiliente (Oxylabs->Scrapfly->Bright Data)
      …
      Auto-escalade de BaseConnector.get() sur blocage (403/429/503/challenge CF)
      ou coupure reseau, via connectors/_resilient.py. Cles lues de l env avec repli
      sur ~/.claude/.env (accepte SCRAPFLY_KEY et SCRAPFLY_API_KEY). Reponse
      compatible requests.Response; coupe-circuit par hote. Aucun connecteur modifie.
      
      Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 2 files +386
  9. Wed, Aug 19, 2026 5

    1. refactor(fiche): ordre des sections = ordre du DOM sur tous les breakpoints
      …
      Standard Groupe Ka « Ordre des sections — pages détail » (même correctif
      que Lou-Ka a6e30ef et Immo-Ka 38634e6) : plus de réordonnancement via
      order:/display:contents — un bloc ajouté sans order retombait à order:0
      et passait devant la galerie sur mobile.
      
      - Product.tsx : hero (prix/solde/CTA) déplacé sous la galerie dans la
        colonne principale ; la comparaison de prix devient la colonne droite
      - styles.css : suppression des order:/display:contents, colonnes empilées
        en flux naturel sur mobile
      - scripts/check-order.mjs : validation Playwright de l ordre visuel
      
      Validé iPhone 14 + desktop 1440px.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 3 files +86 −41
    2. Simon-Pierre Boucher committed 1 mo ago · 1 file +4 −1
    3. docs: Stats v2 — contenu livré dans 452b905 (entrelacé avec KA Agent v2)
      …
      /stats ultra complet (module commun ka-ui v2) + 5 rapports PDF :
      - kacharts.tsx / kapdf.py / SPEC.md canoniques v2 vendorisés
      - statsdash.py : 10 KPI (sparklines + deltas), 4 jauges (fraîcheur 7 j,
        images, prix unitaire, couverture bannières), 5 séries (relevés bar,
        suivis, indice de prix area + compare N-1, baisses, nouveautés),
        multi-courbes prix moyen par bannière (≤4), 2 empilées (baisses vs
        hausses, ajouts par bannière), 4 répartitions (deltas par bannière),
        2 histogrammes (rabais %, prix), heatmaps calendrier + horaire 7×24,
        5 tableaux, 10 records — données réelles, cache 5 min
      - /api/stats/report : 5 modes (inconnu → complet), filename(..., mode)
      - Page /stats réordonnée SPEC v2 + PdfButton menu 5 rapports
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 0 files
    4. Mobile : FAB decale du bandeau temoins, verrous de scroll lightbox et bottom-sheet, anti-zoom iOS, cible tactile du logo
      …
      - CookieConsent.tsx : hauteur du bandeau publiee dans --consent-h sur
        documentElement via ResizeObserver (0 quand ferme) — fin de la collision
        z-index 80/80 avec le FAB (modele lou-ka).
      - styles.css : .fab decale de var(--consent-h) et passe a var(--z-bottombar) ;
        .cookie-banner passe a var(--z-toast) ; lightbox et bottom-sheet filtres
        bascules sur var(--z-modal)/var(--z-overlay) ; extension tactile ::after du
        logo (121x27) ; regles anti-zoom iOS generalisees >=16 px en contexte
        tactile (#f-q, selects hors .field que le breakpoint 900 px ratait).
      - Product.tsx : verrou du scroll d arriere-plan quand la lightbox est ouverte
        + fermeture Escape (pattern App.tsx).
      - Home.tsx : verrou du scroll d arriere-plan quand le bottom-sheet filtres
        est ouvert + fermeture Escape.
      - ka/tokens.css : section SOCLE MOBILE OBLIGATOIRE (echelle --z-*, --vh100,
        verrou ka-scroll-lock, filet anti-zoom iOS).
      - public/ka-agent.js : agent KA corrige (safe-area, textarea 16 px, plein
        ecran auto <=640 px + verrou scroll).
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 6 files +180 −14
  10. Tue, Aug 18, 2026 2

    1. docs: historique Vague 3 (2e52f7c) + fiches regenerees
      …
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 2 files +3 −1
    2. Vague 3 : SAQ (API GraphQL directe) + 6 circulaires Flipp (4 pharmacies, Adonis, Avril) + Metro 4 pages allees prioritaires
      …
      - saq : connecteur Adobe Live Search (catalog-service.adobe.io, cle publique
        du storefront) — 3 282 produits prioritaires/sync (vin/spiritueux/mousseux
        plafonnes, petites categories entieres), prix final+regulier, format ml,
        pays, cepages, pastille de gout, code SAQ, dispo en ligne, images ;
        22 requetes directes, zero Scrapfly. Categorie canonique « Alcool »
        (ajoutee a normalize.CATEGORIES), exclue du matching inter-bannieres
        (matching.EXCLUDED_SOURCES — banniere unique, prix provinciaux uniformes).
      - Flipp : pharmaprix (2170), jean_coutu (2521), brunet (3753), uniprix (3467)
        — keep_categories=GROCERY_CATEGORIES ne garde que les rayons alimentaires
        des cahiers de pharmacie (filtre AVANT la fiche item : zero requete pour
        les items ecartes) ; adonis_flyer (3384) et avril_flyer (3940) completent
        les catalogues adonis/avril. Testes : 127/44/65/25/389/87 produits.
      - _flipp : desambiguisation « eau de parfum/toilette/javel », « creme
        adhesive/corps » (les cahiers pharmacie exposaient ces faux Boissons /
        Produits laitiers).
      - metro : pages_override — 4 pages (au lieu de 2) sur fruits-et-legumes,
        viandes-et-volailles, produits-laitiers-et-oeufs ; 664 -> 1 005 produits.
        Cout mesure 40-80 credits Scrapfly/page (ASP sans render_js).
      - Sondes documentees : Costco (recherche montee cote client, API Lucidworks
        403 sans cle JS — render_js reste la seule voie) ; Dollarama absent de
        Flipp. sources.json : 54 -> 61 entrees ; docs regeneres.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 24 files +574 −77