Projet né d’un besoin réel : comprendre objectivement le marché de l’emploi tech français plutôt que de naviguer à l’instinct dans une recherche de poste.
Collecte des données
- Worker dédié, agrège en continu les offres, stockées dans PostgreSQL via SQLAlchemy async ; l’API FastAPI reste en lecture seule, seul le worker écrit.
- Sources structurées, France Travail, Adzuna et 6 flux ATS publics (Greenhouse, Lever, Ashby, SmartRecruiters, Teamtailor, Workable). Pas de scraping fragile.
Extraction et classification
- Catalogue regex de 207 entrées, avec modélisation des prérequis, maintenu plutôt que fragile.
- Passe LLM avec Claude, qui repasse sur les offres tech après la regex : elle rattrape les technos manquées, désambiguïse d’après le contexte les noms que la regex ignore volontairement (Go, C, R, Tableau…) et juge la force d’exigence de chaque techno (exigée, « un plus » ou simplement mentionnée). Elle fait autorité sur cette force, la provenance (regex ou LLM) reste tracée, et toute techno hors catalogue est écartée.
- Annonces traitées comme des données, les descriptions d’offres sont écrites par des tiers : la passe LLM les analyse sans jamais les suivre comme des instructions, et tourne sans aucun outil, si bien qu’une consigne glissée dans une annonce ne peut au pire que dégrader sa réponse.
- Classification de poste en 11 catégories, dev, data, ia, devops, qa, sécu…
- Stacks de marché, détection des itemsets fréquents.
Dashboard et back-office
- Front Next.js, quelles technos recrutent le plus, carte choroplèthe des 101 départements (d3-geo).
- Statistiques de salaire, p25/p75 par région/rôle/séniorité.
- Moteur de recommandation de compétences, avec une feuille de route qui se garde dans le navigateur.
- Back-office admin, accessible par le SSO GotYeah : scanner de technos inconnues et outils d’audit d’extraction.
Architecture multi-services (worker + API + web), CI/CD GitHub Actions (pytest, ruff, mypy, tsc, eslint, et un job d’intégration sur une vraie base PostgreSQL).
Côté produit
Contexte. Pour choisir quoi apprendre, on s’appuie souvent sur des sondages déclaratifs, des tendances GitHub ou l’effet de mode. Je voulais savoir ce que demandent les offres réelles, et avec quoi chaque techno va de pair.
Mon rôle. J’ai écrit le PRD (problème, cible, périmètre, risques, roadmap) et je tiens un registre de plus de quarante décisions structurantes, chacune avec sa justification.
Décisions.
- Sources structurées uniquement : API et flux ATS publics, jamais de scraping de LinkedIn, Welcome to the Jungle ou Indeed, zone juridique grise.
- Anonyme par principe : ni compte ni alerte ; la feuille de route personnelle se garde dans le navigateur et se partage par un lien.
- Recommandeur avancé dans le MVP : il ne demande que des données agrégées, disponibles dès le premier mois, quand les tendances temporelles attendront six mois de données stables.
- Extraction LLM par API abandonnée faute de budget : la passe Claude s’appuie sur un abonnement déjà payé, à coût marginal nul.
Résultat. En ligne, alimenté chaque jour par France Travail, Adzuna et six flux ATS, avec une CI qui fait tourner tests, lint et typage à chaque push sur la branche principale et sur chaque demande de fusion.
A project born from a real need: objectively understanding the French tech job market rather than navigating a job search on instinct.
Data collection
- Dedicated worker, continuously aggregates job postings, stored in PostgreSQL via SQLAlchemy async; the FastAPI API stays read-only, only the worker writes.
- Structured sources, France Travail, Adzuna and 6 public ATS feeds (Greenhouse, Lever, Ashby, SmartRecruiters, Teamtailor, Workable). No fragile scraping.
Extraction and classification
- Regex catalog of 207 entries, with prerequisite modeling, maintained rather than fragile.
- LLM pass with Claude, which goes over tech postings after the regex: it catches the technologies the regex missed, disambiguates from context the names the regex deliberately skips (Go, C, R, Tableau…) and rates how strongly each technology is required (required, “nice to have” or merely mentioned). It has the final say on that rating, the origin (regex or LLM) stays traceable, and any technology outside the catalog is discarded.
- Postings treated as data, job descriptions are written by third parties: the LLM pass analyzes them without ever following them as instructions, and runs with no tools at all, so an instruction slipped into a posting can at worst degrade its answer.
- Job classification into 11 categories, dev, data, ai, devops, qa, security…
- Market stacks, frequent itemset detection.
Dashboard and back-office
- Next.js front end, which technologies are most in demand, choropleth map of the 101 departments (d3-geo).
- Salary statistics, p25/p75 by region/role/seniority.
- Recommendation engine for skills, with a personal roadmap kept in the browser.
- Admin back-office, reached through the GotYeah SSO: scanner for unknown technologies and extraction audit tools.
Multi-service architecture (worker + API + web), GitHub Actions CI/CD (pytest, ruff, mypy, tsc, eslint, and an integration job against a real PostgreSQL database).
Product side
Context. When choosing what to learn, people often rely on self-reported surveys, GitHub trends or hype. I wanted to know what real job postings ask for, and which technologies go together.
My role. I wrote the PRD (problem, target users, scope, risks, roadmap) and I keep a log of more than forty structuring decisions, each with its rationale.
Decisions.
- Structured sources only: public APIs and ATS feeds, never scraping LinkedIn, Welcome to the Jungle or Indeed, a legal gray area.
- Anonymous by design: no accounts, no alerts; the personal roadmap is kept in the browser and shared through a link.
- Recommender moved into the MVP: it only needs aggregated data, available from the first month, whereas trends over time will wait for six months of stable data.
- LLM extraction through the API dropped for lack of budget: the Claude pass runs on an existing subscription, at zero marginal cost.
Outcome. Online, fed daily by France Travail, Adzuna and six ATS feeds, with CI running tests, lint and type checks on every push to the main branch and on every pull request.