# Trade Me [GitHub repo](https://github.com/Nouuu/AL-TradeMe)
[![github](https://img.shields.io/badge/repository-github-blue)](https://github.com/Nouuu/AL-TradeMe)
Main status[![Coverage](https://sonar.nospy.fr/api/project_badges/measure?branch=main&project=Nouuu_AL-TradeMe&metric=coverage&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe)[![Maintainability Rating](https://sonar.nospy.fr/api/project_badges/measure?branch=main&project=Nouuu_AL-TradeMe&metric=sqale_rating&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=main)[![Quality Gate Status](https://sonar.nospy.fr/api/project_badges/measure?branch=main&project=Nouuu_AL-TradeMe&metric=alert_status&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=main)[![Reliability Rating](https://sonar.nospy.fr/api/project_badges/measure?branch=main&project=Nouuu_AL-TradeMe&metric=reliability_rating&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=main)[![Security Rating](https://sonar.nospy.fr/api/project_badges/measure?branch=main&project=Nouuu_AL-TradeMe&metric=security_rating&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=main)
[![Code smells](https://sonar.nospy.fr/api/project_badges/measure?branch=main&project=Nouuu_AL-TradeMe&metric=code_smells&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=main) [![Bugs](https://sonar.nospy.fr/api/project_badges/measure?branch=main&project=Nouuu_AL-TradeMe&metric=bugs&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=main)[![Vulnerabilities](https://sonar.nospy.fr/api/project_badges/measure?branch=main&project=Nouuu_AL-TradeMe&metric=vulnerabilities&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=main)
[![Technical Debt](https://sonar.nospy.fr/api/project_badges/measure?branch=main&project=Nouuu_AL-TradeMe&metric=sqale_index&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=main)
Dev status[![Coverage](https://sonar.nospy.fr/api/project_badges/measure?branch=dev&project=Nouuu_AL-TradeMe&metric=coverage&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=dev)[![Maintainability Rating](https://sonar.nospy.fr/api/project_badges/measure?branch=dev&project=Nouuu_AL-TradeMe&metric=sqale_rating&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=dev)[![Quality Gate Status](https://sonar.nospy.fr/api/project_badges/measure?branch=dev&project=Nouuu_AL-TradeMe&metric=alert_status&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=dev)[![Reliability Rating](https://sonar.nospy.fr/api/project_badges/measure?branch=dev&project=Nouuu_AL-TradeMe&metric=reliability_rating&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=dev)[![Security Rating](https://sonar.nospy.fr/api/project_badges/measure?branch=dev&project=Nouuu_AL-TradeMe&metric=security_rating&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=dev)
[![Code smells](https://sonar.nospy.fr/api/project_badges/measure?branch=dev&project=Nouuu_AL-TradeMe&metric=code_smells&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=dev) [![Bugs](https://sonar.nospy.fr/api/project_badges/measure?branch=dev&project=Nouuu_AL-TradeMe&metric=bugs&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=dev)[![Vulnerabilities](https://sonar.nospy.fr/api/project_badges/measure?branch=dev&project=Nouuu_AL-TradeMe&metric=vulnerabilities&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=dev)
[![Technical Debt](https://sonar.nospy.fr/api/project_badges/measure?branch=dev&project=Nouuu_AL-TradeMe&metric=sqale_index&token=edc93fd166b059d5befe7e2fe22d2e0d10d9b853)](https://sonar.nospy.fr/dashboard?id=Nouuu_AL-TradeMe&branch=dev)
## Fonctionnalités métiers ### Membres - Ajouter / Modifier / Supprimer un **Contractor** - Ajouter / Modifier / Supprimer un **Tradesman** - Faire une demande de paiement pour un **Contractor** - Faire une demande de paiement pour un **Tradesman** - Libérer un **Tradesman** d'un **Projet** - Assigner un **Tradesman** à un **Projet** - Mettre à jour les attributs professionnel d'un **Tradesman** - Mettre à jour le statut de paiement d'un **Tradesman** - Mettre à jour le statut de paiement d'un **Contractor** - Trouver un **Tradesman** qui match pour un **Projet** - Récupérer un **Tradesman** - Récupérer tout les **Tradesman** - Récupérer les compétences d'un **Tradesman** - Récupérer un **Contractor** - Récupérer tout les **Contractor** ### Paiement - Payer un abonnement pour un **Contractor** - Payer un abonnement pour un **Tradesman** ### Factures - Créer une **facture** - Supprimer les **factures** d'un **Contractor** - Supprimer les **factures** d'un **Tradesman** - Récupérer toutes les **factures** - Récupérer les **factures** des **Tradesman** - Récupérer les **factures** des **Contractor** - Récupérer les **factures** d'un **Tradesman** - Récupérer les **factures** d'un **Contractor** - Récupérer une **facture** ### Projets - Ajouter / Modifier un **Projet** - Terminer un **Projet** - Ajouter / Retirer un métier au **Projet** - Ajouter / Modifier / Retirer une compétence requise à un **Projet** - Assigner un **Tradesman** à un **Projet** - Enlever un **Tradesman** du **Projet** - Récupérer les **Projets** - Récupérer un **Projet** - Récupérer les **Projets** d'un **Contractor** - Récupérer les **Projets** d'un **Tradesman** - Récupérer les compétences requises d'un **Projet** ## Architecture choisie ### Onion Architecture Pour mener a bien le projet l'on s'est inspiré de concept qui viennent des architectures dites **clean** et de garder ces 3 objectifs en tête. 1. Être independent du framework et des librairies externe. 2. Testable : Il doit être facile d'ajouté des tests dans la base de code. 3. Être independent de la manière dont on fait persister nos données. ### Domain-Driven Design Lors de la conception du projet on a essayé d'utiliser une approche pilotée par les usecase et le Domaine, en suivant ce que l'on connaissait du **DDD** (**Domain-Driven Design**) et fonctionnant avec des aggregates. En utilisant ubiquitous langage, pour partager un langage comment au sein de l'équipe, qui est le langage du métier. On a bien séparé nos features dans des **bounded context** qui partage ce qu'ils ont en commun (les **events** et certain **model interne**) via le **shared kernel**. ### Staged event-driven architecture L'**architecture événementielle par étapes** (**SEDA**) fait référence à une approche de l'architecture logicielle qui décompose le cycle de vie d'un processus en un ensemble d'étapes reliées par des files d'attente. Il évite la surcharge élevée associée aux threads basés sur les modèles de concurrence et découple la planification des événements et des threads de la logique de l'application. Chaque fonctionnalité de l'application est gérée par un bus d'évènement principal, qui permet de relier ces évènements à des observateurs présents dans une ou plusieurs autres fonctionnalités afin de pouvoir exécuter certaines actions secondaire. De cette manière, nous pouvons gérer grâce à un maillage entre événement et observateurs tout le comportement de nos fonctionnalités entre elles sans que ces dernières ne communiquent jamais directement entre elle. Un des nombreux avantages que cela représente et le découpage de notre application qui devient beaucoup plus simple, et qui se prête naturellement aux **micro services**. ### Architectural Decision Record Voilà quelques décisions d'architecture que nous avons pris pendant le développement du projet : - [Communications externes](https://wiki2.nospy.fr/attachments/3) - [Communications internes](https://wiki2.nospy.fr/attachments/2) - [Service VS Command/Query Handler](https://wiki2.nospy.fr/attachments/4) - [Utilisation des records](https://wiki2.nospy.fr/attachments/5) - [Validation](https://wiki2.nospy.fr/attachments/6) ## Implémentation ### Dependency Inversion Principle Le principe d'inversion des dépendances correspond au « **D** » de l'acronyme **SOLID**. En suivant ce principe, la relation de dépendance conventionnelle que les modules de haut niveau ont, par rapport aux modules de bas niveau, est inversée dans le but de rendre les premiers indépendants des seconds. Les deux assertions de ce principe sont : 1. Les modules de haut niveau ne doivent pas dépendre des modules de bas niveau. Les deux doivent dépendre d'abstractions. 2. Les abstractions ne doivent pas dépendre des détails. Les détails doivent dépendre des abstractions. Ce principe a été respecté pour cette application. ### Command Query Separation La **séparation commande-requête** est un principe de la programmation impérative. Elle stipule que chaque méthode doit être une ***commande*** qui effectue une action ou une ***requête*** qui renvoie des données à l'appelant, mais pas les deux. Plus formellement, les méthodes ne devraient retourner une valeur que si elles sont référentiellement transparentes et ne possèdent donc pas d'effets de bord. Ce principe a été respecté au maximum au sein de l'application, même les observateurs d'événements utilisent ce principe. ### Packages #### Application Le package applicatif contient le **traitement dit métier** de notre application. Ce sont eux qui vont utiliser les différentes ressources de notre application pour **exécuter les traitements de leurs propres domaines** Les services présents dans ce package se basent principalement sur les **interfaces** de nos autres classes afin de ne pas être dépendants d'une implémentation en particulier. On peut faire ça grâce au **polymorphisme**, la **programmation par interfaces** et le **pattern dependency injection**. Ces mêmes services sont des "micro-services" qui respecte le fameux pattern **CQS** et sont donc des **Query** / **Command** handlers. Cas d'utilisation, création d'un contractor : [![CreateContractorService_handle.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/createcontractorservice-handle.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/createcontractorservice-handle.png) #### API Ce package est utilisé pour pouvoir avoir recours à des services externes en utilisant le **pattern strategy**. L'interface est présente dans le package **api** et son implémentation dans **l'infrastructure**. Pour le moment, une seule API est présente, celle du **paiement** qui peut potentiellement lancer une exception ou pas pour indiquer si la transaction s'est bien effectué. Elle est actuellement implémentée par un **stub** qui ne déclenche pas d'exception (paiement effectué). #### Configuration Ce package est celui qui permet le maillage entre toutes nos interfaces et leurs implémentations, c'est lui qui va gérer le contexte et l'injection de dépendances. #### Domain Ce package contient tous les modèles du domaine métier de notre application. C'est également celui qui contient les différentes interfaces qui peuvent être injectés dans nos services applicatifs (ex : Les interfaces des repositories). ##### Event Afin de pouvoir prendre en compte **différents traitements**, sans avoir à modifier le service et que ce dernier n'ai qu'**une seule responsabilité**, on utilisera le **pattern event, observable** afin de lancer un événement lors de différentes actions menés à l'intérieur d'un service. Ces mêmes événements seront alors pris en charge par des observables (listener) un peu partout dans le programme, qui feront eux même appel à une command / requête pour déclencher une action secondaire au traitement initial. Les différentes tâches à exécuter suite à cet enregistrement n'auront alors qu'à **s'inscrire à cet événement** pour lancer leur propre traitement. Cas d'utilisation, création d'une facture suite à un paiement effectué : [![ContractorSubscriptionPaymentService_handle.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/contractorsubscriptionpaymentservice-handle.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/contractorsubscriptionpaymentservice-handle.png) [![NewContractorSubscriptionPaymentListener_accept.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/newcontractorsubscriptionpaymentlistener-accept.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/newcontractorsubscriptionpaymentlistener-accept.png) ##### Model Ce package contient toutes les entités utilisées dans l'application, elles suivent le **pattern value object** ainsi qu'**entity**. L'objet est donc immutable et possède un identifiant pour son utilisation à travers un repository. ##### Exception Contient les exceptions d'exécution du domaine métiers tel que **PaymentException** si le paiement a échoué, \*\* UserInvalidException\*\* si l'utilisateur n'est pas valide et **UserNotFoundException** si l'utilisateur n'est pas présent dans le repository implémenté. #### Features Chaque fonctionnalité de notre application est séparée dans différents packages à l'intérieur du package feature. Ces dernières ne peuvent utiliser les ressources uniquement de l'application principale, mais jamais directement entre elles. Une feature ne dépend jamais d'une autre feature. Ces dernières reprennent chacune les différents packages (domain, infrastructure, kernel, ...) selon leurs besoins. Actuellement, il existe 4 features : - **Invoices** qui gère la génération et récupération des factures lors d'un paiement d'un utilisateur - **Member** qui gère les utilisateurs de TradeMe (CRUD) - **Payment** qui s'occupe d'effectuer les paiements lorsque cela est nécessaire. - **Projects** qui gère les projets de l'application #### Infrastructure ##### Repositories Pour cela on utilise le **pattern repository et strategy** afin de **séparer son interface**, qui restera dans le \*\* domaine\*\*, de son implémentation dans **l'infrastructure**. Actuellement, il existe deux implémentations de cette interface : - Une en mémoire : les entités en mémoire et se vide quand l'application s'arrête. - Une grâce à un fichier JSON, qui persiste à arrêt de l'application et se charge au démarrage. Il est possible de switcher entre l'un et l'autre grâce à la propriété `repository.in-memory=true|false` dans le fichier `application.properties` #### Kernel Ce package contient les différentes interfaces et leurs implémentations de fonctions "utilitaires" qui pourront être exploité par nos services applicatifs et autre afin d'assurer un fonctionnement correct de notre application. ##### IO Ce package nous permet d'avoir les interfaces **Reader** et **Writer** qui vont nous permettre d'interagir avec différents contenus, tel que des fichiers par exemple. Il y a actuellement deux implémentations pour chacune de ces interfaces. Les deux permettent accéder à des fichiers. ##### Marshaller Le package marshaller met à disposition une interface de **Sérialisation** et de **Désérialisation** de nos objets vers une chaine de caractères. Actuellement, il existe une implémentation de chaque pour le format **JSON**. ##### Exception handler Ce package contient également des intercepteurs permettant d'intercepter les exceptions métiers lancés dans le programme afin d'en avoir un traitement centralisé pour logger l'erreur et faire un retour adapté pour l'utilisateur. [![RuntimeExceptionHandler_toResponse.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/runtimeexceptionhandler-toresponse.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/runtimeexceptionhandler-toresponse.png) ##### Validators Apporte des fonctions utilitaires de validation de nos différentes entités du domaine. Exemple : Lors de la vérification des champs, le programme jouera le diagramme de séquence suivant : [![5c7cc1b9735a6d60726007287ea148f0f0509299.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/5c7cc1b9735a6d60726007287ea148f0f0509299.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/5c7cc1b9735a6d60726007287ea148f0f0509299.png) ##### Command Ce package contient la logique d'exécution d'une commande et le bus qui y est associé. Ce dernier possède une implémentation globale à chaque features et est injecté grâce au package configuration qui aura configuré le maillage correctement entre les commandes et les services associés. Le comportement suivant est observé : [![b03d3454f6c7f3dbeb0336faaf94ee45eb074b77.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/b03d3454f6c7f3dbeb0336faaf94ee45eb074b77.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/b03d3454f6c7f3dbeb0336faaf94ee45eb074b77.png) Création d'un contractor : [![ContractorController_register-16417374095051.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/contractorcontroller-register-16417374095051.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/contractorcontroller-register-16417374095051.png) ##### Query Ce package contient la logique d'exécution d'une requête et le bus qui y est associé. Ce dernier possède une implémentation globale à chaque features et est injecté grâce au package configuration qui aura configuré le maillage correctement entre les requêtes et les services associés. Le comportement suivant est observé : [![226848c6adb9c7b64e310525ca2fe3cc8b8c5654.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/226848c6adb9c7b64e310525ca2fe3cc8b8c5654.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/226848c6adb9c7b64e310525ca2fe3cc8b8c5654.png) Récupération d'un contractor : [![ContractorController_getById.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/contractorcontroller-getbyid.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/contractorcontroller-getbyid.png) ##### Event Ce package est essentiel au bon déroulement de notre architecture SEDA ! Il contient la logique du bus d'événement qui permet à tous les observables de s'enregistrer à un événement. Ainsi, lorsque qu'un événement est publié, il est ensuite distribué à tous ses observateurs. Comportement du bus d'événement par défaut : [![DefaultEventBus_publish.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/defaulteventbus-publish.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/defaulteventbus-publish.png) ##### Logger En utilisant le **pattern strategy** ainsi que **factory**, ce package permet à une classe d'obtenir un logger qui lui est propre grâce au **LoggerFactory**. Les interfaces font parties du **domaine** et leurs implémentations de \*\* l'infrastructure\*\*. Actuellement l'implémentation présente réutilise le la classe **Logger** **de Java**. Une deuxième implémentation utilise le logger **JBoss** qui permet d'avoir des logs formatés autrement en console, en plus de les écrire dans un fichier de logs en temps réel afin de garder une trace du comportement de l'application et des éventuelles erreurs. #### Shared kernel Ce package est présent sur le niveau le plus haut de l'application, avant les **features**. Ce dernier contient les entités qui sont partagées entre les différents usecases. #### Web Ce package fournit une interface pour l'utilisateur afin qu'il puisse utiliser l'application à l'aide de requêtes REST. Ce dernier utilise uniquement les command et les requêtes à travers leurs bus associé, et n'a pas connaissance de quoi que ce soit d'autre dans l'application, ce qui lui permet d'avoir très peu de dépendance sur le fonctionnement global, hormis les entités du domaine. Cas d'utilisation, récupération des factures : [![InvoiceController_getAll.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/invoicecontroller-getall.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/invoicecontroller-getall.png) ## Quarkus Pour gagner en puissance dans notre application et avoir des controller web ainsi qu'une **injection de dépendance** puissante, l'application est soutenue par le framework **Quarkus**. Ce dernier sert à : - Gérer les controller web ainsi que le sérialiseur / désérialiser JSON grâce à **Jackson** - Configurer les différentes **bean** pour l'injection de dépendances au sein des différents services (package configuration) - Gérer le **Scheduler** qui permet de lancer les paiements mensuels. - Intégrer le logger **JBoss** plus facilement. - Intégrer **Swagger** plus facilement grâce à des annotations sur les controller - Gérer certain paramètre de l'application à la volée sans devoir recompiler le code tout le temps grâce à un fichier de configuration **application.properties** (configuration swagger, gestion du prix des abonnements, du jour de paiement, du formatage et du stockage des logs). [![image-20220305155344800.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220305155344800.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220305155344800.png) Le découpage de l'application en amont a permis une intégration très simple de Quarkus. L'application ne dépend pas de quarkus mais utilise simplement le framework comme une implémentation de la solution. ### Dependency Injection Dans le package configuration, les beans sont réparties dans différentes classes : #### GlobalConfiguration C'est lui qui va injecter les bean dites "globales" tel que le logger ou encore la classe contenant les montants pour les abonnements. [![image-20220305153432641.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220305153432641.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220305153432641.png) #### APIConfiguration Comme son nom l'indique, inject les différents API nécessaires au bon fonctionnement de l'application, actuellement il n'y a que l'API de paiement qui est injecté, mais d'autres peuvent être amené à être créés... [![APIConfiguration.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/apiconfiguration.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/apiconfiguration.png) #### CommandConfiguration Injecte les différents bus de commandes selon la feature, la configuration aura fait au préalable le maillage nécessaire entre les commandes et les services applicatifs. [![image-20220305153609910.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220305153609910.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220305153609910.png) #### QueryConfiguration Injecte les différents bus de requêtes selon la feature, la configuration aura fait au préalable le maillage nécessaire entre les requêtes et les services applicatifs. [![image-20220305153653788.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220305153653788.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220305153653788.png) #### EventConfiguration Injecte les différents bus d'événements selon le type d'événement (actuellement uniquement ceux du type \*\* ApplicationEvent\*\*), la configuration aura fait au préalable le maillage nécessaire entre les événements et les observateurs.
[![image-20220305153731926.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220305153731926.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220305153731926.png)[![EventConfiguration.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/eventconfiguration.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/eventconfiguration.png)
#### RepositoryConfiguration Injecte les différents repositories au sein des services qui en ont besoin : [![image-20220305153814991.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220305153814991.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220305153814991.png) #### IOConfiguration Injecte l'implémentation choisie pour nos Reader et Writer : [![image-20220305154003138.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220305154003138.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220305154003138.png) #### MarshallerConfiguration Injecte l'implémentation choisie pour notre Sérialiser et Désérialiser : [![image-20220305154035698.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220305154035698.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220305154035698.png) ## Tests unitaires Afin d'assurer le bon fonctionnement et grâce au découpage de nos composants, l'application est couverte par des tests unitaires (qui se lancent d'ailleurs automatiquement à chaque push sur github grâce à des **actions de CI**). Nous utilisons CodeCov pour analyser les rapports de tests unitaires au moment de push ou de pull requests [![image-20220109160441842.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220109160441842.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220109160441842.png) [![image-20220305134206216.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220305134206216.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220305134206216.png)
Branche DEVBranch MAIN
[![codecov](https://codecov.io/gh/Nouuu/AL-TradeMe/branch/dev/graph/badge.svg?token=07VGBLNOBQ)](https://codecov.io/gh/Nouuu/AL-TradeMe)[![codecov](https://codecov.io/gh/Nouuu/AL-TradeMe/branch/main/graph/badge.svg?token=07VGBLNOBQ)](https://codecov.io/gh/Nouuu/AL-TradeMe)
![grid coverage](https://codecov.io/gh/Nouuu/AL-TradeMe/branch/dev/graphs/tree.svg?token=07VGBLNOBQ)![grid coverage](https://codecov.io/gh/Nouuu/AL-TradeMe/branch/main/graphs/tree.svg?token=07VGBLNOBQ)
## Swagger Lorsque l'application est lancée avec le profil **dev** ou **test** cette dernière rend accessible une page web swagger-ui afin de pouvoir tester directement nos interfaces REST et visualiser nos entités pour les requêtes, ainsi que ceux en réponse. Le Swagger est configurables grâce à quelques propriétés dans le fichier `application.properties` : [![image-20220305155045674.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220305155045674.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220305155045674.png) Le Swagger est accessible à l'adresse suivante lorsque l'application est lancée : http://localhost:8080/q/swagger-ui/#/ [![image-20220305154723783.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220305154723783.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220305154723783.png) ## SonarQube Pour assurer un code propre, le code de l'application est analysé à chaque mise à jour par un serveur Sonarqube autohébergé (https://sonar.nospy.fr) pour assurer que le code rempli bien les critères de maintenabilité, sécurité, fiabilité, ... [![image-20220109155624909.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220109155624909.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220109155624909.png) [![image-20220109155708591.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220109155708591.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220109155708591.png) [![image-20220109155835217.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220109155835217.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220109155835217.png) [![image-20220109155804810.png](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/scaled-1680-/image-20220109155804810.png)](https://wiki2.nospy.fr/uploads/images/gallery/2022-05/image-20220109155804810.png)