DEV Community

Cover image for Retour d'exp√©rience : ūüöÄcomment j'ai "r√©volutionn√©" un SI
Olivier Maléa
Olivier Maléa

Posted on • Updated on

Retour d'exp√©rience : ūüöÄcomment j'ai "r√©volutionn√©" un SI

Sous ce titre quelque peu accrocheur se cache en réalité un projet ambitieux de longue haleine et complexe assorti de beaucoup de décisions stratégiques !

Cet article est l'occasion de décrire une situation, qui à mon sens, n'est pas unique ou isolée, ainsi que les solutions possibles et les transformations à prévoir.

Je vais m'efforcer d'√™tre le moins technique possible, d'autres articles suivront pour ceux qui en sont friands ūüėä.

Au début il y avait le contexte

J'ai été sollicité par une entreprise dont l'activité n'est pas l'informatique, sur mon expérience d'architecte logiciel, pour mettre en place un nouveau socle technique afin de moderniser plusieurs éléments de son écosystème logiciel.

J'ai d√Ľ appr√©hender un passif de plus de 10 ans, beaucoup de petites applications fonctionnant de mani√®re isol√©e, plusieurs outils web d√©di√©s √† la gestion de l'activit√© m√©tier.
L'entreprise avait la culture du PGI (Progiciel de Gestion Intégré ou ERP en Anglais) de ce fait, tout l'applicatif en place était lié par un tronc commun: une base de données monolithique.

Les différentes applications, des sites web, avaient un autre tronc commun: les langages tournaient tous autour du .net, ce qui m'a immédiatement intéressé puisqu'il s'agit de ma spécialité, surtout le .Net Core.

Puis vinrent les problèmes

Et quels étaient les problèmes ?

Beaucoup !

Mais encore ?

Eh bien puisqu'il faut commencer par quelque chose, je dirais en premier le facteur humain.

Le facteur humain

L'√©quipe √©tait tr√®s (trop !) petite: une 2-pizza team ūüćēūüćē ‚Ķ pour l'ensemble de l'√©cosyst√®me.

Pour rappel, le concept de 2-pizza team est l'émanation de Jeff Bezos, CEO d'Amazon, affirmant que la taille idéale d'une équipe correspond au nombre de personnes que l'on peut nourrir avec 2 pizzas, soit entre 5 et 10 personnes.

Bon, cette donnée est relative et dépend tout de même de l'appétit des protagonistes mais passons …

L'équipe était organisée en silos techniques:

  • Les techniciens IT, en charge des infrastructures et du r√©seau ;
  • Les d√©veloppeurs en charge de ‚Ķ dois-je vraiment pr√©ciser ?

Sur le plan op√©rationnel, l'empirisme √©tait la r√®gle: tout se faisait en r√©action plut√īt qu'en pr√©vision.

En effet, les demandes provenant des utilisateurs étaient captées par des experts métiers officiant en tant que support, externes aux équipes informatiques, ce qui induisait une forme d'urgence systémique puisque la majorité de la valeur produite ne consistait qu'au règlement des problèmes rencontrés.

Le fait que chaque p√īle de comp√©tences travaillait en silo ne facilitait d'ailleurs pas la communication et l'organisation √©tait analogue: ferm√©e, compliqu√©e et incapable d'√©voluer.

L'organisation

Le fonctionnement en silo est le fait que chaque équipe (ou département, ou même service) exerce son activité, relative à sa spécialité, sans se soucier de l'activité des autres.
silos

Pour aller à l'essentiel, le principe de silos, s'il permet de bien délimiter les compétences et donc (logiquement ?) les responsabilités de chacun, n'est pas réputé pour ses forces en matière de communication, de synergies entre les équipes et de capacité d'adaptation sur le long terme.

Sur le plan de la m√©thodologie en place, Il n'y en avait pas forc√©ment: la production √©tait simplement port√©e par le besoin ¬ęle plus pressant¬Ľ et quelques projets sporadiques visant √† ajouter des fonctionnalit√©s nouvelles ou des √©volutions n√©cessaires.

Pour accompagner cette activité et donner du liant, des outils étaient bien évidement en place: ticketing, actitivity-tracker et pour le reste … échanges de mails.

En termes de sociologie d'équipes, le fait d'être isolé rend les gens méfiants, suspicieux de la qualité et du travail des autres, peu impliqués dans un effort collectif et tout cela se ressentait, une forme de tension existait entre chaque service et l'activité peinait à atteindre un optimum.

De m√™me, il √©tait compliqu√© de d√©terminer le niveau d'implication et de responsabilit√© de chacun puisque l'activit√© √©tait plut√īt r√©p√©titive et monotone, bref plus contrainte que stimulante.

Le manque de méthodologie clairement définie générait également un manque de traçabilité, tant dans les éléments de travail que dans l'activité de chacun.

La technique

Sur ce point, l'écosystème présent était très … plurale.

Effectivement, beaucoup de langages issus du .Net pour la plupart ont été employés à différents moments de l'histoire de l'entreprise, citons tout de même de manière non exhaustive et non ordonnée: ASP classic, ASP.NET MVC 5, ASP.NET WebForms.

Une multitude d'applications consoles en .Net framework 4.0 à 4.8 revêtant la forme de services Windows, quelques modules PHP, et quelques WinForms venaient compléter ce panel.

Pour ajouter un peu de complexit√© √† cette diversit√© de langages, les d√©veloppements ont √©t√©, dans le pass√©, confi√©s √† des √©quipes qui n'existent plus, il n'y avait bien entendu que le strict minimum en termes de documentation et certains applicatifs n'√©taient m√™me pas publi√©s dans un d√©p√īt de code.

Pour ce qui est des d√©p√īts de code, des partis pris radicaux quant aux bonnes pratiques d'ing√©nierie logicielle et des principes d'industrialisation ne rendaient pas forc√©ment le code disponible exploitable.

En ce qui concerne le code en lui-même, plusieurs éléments m'ont sautés aux yeux immédiatement:

  • Absence totale de tests techniques (unitaires, int√©gration, ‚Ķ), de m√™me que pas de tests de qualification ni de protocole de non-r√©gression mais cela est hors scope si on se place sur le plan technique (dis donc ! tu ne serais pas en train de reproduire un silo id√©ologique l√† ?) ;
  • Niveau de maturit√© du code tr√®s h√©t√©rog√®ne ;
  • Aucune r√®gle de confection de code (organisation des √©l√©ments au sein des classes, r√®gles de nommage, nomenclatures) ;
  • Aucun patron de conception guidant les d√©veloppements ;
  • Une complexit√© cyclomatique, c'est-√†-dire le nombre de chemins ¬ę lin√©airement ind√©pendants ¬Ľ empruntable au sein d'une fonction, proche de l'incroyable ;
  • Une interd√©pendance √©lev√©e entre les diff√©rents blocs de code ;
  • Des couches organisationnelles peu ou pas du tout d√©termin√©es ;
  • Non-respect des principes d'ing√©nierie logicielle (SOLID), redondance, code et fonctions dupliqu√©s ;
  • Des solutions trouv√©es √† des probl√©matiques sp√©cifiques plus proches du bricolage (tiens, c'est √† la mode √ßa en ce moment ‚Ķ), voir du POC (Proof of Concept), que de vrais √©l√©ments techniques robustes et maintenables;
  • Sur le principe de l'ERP: recours √† une super base de donn√©es, un monolithe persistant sur lequel TOUS les applicatifs venaient se raccorder, ainsi qu'un couplage fort avec celle-ci (c'est mal !) ;
  • Une utilisation tr√®s limit√©e des possibilit√©s relationnelles de cette base de donn√©e SQL, beaucoup d'ambigu√Įt√© dans les noms de table / colonne ;
  • Last but not least: pas d'Api's !!!!

La somme de ces éléments rendait les applicatifs très difficiles à maintenir, faire évoluer, et tout reposait sur la connaissance de l'homme du métier puisqu'aucune documentation ne venait assortir le code.

Pour parachever cet instantan√© de la situation technique, le syst√®me de mise en production √©tait tr√®s artisanal, bas√© sur des outils d√©pass√©s et le recours syst√©matique √† une intervention humaine sur les serveurs plut√īt qu'une judicieuse et millim√©trique automatisation‚Ķ

Et au milieu … l'analyse

Tout d'abord, je souhaite rappeler et mettre en avant le fait que cette entreprise n'est pas sp√©cialis√©e dans le domaine informatique, ce dernier ne jouait jusque-l√† qu'un r√īle de support d'activit√©, comme dans bien des entreprises d'ailleurs.

Le probl√®me avec cette approche est relativement simple: la croissance et le d√©veloppement de l'entreprise ont rendu ce r√īle de support inad√©quat. La DSI n'a jamais pris la pleine mesure de l'√©volution et n'a jamais adapt√© son organe √† la r√©alit√© de la situation qui imposait un nouveau champ d'action: grandir et devenir une vraie entit√© produisant de la valeur et du business, et non plus un simple support.

First Principle

first-principle
Mes premi√®res conclusions ont √©t√© dans ce sens et en se r√©f√©rant au ¬ęFirst Principles Thinking¬Ľ - basiquement en me limitant √† poser la question Pourquoi ? - j'ai pu r√©duire le probl√®me √† quelques questions, que voici, livr√©es avec leurs r√©ponses:

  • Pourquoi cette faiblesse technique ?
    • Manque de connaissance architecturale et lacunes en ing√©nierie logicielle;
    • Manque d'ambition et d'engagement pour changer les choses;
    • Manque de confiance en la perspective d'un socle technique moderne, cloisonn√© √† quelques technos mais fortement ma√ģtris√© ;
    • Manque de qualit√© dans le code permettant de d√©celer et d'anticiper les anomalies ;
    • Une technique vieillissante incapable d'accompagner la croissance de l'entreprise et de r√©pondre √† de nouveaux d√©fis, ou tout simplement de traiter l'information de mani√®re optimale.
  • Pourquoi ce fonctionnement en silos et ce manque de communication ?
    • Pas de m√©thodologie clairement √©tablie ;
    • Pas assez d'interactions entre les √©quipes et donc une m√©connaissance de l'¬ęAutre¬Ľ;
    • Des outils peu adapt√©s et peu claires dans leur fonctionnement;
    • Des ambigu√Įt√©s sur les r√īles de chacun;
    • Un manque de confiance de la direction g√©n√©rale envers la technique ainsi qu'une culture du service op√©rationnel quelque peu d√©pass√©e.
  • Pourquoi ces difficult√©s √† produire et publier du code ?
    • Pas de process de livraison clairement d√©taill√© ;
    • Pas ou tr√®s peu de processus de validation des livrables, de m√™me qu'un manque de clart√© pour ces derniers ;
    • Pas d'automatisation (CI / CD) et recours bien trop prononc√© √† l'humain (donc √† ses faiblesses et limites !) ;
    • √Čquipe cr√©ant de la valeur totalement sous dimensionn√©e, d√©pass√©e par les √©v√©nements et travaillant la plupart du temps en mode ¬ępompier¬Ľ.

Une dernière question subsistait, éloignée du pourquoi mais tellement centrale: qu'en est-il de l'utilisateur final ? Tous ces problèmes entachent-ils l'utilisation des différents outils et ces derniers répondent-ils aux attentes des utilisateurs (le personnel de l'entreprise en grande partie)?

Fort de cette analyse, j'ai raisonnablement pu déterminer plusieurs axes d'amélioration, voire de rupture.

Et suivirent les solutions

Organiser le changement technique et technologique

L'√©vidence √©tait l√†: il fallait augmenter le niveau de ma√ģtrise des technologies travaill√©es tout en capitalisant sur les comp√©tences existantes.

En essayant de rationnaliser au maximum, il fallait conserver le savoir-faire existant et donc rester sur les technologies afférentes au .Net.

Il fallait, dans le même temps, s'inscrire dans la modernité et mettre en place un nouveau socle technique, moderne et qui serait également l'opportunité d'une architecture logicielle répondant à certaines caractéristiques, notamment les principes du Reactive Manifesto:

reactive-manifesto

Source https://www.reactivemanifesto.org

Ceci pour plusieurs raisons:

  • Le d√©veloppement de l'entreprise induit d'avoir une solution technique scalable et extensible ;
  • Plusieurs applications, avec chacune leur responsabilit√© et port√©e sp√©cifique, vont √©merger de cette analyse et il faudra les rendre inter-communicantes, quoi de mieux qu'une plateforme √©changeant via un agent de messages pour assurer cette fonction !
  • Il faut, √† termes, √™tre capable, de g√©rer au mieux les anomalies, id√©alement les anticiper, √† minima ne pas perdre d'activit√© et pouvoir d√©bloquer des situations complexes ;
  • Les diff√©rentes applications doivent √™tre totalement user-centric, c'est-√†-dire bas√© sur l'analyse des comportements des utilisateurs, et favoriser l'exp√©rience de la meilleure mani√®re possible ;
  • Apporter des briques rendant possibles l'innovation ;
  • Enfin, la solution technique doit permettre des livraisons rapides, sans faille et √† un rythme soutenu, sur une plateforme offrant souplesse et adaptabilit√©, probablement h√©berg√© via un cloud ‚Ķ

J'avais dès le début en tête une approche basée sur la mise en place d'une nouvelle stack technique, simple mais maitrisée: .Net Core + Angular.

.Net Core

Ce langage permet de développer des applications de haute qualité, modernes, rapides et en accord avec la philosophie des micro-services.

Il met rapidement à disposition les dernières fonctionnalités développées, communautaires ou éditoriales, et permet une grande modularité, il est également totalement tourné vers l'open-source et le cloud.

.Net Core permet de mettre en place relativement facilement une Architecture Orientée Services (SOA) d'entreprise: les données seront désormais exposées via des Api's.

Cela constitue donc l'opportunité de conceptualiser une batterie de micro-services, totalement orientés métier, propriétaires et responsables pour chacun de leur système de persistance (ce qui change radicalement du paradigme existant).

Pour le volet inter-communicabilité, il a fallu mettre en place un broker de messagerie (RabbitMq) assorti d'un framework accélérant les développements (Mass-Transit) et facilitant la concurrence car il repose sur TPL (Task Parallel Library).

Angular

Afin d'homogénéiser les pratiques sur le plan du web, l'expérience utilisateur et la captation des données, il fallait simplifier l'existant, apporter une forme d'unicité dans l'offre de l'entreprise.

En l'état, les solutions traditionnelles proposées par la stack - vieillissante - .Net (asp.Net MVC assorti du moteur de vue Razor, WebForms ou encore ASP Classic) ne donnaient pas satisfaction et n'accompagneraient pas une montée en gamme et en technologie.

D'autant plus que les langages employés imposaient un fort couplage avec le back-office. Il fallait donc assurer un cycle de vie pour les applications front indépendant de celui du back, limiter autant que possible ce que j'appelle l'hybridation, à savoir les langages responsables à la fois du back et du front.

J'avais l'id√©e qu'il fallait id√©alement partir sur une solution front mature, modulaire, √©volutive et ¬ęarchitecturable¬Ľ, cela dans une double optique: organiser la rupture technologique et unifier le processus de cr√©ation web.

Angular a pour particularité de reposer sur TypeScript, un langage typé objet compilant du javascript, proche du C#, et d'être très modulaire puisque basé sur une architecture … en modules !

Il dispose d'une très forte communauté et est très bien documenté, tout en proposant un niveau de maturité et de fonctionnalités très élevé et en plus de tout cela, NG (son petit sobriquet) est mis à jour fréquemment, peut-être trop depuis 2 ans … mais je m'emballe.

Le dernier atout d'Angular est qu'il peut être monté en Micro-Front end moyennant recours à quelques frameworks dédiés. Je pense que nous avons là une très bonne solution front modulaire et permettant de faire beaucoup de choses.

Et tu fais quoi de l'existant ?

Une question est effectivement tout de suite apparue: que faire de l'existant ?

Eh bien je me suis tout de suite fixé comme ligne de conduite de ne pas modifier cet existant, ou du moins le minimum possible, ce qui a rapidement induit une gouvernance claire:

  • D√©veloppement d'un site vitrine et du back office organis√© en micro-services ;
  • √Čtranglement applicatif pour une partie de l'existant ;
  • Maintenance th√©rapeutique sur les √©l√©ments ne supposant ni reprise ni √©volution.

Je vais présenter rapidement les différents principes mis en place sans toutefois apporter trop de détails, cela fera l'objet de futurs articles (un peu de teasing ne fait jamais de mal !).

Site vitrine

Le développement de l'application vitrine, un site web, a été l'occasion de mettre en place une architecture signature qui encadrerait les développements, a permis de développer un maximum de micro-services tout en intégrant des tests techniques ainsi que l'écosystème permettant de gérer le flux produit: des pipelines de CI / CD via Azure DevOps assorti d'une stratégie d'hébergement cloud (Azure).

Ce chantier a été l'opportunité, à travers l'architecture que j'amenais et le mentoring, de faire monter les équipes en compétence sur des techniques que j'avais pris l'habitude d'utiliser:

  • TDD (Test Driven Development) ;
  • Code First en utilisant Entity Framework Core ;
  • Event Sourcing et CQRS, puis MDA (Message Driven Architecture) ;
  • In-Memory testing (In-memory Database, proxy http, Web-Application Factory).

Mais √©galement de nouvelles choses pour moi, comme BDD (Behavior Driven Development) via SpecFlow (.Net Core) et Cucumber (Angular) qui reposent tous 2 sur le langage Gherkin ūü•í et permettent d'√©crire et d√©velopper des tests typ√©s ¬ę comportement ¬Ľ assez facilement.

Dans cet esprit, une équipe a été créée afin de mettre en place le nouvel écosystème, nous pouvons qualifier celle-ci de platform team pour faire référence aux Teams Topologies, puisqu'elle a été en charge de toute la mise en place:

  • Utilisation de l'architecture que j'avais d√©finie et d√©velopp√©e;
  • √Čcosyst√®me micro-services ¬ęCloud-ready¬Ľ pour lequel il a fallu d√©finir et cr√©er les environnements, les pipelines d'int√©gration et d√©ploiement continue;
  • Cr√©ation des ¬ęApis d'√©quipe¬Ľ: pages Swagger pour les micro-services, documentation via un wiki d√©di√© dans Azure DevOps;
Stratégie d'étranglement applicatif

Si l'application vitrine visait à remplacer son pendant existant par une nouvelle application, un traitement différent a été choisi pour les autres éléments de l'écosystème (des sites web) nécessitant une reprise totale: l'étranglement applicatif.
strangler-fig
L'étranglement applicatif est un concept émanant de la démocratisation des micro-services, celui-ci repose sur un passage organisé et cadencé de pans entiers d'applications, systèmes de persistance vers une nouvelle solution technique, il permet de moderniser graduellement l'existant tout en ne dégradant pas l'activité.

Bien évidemment, cette technique suppose de pouvoir échanger les données entre l'ancien et le nouveau paradigme, il a donc fallu conceptualiser et développer … un micro-service raccordé sur la base de données existante capable de détecter automatiquement toute modification de données et de recevoir les modifications provenant des autres services.

Cette fonctionnalité repose sur l'usage massif de l'event-sourcing, en gros de transmettre une information une fois qu'un événement est détecté, et l'échange de messages entre les différents micro-services présents.

Du coup, la mise en place technique résultant des développements du site vitrine rendait possible beaucoup de choses.

A termes, Il n'y a donc plus deux paradigmes distincts (le ¬ęlegacy¬Ľ et le ¬ęnew¬Ľ) mais bel et bien un seul proposant une multitude d'√©l√©ments coh√©rents et inter connect√©s.

Pour le reste, il fallait rapidement rendre l'existant industrialisable (sur le m√™me plan que l'application vitrine) et une phase de migration vers des d√©p√īts Git et une gestion de flux CI / CD via Azure DevOps a √©t√© planifi√©e et ex√©cut√©e, ce qui a √©videmment induit une refonte de l'√©quipe de d√©veloppement.

Très rapidement, pas mal de retour d'expériences sur ces éléments ont permis d'apporter des ajustements sur le site vitrine avant qu'il ne passe en production, ce qui est une forme de capitalisation relativement luxueuse: savoir à l'avance ce qui fonctionne mal et pouvoir l'ajuster.

Organiser le changement organisationnel et méthodologique

Refonte de l'équipe de développement

Si l'on reprend le principe de ¬ęcharge cognitive d'une √©quipe¬Ľ expos√© par Matthew Skelton et Manuel Pais dans leur ouvrage Team Topologies, avoir une seule √©quipe pour g√©rer et maintenir un pool d'applications parait totalement sous-dimensionn√©.

Il a donc fallu redéfinir l'équipe en place et en créer une nouvelle, en adéquation avec le nouveau socle technique mis en place, de manière à avoir une charge cognitive beaucoup plus raisonnable.

Donc, comme exposé dans le paragraphe précédent, cette refonte du SI tourne autour de 2 équipes: l'une (historique) gérant les applications existantes (le legacy) et l'autre dont l'activité tournait autour de la mise en place du nouveau socle technique et d'un site vitrine.

Voyons maintenant comment celles-ci fonctionnent.

L'organisation

Il a fallu mettre en place une organisation capable de supporter les nouvelles contraintes techniques.

Un nouveau service en résulte, plus proche à la fois du besoin utilisateur, des développements et de l'opérationnel.

Pour ce faire, l'approche DevOps a été la ligne directrice, terminé donc le cycle de vie et place au flux continu, exit les silos, bienvenu la collaboration !
devops-toolchain

Les équipes sont désormais constituées de développeurs, de l'AMOA (les fameux experts métiers) ainsi que de business-analysts et de nouvelles compétences propres à l'infrastructure et au réseau, applicables dans un domaine Cloud.

Cela induit √©videmment la destruction des silos par comp√©tence et laisse place √† un fonctionnement o√Ļ tout est plus simple, mieux huil√©, tout le monde travaille dans un seul but: produire de la valeur et donner satisfaction aux utilisateurs.

En termes d'outils, là aussi, une forme d'harmonisation apparait puisque les outils existants ont été remplacés par un seul outil, central, suffisamment puissant et modulaire pour être la colonne vertébrale de l'activité sans toutefois être chronophage dans sa gestion.

J'ai opt√© pour Azure DevOps, j'aurai pu utiliser autre chose mais il se trouve que je souhaitais capitaliser sur mes exp√©riences, mon savoir, et c'est un outil que je ma√ģtrisais d√©j√†.

Je savais qu'il nous permettrait de mener notre barque efficacement et qu'il nous accompagnerait dans nos évolutions.

Il a fallu une période de mise en place puis de training et d'acquisition afin que tout le monde s'adapte et devienne autonome, efficace avec cet outil.

Nous avions désormais les équipes (même si des recrutements étaient nécessaires pour acquérir les compétences manquantes), les outils et le fonctionnement drivant notre activité, ne restait plus qu'à définir quelle méthodologie allait rendre tout cela cohérent et efficient.

La méthodologie

Il nous fallait être efficace, en capacité de produire vite … et beaucoup (un socle technique complet développé en moins de 3 mois avec une équipe réduite !), et gérer un rythme assez soutenu.

Cela supposait une méthodologie adaptée.

J'avais le pressentiment que Scrum était le candidat idéal, sentiment partagé par mon Directeur de projet ainsi qu'une grande partie de l'équipe.

Je ne m'attarderai pas sur Scrum, beaucoup d'articles le dépeignent déjà, mais son apport a été immédiat:

  • Gain en flexibilit√© dans les d√©veloppements ;
  • Meilleure gestion des ressources et ajustement des √©l√©ments √† produire ;
  • Retours d'exp√©rience rapide ;
  • Engagement de chacun.

Ce dernier point est important car, le niveau d'adhésion avant cette refonte était très bas, il n'y avait aucun projet ambitieux et aucun challenge dans l'activité.

L'engagement de tous a permis de se remobiliser, d'avoir un objectif tangible, complexe et difficile à atteindre mais finalement gratifiant pour tout le monde.

De plus l'activité devenant beaucoup plus rationnelle, avec des objectifs et des temps forts, il était désormais possible de voir des résultats rapides, ce que l'on appelle des quick-wins et de redonner une note positive à l'activité informatique.

Le mot de la fin

Pour finir, je citerais simplement Albert Einstein pour qui ¬ęLa folie, c'est de faire toujours la m√™me chose et de s'attendre √† un r√©sultat diff√©rent ¬Ľ ainsi que Bill Campbell (The Trillion Dollar Coach): ¬ęLe leadership consiste √† reconnaitre qu'il y a de la grandeur en chacun et votre travail consiste √† cr√©er un environnement dans lequel cette grandeur peur √©merger¬Ľ.

J'ai eu √† cŇďur d'appliquer ces 2 maximes et d'en faire une r√©alit√© tangible.

J'espère que ce retour d'expérience, même s'il est très en surface pourra donner des pistes à toute personne se retrouvant dans une situation analogue.

Je finirai en disant que rien n'est possible quand on essaye d'avancer seul et qu'il faut s'efforcer de créer des synergies entre les hommes et les outils disponibles.

Top comments (0)

The discussion has been locked. New comments can't be added.