Rapport final Go Farmer

= Rappel du sujet, des besoins et du cahier des charges =

Généralités
Le projet sur lequel nous avons travaillé durant ces dernières semaines s'inscrit dans un autre projet plus vaste et s’étendant sur une plus longue durée. En effet, notre porteur Sylvain Delangue, dans le cadre de son projet de fin d’études à HEC, souhaite développer un prototype d’application mobile/site web qui a pour but de faciliter la mise en relation de particulier avec des producteurs locaux près de leur emplacement. En effet, il n’est pas toujours facile de prendre connaissance des points de vente près de chez soi ni de se faire connaître en tant que producteur.

Principe de l'application
J’origine est donc une application à destination de 2 types d’utilisateurs :
 * les consommateurs : les utilisateurs qui souhaitent situer les producteurs à proximité de leur position, dans leurs trajets habituels ou lors de déplacements particuliers dans des régions inconnues. Grâce à un système de notification, ils pourraient profiter de coupons promotionnels lorsqu’ils passent près d’un producteur local. Un autre volet important que comporterait l’application mais que nous n’avons pas pris en compte dans notre prototype est un système de notation des producteurs par les consommateurs.
 * les producteurs : les utilisateurs qui souhaitent se faire connaître et fidéliser des clients. Ils pourraient renseigner dans l’application leur emplacement fixe ou leurs éventuelles apparitions sur des marchés. Ils fourniraient également des coupons de réductions qui pourraient servir à la publicité ciblée afin d’attirer les acheteurs. Ils pourraient également partager leurs réseaux sociaux.

Objectifs
À notre arrivée, notre porteur nous a tout de suite prévenu qu’il souhaitait que le développement de ce projet s'inscrive dans une méthodologie Kanban. Il y avait donc évidemment des jalons bien précis définis et un objectif de fonctionnalités à atteindre mais également beaucoup d’inconnues ou de spécifications amenées à changer en fonction des apprentissages faits et de l’évolution de la technologie. Les principaux objectifs au début du projet étaient donc de valider l’utilisation de Flutter, de réfléchir à une architecture pour l’application, puis de développer les premières fonctionnalités.

Notre première mission a été de s’assurer que la technologie Dart/Flutter nous permettrait de réaliser toutes les fonctionnalités nécessaires mais aussi de s’assurer qu’elle était suffisamment stable et performante pour ce projet. En effet, Flutter est un framework très récent et ne dispose donc pas de la même communauté que d’autres peuvent avoir. En outre, le langage Dart qu’il utilise est tout aussi récent et il fallait s’assurer que sa prise en main soit correcte. Notre mission était donc de créer un prototype d’interface pour chaque type d’utilisateur en y intégrant les technologies qui seraient nécessaires par la suite (notamment Google Maps) et la récupération de données sur les producteurs.

Nous devions aussi réfléchir à une architecture optimale pour cette application. En effet, une réelle mise en production 24/7 étant envisagée/prévue par la suite, il était nécessaire de réfléchir à la meilleure infrastructure pour ce projet notamment au niveau de la base de données, celle-ci étant amenée à être beaucoup interrogée. De plus, l'organisation des données était également à réfléchir afin de permettre le développement de toutes les fonctionnalités nécessaires par la suite.

En plus de vouloir intégrer un CMS propriétaire sur l’application, notre porteur voulait également pouvoir importer des adresses de producteurs se trouvant sur Datatourisme, une base de données opendata du gouvernement qui permet de recenser les points touristiques en France et donc également les “fournisseurs de dégustation”. Datatourisme permet donc de filtrer les producteurs par type mais aussi par région et de récupérer leurs informations sous format json. Nous devions donc développer un script pour parser ces fichiers json et y créer les producteurs associés dans la base de données de l’application.

= Technologies employées =

Un des atouts principaux de ce projet est sa capacité à être multiplateforme. Disponible sur mobile et web, il réunit ainsi des systèmes d’exploitation très différents. Afin de faciliter la création du prototype, notre porteur nous a orienté vers une technologie très récente : Flutter. Couplé aux technologies de développement de Google, Flutter est un kit de développement très puissant mais avant tout très jeune.

Flutter
Comme dit précédemment, Flutter est un framework mis en place en 2017 par Google dans le but de développer rapidement des applications pour Android et iOS avec un même code source. Depuis plusieurs mois, une version bêta permet également de développer des applications web et une version stable est sortie avec la dernière version de Flutter début mars (version 2.0.1). Ce framework utilise le langage Dart, assez peu connu mais extrêmement bien documenté. L’intérêt de Flutter est donc qu’il fournit une vue pour Android, iOS et web avec un unique code source. Un de ses autres avantages est sa facilité de couplage avec Firebase.

Firebase
Firebase est un ensemble de services d'hébergement pour n'importe quel type d'application. Cette API est extrêmement simple à utiliser tant pour des opérations communes que complexes. Parmi tous les services qu’elle propose nous avons choisi d’utiliser Firestore, Cloud Function, Hosting et Authentication.

Firestore
Cloud Firestore est une base de données NoSQL orientée document fournie par Google. Elle est sans serveur et la plateforme gère automatiquement le partitionnement et la réplication des données. De plus, sa tarification est évolutive, elle permet donc de ne payer aucun frais tant que l’on ne dépasse pas certains quotas d’utilisation (forfait à la journée). Enfin, Firestore est automatiquement scalable et peut donc s’adapter à une montée en charge.

Cloud Functions
Cloud Functions est un service proposant d’implémenter des fonctions dans le cloud, sans avoir à s’occuper de toute l’infrastructure sous-jacente. L’intérêt pour nous d’héberger des parties de notre code est de pouvoir les déclencher à n’importe quel moment (envoyer une Promo à l’utilisateur tous les matins à 10h par exemple).

Hosting
Le service d’Hosting permet, comme son nom l’indique, d’héberger le code source de notre projet Flutter Web, simplifiant grandement le déploiement de l’application sur le Web. En effet, l’opération peut se faire depuis notre terminal (via l’utilisation du service Firebase CLI) en quelques commandes. Le site Web est alors déployé sur une URL de notre choix (ici, notre porteur avait en amont acquis les droits du domaine “jorigine.fr” que nous avons pu utiliser pour le déploiement).

Auhtentication
L’Authentication de Firebase a pour but de faciliter aux développeurs la mise en place de l’authentification sur leurs applis. Le service nous permet de consulter les comptes créés par les utilisateurs, créer nous même des comptes (tels que des compte Admin par exemple), désactiver/supprimer les comptes de notre choix, etc. Le service fournit également une librairie utilisable directement dans notre code source Flutter avec des méthodes basiques de connexion telles que signIn, signUp, signOut, etc.

Google Maps
Un des objectifs fondamentaux de cette application est de pouvoir se localiser sur une carte et de situer les producteurs à proximité. Pour intégrer cette carte nous avons utilisé Google Maps API, qui propose de nombreuses fonctionnalités liées à Google Maps : le plan, la géolocalisation, la représentation de marqueur, le calcul d’itinéraire ou encore l’auto-complétion d’adresse.

= Architecture technique =

Notre prototype final fonctionne sur deux OS : Android et Web. L’application Android est installée sur nos téléphones via des APK que nous avons réalisés. Le site web quant à lui, est déployé grâce au Hosting de Firebase avec des certificats SSL valides fournis par Google. Notre base de données est stockée sur Firestore et donc prête à une montée en charge et les accès à l’application sont gérés par Authentication. L’envoi de notification et la complétion d’adresse utilisent des fonctions hébergées par Cloud functions. Tous ces services appartiennent à Firebase, l'outil de gestion d’application web et mobile de Google.

= Réalisations techniques =

Import de données à partir de Datatourisme
Afin de rendre l’application utile pour les utilisateurs avant que les producteurs y inscrivent leurs informations, il était important qu’elle leur propose déjà des informations. Notre porteur souhaitait donc qu’on importe des données provenant de Datatourisme. Datatourisme est un dispositif national visant à faciliter la diffusion en open data d’informations touristiques piloté par l’Etat. Il propose la création de “flux” afin de récupérer ces informations sous forme de données xml ou json. Sa base de données n’est pas requêtable en temps réel (il y a plusieurs heures de délai après la création d’une nouvelle requête et chaque requête créée ne peut être appelée que quotidiennement). De plus, il ne propose pas que des producteurs mais aussi des musées ou lieux culturels. Et enfin, les informations qu’il contient concernant les producteurs ne contiennent pas seulement des informations essentielles pour l’application. Il s’agissait donc ici de filtrer les informations de la base de données afin de ne récupérer que celles comprenant des producteurs mais aussi de n’extraire que les données qui nous intéressaient dans les fichiers json obtenus. Pour ce faire, nous avons développé un script dans le langage Dart qui consistait à lire une liste contenant tous les producteurs pour connaître le chemin du fichier associé puis ouvrir ce fichier. À partir de ses données, il s’agissait ensuite de générer des documents les contenant dans la base de données Firestore. La difficulté dans cette réalisation venait du fait que peu des champs de Datatourisme sont obligatoires dans la base de données, il faut donc gérer le cas où ceux-ci ne sont pas disponibles pour un producteur ou un autre.

Utilisation de Google Maps
Une des parties majeures de cette application est l’intégration de Google Maps. En effet, les utilisateurs doivent pouvoir localiser les producteurs et ont donc besoin d’une carte pour se repérer. Il existe plusieurs solutions, plus ou moins chères mais nous avons choisi d’utiliser Google Maps car il s’inscrit dans l’idée d’utiliser tous les outils proposés par Google pour le développement. De plus, il propose certaines facilités de programmation, d’analyse et de personnalisation qui lui donnent un avantage par rapport à ses concurrents tels que OpenStreetMap. Google Maps n’est en soi pas difficile à intégrer à un projet flutter : la documentation est plutôt claire sur les étapes à suivre. Nous avons rencontré des difficultés sur son adaptations aux différentes plateformes (pas toujours adapté pour le web qui était encore en version bêta, soucis avec iOS qui n’autorise pas toujours l’accès à ses paramètres). De plus, notre porteur souhaitait offrir aux utilisateurs une carte personnalisée, nous avons donc dû ajouter des marqueurs particuliers.

= Gestion de projet =

Méthode
Notre gestion de projet que ce soit pour notre planning, nos outils, ou nos méthodes de travail ont été imposées par notre porteur. Habitués des méthodologies agiles, nous avons donc réparti notre travail en tickets avec des epics et des stories, récapitulés dans un tableau Kanban. Nous avons utilisé Jira pour suivre notre avancement, Bitbucket pour gérer la gestion du code et Confluence pour documenter notre avancement et nos analyses techniques. Sylvain a tenu à faire une réunion tous les matins et parfois les après-midi pour connaître notre avancement en temps réel et s’assurer que nos visions du projet concordent.

Planning prévisionnel et effectif
Notre planning a dû être divisé en deux temps : tout d’abord la validation de l’utilisation de Flutter, puis la création du prototype. Étant donné que le framework est nouveau et encore peu utilisé, notre porteur voulait vérifier qu’il permettait de répondre à tous ses besoins (notamment la localisation, les notifications ou encore la base de données). Nous avons donc passé les deux premières semaines à développer deux prototypes basiques, un pour les producteurs (Baptiste et Rémy) et un pour les consommateurs (Leila et Manon). Une fois les deux prototypes validés, nous avons réuni les groupes et fusionné les prototypes pour réaliser une première release de l’application.

Rôle des membres
Sylvain avait donc le rôle de product owner : il définissait les fonctionnalités nécessaires dans le projet en les mettant sous forme de tickets, et les ordonnait également dans l’ordre de priorité le plus logique. Son rôle lui demandait aussi de valider les fonctionnalités implémentées avant de pouvoir les considérer comme terminées. De notre côté nous nous sommes tout d’abord séparés en deux équipes : une pour le côté consommateur, l’autre pour le côté producteur. Il nous a été utile de commencer à coder par pairs afin d’apprendre le langage, et les bonnes méthodes de recherche et de programmation. Une fois les deux prototypes opérationnels nous avons réuni les équipes afin de travailler individuellement sur la même application. Personne n’avait nécessairement de rôle prédéfini, nous prenions les tickets au fur et à mesure de l’avancement du tableau Kanban. On notera tout de même que Baptiste et Rémy se sont plus spécialisés sur le côté Firebase / Devops, Manon et Leila sur l’utilisation de Google Maps et l’aspect front.

= Outils (collaboration, CD/CI ...) =

CI/CD et gestion de code
Jira et Bitbucket étant tous deux des services Atlassian, il est possible de relier un Tableau Kanban de Jira avec un ou plusieurs dépôts Bitbucket. Cela nous permettait donc de créer une branche portant le nom d’un ticket Jira directement depuis le tableau Kanban. De plus, insérer le numéro du ticket associé dans un commit permettait d’accéder à ce ticket depuis Bitbucket lorsqu’on visualisait le commit. Étant un groupe de 4 développeurs, nous avons mis en place un processus d’intégration continue plutôt simple mais suffisamment robuste pour éviter les accidents. En effet, nous utilisions le principe de feature-branching avec une branche principale nommée dev et une branche master pour la production. Nous avons donc désactivé l’écriture directe dans ces branches et mis en place les codes reviews. Ainsi à chaque pull request vers dev effectuée, il était nécessaire que deux reviewers l’approuvent avant que celle-ci soit fusionnée. Notre projet n’étant qu’à la phase de prototype et la sécurité nécessaire n’étant pas été mise en place dès le début, il n’était pas continuellement déployé en production mais plutôt ponctuellement. Ceci, afin d'éviter d’engendrer des coûts supplémentaires mais aussi des failles de sécurité. Nous n’avons donc pas mis en place de déploiement continu.

Les différents environnements
L’utilisation de la plupart des services de Firebase entraîne des facturations au-delà d’un certain quota d’utilisation. Il nous était donc difficilement possible de mettre en place un environnement de test sur un serveur sans engendrer des coûts supplémentaires. En revanche, il nous était nécessaire de pouvoir tester des fonctionnalités et notamment des accès à la base de données sans passer par la production. C’est pourquoi nous avons utilisé un service de Google appelé Firebase Emulators Suite permettant d’émuler une grande partie des services proposés en ligne. Il nous a notamment permis d’avoir une base de données locale sur chacune de nos machines nous permettant de simuler la production de façon performante et viable. Une fois cet environnement de développement mis en place sur chacune de nos machines, il nous suffisait alors de lancer notre émulateur puis de lancer notre projet Flutter. De plus, au sein du projet Flutter, deux fichiers différents nous permettaient de faire tourner notre projet respectivement avec des services Firebase émulés et avec les services en ligne utilisés par la production. Dans le cas de l’environnement de développement, la Firebase Emulators Suite propose également une interface web permettant de visualiser en temps réel les entrées de la base de données mais aussi les données du service d’authentification.

Documentation du projet
Le projet n’étant qu’à la phase de prototype et notre porteur ayant recruté des stagiaires pour prendre la suite, il était nécessaire de rendre un code très structuré et maintenable pour faciliter leur adaptation. Mais par-dessus tout, comme ils arrivent après notre départ, il fallait que toutes les technologies utilisées ou outils mis en place soient très bien documentés. C’est pourquoi notre porteur a mis en place l’outil Confluence d’Atlassian permettant de gérer un wiki sous forme d’arborescence de pages. Ainsi l’espace Confluence associé au projet Jira contient 33 pages de documentation expliquant les divers choix d’implémentation, schémas et tutoriels nécessaires à la bonne compréhension du projet.

= Métriques logicielles =

Pour cette application nous avons écrit 2831 lignes de code. Le langage principal utilisé est Dart, mais nous avons aussi utilisé du Javascript, du Json et du yaml. Ce projet a duré 5 semaines, nous étions une équipe de 4 personnes et avons travaillé 35h par semaine nous avons donc un temps de travail d’environ 175h chacun. Nous avons travaillé sur Bitbucket et avons la répartition suivante des commits et des lignes de code :

= Conclusion (Retour d'expérience) =

= Transparent expliquant la démonstration =