SPB Git

spb/job-ka

Public
History of tests Clear filter
page 1
  1. Wed, Sep 16, 2026 2

    1. [ka6] fix connecteur eq3_ltd: retrait immédiat des offres CONFIRMÉES fermées — dans la nuit du 15 au 16/09, EQ3 a réellement fermé ses 12 postes (« Position Closed » vérifié live sur chacune des 12 pages /p/, plus aucun formulaire APPLY), étape suivante du délisting du board traité en 6012d1c ; le repli « board délisté » a fonctionné exactement comme conçu (re-vérification des 12 offres, rejet des pages fermées → found=0, volume désormais légitime), mais la garde anti-dérive du moteur (found=0 vs médiane 12 → retraits suspendus) maintenait les 12 offres fermées EN LIGNE sur le site (active=1, miss_count=0) pendant que la fenêtre de médiane (DRIFT_HISTORY=5) se vidait — correct pour un connecteur cassé, injustifié quand la fermeture est PROUVÉE page par page. Correctif tenant-spécifique dans eq3_ltd.py seul (db.py intact) : le repli collecte les uid des offres dont la page /p/ affiche « Position Closed » et les désactive directement (_deactivate_closed, UPDATE active=0), fermeture vérifiée à la source — les offres injoignables ou hors QC continuent de suivre le chemin normal miss_count. Vérifié live : la page carrières officielle eq3.com pointe toujours vers eq3-ltd.breezy.hr (pas de migration d'ATS), /json toujours [], validThrough des 12 offres tous dans le passé. Test unitaire adapté (offre « Position Closed » → retrait direct capturé, vivante conservée, hors-QC simplement lâchée). Sync réel rejoué : 12 offre(s) confirmée(s) fermée(s) — retirées, 0 offre active restante en base, found=0 légitime (le tenant n'a plus aucun poste ouvert ; dès republication le chemin normal /json reprend seul). 105 tests pytest verts. pm2 restart job-ka-sync OK, site 200.
      Simon-Pierre Boucher · 1 file +16 −7
  2. Tue, Sep 15, 2026 1

    1. [ka6] fix connecteur eq3_ltd: repli « board délisté » — /json vide alors que les 12 offres restent EN LIGNE (re-vérification live des pages /p/) — le 2026-09-15 vers 12:07, le board Breezy eq3-ltd a cessé de lister ses postes (/json et /json?verbose=true = [] — vérifié direct, UA navigateur ET proxy résidentiel CA —, sitemap.xml sans aucune offre, HTML %LABEL_NO_POSITIONS%) alors que les 12 offres QC connues sont toutes encore en ligne et ouvertes aux candidatures (pages /p/ 200 avec JSON-LD JobPosting complet et bouton APPLY, aucune « Position Closed ») et que la page carrières officielle eq3.com/ca/en/aboutus/careers pointe toujours vers ce même board : delisting du portail côté tenant, PAS une dépublication (contrairement aux précédents hera 4990c80/autotradercanada e3bb827 où les offres retirées affichaient « Position Closed »/404). L'API Breezy est saine globalement (bellatrx 14, brandmomentum 34, recruiting 78…) ; aucun slug alternatif (eq3.breezy.hr existe mais vide) ni endpoint de rechange (embed/feed/rss → 302). Correctif tenant-spécifique dans eq3_ltd.py (breezy.py intact) : quand la liste est vide, re-vérification live de chaque offre active connue via sa page /p/ — JSON-LD JobPosting exigé, rejet des pages « Position Closed »/« no longer accepting » et hors Québec, champs frais depuis le JSON-LD (titre, description, ville, date), libellé salarial conservé du dernier état liste (8/12 avec salaire, préservés). Données réelles constatées à la source, jamais inventées ; limite assumée : pas de découverte de NOUVELLES offres tant que le board est délisté — dès que /json redevient non vide, le chemin normal reprend seul et les offres réellement fermées suivront miss_count → retrait. Correction au passage du même artefact sources.json que samsara/delos_data/solmentalhealth/hera : url vide → https://www.eq3.com. Test unitaire ajouté (offre vivante QC conservée avec salaire, « Position Closed » et hors-QC lâchées, repli jamais sollicité sur liste non vide, 0 requête si base vide). Syncs réels rejoués : found=12 (médiane exacte) ×2, updated=4 puis 0, aucune alerte, miss_count=0 partout. 105 tests pytest verts. pm2 restart job-ka-sync OK, site 200.
      …
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +91 −1
  3. Mon, Sep 14, 2026 2

    1. [ka6] fix connecteur solmentalhealth: faux positif du filtre Québec — « Quebec St. » (nom de rue à Denver) matchait \bquebec\b — le statut stale vient de la dépublication NORMALE de l'unique offre du tenant (Psychiatric Clinician, id 4704220005, 404 live, retirée à 16:08 miss_count=2 → active=0), mais cette offre n'aurait JAMAIS dû être publiée : son lieu réel est « 3401 Quebec St. Suite 8000, Denver, CO, 80207 » (bureau de SOL Mental Health sur Quebec Street à Denver), classé ville=Québec/Capitale-Nationale et géocodé à Québec parce que _QC_MARKERS (\bquebec\b) est évalué avant le rejet _NON_QC_REGION_RE (« , CO ») dans is_quebec_location. La médiane historique 1.0 est donc elle-même un artefact : le bon volume QC de ce tenant est 0 (vérifié live : API Greenhouse 200, 65 offres, toutes aux États-Unis — NY/VA/MD/CO/DC). Correctif : nouveau _QUEBEC_STREET_RE — « quebec » suivi d'un type de voie anglophone (st/street/ave/blvd/rd/dr/ct/ln/way/pl/hwy/pkwy…) = nom de rue, neutralisé avant tout matching dans is_quebec_location ET parse_location ; le garde (?!-) préserve les abréviations de saints des libellés QC légitimes vérifiés en base (« CAN Quebec St-Hubert/St-Laurent/St-Hyacinthe/Ste-Thérèse », agropur). Tests unitaires ajoutés (4 rues US rejetées, libellés agropur et QC classiques conservés). Correction au passage du même artefact sources.json que samsara/delos_data/findevcanada/dupont : url vide → https://www.solmentalhealth.com (la fiche affichait « Site : []() »). Sync isolé rejoué post-patch : found=0 en 0,2 s, ok — 0 est le volume légitime, l'offre Denver ne reviendra plus même si republiée. 104 tests pytest verts. pm2 restart job-ka-sync OK, site 200.
      Simon-Pierre Boucher · 1 file +14 −1
    2. [ka6] fix connecteur lassonde: faux positif de supervision (épisode Sucuri transitoire) — repli Bright Data sur la page liste — le statut stale vient d'un unique échec à 08:17 (RuntimeError explicite de la garde du 2026-09-05 : 3× « HTTP 200 via scrapfly, 4515 octets » sans le conteneur job-result-default), combiné à la panne SQLite du matin (2b01fd4) qui avait empêché tout sync entre 05:32 et 08:17 — le connecteur est INTACT : rejeu = found=35, médiane exacte. Vraie faiblesse corrigée : pendant un épisode Sucuri, TOUTE la chaîne principale (direct→oxylabs→scrapfly) sert la même page tronquée « propre en apparence » (200 sans marqueur connu — 'access denied', 'sucuri_cloudproxy' etc. déjà couverts par is_blocked) à chaque essai, et le backoff 10-20 s ne suffit pas à sortir de l'épisode ; escalate() acceptait la réponse Scrapfly et ne tentait jamais Bright Data. La liste étant rendue serveur (render_js ne sert qu'au challenge), _fetch_list tente désormais Bright Data Web Unlocker (vendeur de déblocage différent) à chaque essai raté — vérifié live : BD livre 200/110 ko/35 cartes au moment même où le direct sert le challenge Sucuri 307. L'échec reste explicite (offres conservées) si BD échoue aussi. Test unitaire ajouté (repli BD gagnant, échec explicite si BD muet, BD jamais sollicité sur liste saine). Syncs rejoués post-patch : found=35 ok ×2. 104 tests pytest verts. pm2 restart job-ka-sync OK, site 200.
      …
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +59 −1
  4. Sun, Sep 13, 2026 2

  5. Sat, Sep 12, 2026 1

    1. [ka6] fix connecteur cambria: ajout de Fermont au dictionnaire _QC_CITIES (normalize.py) — l'offre QC courante du tenant workday cambria.wd1 (« Mechanic » R-103013, site minier Sitec à Fermont, Côte-Nord, publiée le 2026-04-10, description en français) était INVISIBLE depuis la création du connecteur (Vague D 2026-08-25) : Workday l'affiche sous le libellé « Sitec Fermont » sans province ni code postal, et Fermont manquait au dictionnaire partagé _QC_CITIES, si bien que is_quebec_location la rejetait au filtre client ET au repli de facette serveur (_find_qc_facet — ce tenant n'expose aucune facette province, seulement pays Canada=1 + lieux plats). Le connecteur ne voyait donc que l'offre montréalaise historique (Market Sales Representative R-103079), dépubliée par l'employeur le 2026-09-02 (miss_count=2, retrait normal) → found=0 depuis, d'où le statut stale (la supervision date le succès au dernier sync found>0). L'unique vrai échec (2026-09-12 03:08, « Workday non-JSON HTTP 200 text/html ») est la fenêtre de maintenance hebdomadaire Workday du vendredi nuit, transitoire. Correctif minimal dans la couche partagée (même famille que f4038e4) : « fermont »: « Fermont » — mot à graphie unique, aucun homonyme hors QC (≠ Fremont), garde-fous _NON_QC_CITIES/_NON_QC_REGION_RE intacts ; test ajouté sur le libellé exact « Sitec Fermont ». Sync isolé rejoué : found=1, added=1 en 2,9 s — R-103013 en base, ville Fermont, région Côte-Nord, statut ok (médiane historique 0–1). 102 tests pytest verts. pm2 restart job-ka-sync OK, site 200.
      Simon-Pierre Boucher · 1 file +5 −1
  6. Tue, Aug 25, 2026 1

    1. Phase 3 — enrichissement des 1050+ connecteurs (exigences, séniorité) + refonte du display des offres avec métriques claires
      …
      Backend (enrichissement central via finalize() -> tous les connecteurs) :
      - normalize.py : extract_requirements() (années d'expérience, scolarité,
        langues exigées, FR/EN, bornes de plausibilité), parse_seniority()
        (stage/junior/intermédiaire/senior/direction : titre, libellés ATS,
        années d'expérience), en-têtes d'avantages élargis
      - schema.py : champ seniority + branchement des extracteurs (setdefault,
        jamais d'écrasement des valeurs ATS)
      - db.py : colonne seniority (migration auto) dans insert/update
      - web.py : filtre + facette séniorité, salary_context (médiane/quartiles
        de la catégorie + écart % de l'offre, cache 10 min), employer_jobs,
        median_salary_year dans /api/stats
      - scripts/backfill_enrich.py : backfill exécuté — 23 680 offres scannées,
        16 606 exigences ajoutées (26 % -> 77 %), 10 966 séniorités (0 -> 46 %)
      - tests/test_enrich.py : 27 nouveaux tests (101 au total, tous verts)
      
      Frontend (display + métriques claires) :
      - JobCard : badge Nouveau (≤3 j), salaire avec équivalent annuel, badges
        séniorité/exigences/bilingue, pied fraîcheur · avantages · plateforme
      - Fiche : panneau « En un coup d'œil » (salaire vs marché avec barre
        interquartile P25-P75, expérience, scolarité, langues, fraîcheur, date
        limite), volume d'offres de l'employeur, historique du salaire affiché
      - Accueil : filtre séniorité ; api.ts : types + helpers (compactMoney,
        yearlyEquiv, daysSince)
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +172
  7. Sat, Aug 22, 2026 1

    1. Vague B — 110 nouvelles sources (26 Dayforce nouvelle famille + 84 sur familles existantes)
      …
      - Nouvelle famille Dayforce HCM (jobs.dayforcehcm.com, API JSON du frontal Next.js,
        csrf anonyme + recherche paginée, détail PayClass/PayType avec cache et budget) :
        26 employeurs dont Groupe Maurice, Groupe CH, La Vie en Rose, Eidos-Montréal,
        Air Canada Rouge, Port de Québec, Soprema, BPA…
      - Ajouts sur familles existantes : Workday +17 (Simons, Cineplex, TJX, FedEx, Abbott…),
        Greenhouse +17 (Coveo, KRAFTON, Lyft, AutoTrader…), SmartRecruiters +13,
        Workable +11, Breezy +8, Recruitee +7, Lever +6, Ashby +5.
      - sources.json : 244 → 354 sources ; docs/connecteurs régénérées (376 fiches).
      - docs/CONFORMITE.md : bases d'accès vérifiées 2026-08-22, 20+ sources écartées
        avec raisons (agences, agrégateurs, babillards vides, faux positifs français).
      - Sync validé : 110/110 sources OK, 2 102 offres ajoutées (total BD 25 280).
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 14 files +243
  8. Wed, Aug 19, 2026 5

    1. Famille Workland réécrite sur l'API JSON publique du frontal Atlas (jobs-prod published-external + default-profiles) : descriptions complètes fr/en, lieux géocodés, dates, mode de travail — 2 requêtes par cycle pour TOUT le réseau. Nouveau connecteur réseau atlas_workland (~80 employeurs QC : CSS scolaires, cégeps, CIUSSS Ouest-de-l'Île, Santé Québec Côte-Nord, ICM, STQ, UQTR, INRS… ; 1 238 offres QC). Connecteur cssdm retiré (couvert par le réseau), fixture remplacée par atlas_workland (sous-ensemble rejouable). Corrige la limite « workland description 0 % ».
      …
      Dans le même train : famille Njoyn paginée (rejeu du formulaire public Inp_ItemsPerPage/pn — Santé Montréal passe de 50 offres lues à 762 —, habillage tableau 5 colonnes titre/catégorie/ville/pays, filtre Québec optionnel, budget détail par classe, POST via Scrapfly pour les babillards Radware) ; famille UltiPro : hôte paramétrable (recruiting.ultipro.ca) ; lassonde réparé (l'ADP WFN ne sert plus que les postes américains — connecteur réécrit sur le site maison lassonde.com/fr/emplois, 31 offres QC).
      Simon-Pierre Boucher · 4 files +1,717
  9. Tue, Aug 18, 2026 1

    1. Simon-Pierre Boucher · 6 files +12,870
  10. Mon, Aug 17, 2026 2

    1. Création massive : 135 connecteurs employeurs québécois sur 9 plateformes ATS
      …
      - 4 nouvelles classes de plateforme : Ashby (salaires structurés natifs),
        Workable (widget v1), Recruitee (offres complètes en liste), Breezy
        (verbose=true), BambooHR (détail + atsLocation)
      - Générateur en série scripts/gen_connectors.py (idempotent) + flux vérifiés
        data/feeds*.json — chaque flux validé par requête HTTP réelle avant génération
      - 124 connecteurs générés : Circle K, TD, BMO, CIBC, Autodesk, Manuvie, CIMA+,
        Transat, Reitmans, Rodeo FX, TEHORA, MaintainX, Hopper, Xsolla, dcbel,
        Robotiq, Toon Boom, BIXI, LG2, Framestore, NOVIPRO, etc.
      - Corrections : pagination Workday avec facette (total absent après la page 1),
        lieux « N Locations » résolus via la page détail, canonicalisation des villes,
        timeout iA à 90 s
      - 2 796 offres actives, 104 sources productives au moment du commit
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 461 files +9,737
    2. Fondation Job·Ka : socle backend, 5 connecteurs pilotes, frontend, tests
      …
      - Schéma JobPosting + normalisation (salaires $/h↔$/an, dates ISO, villes
        canoniques, catégories) — 25 tests unitaires
      - Pipeline hérité de Lou·Ka : diff par content_hash, délai de grâce,
        anti-dérive, expiration sur date limite, dédup union-find, géocodage
        Nominatim + Adresses Québec avec cache
      - Plateformes ATS : Workday (facette Québec auto-découverte), Lever,
        Greenhouse, SmartRecruiters — connecteurs pilotes CAE, Desjardins, Poka,
        Mistplay, Ubisoft (442 offres QC)
      - API FastAPI (/api/jobs, geojson, facets, sources, stats, /health) +
        frontend React/Vite (liste, fiche, carte MapLibre, stats)
      - Fixtures HTTP enregistrées/rejouées hors ligne + hook pre-commit
        d'en-tête d'auteur (section 17)
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 9 files +411
Menu

Theme