---
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.info/en/achievements/extranet-pim-b2b-objets-publicitaires"
source: "https://portfolio.josedacosta.info/en/achievements/extranet-pim-b2b-objets-publicitaires.md"
html_source: "https://portfolio.josedacosta.info/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-04-23T15:47:48.376Z"
---

# 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)

**Content:** 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.

**Domain:** Domain

**Target Users:** Target Users

**Functional Scope:** Functional Scope

**Scope Catalog:** Product Catalog Management

**Scope Suppliers:** Supplier & CRM Management

**Scope Resellers:** Reseller & MyEasyWeb Sites

**Scope Advertising:** Advertising Services

**Scope Import:** CSV Import/Export (6 steps)

**Scope Stats:** Statistics & Reporting

**Scope Multilingual:** Multilingual Management (7 languages)

**Scope Contracts:** 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.

### Stake 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.

### Stake Relations

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

### Stake Multi Site

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

- 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

**Objectives:** Objectives

**Context:** Context

**Stakes:** Business Stakes

**Stake Catalog:** Massive Catalog

**Stake Relations:** B2B Relationships

**Stake Multi Site:** Multi-Site Ecosystem

**Risks:** Identified Risks

**Risk1 Title:** v1 to v2 Migration Complexity

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

**Risk2 Title:** Monolithic Database

**Risk2 Desc:** 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.

**Risk3 Title:** v1 Technical Debt

**Risk3 Desc:** 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.

## The Steps - What I Did

_Chronological phases and personal contributions_

- Phase 1 - Extranet v1
- Phase 2 - Rebirth (Symfony 3)
- Phase 3 - Supplier Back-Office

**Phase1 Period:** 2011 - 2016

**Phase2 Period:** 2016 - 2019

**Phase3 Period:** 2014 - 2016

## The Actors - Interactions

_Team and stakeholders_

**Content:** **Development Team (4 active developers)**
The core team consisted of 4 developers with distinct areas of expertise. I contributed **629 merge requests** and **117,916 lines of application code**, being the primary author of v1 and the Supplier BO. Thomas C. served as lead developer on the v2 Rebirth. IronXtreme contributed to the v2 Rebirth, and Wamania focused on refactoring and corrections.

**External Stakeholders**
- **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), before we migrated the entire infrastructure to OVH
- **OVH**: Primary provider of dedicated servers - we handled all sysadmin operations ourselves (provisioning, configuration, security hardening, monitoring, backups)
- **Suppliers**: Hundreds of European promotional product companies - the B2B clients
- **Resellers**: 50+ distributors using MyEasyWeb sites powered by the extranet data

## Results

_Impact for me and for the organization_

### For Me

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 made the project extremely formative on **data manipulation**, **data architecture**, **complexity of business rules**, **infrastructure and server administration**, and **large-scale data backup strategies** - taught me to think about **performance, scalability, and data integrity** at a level impossible to reach on smaller projects.

**Search engines and indexing**: progressive transition 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. Learning the deep differences between a relational engine and a search engine.

**Complex algorithms and business rules**: design and implementation of 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). Mastery of **dynamic pricing rule modeling** and **business decision engines**.

### For Company

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

**For Me:** Results for Me: Professional Growth

**For Company:** Results for the Organization: Business Impact

## The Aftermath

_What happened after the project_

**Content:** **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

_Honest retrospective analysis_

### What Worked

- **Extremely rich functional scope**: the extranet covers every administration need of a complex B2B platform - catalog, suppliers, resellers, advertising, statistics, import/export, multilingual
- **Modular architecture (v2)**: the decision to create shared bundles (ESCoreBundle, ESSourcingBundle) to mutualize code between sub-projects was a pertinent architectural choice
- **Courageous technology migration**: moving from a custom framework to Symfony 3 and from MySQL to PostgreSQL shows a willingness to modernize
- **Automated provisioning**: using Vagrant + Chef for v2 guarantees reproducible development environments

### What Would Change

- **Implement CI/CD from the beginning**: GitHub Actions didn't exist yet, but Travis CI or Jenkins were available and would have caught regressions earlier
- **Separate the database**: into microservices or at least distinct schemas to reduce the strong coupling between 15+ sub-projects
- **Adopt Docker instead of Vagrant + Chef**: for lighter and more portable provisioning

### Lessons

- **Shared bundles are a long-term investment**: mutualizing business code between sub-projects reduces duplication but creates strong dependencies and requires good version management
- **Data import is a full engineering problem**: the 6-step CSV import system with validation, preview, and history demonstrates the complexity of mass data management
- **Documenting architecture is essential**: when the number of sub-projects and developers grows, documentation becomes critical for onboarding and maintenance

**What Worked:** What Worked Well

**What Would Change:** What I Would Do Differently

**Lessons:** Lasting Lessons
