Un outil métier,
livré selon les specs.
Un outil de recrutement développé en interne chez Solutec, à partir d'un cahier des charges, de maquettes Figma et d'une base de code fragile. Architecture repensée de zéro, développement full-stack complet, V1 fonctionnelle livrée avec tests, CI/CD et documentation.

Un vrai client. Un besoin documenté.
Solutec est une ESN française de 1 500 collaborateurs. Sa cellule recrutement à Toulouse pilotait l'ensemble de ses recrutements sur Microsoft Planner. Un outil jamais conçu pour ça. Étapes, candidats, entretiens : tout éparpillé dans des cartes sur un tableau partagé. Ça fonctionnait. À peine.
Des consultants fonctionnels ont conduit le recueil du besoin directement auprès de la cellule recrutement et produit les documents de référence : un cahier des charges en 7 modules, une matrice de droits à trois rôles, des maquettes Figma. Ce n'était pas une idée vague : c'était une commande avec un client, un livrable et des attentes.
C'est ce contexte qui donne son poids à GeReCo. Chaque décision devait être justifiée par le besoin, pas dictée par la facilité.
Spéc. des Exigences Fonctionnelles
Outil de Gestion du Recrutement
7 modules fonctionnels · 4 livrés en V1
Deux équipes. Un processus partagé.
GeReCo coordonne deux équipes sur les mêmes candidats : les recruteurs pilotent le processus de bout en bout, les ingénieurs commerciaux n'y accèdent qu'à partir de l'évaluation technique. Mêmes données, rôles distincts, visibilité différenciée.
Le Candidat
L'objet central de l'application. Chaque candidat est suivi avec ses informations personnelles, ses domaines techniques et son stade dans le processus de sélection. Son dossier est partagé entre les deux équipes, chacune avec son niveau de visibilité.
Restreint — non visible pour les Ingénieurs Commerciaux
Trois rôles
Recruteur
Accès complet. Pilote l'intégralité du processus, de la candidature à la décision : candidats, entretiens, paramètres.
Ingénieur Commercial
Lecture seule. Candidats visibles à partir d'un certain stade du processus.
Admin
Droits Recruteur et gestion des comptes utilisateurs.
Les étapes clés
Entretien RH
Premier entretien mené par le recruteur. Le candidat n'est pas encore visible pour l'ingénieur commercial.
Entretien technique
Le commercial assigné évalue l'aptitude technique du candidat et accède au dossier pour la première fois.
Proposition
Le candidat a été retenu. Le recruteur ou le commercial formalise la proposition salariale.
La codebase existait. L'architecture, non.
Reprendre le projet, c'était hériter d'un début de code écrit un an plus tôt : backend aux fondations fragiles, frontend réduit à une page de connexion. Quelques jours d'analyse ont suffi : corriger demanderait plus d'efforts que repartir de zéro.
Structurellement fragile dès les fondations : pas une question de finition, mais de bases.
- Modèle de données inadapté au besoin : candidats modélisés comme des utilisateurs, table de jonction dupliquée
- JWT court-circuitant Spring Security : clé volatile, tokens sans expiration ni révocation, routes métier ouvertes
- Structure sans rigueur : controllers câblés aux repositories, entités exposées brutes, aucune séparation des responsabilités
Même stack, architecture entièrement différente : chaque choix dicté par le besoin, pas par l'existant.
- Modèle de domaine repensé avec Merise : conforme aux exigences fonctionnelles, relations cohérentes et extensible aux modules V2
- Spring Security intégré : filtre JWT global, tokens avec durée limitée et révocation en base, routes protégées par @PreAuthorize
- Architecture en couches : controller → service → repository → mapper, chaque responsabilité isolée, entités jamais exposées brutes
Stack imposée. Architecture maîtrisée.
Faire fonctionner une app et la construire correctement sont deux objectifs distincts. Du modèle de données au packaging, chaque couche a été pensée avec la même rigueur : le bon outil, au bon endroit, pour la bonne raison.
JPA Specifications — filtrage composable
Filtrer sur étape, domaine et disponibilité à la fois représente des dizaines de combinaisons. Plutôt qu'une méthode par cas, chaque filtre est un bloc autonome assemblé à la volée. Requêtes typées, testables en isolation, sans SQL écrit à la main.
OpenAPI codegen — contrat partagé
Écrire les services HTTP Angular à la main, c'est risquer une désynchronisation à chaque évolution du backend. La spec OpenAPI générée par Spring sert de contrat : ng-openapi-gen en dérive les services TypeScript côté client. Zéro drift, l'API reste la source de vérité.
Modules Angular — chargement à la demande
Sans lazy-loading, tout le code Angular se charge au premier accès, y compris les pages jamais visitées. Quatre modules indépendants (candidats, calendrier, paramètres, API) chargés uniquement à la navigation. Bundle initial réduit, chaque fonctionnalité isolée.
Docker — stack portable en une commande
Sans conteneurisation, reproduire le stack exige une installation locale spécifique. Build multi-stage (JDK → JRE, Node → Nginx), Docker Compose orchestrant Spring Boot, MariaDB et Nginx. Un docker compose up suffit à tout lancer, identique sur n'importe quelle machine.
L'outil à l'œuvre.
L'ingénierie au complet.
Tests
607
Cas de test
281
Tests d'intégration
92 %
Couverture back-end
61 %
Couverture front-end
Chaque endpoint est testé de bout en bout sur base H2 en mode MariaDB : JWT, contrôles d'autorisation, logique métier, persistance. Côté front, Jasmine couvre les composants des trois modules métier. Un pipeline CI qui bloque sur échec, une base de code qu'on peut faire évoluer sans craindre de régressions silencieuses.
CI/CD
Chaque application dispose d'un pipeline GitLab CI dédié : aucun code n'atteint le registry sans avoir démontré un niveau de stabilité suffisant à travers ses tests. Les images Docker produites sont versionnées et publiées directement dans le registry GitLab à chaque run, prêtes à être tirées pour un déploiement ou intégrées dans un environnement plus large. L'ajout d'un stage de déploiement automatique serait la suite naturelle de cette structure.
Documentation
La documentation couvre chaque couche du projet. Compodoc certifie 100% de couverture JSDoc sur les composants, pipes et interfaces Angular. La spec OpenAPI recense 33 endpoints et 25 schémas de données, testables en direct depuis l'UI Swagger. Deux READMEs couvrant architecture, flux JWT et procédures CI. À la livraison : notice d'installation, spécification fonctionnelle et présentation à l'équipe métier.
Avec du recul.
Ce que j'ai appris
Spring Boot & Angular en contexte professionnel
Je m'étais déjà formé seul sur Spring Boot et Angular : cours en ligne, projets personnels. Avec GeReCo, je les ai appliqués pour la première fois en projet professionnel : API intégrée à un client Angular, logique métier complexe, vraies contraintes de qualité. Ce que l'autoformation ne peut pas donner, je l'ai acquis ici : une maîtrise professionnelle de cette stack.
Construire à partir d'un cahier des charges
Dans mes autres expériences professionnelles, j'ai développé, rarement conçu. Sur mes projets personnels, je conçois librement, sans contraintes formelles. GeReCo a combiné les deux : concevoir la solution technique à partir d'un cahier des charges, en tant qu'architecte autant que développeur.
Lead technique, en cours de projet
Pendant la majeure partie du projet, j'ai tout assumé seul : découpage technique, priorisation des fonctionnalités, coordination client. Quand un second développeur a rejoint le dernier mois, c'était le vrai test de la lisibilité du projet. Son intégration a été rapide, la collaboration naturelle.
Ce que je ferais différemment
Layout plein écran
Les maquettes prescrivaient une interface plein écran, sans scroll principal. J'ai suivi ce paradigme sans le remettre en question. En pratique, il a fallu calculer en JavaScript ce que le CSS ne pouvait pas résoudre seul, preuve que la fondation était fragile. J'aurais proposé un layout à scroll naturel dès le départ : une maquette dit le quoi, pas le comment.
JWT en localStorage
Dans GeReCo, j'ai stocké le token JWT en localStorage : l'approche la plus directe, et la plus vulnérable aux attaques XSS. C'est en construisant StrivPath que j'ai mesuré le risque réel et opté pour des httpOnly cookies à la place. Ce choix, je l'aurais fait en premier.