MCE LOCKERS APP
Introduction
Ce document décrit le fonctionnement de l'application MCE Lockers. Cette application permet de gérer l'utilisation des casiers connectés avec plusieurs types de flow differents. Ce document est destiné aux développeurs et aux administrateurs de l'application.
Objectifs de l'application
Au long des années, on a développé plusieurs applications pour gérer les différents types de besoins des clients. Celà a rendu la maintenance et l'évolution des applications très compliquées. L'objectif de cette application est de regrouper toutes les fonctionnalités dans une seule application, ce qui va simplifier la maintenance, les mises à jour et les futurs dévelopments. Pour cela, il est important de comprendre les différents besoins des clients et les élements principaux de l'application.
Besoins
Les besoins principaux sont les suivants: - Un client peut avoir plusieurs projets - Chaque projet peut gérer plusieurs services - Chaque projet peut avoir plusieurs applications - Chaque application peut avoir un ou plusieurs blocs de casiers - Chaque application peut gérer un ou plusieurs types de flow du projet - Chaque device est relié à une seule application - Chaque ordre est relié à un seul service - Un utilisateur peut avoir plusieurs ordres - Chaque ordre peut être relié à un casier
Eléments principaux de l'application
Client
Un client est une entité qui utilise l'application pour gérer ses besoins humaines via les casiers. Le client peut avoir plusieurs projets et plusieurs blocs de casiers pour chaque projet.
Projet
Un projet est un site ou un lieu où les casiers sont installés pour un client. Un projet peut avoir plusieurs blocs de casiers gérés par une application. Le projet est un des objets les plus importants de l'application. La plupart des objets de l'application ont une relation avec le projet, soit elle directe ou indirecte. Il permets de filtrer les données et de les organiser.
Network Device
Un Network Device est un mini-PC installé sur le site du client et il gère plusieurs choses: - Il affiche l'application IHM aux clients sur place - Il gère la lecture des badges RFID / QRCODE - Il gère la communication avec les cartes contrôleurs - Dans le cas où l'application utilise le paiement, il gère la communication avec le terminal de paiement
Les network devices utilisent toujours le système d'exploitation Debian. Actuellement, on utilise la version 11 (Bullseye). L'application Django est installée sur le network device avec des settings differents de l'application principale. Il a sa propre base de données PostgreSQL qui est synchronisée avec la base de données principale via le module réplication. Il est connecté à un serveur principale (local ou cloud) via websockets pour synchroniser les données et les actions effectuées sur les casiers. Il est toujours relié à une seule application.
Carte contrôleur
La carte contrôleur est un élément physique qui permet de contrôler les casiers. On utilise des cartes Metra. Toutes les actions effectuées sur les casiers sont faites via les cartes contrôleurs via une communication TCP.
Application
Dans ce contexte, une application est une réprésentation des differents elements necessaires pour gérer les flows. Les applications sont reliées à un seul projet et peuvent être utilisés sur plusiuers network devices.
Stack technique
L'application se compose de deux parties: backend et frontend.
Backend
- Langage: Python +3.10
- Framework: Django 4.2
- Base de données: PostgreSQL +13
- Serveur d'application: Daphne
- Datastore: Redis
- Serveur web: Nginx
- Serveur de fichiers statiques: Whitenoise
- Websocket: Django Channels
- Versionning: Git
- Gestions des dépendances: Poetry
- API: Django Ninja
- Serialization: Pydantic
Architecture
Architecture générale des données
Services et Ordres
Quand on a besoin d'ajouter un nouveau type de flow (service), on commence par créer un nouveau service dans le module services.
Il faut d'abord l'ajouter dans la classe Services dans le fichier models.py. Ensuite il faut créer l'objet dans la base de données en utilisant la méthode create_service de la classe ServiceModel,
soit via un shell python ou en utilisant la commande python manage.py create_services (TODO).
Une fois le service est créé, il faut créer le modèle proxy de l'ordre dans le module orders.models.
Toujours créer un nouveau fichier dans le dossier models pour chaque service et importer le ou les modèles dans le fichier __init__.py.
Attention, il faut
que le nom du modèle soit le même que le nom du service + "Order". Par exemple, si le service est "Sharing", le modèle doit s'appeler "SharingOrder".
Le modèle doit être un modèle proxy du modèle Order dans le module orders.models.
Il faut définir 4 constantes dans le modèle:
- SERVICE_TYPE: Le service correspondant
- ORDER_TYPES: Les types possibles de l'ordre. Les choix possibles doivent être définis dans le fichier types.py.
- VALID_STATES: Liste d'états possibles de l'ordre. Les choix possibles doivent exister dans le fichier states.py, donc si le nouveau service a besoin de nouveaux états, il faut les ajouter d'abord dans la classe OrderStates.
- END_STATES: Liste d'états finaux de l'ordre. Ces états indiquent que la commande est finalisée. Les choix possibles doivent exister dans le fichier states.py, donc si le nouveau service a besoin de nouveaux états, il faut les ajouter d'abord dans la classe OrderStates.
Ensuite, on peut ajouter les méthodes de transition spécifiques au service et modifier les méthodes existantes si nécessaire.
Par exemple, on peut modifier la méthode save pour remplir automatiquement des champs, ou la méthode clean pour ajouter de la validation des données.
Il faut aussi créer un manager/queryset pour le modèle. Le manager doit hériter de OrderManager et le queryset de OrderQueryset.
Dans le manager, modifier la méthode get_queryset pour filtrer les résultats selon le service.
Ensuite, on peut ajouter les méthodes spécifiques au service.
Résolution des problèmes
TODO