Contact
Moteur de Recherche Européen B2B d'Objets Publicitaires (European Sourcing)

Moteur de Recherche Européen B2B d'Objets Publicitaires (European Sourcing)

Moteur de recherche B2B faisant office de salon en ligne pour les revendeurs d'objets publicitaires en Europe - précurseur des marketplaces actuelles.

2010 - 2016
~6 ans
Software Engineer puis Senior Software Engineer
European Sourcing Group
PHP 5.xSymfony 2/3MySQLElasticsearchAngularJSDoctrine ORMZend FrameworkMemcacheRabbitMQApacheProxmox VE

Lignes de code

~9.2M

PHP, JS, Twig, CSS, HTML

Tables en base

97

MySQL (master-slave)

Sous-applications

15+

Écosystème microservices

Langues supportées

7

FR, EN, DE, ES, IT, NL, PT

Serveurs dédiés

9

OVH Proxmox VE

Connecteurs fournisseurs

26+

Import automatisé de données

Entrees de versioning

1 234

836 Git + 398 SVN

Sites revendeurs

~160

CMS hébergé MyEasyWeb

Présentation et définition du projet

Une quinzaine de sous-applications interconnectées, quatre générations de moteurs de recherche, 8 ans de développement

European Sourcing est un moteur de recherche B2B d'objets publicitaires faisant office de salon professionnel permanent en ligne a l'échelle européenne - un précurseur de ce qu'on appelle aujourd'hui les marketplaces, destiné a tous les revendeurs d'objets publicitaires en Europe. Le projet constitue un écosystème applicatif complet compose d'une quinzaine de sous-applications interconnectées, developpees sur une periode de plus de 6 ans (2010-2017).

La plateforme met en relation trois types d'acteurs du marche de l'objet publicitaire :

  • Les fournisseurs (fabricants/grossistes) qui référencent leurs catalogues produits → B2B
  • Les revendeurs/distributeurs (agences de communication par l'objet) qui recherchent des produits pour leurs clients → B2B
  • Les visiteurs qui consultent le catalogue en ligne sur les sites revendeurs (clients finaux) → B2C

Le système fonctionne comme un salon professionnel permanent en ligne, offrant aux fournisseurs une vitrine multicanal (catalogue en ligne, newsletters, bannieres publicitaires, guidebook annuel, Google Ads) et aux revendeurs un moteur de recherche produits multilingue couvrant 7 langues européennes.

Domaine métier

Communication par l'objet B2B - mise en relation des fournisseurs, revendeurs et agences européens dans l'industrie de l'objet promotionnel.

Utilisateurs cibles

Professionnels B2B a travers l'Europe - agences de communication par l'objet, distributeurs, et exemples de fournisseurs européens intégrés (Midocean, PF Concept, BIC, Paul Stricker, SOL'S, TopTex, Topico, Inspirion, Makito, Xindao, Clipper, Cybernecard, Pixika, Delta, Passot, Lm, Boomerang, Axpol, Goya, GetImpressed, Giving, Lensen Toppoint, Cottel, Eljte, Frezal, Imbretex).

Périmètre fonctionnel
Catalogue produits multilingue (7 langues)
Recherche full-text (Elasticsearch)
Back-office fournisseurs/revendeurs
Import automatisé de données fournisseurs (26+ connecteurs)
API REST avec authentification WSSE
Système de traduction centralisé
Paiement en ligne (Sogenactif)
CMS mini-sites revendeurs (MyEasyWeb)
Applications mobiles (PhoneGap/Cordova)
Statistiques de consultation (vues, recherches, clics)
Export de données (CSV + images produits)
Back-office SEO / Marketing

Objectifs, contexte, enjeux et risques

Digitaliser le marche européen de l'objet publicitaire

Objectifs
  • Positionner la plateforme comme la référence européenne du sourcing B2B d'objets publicitaires en ligne, en remplacement des catalogues papier et salons physiques
  • Proposer un catalogue produits multilingue agregeant plusieurs millions de produits et variantes provenant de dizaines de fournisseurs
  • Fournir aux revendeurs un moteur de recherche avance avec filtres par categorie, marque, prix, attributs, marquage
  • Automatiser l'import des flux de données fournisseurs (prix, stocks, docs, descriptions) de 26+ fournisseurs
  • Offrir aux revendeurs une solution clé en main de mini-sites e-commerce (MyEasyWeb) avec leur propre vitrine brandée connectée au catalogue central
  • Générer des statistiques de consultation détaillées pour les fournisseurs (vues produits, recherches, clics)
Contexte

Le projet initial (v1/v2) a été développé par SQLI, une ESN française, avec un framework PHP custom et des templates Smarty. Le code legacy contenait 398 revisions SVN couvrant la periode 2010-2013.

A mon arrivée chez SQLI, 5 développeurs PHP étaient dédiés à plein temps au projet. Au fil du temps, j'ai pris en charge une part croissante du périmètre technique, jusqu'à assurer seul l'essentiel des évolutions - un rôle qui a naturellement évolué avec mon expertise grandissante et l'autonomie que me conférait l'environnement PME. Après avoir couvert seul le périmètre pendant un certain temps, j'ai demandé du renfort et obtenu l'embauche d'un second développeur.

A partir de 2014-2016, notre nouvelle équipe Medialeads a entrepris une réécriture complète de la plateforme, migrant progressivement du framework custom vers Symfony 2/3 tout en maintenant le site public sur un framework MVC custom plus leger.

La plateforme était multilingue (7 langues), multi-pays, avec une forte volumetrie de données produits, et la nécessite de maintenir la compatibilité avec les flux de données fournisseurs existants - le tout hébergé sur des serveurs dédiés OVH entièrement autogérés : nous faisions absolument tout nous-mêmes, de la configuration système aux déploiements.

Enjeux

Modèle economique

Revenus des abonnements fournisseurs (240-288 EUR/an) et des services publicitaires (bannieres, newsletters, guidebook, Google Ads, mediaplanning).

Position stratégique

European Sourcing se positionnait comme la référence du sourcing d'objets publicitaires en ligne en Europe - un précurseur des marketplaces B2B actuelles, remplaçant les catalogues papier et salons physiques traditionnels.

Écosystème de marques

La société opérait egalement TendanceObjet.com, Kadobjet.fr, FranceObjet.com, Omyague.com, GourmetOnline.pro, Recherche-Publicitaire.com, GraphicSourcing.com, CPrint-Sourcing.com, WineSpiritSourcing.com, Tradexpo-Online.fr - chaque marque ciblant un segment spécifique du marche.

Risques identifiés

Dette technique

Migration progressive d'un framework custom vers Symfony, coexistence de deux architectures (SVN legacy + Git moderne), hachage MD5 des mots de passe avec une seule iteration et sans salt - cohérent avec l'état de l'art PHP de la décennie 2008-2014, avant que bcrypt ne devienne le standard par défaut.

Complexité d'intégration

Les flux de données fournisseurs étaient hétérogènes (CSV, XML, API), nécessitant un adaptateur spécifique par fournisseur, tous maintenus dans flux.europeansourcing.com.

Dépendance a l'infrastructure

9 serveurs dédiés OVH avec virtualisation Proxmox, replication MySQL master/slave, déploiements manuels via svn up - reflet des contraintes techniques de l'époque, avant la démocratisation de Docker et des pipelines CI/CD modernes.

Bus factor

Seulement 3 développeurs principaux pour l'ensemble de l'écosystème de 38 sous-projets et 9 serveurs.

Les étapes - Ce que j'ai fait

Du monolithe SQLI a l'architecture microservices distribuee

Phase 1
Développement SQLI et legacy SVN (2008-2013)
2008 - 2013
  • J'ai géré le code legacy hérité de SQLI - un monolithe PHP avec templates Smarty, sous versioning SVN (398 révisions)
  • Côté extranet fournisseurs et revendeurs, j'assurais à la fois la maintenance et les extensions fonctionnelles (CRUD produits, gestion d'images, prix, attributs, marquages)
  • En parallèle, je pilotais les opérations de déploiement sur serveurs dédiés et coordonnais le travail avec la documentation SQLI (47+ documents de spécifications)
  • Pour résoudre les problèmes de qualité (catégories parentes manquantes, couleurs incorrectes, images cassées), j'ai développé des scripts de correction de données dédiés
Phase 2
Reprise interne et microservices (2014-2016)
Jan 2016 - Dec 2016
  • J'ai piloté la migration de SVN vers GitHub - 13 dépôts créés en janvier 2016, organisation medialeads avec 8 membres et 20+ repos privés
  • Côté extranet, je me suis chargé de la réécriture complète (177 commits) sur un framework PHP MVC custom avec accès direct à la base MySQL
  • Sur la partie back-end, j'ai développé l'API REST (api.europeansourcing.com) en Symfony 2.4 avec Propel ORM et authentification WSSE
  • Pour automatiser l'import des données fournisseurs (flux.europeansourcing.com), j'ai construit des connecteurs dédiés à Pixika, Makito, Midocean, BIC, Paul Stricker, TopTex et Cybernecard
  • Du côté de la recherche full-text, je suis passé à Elasticsearch avec des index multilingues dédiés
  • En parallèle, j'ai mis en place le système de traduction centralisé (translate.europeansourcing.com) en Symfony 3.0
Phase 3
Modernisation architecturale (2016-2017)
Mar 2016 - Nov 2016
  • J'ai initié la réécriture architecturale autour de bundles Symfony partagés (ESCoreBundle : 143 commits, ESSourcingBundle : 15 commits)
  • Côté modélisation, j'ai conçu les comportements Doctrine : Sluggable, Sortable, Timestampable, Translatable, Blameable, Toggleable, Visible, Overloadable, Tree
  • Pour absorber les pics de charge, je me suis appuyé sur RabbitMQ afin d'introduire un traitement asynchrone pour l'import de données et les calculs de visibilité
  • Sur le volet infrastructure, j'ai mis en place le provisioning avec Chef pour le projet extranet_rebirth
Project Timeline
European Sourcing - 2008-2017
Supplier Data Import Flow

Les acteurs - Les interactions

Comment j'ai collaboré au sein d'une équipe réduite mais hautement productive

Équipe de développement

Selon les périodes, j'ai travaillé avec 3 à 5 développeurs actifs, dans une répartition claire des responsabilités :

José DA COSTA

Mon rôle - lead développeur. J'ai produit 35,3 % du versioning total (225 Git + 116 SVN), avec une empreinte dominante sur l'extranet (177 commits), flux (15) et la gestion du legacy SVN.

Thomas C.

Développeur senior avec qui j'ai travaillé au quotidien - 36,9 % (355 Git + 1 SVN). Dominant sur ESCoreBundle (113), translate (88), supplierbo (19).

wamania

Développeur avec qui j'ai partagé le code de la plateforme - 24,2 % (226 Git + 8 SVN). Dominant sur europeansourcing.com (166 commits), extranet (49).

IronXtreme

Développeur en renfort ponctuel sur ESCoreBundle - 3,0 % (29 commits Git), que j'ai croisé sur ce périmètre.

Contribution Distribution (Git + SVN)
Parties prenantes externes avec qui j'ai interagi

SQLI

J'ai repris et exploité les livrables de cette ESN qui avait développé la v1/v2/v3 (spécifications, développement initial)

Dolead

Côté acquisition payante, j'ai collaboré avec cette agence pour la gestion Google AdWords

Universem

Sur le SEO, je me suis appuyé sur cette agence pour les audits TendanceObjet et Kadobjet

OVH

Pour l'hébergement, je pilotais au quotidien leurs 9 serveurs dédiés

Les résultats

Impact mesurable pour l'entreprise et pour ma carriere

Pour moi
  • Gestion massive de données et optimisation SQL : j'ai affûté ma maîtrise des formes normales SQL (1NF, 2NF, 3NF, BCNF), de tous les types de jointures (INNER/LEFT/RIGHT/CROSS/SELF) et de l'indexation avancée (index B-tree, composites, covering), avec une analyse constante des plans d'exécution via `EXPLAIN ANALYZE`, en m'appuyant sur la réplication MySQL master-slave et le cache Memcache. Je faisais tourner des batchs nocturnes de plusieurs heures pour recalculer stocks, prix et promotions sur l'ensemble du catalogue - à cette échelle, un index manquant pouvait transformer une requête de 50 ms en timeout de 30 secondes, donc chaque milliseconde gagnée par requête se multipliait sur des millions d'exécutions.
  • Moteurs de recherche et indexation : je suis passé par quatre générations de moteurs - (1) MySQL LIKE / FULLTEXT (MyISAM/InnoDB), (2) recherche full-text PostgreSQL avec `tsvector`/`tsquery`, index GIN et fonctions `to_tsvector`/`ts_rank`, (3) Apache Solr, où j'ai indexé des centaines de milliers de produits avec facettage avancé (catégories, couleurs, prix, fournisseurs), suggestions, correction orthographique et scoring de pertinence personnalisé, (4) Elasticsearch avec inverted index, analyzers multilingues (stemming, tokenization, normalisation), scoring TF-IDF, agrégations et facettes. Ce parcours m'a permis de saisir en profondeur les différences entre un moteur relationnel et un moteur de recherche dédié.
  • Algorithmes et règles métier complexes : j'ai conçu et implémenté de nombreux algorithmes et des règles métier très complexes - par exemple le calcul de toutes les combinaisons possibles de prix, de variantes produit et de disponibilité (produit cartésien / explosion combinatoire pouvant générer des milliers de combinaisons par produit entre tailles, coloris, quantités, types de marquage, zones de marquage et finitions). La modélisation de règles de pricing dynamiques et de moteurs de décision métier fait désormais partie de ma boîte à outils.
  • J'ai consolidé ma maîtrise de l'écosystème Symfony 2/3 en production à grande échelle (Propel, Doctrine, bundles, services, sécurité, WSSE).
  • Côté migration de code legacy, je me suis forgé des compétences solides en pilotant la transition du monolithe SVN vers les microservices Git sans interruption de service.
  • Sur le plan métier, j'ai acquis une connaissance fine du marché B2B de l'objet publicitaire, de l'automatisation des flux de données et de l'e-commerce multi-pays.
  • Enfin, ce projet a changé ma façon de travailler : j'ai appris à me coordonner dans une petite équipe où chaque développeur possède des portions significatives du code, et à porter des périmètres de bout en bout.
Pour l'entreprise

Couverture fonctionnelle

Cycle complet du sourcing B2B pris en charge par un seul écosystème - du dépôt catalogue fournisseur à la vitrine revendeur, sans rupture manuelle entre les services

Volume de catalogue

Indexation de la plus grande base de données européenne d'objets publicitaires - plusieurs millions de produits et variantes agrégés depuis 26+ flux fournisseurs, stockés dans 97 tables MySQL avec réplication master-slave

Portee multilingue

7 langues européennes avec des index Elasticsearch dédiés et une gestion centralisée des traductions

Couverture géographique

Sous-domaines localisés couvrant les principaux marchés européens : UK, Ibérique, Italie, Allemagne, plus un vertical Textile dédié

Échelle d'automatisation

26+ connecteurs automatisés de données fournisseurs gérant des formats hétérogènes (CSV, XML, API) de grandes marques européennes

Réseau revendeurs

~160 mini-sites revendeurs hébergés sur la plateforme CMS MyEasyWeb

Écosystème de marques

11+ marques operees : europeansourcing.com, tendanceobjet.com, kadobjet.fr, franceobjet.com, omyague.com, gourmetonline.pro, recherche-publicitaire.com, graphicsourcing.com, cprint-sourcing.com, winespiritsourcing.com, tradexpo-online.fr

Fonctionnalites clés livrées

Catalogue produits multilingue avec index Elasticsearch dédiés et scoring de pertinence personnalisé
API REST avec authentification WSSE stateless (nonce + timestamp + digest)
Connecteurs d'import automatisé gérant des flux hétérogènes CSV / XML / API
Back-office fournisseurs/revendeurs avec gestion complète des produits
Dashboard fournisseurs SPA (AngularJS 1.2 + CoffeeScript + Grunt + Bower)
CMS mini-sites revendeurs (MyEasyWeb) avec vitrines brandées connectées au catalogue central
Intégration paiement en ligne (Sogenactif, Société Générale)
Back-office SEO / marketing (Zend Framework + ExtJS + crawler web)
Applications mobiles hybrides (jQuery Mobile + PhoneGap/Cordova)
Microservices Ecosystem
Technology Distribution
Échelle du code
7 514Fichiers PHP
4 505Fichiers JS
909Controllers
2 222Vues / templates
87Cron jobs
1 506Fichiers i18n
611Fichiers de test

Les lendemains du projet

Ce qui s'est passe après mon départ du projet

J'ai quitté le projet en novembre 2016, en laissant une plateforme en ordre de marche. L'équipe a continué d'exploiter et de faire évoluer European Sourcing - le projet n'a pas été interrompu, il a simplement continué sans moi. La phase finale de consolidation autour de bundles Symfony partagés, que j'avais initiée, a été menée à terme par l'équipe.

Avec le recul, les choix architecturaux de la Phase 2 se sont révélés pertinents et modernes pour leur époque : l'approche orientée services avec sous-domaines dédiés, l'authentification WSSE stateless inter-services, l'architecture du moteur de recherche et l'infrastructure de connecteurs fournisseurs automatisés sont restés techniquement impressionnants bien après mon départ.

Mon regard critique

Comment je juge ce projet, avec le recul de 8 années de développement

Points forts
  • Architecture microservices bien pensée

    Avec le recul, je considère que l'éclatement du monolithe SQLI en services spécialisés (API, recherche, flux, traduction, export, statistiques) témoigne d'une vision architecturale solide. Chaque service que nous avons découpé a une responsabilité claire et un périmètre fonctionnel bien délimité.

  • Périmètre produit rare sur le marché

    À l'époque, très peu de concurrents proposaient l'ensemble du cycle de sourcing B2B dans un seul écosystème. Je reste convaincu que ce niveau d'intégration, que nous avons poussé loin, est ce qui a positionné European Sourcing en tête du marché européen.

  • Internationalisation native

    Je revendique le choix des index Elasticsearch dédiés par langue et du système de traduction centralisé : nous avons pensé l'ambition européenne dès le départ, plutôt que de l'ajouter après coup.

  • Automatisation des imports fournisseurs

    Avec le temps, je mesure la valeur des connecteurs que j'ai bâtis pour gérer des formats hétérogènes (CSV, XML, API) - un investissement technique considérable et une valeur métier fondamentale qui ont constitué un vrai fossé concurrentiel.

Points d'amélioration
  • Déploiement pré-CI/CD

    Je ne déployais qu'en manuel via svn up, sans pipeline d'intégration continue ni tests automatisés. C'était cohérent avec les pratiques de l'écosystème PHP de la décennie 2008-2014 (GitHub Actions n'existait pas, l'outillage CI/CD Jenkins ou Travis CI balbutiait), mais je l'identifie clairement comme une limite aujourd'hui.

  • Versioning pré-SemVer

    Je n'ai posé aucun tag Git sur les 13 dépôts - reflet de l'époque, avant l'adoption massive de SemVer dans l'écosystème PHP et la généralisation de GitHub Releases. Avec le recul, je le regrette.

  • Écosystème multi-frameworks

    J'ai dû composer avec la coexistence de plusieurs frameworks (PHP custom, Symfony 2.4, 2.8, 3.0, 3.1, Zend Framework 1) et 2 ORM (Propel, Doctrine) - conséquence d'une migration progressive étalée sur plusieurs années, cohérente avec l'évolution de l'écosystème PHP entre 2010 et 2016, mais lourde à maintenir.

Ce que j'aurais fait différemment

Avec les standards et le recul d'aujourd'hui, voici les choix que je referais différemment - chaque décision avait du sens dans les contraintes de son époque :

  • Adopter un framework unique dès le départ plutôt que de maintenir un framework PHP custom en parallèle de Symfony, même si le contexte historique justifiait cette coexistence pendant la migration.
  • Mettre en place une CI/CD dès la migration vers GitHub (janvier 2016) - GitHub Actions n'existait pas encore, mais Jenkins, Travis CI ou GitLab CI étaient disponibles.
  • Utiliser Docker pour les environnements dev et déploiement, même si Proxmox restait le standard de virtualisation mature pour les PME PHP à l'époque.
  • Centraliser l'accès aux données via une seule API plutôt que de connecter chaque service directement à la base MySQL - un pattern qui ne s'est généralisé qu'après 2017.
Les enseignements durables que ce projet m'a apportés

La migration d'un legacy est un marathon

La transition du monolithe SQLI vers une architecture microservices m'a pris plus de 3 ans et restait en cours quand j'ai quitté le projet. J'en tire la conviction qu'il faut planifier des jalons réalistes et accepter des compromis temporaires.

L'automatisation des imports de données est critique

Je mesure à quel point les connecteurs fournisseurs que j'ai bâtis représentent une valeur métier considérable mais aussi une dette de maintenance permanente - chaque fournisseur peut changer son format à tout moment, et chaque rupture se transforme en incident de production.

L'internationalisation doit être pensée dès le début

J'ai vécu combien le système de traduction centralisé est un excellent pattern. Ajouter le multilingue après coup m'aurait coûté exponentiellement plus cher que de le concevoir dès le départ.

La documentation SSII est précieuse

Des années après la fin de la prestation, je pouvais encore m'appuyer sur les spécifications SQLI pour comprendre l'architecture. J'en retiens qu'investir dans la documentation technique a un ROI long terme.

Architecture technique

Architectural Évolution - Monolith to Microservices

Parcours associé

Expérience professionnelle liée à cette réalisation

Compétences mobilisées

Compétences techniques et humaines appliquées

Galerie d'images

Captures et visuels du projet

Vous avez un portail B2B multilingue a concevoir ?

J'ai livre le portail European Sourcing de bout en bout : modelisation produit multilingue, catalogue de sourcing et workflows acheteurs. Parlons de votre contexte.

Contactez-moi