{"id":30031771,"url":"https://github.com/thierrybeaulieu/polyzon","last_synced_at":"2025-08-06T20:48:52.194Z","repository":{"id":307402959,"uuid":"1029395720","full_name":"ThierryBeaulieu/Polyzon","owner":"ThierryBeaulieu","description":"Assignment created in 2024 for the course LOG2440","archived":false,"fork":false,"pushed_at":"2025-07-31T01:50:39.000Z","size":3065,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-31T04:25:42.576Z","etag":null,"topics":["development","web"],"latest_commit_sha":null,"homepage":"https://www.polymtl.ca/programmes/cours/method-de-develop-et-conc-dapplic-web","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ThierryBeaulieu.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-31T01:49:42.000Z","updated_at":"2025-07-31T02:08:10.000Z","dependencies_parsed_at":"2025-07-31T04:26:08.329Z","dependency_job_id":"5a7a9bf3-e666-4f99-b6b8-ea733b2e5397","html_url":"https://github.com/ThierryBeaulieu/Polyzon","commit_stats":null,"previous_names":["thierrybeaulieu/polyzon"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ThierryBeaulieu/Polyzon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThierryBeaulieu%2FPolyzon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThierryBeaulieu%2FPolyzon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThierryBeaulieu%2FPolyzon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThierryBeaulieu%2FPolyzon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ThierryBeaulieu","download_url":"https://codeload.github.com/ThierryBeaulieu/Polyzon/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThierryBeaulieu%2FPolyzon/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269153442,"owners_count":24369359,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-06T02:00:09.910Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["development","web"],"created_at":"2025-08-06T20:48:51.126Z","updated_at":"2025-08-06T20:48:52.116Z","avatar_url":"https://github.com/ThierryBeaulieu.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TP4 PolyZon\n\n# Mise en context et objectifs du travail pratique\n\nLe but de ce travail pratique est de vous familiariser avec le développement d'une application web _full stack_ utilisant une base de données pour assurer la persistance des données. Pour ce faire, vous utiliserez la librairie _React_ pour le côté client et vous vous connecterez à une base de données _MongoDB_ à partir d'un environnement _NodeJS_ pour le côté serveur.\n\nL'application à compléter est une preuve de concept d'un magasin en ligne qui permet à l'utilisateur de consulter des produits, de les ajouter à un panier et de passer une commande. Par la suite, l'utilisateur peut consulter ses commandes passées et faire une demande de remboursement. L'application est déjà partiellement développée et vous devez compléter les fonctionnalités manquantes.\n\nLe code source fourni contient deux applications distinctes, soit une application ReactJS (répertoire `site-web`) ainsi qu'une application NodeJS/Express (répertoire `server`). L'application React est constituée de composantes qui se retrouvent dans les répertoires `components` et `pages`.\nLe serveur, pour sa part, comprend des contrôleurs, des services et des données par défaut que vous pourrez retrouver dans `server/controllers`, `server/services` et `server/data`. C'est le fichier `server.js` qui sera exécuté au lancement du serveur.\n\n## Configuration de la base de données\n\nVous devez configurer une instance MongoDB pour la persistance de vos données. Vous devez utiliser le service [Cloud Atlas](https://www.mongodb.com/cloud/atlas).\n\nVous devez configurer votre instance avant de pouvoir effectuer le travail demandé. Un guide pour la configuration d'instances MongoDB avec Cloud Atlas est disponible sur le projet [GitHub du cours](https://github.com/LOG2440/Cours-11-MongoDB/blob/master/README.MD) de l'exemple sur MongoDB présenté en classe.\n\nLe fichier `env.js` contient les constantes avec les informations de connexion à votre instance MongoDB. Vous devez les remplacer avec les bonnes valeurs de votre propre instance. \n\n**Important** : Assurez-vous de remettre le fichier `env.js` avec les bonnes valeurs avant de remettre votre travail.\n\n## Installation des librairies nécessaires\n\nPour installer les dépendances nécessaires, lancez la commande `npm ci` dans la racine de chaque application (et donc deux fois au total). Ceci installera toutes les librairies définies dans le fichier `package-lock.json`. Vous pouvez par la suite utiliser les libraires de test (pour le serveur) et les scripts définis dans le même fichier.\n\n## Déploiement local\n\nLors du développement, vous pouvez faire un déploiement local d'un serveur statique qui servira votre site web et de votre serveur dynamique avec la commande `npm start`. Notez bien qu'il faut exécuter la commande à la racine de chaque application (dans `/site-web` et `/server`) dans deux consoles distinctes afin que les deux fonctionnent en parallèle.\n\nLe serveur statique sera déployé à l'adresse `localhost:5010` (ou `\u003cvotre-adresse IP\u003e:5010`). Le serveur dynamique sera déployé à l'adresse `localhost:5020` et commencera à écouter le port 5020.\n\nNotez que l'origine du site web n'est pas le serveur dynamique. Vous devez donc configurer votre serveur dynamique en conséquence pour accepter les requêtes provenant de l'origine du serveur statique.\n\n# Description du travail à compléter\n\nIl est conseillé de lire l'ensemble du travail demandé et d'implémenter les fonctionnalités une à la fois sur le serveur ET le site web. Vous pouvez également commencer par implémenter le code côté serveur en premier avant de vous attaquer au site web.\n\n## Format des données et les données initiales\n\nConsultez le fichier `products.json` dans le répertoire `data` pour des exemples de la structure de l'objet d'un produit à manipuler. \n\nLes commandes sont représentées comme des objets JSON avec les attributs suivants qui font référence aux produits achetés, le coût total de la commande et un identifiant unique. Voici un exemple :\n```json\n{\n    \"productIds\": [ \"1\", \"2\", \"3\" ],\n    \"totalCost\": 123.45,\n    \"id\": \"acb86e8a\"\n  }\n```\nLa génération d'un id unique pour les commandes est déjà implémentée pour vous dans le fichier `purchase.service.js`.\n\nLe résultat des manipulations de votre système doit produire des objets ayant la même structure. La persistance et toute donnée supplémentaire sera gérée par votre base de données MongoDB. \n\n# Serveur dynamique\n\nVous devez établir la communication avec une base de données MongoDB à partir de votre serveur dynamique. Pour ce TP, on vous demande de placer les différentes données dans 2 collections séparées nommées `PURCHASES` et `PRODUCTS`.\n\nLors du lancement du serveur dans `server.js`, celui-ci se connecte à la base de données et ajoute les données initiales dans la collection des produits, seulement si cette collection est vide. Initialement, il n'y a aucune commande dans le système. Ceci vous permettra d'avoir des données initiales avec lesquelles tester votre système.\n\nVous devez implémenter les fonctionnalités présentes dans les classes `ProductService`, `PurchaseService` et `DatabaseService` qui représentent les services principaux dans votre système. La classe `SearchBarService` est implémentée pour vous, mais fera appel à la fonction que vous aurez à implémenter. \n\nVous n’avez pas besoin de modifier les contrôleurs des routeurs Express fournis, mais vous devez compléter la configuration du serveur (TODO dans `server.js`). Chaque fonction à implémenter contient le mot clé TODO dans son en-tête. Les fonctions à compléter retournent des valeurs par défaut afin de permettre l’exécution du code, mais vous devez modifier ces valeurs de retour.\n\n### DatabaseService\n\nVous devez implémenter la fonction `populateDb` qui remplit une collection avec des données seulement si la collection est vide. Cette fonction est exécutée lors du lancement du serveur et remplit la BD avec les valeurs du fichier JSON du répertoire `data` du projet. Si la collection de la BD contienne déjà des valeurs, aucune modification ne devra avoir lieu. \n\n### ProductService\n\nCe service s'occupe des produits et leurs manipulations sur la base de données. Consultez les en-têtes des fonctions à implémenter ainsi que les tests présents dans `product.service.test.js` pour bien comprendre le fonctionnement des méthodes.\n\nNotez qu'il n'y a pas de méthodes d'ajout de nouveaux produits dans la base de données. Les produits sont ajoutés à la base de données lors du lancement du serveur à partir du fichier `products.json`. Vous pouvez ajouter vos propres produits dans ce fichier pour les ajouter à la base de données si vous le désirez.\n\n### PurchaseService\n\nCe service s'occupe des commandes et leurs manipulations sur la base de données. Consultez les en-têtes des fonctions ainsi que les tests présents dans `purchase.service.test.js` pour bien comprendre le fonctionnement des méthodes. Contrairement aux produits, il est possible d'ajouter et supprimer des commandes (appelé **demande de remboursement** dans le reste de l'énoncé). Notez que la fonction `getPurchaseProducts` permet de récupérer des informations sur les produits achetés dans une commande et doit donc intéragir avec le service `ProductService`.\n\n### SearchBarService\n\nLe code de la fonction `search` vous est déjà fourni. Vous devez compléter la fonction `search` dans `ProductService` qui va effectuer la recherche par mot clé.\n\nLa recherche doit tenir compte des champs possibles (nom et description du produit) et tenir compte du paramètre `exact` (recherche sensible à la case). *Astuce* : l'opérateur logique [$or](https://www.mongodb.com/docs/manual/reference/operator/aggregation/or/) de MongoDB vous sera utile.\n\nLa recherche se fait sur une sous-chaîne dans les attributs. Par exemple, la recherche `Savon` sans attribut `exact` devrait retourner les produits \"Savon à la main\" et \"Barre de savon\". La même recherche avec attribut `exact` devrait retourner seulement \"Savon à la main\" (sensible à la case).\n\n# Site web\n\nVous allez utiliser le patron [SAM](https://sam.js.org/) et le concept de `Reducer` pour gérer les actions envoyées par les composantes et modifier l'état de votre panier. Chaque action contient obligatoirement un type et, optionnellement, un contenu (`payload`). Par exemple : `{ type: ACTIONS.ADD_TO_CART, payload: { product } }`. Le fichier `reducer.js` contient le `Reducer` utilisé. Lisez bien le code fourni pour comprendre la bonne formulation des actions à envoyer. Vous aurez à implémenter la logique de gestion de certaines actions.\n\n### Composantes de pages\n\nLe répertoire `pages` contient l'ensemble des composantes React qui définissent les différentes \"pages\" de votre site web. Le site possède plusieurs pages : `Home` (Page principale), `About` (À propos), `Product` (Page de produit), `Cart` (Panier), `Returns` (Retour et commandes) et `Search` (Résultats de la recherche). Comme vous avez un site monopage (_SPA_), toutes ces pages sont des composantes React dans le même document HTML. Vous devez configurer correctement les routes vers chacune des pages dans le fichier `App.jsx` pour s'assurer que chaque URL est lié à la bonne composante à afficher.\n\nLa composante `About` (page à propos) vous est fournie et vous n'avez pas à la modifier. Les autres composantes contiennent le mot clé **TODO** aux endroits à compléter.\n\n#### Page Principale (Home.jsx)\n\nCette page affiche les produits disponibles dans votre magasin. Voici le visuel avec les donnes initiales fournies : \n\n![Page principale](Doc/20241_tp4_home.png)\n\nVous devez compléter la récupération des produits au chargement de la composante et leur affichage à l'aide de composantes `ProductCard`. Chaque produit est affiché dans une vignette avec son image, son nom et un bouton d'ajout au panier. Si le produit est déjà dans le panier, le même bouton permet de le retirer.\n\n#### Page d'un produit (Product.jsx)\n\nCette page affiche les informations d'un produit spécifique. La page offre la possibilité d'ajouter le produit au panier ou de procéder à son achat directement sans avoir à passer par le panier.\n\nVoici son visuel : \n\n![Page de produit](Doc/20241_tp4_product_add.png)\n\nTout comme la page principale, si le produit est déjà dans le panier, le premier bouton permet de le retirer. Le deuxième bouton permet d'acheter directement le produit sans passer par le panier et génère une commande dans le système.\n\n![Page de produit avec panier](Doc/20241_tp4_product_remove.png)\n\nVous devez compléter le HTML de la composante pour l'affichage des informations du produit. Vous devez implémenter le fonctionnement des deux boutons dans l'interface pour l'ajout du produit dans le panier ou son achat direct.  Consultez l'implémentation du `reducer` pour bien comprendre les actions à envoyer.\n\n### Page de panier (Cart.jsx)\n\nCette page permet d'afficher le panier et son contenu : chaque nom de produit accompagné de son prix. Un bouton permet de retirer chaque produit du panier. Vous devez implémenter cette action dans le `reducer`.\n\nLe prix total est toujours affiché à la fin de la liste et doit être mis à jour à chaque modification du panier. Voici le visuel de la page suite à 2 ajouts de produits différents :\n\n![Page de panier](Doc/20241_tp4_cart.png)\n\nLe bouton \"Vider le panier\" permet de retirer tous les produits du panier. Un message \"Le panier est présentement vide\" est alors affiché. Vous devez implémenter cette action dans le `reducer`.\n\nLe bouton \"Procéder à l'achat\" permet de générer une commande dans le système. Le panier est vidé suite à cette action et l'interface est mise à jour.\n\nLes 2 boutons sont disponibles seulement si le panier n'est pas vide.\n\nVous devez compléter le HTML de la composante pour l'affichage des informations du panier et la gestion de la suppression des produits.\n\n### Page de retour et commandes (Returns.jsx)\n\nCette page permet d'afficher les commandes passées par l'utilisateur et de faire une demande de remboursement. Chaque commande est affichée à l'aide de la composante `Purchase`. Si aucune commande n'est présente, le message \"Aucun produit n'a été acheté\" est affiché à l'utilisateur. Voici le visuel de la page suite à 2 commandes différentes :\n\n![Page de retours et commandes](Doc/20241_tp4_returns.png)\n\nVous devez compléter le HTML de la composante pour l'affichage des informations des commandes et la gestion de la demande de remboursement. La fonction `updatePurchases` permet la mise à jour de la liste de commandes suites à une demande de remboursement.\n\n### Page de recherche (Search.jsx)\n\nCette page est visuellement similaire à la page principale, mais contient seulement le résultat d'une recherche à travers la barre de recherche dans l'entête du site. Vous êtes redirigé vers cette page lors d'une recherche, peu importe la vue d'origine. Voici le visuel de la page :\n\n![Page de recherche](Doc/20241_tp4_search.png)\n\nVous devez compléter la récupération des produits au chargement de la composante et leur affichage à l'aide de composantes `ProductCard`. \n\n### Autres composantes\n\nLe répertoire `components` contient l'ensemble des autres composantes React qui définissent les différents éléments utilisés dans les composantes de pages du site web. Les composantes `SearchBox` et `Footer` vous sont fournies pour vous aider avec votre travail et vous n'avez pas à les modifier sauf pour ajouter vos noms dans `Footer`.\n\nLes autres composantes contiennent des éléments à compléter. Le mot clé **TODO** est présent aux endroits à compléter. Vous devez compléter des fonctions ou compléter le HTML retourné par la composante en utilisant la bonne syntaxe JSX.\n\n#### Barre de navigation (NavBar.jsx)\n\nCette composante est partagée par toutes les pages.\n\nVous devez ajouter les bons liens vers les pages `/about`,`/cart` et `/returns` en utilisant les bons éléments de la librairie `react-router-dom` et non la balise `\u003ca\u003e`. Référez-vous aux captures d'écran plus haut pour le visuel attendu.\n\nNotez que le lien vers le panier indique le nombre de produits dans celui-ci. Vous devez compléter le code qui permet une mise à jour automatique de ce nombre à chaque modification (ajout ou retrait) du panier.\n\n#### Carte de produit (ProductCard.jsx)\n\nCette composante est utilisée dans `Home.jsx` et `Search.jsx` pour afficher les produits disponibles dans le magasin. Vous devez compléter le code HTML pour l'affichage des informations du produit. Referrez-vous à la première capture d'écran pour le visuel attendu.\n\nCliquer sur l'image du produit devrait rediriger l'utilisateur vers la page du produit en question. Le bouton d'ajout au panier doit ajouter le produit au panier ou le retirer si le produit est déjà dans le panier. Le code JSX du bouton vous est fourni et vous devez implémenter la logique de gestion de ces 2 actions dans `reducer.js`. \n\nNotez qu'un produit ne peut pas se retrouver dans le panir plus qu'une fois et que toute modification du panier doit être réflétée dans la barre de navigation.\n\n#### Commande (Purchase.jsx)\n\nCette composante est utilisée dans `Returns.jsx` pour afficher les commandes passées par l'utilisateur. Chaque commande est composée d'au moins 1 produit et le prix total de la commande. Vous devez compléter le code HTML pour l'affichage des informations de la commande. Referrez-vous à l'avant dernière capture d'écran pour le visuel attendu.\n\nCette composante contient 1 seul bouton qui permet de faire une demande de remboursement pour la commande en question. Vous devez compléter le code pour envoyer une action de remboursement au `reducer` et une mise à jour de la page parent par la suite. Une demande de remboursement ne doit pas affecter le contenu du panier en cours.\n\n## Exécution des tests\n\nVeuillez consulter le fichier [TESTS.MD](./TESTS.MD) pour plus d'informations sur les tests du travail.\n\n## Fonctionnalité bonus\n\nDans la version de base de votre projet, le contenu du panier n'est pas persisté. Si l'utilisateur rafraîchit la page ou ferme le navigateur, le contenu du panier est perdu. Vous devez mettre en place une persistance du panier qui permet de conserver le contenu du panier tant et aussi longtemps que la page n'est pas complétement fermée. Vous devez implémenter cette fonctionnalité dans la logique du `reducer` seulement. Vous n'avez pas à modifier le serveur pour cette fonctionnalité.\n\n# Correction et remise\n\nLa grille de correction détaillée est disponible dans [CORRECTION.MD](./CORRECTION.MD). Le navigateur `Chrome` sera utilisé pour l'évaluation de votre travail. L'ensemble des tests fournis doivent réussir lors de votre remise. Les tests ajoutés par l'équipe doivent aussi réussir.\n\nLe travail doit être remis au plus tard le mardi 16 avril à 23:55 sur l'entrepôt Git de votre équipe. Le nom de votre entrepôt Git doit avoir le nom suivant : `tp4-matricule1-matricule2` avec les matricules des 2 membres de l’équipe.\n\n**Aucun retard ne sera accepté** pour la remise. En cas de retard, la note sera de 0.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthierrybeaulieu%2Fpolyzon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthierrybeaulieu%2Fpolyzon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthierrybeaulieu%2Fpolyzon/lists"}