🏁 Track : SaaS no limit

🌐 Application : https://zako.nc/avp/
💻 Code : https://github.com/C2Bx/adopte-un-job
🎬 Vidéo : https://zako.nc/avp/video/adopte-un-job.mp4

🎯 Le problème

« Une offre d'emploi publiée n'est pas une offre d'emploi trouvée. »
— l'énoncé du #HackAVP

Les avis de vacance de poste (AVP) de l'OPT-NC sont ouverts, au format schema.org/JobPosting, et servis par une API.

📦 La donnée est là.

Ce qui manque, c'est le chemin entre une Calédonienne ou un Calédonien et le poste qui lui correspond :

  • 🗂️ un vocabulaire administratif qui n'est pas le sien ;
  • 🤷 des fiches qui ne disent pas à qui elles s'adressent ;
  • ❓ et aucune réponse à la seule question qui compte : « est-ce que ce poste est pour moi ? »

💡 La réponse : Adopte un Job

Une application où l'on fait défiler les vrais postes ouverts à l'OPT-NC :

  • 👉 à droite pour candidater ;
  • 👈 à gauche pour passer ;
  • 📊 et pour chaque offre, une adéquation qui s'explique, compétence par compétence.

🎬 La démo en vidéo

Regarder la démo d'Adopte un Job (2 min 33)

▶️ Clique sur l'image pour regarder la vidéo dans ton navigateur (2 min 33, 1080p).

🧩 Un module dans une équipe de sept

Adopte un Job n'est pas seul. C'est MS3, le front candidat d'un projet en sept modules. Le profil du candidat y circule dans un format commun, le JSON Resume ; les offres gardent celui des AVP.

Module Qui Ce qu'il fait
📄 MS1 CVForge Florian lit le CV déposé et en tire un JSON Resume
🗄️ MS2 HACKAVPI Dan et Timothée l'API commune : comptes, offres, profils, CV, candidatures
📱 MS3 Adopte un Job Bastian le front candidat — cet article
✍️ MS4 CV Generator Anthony et Kim CV, lettre de motivation, guide d'entretien
🎯 MS5 CV-Matching Jo-Michel le calcul d'adéquation entre un CV et les offres
👥 MS6 AVPRO-NC Damien et Lucas l'espace recruteur
📈 MS7 Insight Squad Élodie et Mathieu les indicateurs

🔒 Adopte un Job ne garde rien : ni base de données, ni API à lui, ni CV.

Il affiche ce que HACKAVPI et CV-Matching lui donnent, et leur transmet ce que la personne saisit. Une seule source de vérité, et aucune donnée personnelle dupliquée dans un coin.

👀 Ce qu'on voit à l'écran

🃏 Le deck

Une carte = un vrai AVP : l'intitulé, la direction, le lieu, le contrat, le nombre de jours avant la clôture, puis les missions et ce que le poste demande, page par page.

On glisse depuis n'importe quel point de la carte, on clique sur les boutons, ou on utilise le clavier :

Touche Action
➡️ candidater
⬅️ passer
⬇️ mettre à plus tard
⌫ Retour arrière revenir sur la dernière décision

🔎 Le détail de l'offre

L'AVP en clair : description, missions, relations de travail, employeur.

Un encadré En bref résume l'essentiel : rattachement hiérarchique, place dans l'organigramme, corps, métier OPT et métier ROME, horaires, habilitations, condition de résidence quand l'avis en pose une.

📬 Et surtout : à qui écrire pour candidater, avec un mail déjà adressé au bon contact, objet compris.

👤 Le profil

Trois façons de le remplir, côte à côte :

  • ✏️ à la main ;
  • 💬 par neuf questions courtes ;
  • 📎 en déposant son CV (PDF, PNG, JPEG).

📋 Les candidatures

La décision du recruteur, lue dans l'API de l'équipe :

  • ⏳ en attente
  • ✅ retenue
  • ❌ non retenue
  • 📅 entretien à programmer

📱 Et partout

  • Mobile d'abord : recherche et filtres tiennent dans la barre du haut d'un téléphone.
  • 🌙 Mode jour et mode nuit, dans le menu.
  • 🤝 Une interface qui tutoie : on parle à une personne, pas à un dossier.

⚙️ Les quatre fonctions, une par une

1️⃣ Un profil entre dans le système

Trois portes, et aucune n'est plus « officielle » que les autres : le formulaire guidé, les neuf questions (métiers visés, zones, contrat, disponibilité…), ou le CV déposé.

Le CV part dans l'API de l'équipe, où CVForge (Florian) le lit et en tire un JSON Resume.

🛡️ Une règle tient tout le reste : la lecture du CV ne remplace jamais ce que la personne a saisi.

La lecture automatique est rangée à part (cvJsonGenere). L'interface ne la recopie dans le profil que si le parcours est encore vide (aucune expérience, formation, compétence ni langue) ; sinon, la lecture reste à part et ne touche à rien. Le candidat relit et corrige ce qu'elle a rempli : il reste le seul rédacteur de son profil.

📤 Le profil s'exporte et s'importe au format JSON Resume : il n'est prisonnier d'aucune application.

2️⃣ Le matching, et pourquoi il s'explique

Le calcul d'adéquation est celui de CV-Matching (Jo-Michel) : des embeddings bge-m3 et un reranker, qui notent chaque compétence attendue par l'AVP face au contenu du CV.

Adopte un Job ne refait pas ce calcul : il le rend lisible.

🏷️ Sur chaque carte, une pastille : « Bonne adéquation · 42 % ».

📊 Dans le détail de chaque offre, un petit tableau de bord :

Le tableau de bord d'adéquation (exemple illustratif, profil fictif)

  • 🟢 une jauge : la part des compétences du poste couvertes par le profil, pondérées par leur importance ;
  • 🔢 quatre indicateurs : compétences couvertes (ici 3 sur 5), rang de cette offre parmi toutes celles analysées (« 2e sur 25 »), savoir-être à montrer en entretien, prérequis à vérifier ;
  • 📏 une barre par compétence, notée sur 100. Au survol ou au clavier, la preuve : Couverte à 76 / 100, puis la phrase du profil qui le montre (Dans ton profil : « … »).

Les compétences à travailler viennent ensuite, de celle qui pèse le plus dans le score à celle qui pèse le moins.

💬 C'est ce qui rend le score explicable : on voit pourquoi ce poste et ce profil se rencontrent, et où ils ne se rencontrent pas.

⚠️ Les prérequis (diplôme, permis…) sont montrés à part et ne sont jamais notés : chacun porte un statut (rempli, à vérifier, pas encore…), avec la raison donnée par CV-Matching.

Deux choix de conception assumés :

  • 🧭 L'adéquation est une indication, pas un filtre. Toutes les offres restent dans le deck : une adéquation faible ne cache rien et n'empêche pas de candidater.
  • 🕶️ Les champs d'identité ne partent pas. Le nom, l'e-mail, le téléphone et l'adresse du profil ne sont pas envoyés au matching : seuls le titre, le résumé, les expériences (bénévoles comprises), la formation, les compétences, les projets, les certifications et les langues le sont. Ces textes partent tels quels : ce qu'on y a écrit soi-même part avec.

3️⃣ Les assets de candidature

📊 La restitution du matching est dans Adopte un Job : où le profil est fort (avec la preuve), où il est en écart, ce qui pèse le plus dans cet écart, et ce qu'il faut préparer pour l'entretien.

✍️ La lettre de candidature, le CV recentré sur le poste et le guide d'entretien sont produits par CV Generator (Anthony et Kim), à partir du JSON Resume du candidat et du numéro de l'AVP visé.

👉 Leur article détaille comment :

4️⃣ La candidature part

👉 Glisser une carte à droite crée une vraie candidature dans l'API de l'équipe.

Elle arrive dans AVPRO-NC (Damien et Lucas), l'espace recruteur, où elle est retenue ou non, avec un entretien à programmer le cas échéant. Le candidat suit cette décision dans l'onglet Candidatures.

📧 Et parce qu'un AVP de l'OPT-NC dit à qui écrire, chaque offre propose aussi le contact de l'avis, avec un mail prêt à partir : bon destinataire, objet « Candidature — intitulé du poste (référence) ». La candidature peut sortir de l'application sans dépendre d'elle.

🛠️ Sous le capot

Schéma : Adopte un Job, le relais, HACKAVPI et CV-Matching

  • ⚛️ React 19 + TypeScript strict + Vite, sortie statique, plus un petit relais PHP : un dossier à déposer sur un hébergement PHP, rien d'autre à faire tourner.

  • 🛡️ Un relais PHP sans état, parce que l'API commune n'envoie pas encore d'en-têtes CORS. Il ne relaie que les routes que l'interface utilise, chacune avec sa seule méthode.

  • 🔑 Pour CV-Matching, le relais ajoute la clé du service côté serveur : elle n'est ni dans le dépôt, ni dans le code envoyé au navigateur, et le jeton de l'utilisateur n'est jamais transmis au service de matching.

  • 📐 Les standards ouverts plutôt que des formats maison :

    • les AVP au format schema.org/JobPosting publiés par l'OPT-NC ;
    • le JSON Resume comme format commun de profil ;
    • le référentiel des métiers OPT-NC (84 métiers, 409 compétences), régénéré depuis sa publication officielle et servi comme un fichier ;
    • les codes ROME, affichés dans le détail de chaque offre qui en porte un.
  • 🔌 Un seul fichier parle aux API (api.ts) : il traduit leurs réponses dans les formes que les écrans connaissent. Les écrans ne savent rien des API.

♿ Accessibilité

C'est le sujet même du hackathon, donc pas une case à cocher :

  • ⌨️ le deck se pilote entièrement au clavier, et les boutons portent leurs libellés pour les lecteurs d'écran ;
  • 🐢 les animations s'arrêtent quand le système demande moins de mouvement (prefers-reduced-motion) ;
  • 🌗 mode jour et mode nuit au choix, mémorisés ;
  • 👍 mobile d'abord : tout se fait au pouce sur un téléphone ;
  • 🗣️ un langage clair : « Ton adéquation avec ce poste », « rien ne t’empêche de candidater », et un écran vide qui dit clairement qu'aucune offre n'est ouverte, plutôt qu'un « aucun résultat » qui fait croire à une panne.

♻️ Réutiliser Adopte un Job ailleurs

L'essentiel ne dépend pas de l'OPT-NC.

Une autre organisation de la fonction publique qui publie ses offres au format schema.org/JobPosting remplace :

  1. l'adresse cible du relais ;
  2. la traduction d'une offre dans api.ts ;
  3. le référentiel des métiers ;
  4. les quelques libellés qui nomment l'OPT-NC.

Le deck, le profil, l'adéquation et les candidatures suivent.

🧪 Le dépôt contient aussi la démo de départ (demo/), en HTML, CSS et JavaScript, sans framework ni étape de build, qui s'ouvre sans compte ni API sur des offres fictives.

🔐 Données personnelles

  • 🎭 Les démonstrations, la vidéo et les visuels utilisent un profil fictif.
  • 🚫 L'application n'enregistre aucun CV de son côté.
  • 🧳 Ce qui reste dans le navigateur se limite à la session (le jeton et l'adresse e-mail, dans l'onglet), aux offres mises à plus tard ou remises dans le deck, et au choix jour / nuit.

Bastian — MS3, #HackAVP.