SPB Git forge

spb/job-ka

Public
229commits 1branches 0releases
38.1 MBsize
maindefault branch
3 h agolast push
HTML 82.1% Python 14.6% TypeScript 1.9% CSS 1% JavaScript 0.5%

History of jobka/normalize.py · clear filter

  1. Fri, Sep 18, 2026 1

    1. [ka6] fix connecteur awc: ajout de Rougemont (Montérégie) au dictionnaire _QC_CITIES — le connecteur était aveugle aux offres du vignoble québécois d'Arterra — le statut broken combinait trois éléments : (1) une NameResolutionError DNS transitoire le 18/09 12:53 sur awc.wd3.myworkdayjobs.com (même vague que altusgroup/autotradercanada à 12:51, non reproduite), (2) la dépublication NORMALE de l'unique offre suivie « Représentant des ventes (SAQ/licenciés) Montréal/Brossard » R-13270 (absente du board live, miss_count=2 → active=0), qui a fait tomber found de 1 à 0, et (3) un VRAI défaut : le tenant Workday awc.wd3 n'expose qu'une facette de lieux plate au niveau ville, et sa seule localisation QC restante est « Rougemont » (Montérégie, vignoble d'Arterra) — absente du dictionnaire curé _QC_CITIES de normalize.py, donc invisible à la fois pour le filtre client is_quebec_location ET pour le repli facette-serveur de _find_qc_facet (qui agrège les valeurs de facette via la même fonction). Résultat : 2 offres QC réelles ignorées, dont « Électromécanicien - syndiqué (Qc) » R-13064 parue le 2026-08-19 (aveuglement d'un mois) et « Partenaire d'affaires en ressources humaines » R-13556 parue le 2026-09-10. Correction minimale dans normalize.py : entrée « rougemont » → « Rougemont » dans _QC_CITIES (regions-qc.json connaissait déjà rougemont → Montérégie ; le garde-fou _NON_QC_REGION_RE continue d'exclure « Rougemont, NC »). Bénéficie aussi au connecteur lassonde (Industries Lassonde, Rougemont). Sync isolé rejoué : found=2, added=2 en 4,6 s — R-13556 et R-13064 en base, actives, ville Rougemont, région Montérégie, volume 2 ≥ médiane 1.0. 106 tests pytest verts. pm2 restart job-ka-sync OK, site local 200, www.job-ka.com 200.
      …
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 6 days ago · 1 file +2 −1
  2. Mon, Sep 14, 2026 1

    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 committed 10 days ago · 1 file +12 −3
  3. 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 committed 12 days ago · 1 file +2 −1
  4. Wed, Aug 26, 2026 1

  5. 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 committed 1 mo ago · 1 file +187 −7
  6. Wed, Aug 19, 2026 1

  7. Tue, Aug 18, 2026 2

    1. Expansion ×: 59 nouveaux employeurs connectés via sondage massif d ATS + détection de pages carrières
      …
      - scripts/probe_ats.py : sonde 800+ slugs candidats sur les 9 ATS (timeout 6 s,
        throttle 0,3 s/domaine, 8 threads) ; confirmé = ≥1 offre ET ≥1 offre QC
        (is_quebec_location du projet). Découverte Workday sans page HTML (bloquée
        406) : cxs 422=tenant absent / 404=hôte bon, puis devinette du site.
      - scripts/detect_ats.py : visite 6 337 domaines d employeurs QC (accueil +
        /carrieres|/careers|/emplois|/jobs|/fr/carrieres + liens carrières),
        reconnaît l ATS par motifs URL/DOM ; ATS non supportés (taleo 11,
        successfactors 6, adp 5, icims 4, njoyn 4, ukg 3) consignés dans
        data/detected-other-ats.jsonl pour traitement séparé.
      - data/feeds-expansion.json : 59 flux vérifiés -> 59 connecteurs générés
        (workday 22, smartrecruiters 10, bamboohr 12, greenhouse 6, lever 4,
        workable 2, ashby 1, recruitee 1, breezy 0) dont Vidéotron, CDPQ, BDC,
        Beneva, Intact, PSP, Investissement Québec, Rio Tinto, Alcoa, Airbus,
        Walmart Canada, Canadian Tire, RCGT, Lightspeed, Behaviour, Cirque du
        Soleil, Gameloft, Canam, QSL, Promutuel, EXFO…
      - 2 107 offres actives ajoutées, 100 % villes QC ; faux positif retiré
        (genetec smartrecruiters, doublon faible de genetec_inc workable)
      - normalize.py : villes hors-QC supplémentaires (Las Vegas, Orlando…)
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 1 file +2 −1
    2. Qualité lieux : rejet des villes canadiennes/monde hors Québec + bâtiments McGill mappés vers Montréal
      …
      - normalize.py : _NON_QC_CITIES (villes CA hors QC + grandes villes monde) —
        parse_location ne prend plus ces libellés pour des villes et
        is_quebec_location les rejette explicitement ; purge BD : 127 offres
        actives hors-QC désactivées (Toronto 50, etc.)
      - mcgill.py : les lieux Workday de McGill sont des bâtiments (Bronfman
        Building, Currie Gymnasium…) -> ville forcée Montréal (Outaouais ->
        Gatineau) ; 182 offres corrigées en BD
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher committed 1 mo ago · 1 file +31 −1
  8. 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 committed 1 mo ago · 1 file +10 −5
    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 committed 1 mo ago · 1 file +480