# Architecture Web : Rapport Sébastien Martinez Balbuena 18360 ## Introduction Dans l'organisation à laquelle j'appartiens, il y a plusieurs bâtiments servant de logement, où les ailes et et les étages abritent des groupes d'étudiants par année/promotion. La prévention/gestion incendie est considérée comme très importante et un tableau en bois est mis à l'entrée du bâtiment afin que les étudiants puissent indiquer s'ils sont présents ou non dans le batiment. Ceci permet d'avoir une liste des personnes présentes et donc de pouvoir faire l'appel en cas d'incendie. Hélàs ce tableau est peu pratique : il est difficile d'identifier facilement son emplacement à soi (trop de noms), il est ambigu (vert pour absent, rouge pour présent) ce qui fait que selon les promotions les usages diffèrent, ce tableau ne se trouve qu'à une seule des nombreuses entrées (ce qui implique de devoir faire détour) et finalement c'est généralement la cohue lors d'un incendie et il est donc peu pratique d'aller voir le tableau dans ce genre de moments. Bref, tout ceci fait que ce tableau n'est pas du tout utilisé en pratique, ce qui pourrait causer des problèmes en cas d'incendie : pompiers allant rechercher un élève alors que celui-ci n'est pas présent ou l'inverse. Le but de cette application web serait de pouvoir remplacer ce tableau, en permettant une plus grande clarté et une meilleure accessibilité. ## Spécifications ### Objectif du site Le site doit permettre à un utilisateur, appartenant à un groupe, d'indiquer sa présence ou son absence dans le bâtiment. Il doit pouvoir modifier son numéro de chambre. Un gestionnaire de groupe doit pouvoir générer une liste des présences des membres de son groupe afin de pouvoir faire l'appel depuis un point de rendez-vous. Le gestionnaire de groupe doit pouvoir ajouter et supprimer des utilisateurs à son groupe. Les utilisateurs devraient pouvoir alerter qu'il y a un incendie et ainsi alerter les utilisateurs faisant partie du même bâtiment. Les utilisateurs et managers pourront se connecter et les fonctionnalités auront besoin d'autorisations (sections reservées au manager, update de la chambre uniquement par l'utilisateur lui-même, etc.). ### User stories | User story | Priorité | | -------- | -------- | | En tant qu'utilisateur je veux pouvoir mettre à jour ma présence dans la chambre | 1 | | En tant qu'utilisateur je veux pouvoir changer ma chambre actuelle | 2 | | En tant qu'utilisateur je veux pouvoir alerter qu'il y a un incendie dans le bâtiment | 2 | | En tant que manager je veux pouvoir consulter les présences dans les chambres | 1 | | En tant que manager je veux pouvoir gérer l'ajout/la suppression des membres dans mon groupe | 1 | | En tant que manager je veux pouvoir faire marquer les présences à un point de rendez vous | 2 | | En tant que manager je veux pouvoir trier les membres du groupe par présence ou ordre alphabétique | 3 | #### Constraintes non fonctionnelles Le site sera ergonomique et responsive. Exemple: il devra permettre de notifier l 'utilisateur qu'il y a une alerte incendie en cours dans son bâtiment, par exple par l'affichage d'une banderole rouge. Il serait intéressant de limiter les appels à l'API pour avoir une liste des présences (ex: 3x par mois), cela permettrait d'éviter les abus où les responsables pourraient traquer en direct la présence ou non d'un élève. #### Acteurs * Utilisateur : Personne logeant dans le bâtiment, essentiellement des élèves. * Gestionnaire de groupe : Responsable designé au sein d'une promotion. Accésoirement, il y aura un administrateur : il peut créer/supprimer des promotions et y assigne les gestionnaires. ### Mockup Voir les présences : ![](https://i.imgur.com/CMn9w6d.png) Pour l'utilisateur : Interface très simple pour pouvoir indiquer sa présence et alerter d'un incendie, avec mise en évidence de l'état actuel. ![](https://i.imgur.com/5x7woBh.png) La plupart des autres fonctions (changement de chambre, ajout d'utilisateurs), seront des formulaires plutôt simples, avec un champ de texte et un boutton de validation. ## Base de données ### Diagramme entité relation ![](https://i.imgur.com/YsdxJ3E.png) ### Diagramme relationnel J'utilise une base de données MySQL, gérée par Sequelize. Chaque promotion contient des utilisateurs (relation 1 -> n) et peut avoir plusieurs managers, qui sont eux-mêmes des utilisateurs (relation n -> n). La table "managers" gère l'association entre les gestionnaires et les promotions. <!-- ![](https://i.imgur.com/AXdnGlH.png) --> ![](https://i.imgur.com/raKypCh.png =400x) ### Champs importants * service_number : Numéro de matricule, qui sera utilisé pour identifier l'utilisateur. * inside : Boolean qui donne la présence ou non de l'élève dans sa chambre. * isAdmin : Permet de donner des droits d'administrateur à l'utilisateur. * prom_name : Le nom de la promotion. Dans users, permet de déterminer à quelle promotion appartient l'utilisateur (utilisé comme foreign key). * battalion : Définit à quel groupe appartient la promotion (2 possibilités). Propre à l'organisation à laquelle j'appartiens. Les autres champs ne présentent rien de particulier et sont assez explicites par leur nom. ## Documentation API et implémentation en NodeJs ### Routage Script concerné : https://github.com/smarbal/firesave-API/blob/main/router.js Toutes les requêtes (sauf celles d'Authentification) ont besoin de l'envoi d'un JWT (en paramètre post ou en header) afin de vérifier les autorisations. #### Authentification | Méthode HTTP | URI | Action | Description | | -------- | -------- | -------- | ----------------| |post | /register | userController.userCreate | Créer un utilisateur | |post | /login | authController.login | Se connecter. Renvoie un JWT | Les mots de passes sont hashés. Script concerné : https://github.com/smarbal/firesave-API/blob/main/controllers/authController.js #### Gestion utilisateur | Méthode HTTP | URI | Action | Description | Autorisation | | -------- | -------- | -------- | ----------------| ---| |get | /user | userController.userList | Liste tous les utilisateurs | Admin |get | /user/find/:service_number | userController.userFindOne | Renvoie un utilisateur identifié par son matricule | Utilisateur |put | /user/:service_number | userController.userUpdate | Modifie un utilisateur identifié par son matricule | Utilisateur |put | /inside/:service_number | userController.userUpdateInside | Met à jour la présence/absence de l'utilisateur identifié par son matricule | Utilisateur |delete | /user/:service_number | userController.userDelete | Supprime l'utilisateur identifié par son matricule | Utilisateur Script concerné : https://github.com/smarbal/firesave-API/blob/main/controllers/userController.js #### Gestion des promotions | Méthode HTTP | URI | Action | Description | Autorisation | -------- | -------- | -------- | ----------------| ---| |get | /prom | promController.promList | Liste toutes les promotions, avec les utilisateurs qu'elles contiennent | Admin |get | /prom/find/:prom_name | promController.promFindOne | Renvoie une promotion identifiée par son nom | Admin |post | /prom | promController.promCreate | Crée une promotion | Admin |put | /prom/:prom_name | promController.promUpdate | Modifie une promotion, identifiée par son nom | Admin |put | /promAdd/:prom_name | promController.promAddUser | Ajoute un utilisateur identifié par son matricule à une promotion, identifiée par son nom | Manager |put | /promRemove/:prom_name | promController.promRemoveUser | Retire un utilisateur (matricule) d'une promotion | Manager |delete | /prom/:prom_name | promController.promDelete | Supprimer une promotion identifiée par son nom | Admin Script concerné : https://github.com/smarbal/firesave-API/blob/main/controllers/promController.js ## Alertes Le champ **inside** n'est pas inclus par défaut dans les utilisateurs renvoyés par les promotions. Ceci est dû au fait que, pour des raisons de confidentialité, ce champ n'est inclus que lorsque une alerte est activée. Une alerte doit être envoyée par plusieurs personnes pour que le serveur passe en mode alerte et qu'il inclue donc le champ **inside** pour les utilisateurs listés. De manière pratique, les alertes sont gérées par un websocket. On peut ainsi recevoir un message d'alerte mais également en envoyer vers les utilisateurs (affichage d'une banderole lors d'un message d'alerte.). Le fait de différentier les utilisateurs qui envoient des alertes n'est pas implémenté. Lorsqu'un certain nombre d'alertes est envoyé, un boolean global passe à 1 sur le serveur et est remis à 0 au bout d'un certain temps. Lorsqu'il est à 1, le champ **inside** est inclus. Script concerné: https://github.com/smarbal/firesave-API/blob/main/sockets/socketHandler.js ## Exemple de requête Je vais montrer ici le résultat d'une requête get vers `/prom` (pas en alerte) puisque ceci permettra de voir le renvoi d'une promotion ainsi que la structure d'un utilisateur . *Réussie* : statut 200 ``` [ { "prom_name": "SDIV", "battalion": "ASEA", "users": [ { "firstname": "a", "lastname": "aa", "service_number": 1, "room": "a" }, { "firstname": "Sebastien", "lastname": "Martinez", "service_number": 1701722, "room": "4k82" } ], "manager": [ { "firstname": "Sebastien", "lastname": "Martinez", "service_number": 1701722, "room": "4k82", "managers": { "prom_name": "SDIV", "service_number": 1701722 } } ] } ] ``` ## Interface Angular https://github.com/smarbal/firesave/tree/main/src/app Le site est conçu en SPA. Il faut se connecter afin de pouvoir intéragir avec les différentes fonctions. Il y a une possibilité de s'enregistrer même si je ne pense pense pas qu'elle devrait figurer si le site viendrait à être déployé réellement. L'eneregistrement et le login n'affichent pas d'erreur, mais il y a une redirection en cas de succès. Pour pouvoir s'enregistrer il faut qu'il y ait une promotion qui soit déjà enregistrée. Lors de la connection, un JWT est stocké dans le LocalStorage ainsi qu'un objet représentant l'utilisateur avec ses attributs (nom, prénom, matricule, etc.) afin de faciliter l'accès à ces informations aux différents services. J'ai choisi de stocker le token en LocalStorage plutôt qu'en cookie afin que l'utilisateur puisse rester connecter indéfiniment et donc éviter d'éventuels problèmes de connexion lors d'un incendie. À part pour la connection/enregistement, il n'y a pas de formulaires à envoyer donc à priori pas d'erreurs générées par l'utilisateur. Je n'ai donc pas cherché à implémenter une gestion d'erreurs (ou vérification de champs) même si cela pourrait être intéressant pour la suite. ### Architecture J'utilise les composants suivants : * AppComponent * LoginComponent * PageNotFoundComponent * HomeComponent * RegisterComponent * GroupComponent * SettingsComponent * AdminComponent Et les services suivants : * AuthService -> LoginComponent, RegisterComponent, AppComponent * UserService -> HomeComponent, SettingsComponent * GroupService -> GroupComponent * AdminService -> AdminComponent ### Résultat ![](https://i.imgur.com/35XAF75.png) ![](https://i.imgur.com/NFL4O3h.png) ![](https://i.imgur.com/myR8c1q.png) ## Conclusions Le site est fonctionnel et répond aux attentes de base. L'interface est soignée et varie en fonction de l'utilisateur (seul un admin aura le menu admin, seul un manager aura accès au bouton edit). | User story | Priorité | API | Frontend | Commentaire | | -------- | -------- | ----| -----| ----| | En tant qu'utilisateur je veux pouvoir mettre à jour ma présence dans la chambre | 1 | 100% | 100 % | | En tant qu'utilisateur je veux pouvoir changer ma chambre actuelle | 2 | 100% | 100% | En tant qu'utilisateur je veux pouvoir alerter qu'il y a un incendie dans le bâtiment | 2 | 100% | 100% | Les alertes ont même un effet sur les réponses de certaines routes. | En tant que manager je veux pouvoir consulter les présences dans les chambres | 1 | 100% | 100% | Seulement en cas d'incendie. | En tant que manager je veux pouvoir gérer l'ajout/la suppression des membres dans mon groupe | 1 | 100% | 100% | | En tant que manager je veux pouvoir faire marquer les présences à un point de rendez vous | 2 | 100% | 100% | Se fait via une checkbox, purement visuel. | En tant que manager je veux pouvoir trier les membres du groupe par présence ou ordre alphabétique | 3 | 0% | 0% | Pas implémenté ### Pistes d'amélioration * Bouton refresh qui permettrait d'actualiser la présence ou non des membres d'un groupe (plutôt que de rafraichir la page ou le composant). * Adapter l'affichage sur mobile. * Mieux gérer la gestion d'alertes (ex: obligation que ce soient plusieurs utilisateurs dictincs qui l'activent) * Envoi de la prise de présence à un lieu de rassemblement vers le serveurs, pour que cela puisse être accessible par un admin. * Ajout d'une route pour pouvoir créer des admins via l'API, sans devoir le faire manuellement dans la database.