\documentclass[12pt, a4paper]{article} \setlength{\parskip}{1em} \usepackage[T1]{fontenc} \usepackage[a4paper, margin=0.7in]{geometry} \usepackage[french]{babel} \usepackage{amsfonts} \usepackage{mathabx} \usepackage{listings} \usepackage{xcolor} \usepackage{float} \usepackage{cite} \usepackage{subcaption} \usepackage{hyperref} \hypersetup{ colorlinks=true, linkcolor=blue, urlcolor=blue, pdftitle={Adrien Burgun - Rapport de stage ST40 - A2022} } % From https://github.com/pinam45/utbm-latex-internship-report-covers % Requires xelatex to run (or maybe also lualatex) \usepackage{utbmcovers} % From https://tex.stackexchange.com/questions/89574/language-option-supported-in-listings \lstdefinelanguage{JavaScript}{ keywords={ typeof, new, abstract, class, interface, type, function, return, try, catch, finally, switch, case, break, var, let, const, if, else, for, while, in, of, do, true, false, null, undefined }, keywordstyle=\color{blue}\bfseries, ndkeywords={ export, implements, import, this, private, public, readonly, constructor, @Inject, @Injectable, @Controller, @Module }, ndkeywordstyle=\color{darkgray}\bfseries, identifierstyle=\color{black}, sensitive=false, comment=[l]{//}, morecomment=[s]{/*}{*/}, commentstyle=\color{purple}\ttfamily, stringstyle=\color{red}\ttfamily, morestring=[b]', morestring=[b]" } \lstdefinelanguage{hbs}{ morecomment=[s]{\{\{!}{!\}\}}, commentstyle=\color{purple}\ttfamily, stringstyle=\color{red}\ttfamily, morestring=[s]{\{\{}{\}\}}, } \definecolor{bgColor}{rgb}{0.95,0.94,0.92} \lstdefinestyle{JavaScript}{ backgroundcolor=\color{bgColor}, commentstyle=\color{gray}, keywordstyle=\color{magenta}, numberstyle=\tiny\color{gray}, stringstyle=\color{purple}, basicstyle=\footnotesize, breakatwhitespace=false, breaklines=true, captionpos=b, keepspaces=true, numbers=left, numbersep=5pt, showspaces=false, showstringspaces=false, showtabs=false, tabsize=2, language=JavaScript } \graphicspath{{build/figures/}{images/}} \newfontfamily{\Tahoma}{Tahoma} \newfontfamily{\SourceSans}{Source Sans Pro} % Looks like the font from google fonts has a different case, % so I'm stuck with scanning for existing fonts \IfFontExistsTF{Source Sans Pro Semibold}{ \newfontfamily{\SourceSansSB}[UprightFont={* Semibold}]{Source Sans Pro} }{ \newfontfamily{\SourceSansSB}[UprightFont={* Semi-Bold}]{Source Sans Pro} } \setmainfont{Source Sans Pro} % \newfontfamily{\ossb}[UprightFont={* Semibold}]{Open Sans} \newcommand{\entity}[1]{{\SourceSansSB #1}} \newcommand{\entityb}[1]{#1} \newcommand{\person}[2]{#1 #2} \newcommand{\term}[1]{\textit{#1}} \newcommand{\figref}[1]{[Figure~\ref{#1}]} \newcommand{\inputfig}[1]{\input{figures/#1}} \title{Rapport de stage ST40 - A2022} \author{Adrien Burgun} \date{Automne 2022} \setutbmfrontillustration{assets/priscilla-du-preez-BjhUu6BpUZA-unsplash} \setutbmtitle{Stage développeur full stack} \setutbmsubtitle{Rapport de stage ST40 - A2022} \setutbmstudent{BURGUN Adrien} \setutbmstudentdepartment{Département Informatique} \setutbmstudentpathway{} \setutbmcompany{Moment - T\&M} \setutbmcompanyaddress{3 boulevard Richard Lenoir\\75011 Paris} \setutbmcompanywebsite{\href{https://moment.tech/}{moment.tech}} \setutbmcompanytutor{PERRIN Pierre} \setutbmschooltutor{HOLWECK Frederic} % From https://moodle.utbm.fr/pluginfile.php/117803/mod_book/chapter/595/CARNET-A22-20220711.pdf \setutbmkeywords{Télécommunications - Informatique - Développement logiciel - Logiciel de gestion - Logiciel de réseaux} \setutbmabstract{ J'ai effectué mon stage ST40 au sein du département de développement full-stack de l'entreprise \entity{Moment}, une start-up française basée à Paris et fondée en 2013. \newline % TODO: check wording (maritime) Moment propose à ses clients des offres de divertissement pour l'aviation, le secteur maritime, les chemins de fer et plus récemment le domaine de la santé. Leur offre principale, \og Flymingo \fg, permet d'accéder aux divertissements directement depuis les appareils mobiles des passagers. \newline J'ai pu contribuer au développement de fonctionnalités pour la nouvelle offre déployée dans les cliniques de santé, à l'optimisation de l'application tournant sur des télévisions connectées et au maintien du code front-end. } \begin{document} % \maketitle \makeutbmfrontcover{} { \Tahoma \tableofcontents } \newpage \section{Présentation} \subsection{Présentation de l'entreprise} \entity{Moment} est une entreprise fondée en 2013, avec pour but de rendre l'expérience des voyageurs plus simple, plus plaisante et plus connectée \cite{momenttech}. Pour y parvenir, \entity{Moment} propose une plateforme digitale déployée dans les avions, les trains, les bateaux de croisière et plus récemment les cliniques de santé. Cette plateforme permet aux voyageurs de se connecter à un réseau wifi avec leurs propres appareils, et de profiter de divertissements directement sur ceux-cis. % TODO: récupérer le vrai nombre d'employés et de projets À ce jour, \entityb{Moment} s'apprête à compter 10 ans de travail dans ce domaine, et possède une trentaine d'employés. \entityb{Moment} a lancé une cinquantaine de projets, dans 15 pays, et ses produits sont utilisés par plus de 10 millions de passagers par jour. % TODO: valider Air France? \entityb{Moment} fournit ses services aujourd'hui à \entity{Air France}, l'\entity{Aéroport de Paris}, \entity{TGV InOui}, \entity{Air Belgium}, \entity{Brittany Ferries} et \entity{Air Senegal}. L'entreprise \entityb{Moment} a lancé en 2021 une filiale nommée \entity{Moment Care}, qui se spécialise dans le divertissement dans le domaine de la santé: \entity{Moment Care} souhaite révolutionner le contenu des offres de divertissement dans les établissements de santé, et la manière d'y accéder \cite{momentcare}. \subsection{Présentation du lieu de stage} Lors de mon stage, les locaux de \entityb{Moment} se trouvaient à Paris, près de la place de la Bastille. Ces bureaux sont partagés par la grande majorité des employés de \entityb{Moment}, qui sont organisés en différents pôles: \begin{description} \item[Développement full-stack:] C'est au sein de cette équipe que mon stage s'est déroulé, sous la supervision de son chef d'équipe, Pierre Perrin. \item[Marketing \& Design:] Ce pôle s'occupe de l'image de l'entreprise et des produits, à la fois sur les réseaux sociaux et auprès des clients présents et futurs. Cette équipe décide notamment du design des différentes applications, qui est envoyé à l'équipe \entity{Fullstack R\&D} pour implémentation. \item[PMO (Project Management Office):] Ce pôle est constitué de chefs de projets, qui gèrent les demandes des clients, les dates limites, les statistiques à relayer aux clients et les difficultés techniques. \item[Contenu:] L'équipe contenu s'occupe de maintenir la base de contenus disponibles sur les différentes plateformes déployées. Elle négocie auprès des distributeurs de films, de séries et de magazines, et elle maintient à jour le \term{Content Management System} (CMS). \item[Business Developers:] Cette équipe est en contact avec nos clients actuels et de potentiels clients futurs. Elle met en place le business plan, amène à l'entreprise de nouvelles opportunités de partenariat et négocie les prix lors de la vente des produits de l'entreprise. % TODO: reste \end{description} \newpage % Moment -> Moment + Moment Care % Fondateur? (TODO:) % Chiffres? (TODO:) % Équipes % Agile, réunions % Jira % Gitlab % TODO: valider tout ça % Le groupe \entity{Moment} a été fondé en 2013, et est constitué à ce jour de deux entreprises: % \begin{itemize} % \item \entity{Moment}, qui se spécialise dans le développement de solutions de divertissement pour l'aviation, le secteur maritime, % les chemins de fer et les aéroports. % \item \entity{Moment Care}, qui se spécialise dans le développement de solutions de divertissement pour le domaine de la santé. % \end{itemize} % À ce jour, les deux entreprises partagent les mêmes bureaux à Paris. % J'ai réalisé mon stage dans l'équipe \entity{développement full-stack}, qui maintient et développe les applications front-end pour % \entityb{Moment} et \entityb{Moment Care}, ainsi qu'une partie des applications back-end (en grande partie pour \entityb{Moment Care}). % Notre équipe est menée par mon tuteur de stage, \person{Pierre}{Perrin}, et nous travaillons en collaboration avec les chefs de projets % de \entityb{Moment} et de \entityb{Moment Care}, l'équipe \entity{\og SysOps \fg} et l'équipe \entity{Design}. % % TODO: trouver une source sur agile, utiliser la nomenclature associée % Notre équipe fonctionne avec la méthode \term{agile}: chaque semaine, nous faisons une réunion présentant les sujets et taches de la semaine, % ainsi que leurs priorités. % Chaque matin, nous faisons également une courte réunion où chaqu'un présente le travail qu'iel a réalisé la veille, % et ce qu'iel va faire ce jour. % La distribution du travail se fait via \entity{Jira}: en début de semaine, le \term{backlog} est mis à jour pour contenir l'ensemble % des taches retenues pour la semaine, ainsi que celles non-réalisées de la semaine dernière. Chaqu'un peut ensuite s'assigner % des taches, travailler dessus, puis marquer la tache comme prête à être revue. % L'assurance de qualité se fait via des revues sur \entity{GitLab}: chaque modification au code doit être mise dans une \term{Merge Request} % (l'équivalent des \term{Pull Request} sur \entity{GitHub}), et un membre de l'équipe n'ayant pas contribué à cette modification % doit approuver celle-ci avant qu'elle ne puisse être ajoutée à la branche principale de développement. % Tests unitaires % \subsection{Produits de Moment} \subsubsection{Flymingo} \entity{Flymingo} est le produit principal de \entityb{Moment}: % Pitch de Moment, dire sur quoi c'est déployé Ce produit est composé d'un serveur, nommé \entity{Flymingo Box}, sur lequel tournent plusieures applications: \begin{itemize} \item Une application web, \entity{Flymingo Digital}, sur laquelle les passagers peuvent se connecter. \item La \entity{Content API}, qui est une API pour accéder aux informations sur les différents divertissements disponibles sur le serveur. Cette API permet aux clients d'avoir un certain degré de customabilité. Cette API sert également les différents contenus (vidéo, musique, magazines). % Zirock? \end{itemize} \subsubsection{Mint} % TODO: add logo floating to the right \entity{Mint} est le produit que \entityb{Moment} développe et déploie en ce moment dans les cliniques de santé: \begin{description} \item[Mint Admin] est une application web permettant aux clinique de fixer les prix pour les offres que celles-cis souhaite mettre à disposition, ainsi que de gérer l'assignement des différents appareils (comme les télévisions et les tablettes) aux chambres, des différents patients à ces chambres, et des offres aux patients. \item[Mint Digital] est une application web que les patients des cliniques utilisent pour se connecter, acheter des offres en ligne, regarder des films, documentaires, magazines et écouter de la musique. \item[Mint Service] est le back-end avec lequel \entity{Mint Admin} et \entity{Mint Digital} communiquent. \entity{Mint Service} expose une API permettant à \entity{Mint Admin} de faire des modifications aux offres et aux patients, et à \entity{Mint Digital} de permettre aux utilisateurs de se connecter et d'acheter des offres en ligne. \item[Mint Tab] est une application pour tablettes \term{iPad}, qui permet aux patients des cliniques d'accéder au même contenu que sur \entity{Mint Digital}. \item[Mint TV] est une application tournant sur les télévisions connectées, qui permet aux patients des cliniques d'accéder au même contenu que sur \entity{Mint Digital}. \end{description} Durant ce stage, j'ai surtout travaillé sur les applications suivantes: \begin{itemize} \item Mint Service \item Mint Admin \item Mint Digital \item Mint TV et Mood TV \end{itemize} \section{Travail réalisé sur Mint Service} Mint Service est une application construite avec \entity{NestJS}. NestJS est un framework permettant de construire des applications côté serveur en Javascript, et de s'assurer que ces applications soient à la fois sûres, efficaces et flexibles \cite{nestjs}. \subsection{NestJS et organisation du code} % TODO: hiérarchiser l'argumentaire NestJS emploie à son coeur les principes de \term{modularité} et d'\term{inversion de contrôle} (\term{IoC}): \\ L'application est séparée en différents modules, qui eux-mêmes contiennent des \term{services} et des \term{controleurs}. \figref{nestjs3} \begin{description} \item[Les services] (aussi appelés \term{providers}) contiennent l'implémentation de la logique nécessaire pour répondre aux besoins de l'application: contacter une base de donnée, traiter l'information, faire des requêtes réseau, etc. \item[Les controleurs] sont responsables d'accepter les requêtes des \entity{clients}, de les transformer, de vérifier leur légitimité et d'appeler les méthodes des \entity{services} avant de transformer la réponse à envoyer au \entity{client}. \\ NestJS fournit un ensemble d'outils simplifiant l'implémentation des controleurs. \item[Les modules] s'occupent de gérer la configuration des \entity{services} et des \entity{controleurs}: chaque \entity{module} indique à NestJS quels \entity{services} et \entity{controleurs} il contient, ainsi que comment NestJS doit construire ces services dans les cas plus complexes. \\ Les modules peuvent exporter un sous-ensemble de leurs services, ce qui permet de rapidement réutiliser des services en important le module leur étant associé. \figref{nestjs2} \end{description} \begin{figure}[H] \centering \includegraphics{nestjs3} \caption{Organisation d'un module NestJS typique} \label{nestjs3} \end{figure} La séparation entre controleurs et services permet d'avoir une claire \term{séparation des préoccupations}: \begin{itemize} \item Les controleurs s'occupent de gérer, valider et répondre aux requêtes faites par un client; \item Les services s'occupent de l'implémentation de la logique permettant de satisfaire la requête; \item Les modules s'occupent de configurer les services et les controleurs, et permettent la modularisation du code. \end{itemize} Pour limiter le couplage entre les services, et pour simplifier la réutilisation des services, NestJS permet de faire de l'\term{injection de dépendances} par \term{constructeur sans défaut} \cite{yang2008empirical} dans les services et dans les controleurs, d'une manière similaire au framework \entity{Spring} en \entity{Java}. \figref{nestjs1} % TODO: trouver une source % Separation of concerns % https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=0fd24fa8ac2a77c4709103eb8a179fec38311fe8 % "On the importance of the separation-of-concerns principle in secure software engineering" Il devient ainsi plus simple avec ce système de modifier différentes parties du code sans accidentellement casser une autre partie du code. Il est aussi plus simple de tester du code organisé de la manière suivante, car les services et les controleurs peuvent être placés dans un environnement isolé et testés individuellement ou collectivement. \subsection{Système d'envoi de mail} \subsubsection{Analyse et prototype} On m'a donné en début de stage la tâche d'implémenter un système d'envoi de mail pour \entity{Mint Service}. Ce système prend la forme de plusieurs librairies, qui doit remplir les conditions suivantes: \begin{itemize} \item Il doit être facilement réutilisable dans d'autres projets. \item Il doit permettre de changer de fournisseur de service pour l'envoi d'emails sans devoir faire de grands changements du côté des utilisateurs de la librairie. \item Il doit pouvoir envoyer des emails qui s'affichent de la manière voulue sur la majorités des boîtes mail. \item Il doit pouvoir envoyer des emails contenant des informations sur l'utilisateur. \item Il doit permettre de décrire le contenu des emails d'une manière facilement maintenable et réutilisable. \end{itemize} Mon travail a commencé par l'analyse de différentes solutions permettant d'adresser les deux dernières conditions. Par le passé, l'entreprise avait déjà utilisé le moteur \entity{Handlebars} \cite{handlebars}, une librairie de recherche et de remplacement de texte, qui permet d'avoir des formes simples de logique, comme des conditions ou des boucles. Bien que \entity{Handlebars} fonctionne bien pour insérer les informations de l'utilisateur dans les mails, il ne permet pas de facilement réutiliser du code, qui est souvent complexe afin d'assurer un bon affiche sur les différents programmes de boîte mail. J'ai donc cherché à avoir un système de \og composants \fg dans la solution choisie, afin de pouvoir construire des couches d'abstraction et de réutiliser facilement le code. Ces composants doivent, plus spécifiquement: \begin{itemize} \item Pouvoir être appelés avec différentes valeurs en arguments \item Pouvoir appeler d'autres composants \end{itemize} % TODO: source sur search and replace J'ai selectionné deux moteurs de recherche et de remplacement de texte (\term{Search and Replace}): \entity{Handlebars} \cite{handlebars} et \entity{Mustache} \cite{mustache}. Ces deux moteurs opèrent de manière similaire: ils lisent le code source, et lorsqu'une variable indiquée par les balises \texttt{\{\{} et \texttt{\}\}} est rencontrée, celle-ci est subtituée par la valeur assignée au nom de cette variable. \entity{Handlebars} et \entity{Mustache} peuvent tous les deux être utilisés pour implémenter le système de composants voulu, car ils permettent de définir des variables spéciales, que les deux moteurs appelent \term{partials}, qui peuvent appeler du code javascript arbitraire. J'ai enfin fait un prototype en \entity{Typescript}, qui transforme un email décrit à partir de composants \entity{Handlebars} ou \entity{Mustache} en du HTML. Après avoir montré ce prototype à mon chef de projet, nous étions tous les deux d'accord que le moteur \entity{Handlebars} remplissait mieux nos attentes, en grande partie parce que \entity{Handlebars} permet de passer du code en tant qu'\og enfants \fg, tandis que \entity{Mustache} requiet de passer par deux composants (un avant et un après le code \og enfant \fg). \figref{hbs1} \inputfig{hbs1} Pour le premier projet sur lequel \entity{Mint Service} allait être déployé, \entity{Amazon SES} \cite{amazonses} allait être utilisé pour faire l'envoi de mails. \entity{Amazon SES} permet d'envoyer les emails sous format texte et HTML en même temps, permettant d'avoir des emails facilement lisibles par un lecteur d'écran ou sur une messagerie configurée pour afficher les mails sans leur mise en forme. La partie \entity{Handlebars} a donc été étendue pour permettre d'annoter quels parties du code doivent être placés dans la version texte du mail. [Figures~\ref{hbs2a} et \ref{hbs2b}] \inputfig{hbs2} \subsubsection{Implémentation initiale dans Mint-Service} Une fois que le prototype me donnait des résultats satisfaisants, j'ai pu passer à l'implémentation au propre du système d'envoi de mails dans \entity{Mint Service}. Cette première implémentation devait faire l'envoi de mail en deux étapes: \begin{enumerate} \item Les mails sont chargés et sont rendus, puis sont mises en lignes sur \entity{Amazon SES} en tant que \og templates \fg \cite{amazonsestemplate} \item Les mails sont ensuite envoyés en instructant à \entity{Amazon SES} de faire le rendu et l'envoi d'une des \term{templates} à l'adresse mail voulue, avec les données voulues \end{enumerate} J'ai d'abords créé et implémenté une librairie permettant de compiler du code \entity{Handlebars} ainsi que des composants en format HTML et en format texte, nommée \texttt{handlebars-generator}. Cette librairie ne s'occupe pas du chargement des fichiers, ni de l'envoi des mails, et est implémentée sans framework, ce qui permet de la réutiliser dans le futur pour d'autres projets. Puis, j'ai créé et implémenté une librairie Nest.JS nommée \texttt{mailing-nest} qui s'occupe de: \begin{itemize} \item Charger les composants et les emails depuis un dossier donné \item Transformer ceux-cis avec \texttt{handlebars-generator} en HTML et en texte \item Mettre en ligne des \term{templates} pour utiliser le service d'envoi d'emails personalisés d'\entity{Amazon} \item Envoyer les \term{templates} avec les informations de l'utilisateur dedans \end{itemize} Afin de pouvoir tester le fonctionnement de la librairie \texttt{mailing-nest}, j'ai également créé une petite application Nest.JS qui affiche dans le navigateur les emails en format HTML et en format texte. Cette application permet aussi de développer rapidement les emails sans devoir passer par Amazon pour tester les modifications. % TODO: screenshots Enfin, j'ai implémenté un module Nest.JS dans l'application \entity{Mint Service}, qui charge le module de \texttt{mailing-nest} avec en paramètre le chemin des emails pour \entity{Mint}. Ce module est importé à plusieurs endroits dans le code, et expose des méthodes dans son service permettant de convertir les entités de \entity{Mint Service} au format attendu par les emails. \begin{figure}[H] \includegraphics[width=\textwidth]{mailingnest} \caption{Organisation initiale du système d'envoi de mail dans Mint-Service} \end{figure} \newpage \section{Annexes} \inputfig{nestjs1} \inputfig{nestjs2} \bibliographystyle{plain} \bibliography{references}{} \makeutbmbackcover{} \end{document}