---
title: "PIM Extranet for B2B Promotional Products Search Engine (European Sourcing)"
description: "Complete back-office for managing the largest European online trade show for promotional products - 229K lines of application code, 38 data models, 7 languages, 15 GB database."
locale: "en"
canonical: "https://portfolio.josedacosta.net/en/achievements/extranet-pim-b2b-objets-publicitaires"
source: "https://portfolio.josedacosta.net/en/achievements/extranet-pim-b2b-objets-publicitaires.md"
html_source: "https://portfolio.josedacosta.net/en/achievements/extranet-pim-b2b-objets-publicitaires"
author: "José DA COSTA"
date: "2014"
type: "achievement"
slug: "extranet-pim-b2b-objets-publicitaires"
tags: ["PHP 5.x", "Symfony 3.1", "MySQL", "PostgreSQL", "Doctrine ORM", "RabbitMQ", "AngularJS", "Node.js", "jQuery", "Bootstrap 3", "Vagrant", "Chef"]
generated_at: "2026-06-02T15:38:05.941Z"
---

# PIM Extranet for B2B Promotional Products Search Engine (European Sourcing)

Complete back-office for managing the largest European online trade show for promotional products - 229K lines of application code, 38 data models, 7 languages, 15 GB database.

**Date:** 2011 - 2016  
**Duration:** ~6 years  
**Role:** Software Engineer then Senior Software Engineer  
**Technologies:** PHP 5.x, Symfony 3.1, MySQL, PostgreSQL, Doctrine ORM, RabbitMQ, AngularJS, Node.js, jQuery, Bootstrap 3, Vagrant, Chef

### Key Metrics

- Lines of Code: **-** - Application code (PHP, JS)
- Merge Requests: **-** - 4 active contributors
- Database: **-**
- Languages: **-** - FR, EN, DE, ES, IT, NL, PT

## Presentation

_Project definition and scope_

### Domain

B2B promotional products - European online trade show connecting suppliers, resellers, and brands

### Target Users

Internal team (sales, catalog managers, administrators) + 800+ European suppliers (via Supplier BO) + 50+ resellers (via MyEasyWeb)

The **Extranet European Sourcing** is the central back-office of the European Sourcing platform, the largest European online trade show dedicated to promotional and advertising products. This internal administration tool enables the European Sourcing team - operating under the name **Medialeads**, the **IT development and IT consulting division of European Sourcing** - to manage the entire product catalog, suppliers, resellers, advertising services, and platform statistics.

Originally designed by **SQLI consulting (Phase 1, 2008-2013)** with extensive functional and technical specifications - reflecting the state-of-the-art consulting practices of the time - the project was **taken over by the internal team in 2014** to bring development closer to the business and increase iteration velocity. From there, the project went through **two major versions**: **Extranet v1**, a custom PHP MVC application with MySQL, used in production for several years; and **Extranet v2 "Rebirth"**, a complete rewrite under **Symfony 3.1** with **PostgreSQL** and **RabbitMQ**, initiated on **March 14, 2016**, aimed at modernizing the architecture and centralizing shared business bundles.

A third associated component, the **Supplier Back-Office**, is an **AngularJS/Node.js** single-page application offering suppliers a dedicated space to manage their profile, products, statistics, and contracts.

### Functional Scope

### Product Catalog Management

### Supplier & CRM Management

### Reseller & MyEasyWeb Sites

### Advertising Services

### CSV Import/Export (6 steps)

### Statistics & Reporting

### Multilingual Management (7 languages)

### Contracts & Subscriptions

## Objectives, Context, Stakes & Risks

_Strategic vision and constraints_

### Context

The project operates within a complex software ecosystem of **15+ interconnected sub-projects** (sourcing front, export, flux/auto-update, API, translation, statistics, MyEasyWeb, etc.). The shared MySQL database weighs approximately **15 GB** (uncompressed) across **97 tables** and is accessed by all applications.

Infrastructure is hosted on **OVH dedicated servers** (sql1, sql2 for MySQL, dedicated web servers). Versioning migrated from **SVN** to **GitHub** (medialeads organization) **in January 2016**. Development environments are provisioned via **Vagrant + Chef** with 25+ cookbooks.

### Massive Catalog

Millions of products with their variations across 7 languages, **32+ fields per product/variant**, **36 fields per marking option**, **up to 50+ degressive pricing grids per product**, **32 currencies** (ECB rates). Some suppliers like **SOL's** maintained up to **15,000 variations for a single product** (e.g. a T-shirt declined by size, color, V-neck or round neck, with or without sleeves, finishings, etc.). A PIM/data model complexity that was the state of the art at the time for this kind of B2B catalog - a level of modeling that off-the-shelf PIM solutions only started to approach years later.

### B2B Relationships

Tracking supplier subscriptions, contracts, advertising service orders generating the platform revenue

### Multi-Site Ecosystem

Extranet data feeds europeansourcing.com, tendanceobjet.com, export site, 50+ MyEasyWeb reseller sites

### v1 to v2 Migration Complexity

Complete rewrite of a production tool used daily, with risk of functional regression and prolonged coexistence of both versions.

### Monolithic Database

A single shared MySQL database between 15+ sub-projects - an architecture pattern aligned with the practices of the late 2000s, which became a structural challenge as the platform grew.

### v1 Technical Debt

Custom MVC framework reflecting the state-of-the-art PHP practices of the 2008-2010 period (before Symfony 2 and modern ORMs became mainstream) - increasingly demanding to evolve as the ecosystem grew.

### Objectives

- Provide a unified administration tool to manage a catalog of hundreds of thousands of products from hundreds of European suppliers
- Rewrite the extranet with a modern framework (Symfony 3) to improve maintainability, testability, and code reusability via shared bundles
- Migrate from MySQL to PostgreSQL and introduce asynchronous messaging with RabbitMQ
- Offer suppliers an autonomous modern interface (AngularJS SPA) to manage their presence on the platform

### Business Stakes

### Identified Risks

## The Steps - What I Did

_Chronological phases and personal contributions_

### Project Timeline

### Phase 1 - Extranet v1 (2011 - 2016)

- I developed the original extranet on a custom PHP MVC framework
- On the data ingestion side, I built a 6-step CSV import system: upload, column mapping, validation, preview, insertion, history with rollback
- To feed the catalog continuously, I built and maintained **37 distinct automated supplier import connectors** (FTP, HTTP, REST APIs - including Pixika, Makito, Midocean, BIC, Paul Stricker, Clipper, TopTex, Cybernecard, etc.)
- On the catalog side, I implemented the full product management: attributes, variants, markings, multi-language translations
- For the CRM, I created supplier management, reseller management and MyEasyWeb site creation and backup
- On the advertising side, I developed the services: banners, AdWords campaigns, homepage sliders, partner management
- To enable steering, I built a comprehensive statistics module: by supplier, product, reseller, MyEasyWeb, advertisements

### Phase 2 - Rebirth (Symfony 3) (2016 - 2019)

- I took part in the Symfony 3.1 rewrite (initiated March 14, 2016) with PostgreSQL, Doctrine ORM and RabbitMQ for async messaging
- On the mutualization side, I worked on the shared business bundles: ESCoreBundle (entities, auth, file system) and ESSourcingBundle (business logic)
- To industrialize the admin screens, I implemented a generic list system (EntityList) with configurable columns, bulk actions, row actions and pagination
- On the forms side, I developed 70+ Symfony Form Types covering products, variants, product images, markings (static/dynamic with profiles), attributes (simple/multi/groups), categories, keywords, labels with synonyms, subscriptions and import/export workflows
- To secure the rewrite, I built a full PHPUnit test suite with 611 test files validating entities, controllers and business logic
- On the DevOps side, I set up Vagrant + Chef provisioning with 25+ cookbooks for reproducible development environments

### Phase 3 - Supplier Back-Office (2014 - 2016)

- I built the supplier self-service SPA with AngularJS and CoffeeScript (19,007 lines)
- On the functional side, I implemented the modules: Dashboard, Profile, Contacts, Products, News, Statistics, Contracts
- On the i18n side, I shipped a multilingual interface supporting 7 languages (FR, EN, DE, ES, IT, NL, PT)
- To plug the SPA into the ecosystem, I integrated it with the European Sourcing REST API for all supplier operations

## The Actors - Interactions

_Who I interacted with directly and how I collaborated_

### Contribution Distribution - Application Code (229,090 lines)

**Development team - my day-to-day teammates (4 active developers)**
Inside this tight-knit team, I contributed **629 merge requests** and **117,916 lines of application code** - I was the primary author of v1 and the Supplier BO. Alongside me, Thomas C. took the lead on the v2 Rebirth; IronXtreme brought targeted reinforcement on the v2 Rebirth, and Wamania focused on refactoring and corrections.

**External stakeholders I interacted with**
- **SQLI**: External consulting firm (Phase 1, 2008-2013) where I authored 47+ detailed specification documents for the extranet supplier module (ESV3) - covering functional specs, technical specs, exploitation and installation guides, data model and requirements traceability
- **Systonic**: Former hosting provider (2009-2010); I then helped drive the migration of the entire infrastructure to OVH
- **OVH**: Primary provider of dedicated servers - we handled all sysadmin operations ourselves (provisioning, configuration, security hardening, monitoring, backups), and I took an active share in that work
- **Suppliers**: Hundreds of European promotional product companies, B2B clients for whom I was the technical contact through the extranet
- **Resellers**: 50+ distributors using MyEasyWeb sites that I fed from the extranet

## Results

_Impact for me and for the organization_

### Results for Me: Professional Growth

This project was a foundational experience in my career as a software engineer. Over **nearly 5 years of involvement**, I developed **deep expertise across the full stack**: **backend PHP development** (custom framework then Symfony), **relational databases** (MySQL and PostgreSQL), **frontend SPA development** (AngularJS) and **DevOps practices** (server administration, Vagrant/Chef provisioning, Git workflow).

**An XXL-scale project, exceptional in every dimension**: the Extranet was the orchestration brain of an entire ecosystem - **9.1M total lines of code**, **7,510+ PHP files**, **4,510+ JavaScript files**, **910+ controllers**, **2,220+ views/templates**, and a search engine indexing **22,000+ words** derived from this Extranet. This project changed the way I work: I learned to think about **performance, scalability and data integrity** at a level impossible to reach on smaller projects, confronted daily with **data manipulation**, **data architecture**, **business rule complexity**, **infrastructure and server administration** and **large-scale data backup strategies**.

**Search engines and indexing**: I progressively moved from native database indexing (MySQL full-text MyISAM/InnoDB, then PostgreSQL full-text search with `tsvector`/`tsquery`, GIN indexes and `to_tsvector`/`ts_rank` functions) to a true search engine with **Elasticsearch** - inverted index, multilingual analyzers (stemming, tokenization, normalization), TF-IDF scoring, aggregations, facets. Going through every step let me grasp in depth the differences between a relational engine and a search engine.

**Complex algorithms and business rules**: I designed and implemented many algorithms and very complex business rules - for example the calculation of all possible combinations of prices, product variants and availability (**Cartesian product / combinatorial explosion** that can generate **thousands of combinations per product** across sizes, colors, quantities, marking types, marking zones and finishes). **Dynamic pricing rule modeling** and **business decision engines** are now part of my toolbox.

### Results for the Organization: Business Impact

The extranet was the **operational heart** of European Sourcing. Without this tool, it would have been impossible to manage the catalog of hundreds of thousands of products, supplier relationships, and advertising services that generated the platform's revenue.

- **Catalog Management**: Hundreds of thousands of products managed across 7 languages with attributes, variants, markings, and pricing
- **Multilingual Search**: **7 dedicated Elasticsearch indexes** (one per language) powering full-text product search across the platform
- **Supplier Network**: **800+ European suppliers** managed with subscriptions, contracts, and dedicated self-service portal
- **Multi-Site Distribution**: Data feeding europeansourcing.com, tendanceobjet.com, export site, graphicsourcing, 50+ MyEasyWeb reseller sites
- **Revenue Generation**: Advertising services (banners, AdWords, sliders, partner placements) managed entirely through the extranet
- **Operational Efficiency**: Internal team of 5-10 people managing the entire European promotional products market through a single unified tool

### Technical Metrics

## The Aftermath

_What happened after the project_

**Immediate Post-Delivery**
The v1 and v2 coexisted in production for several years, with the v1 continuing to handle daily operations while the v2 Rebirth was being developed module by module. **The v2 is still in production today**, powering the European Sourcing platform.

**Career Impact**
This experience at European Sourcing - within Medialeads, its IT development and IT consulting division - **was instrumental in shaping my approach to large-scale web development**. The lessons learned about **managing complex data models**, **building multi-tenant architectures**, and **working with massive datasets** directly informed my subsequent work on even more ambitious projects.

## Critical Reflection

_With hindsight, how I judge this project_

### What worked well

- **Extremely rich functional scope**: with hindsight, I measure how thoroughly the extranet covers every administration need of a complex B2B platform - catalog, suppliers, resellers, advertising, statistics, import/export, multilingual
- **Modular architecture (v2)**: I stand behind the decision to create shared bundles (ESCoreBundle, ESSourcingBundle) to mutualize code between sub-projects - a choice that held up over time
- **Courageous technology migration**: moving from a custom framework to Symfony 3 and from MySQL to PostgreSQL took guts, and I would do it again
- **Automated provisioning**: by pushing Vagrant + Chef on v2, I secured reproducible development environments

### What I would do differently

- **Implement CI/CD from the beginning**: I would have set up a pipeline with Travis CI or Jenkins from day one (GitHub Actions didn't exist yet) and it would have caught regressions earlier
- **Separate the database**: I would have split the monolithic database into microservices or at least distinct schemas to reduce the strong coupling between 15+ sub-projects
- **Adopt Docker instead of Vagrant + Chef**: I would have switched to Docker earlier for lighter and more portable provisioning

### The lasting lessons this project brought me

- **Shared bundles are a long-term investment**: I saw how mutualizing business code between sub-projects reduces duplication but creates strong dependencies and demands solid version management
- **Data import is a full engineering problem**: after shipping the 6-step CSV import system with validation, preview and history, I now treat mass data management as a first-class engineering concern
- **Documenting architecture is essential**: I experienced that when the number of sub-projects and developers grows, documentation becomes critical - I now apply this systematically

## Skills applied

_Technical and soft skills applied_

- **[Problem Solving & Adaptability](https://portfolio.josedacosta.net/en/skills/problem-solving-adaptability.md)** - Modelled complex business rules (dynamic pricing, marking variants, multi-currency) - some suppliers reaching 15,000 variations per product. Picked up the project from SQLI in 2014, then drove the rewrite from custom MVC to Symfony 3.1 + PostgreSQL + RabbitMQ
- **[Software & System Architecture](https://portfolio.josedacosta.net/en/skills/system-architecture-design.md)** - PIM/data model bigger than Akeneo: 32+ fields per variant, 36 per marking option, 50+ pricing grids, 97 MySQL tables on 15 GB. European Sourcing REST API consumed by the Supplier BO SPA and downstream services across 7 languages. Shared Symfony bundles (ESCoreBundle, ESSourcingBundle), 70+ Form Types, generic EntityList system, MVC + SPA + ETL
- **[Fullstack Development](https://portfolio.josedacosta.net/en/skills/fullstack-development.md)** - PHP custom MVC then Symfony 3.1, Doctrine ORM, RabbitMQ async messaging, MySQL then PostgreSQL over 5+ years. Owned 229K lines across the Extranet v1, v2 Rebirth and Supplier BO (AngularJS SPA), front-to-back ownership
- **[DevOps, Cloud & Production Industrialization](https://portfolio.josedacosta.net/en/skills/devops-cloud-production.md)** - PHPUnit test suite with 611 test files validating entities, controllers and business logic on the v2 Rebirth. OVH dedicated servers self-administered: Vagrant + Chef provisioning, 25+ cookbooks, Apache, security, monitoring, backups
- **[Data, AI & Machine Learning](https://portfolio.josedacosta.net/en/skills/data-ai-machine-learning.md)** - MySQL then PostgreSQL with Doctrine, 6-step CSV import pipeline, 37 supplier connectors via FTP/HTTP/REST
- **[Reverse Engineering & Algorithms](https://portfolio.josedacosta.net/en/skills/reverse-engineering-algorithms.md)** - Cartesian-product pricing engine: thousands of combinations per product (sizes × colors × markings × zones × finishings)

## Related journey

_Professional experience linked to this achievement_

- **Software Engineer · PHP Zend Framework Developer**

## Image gallery

_Project screenshots and visuals_

## Need a partner extranet designed?

I delivered the European Sourcing extranet: fine-grained partner access management, contract document space and order tracking. Let's talk about your context.

**Contact me**
