Marc CHEVALDONNE
0f4f97cd35
|
1 month ago | |
---|---|---|
images | 1 month ago | |
.gitignore | 3 months ago | |
README.md | 1 month ago |
README.md
TP_MVVM_2024
Marc Chevaldonné • le 2 septembre 2024
Contexte
La gestion du matériel au département informatique de l'IUT Clermont Auvergne, et en particulier la gestion des prêts et des emprunts, n'est pas satisfaisante aujourd'hui.
Nous souhaiterions permettre aux usagers (étudiants, enseignants, personnel) de facilement emprunter et rendre du matériel, tout en gardant un contrôle.
Le plus simple est de faire une application mobile multiplateformes (Android ou iPhone) pour faciliter son utilisation.
On distingue alors trois types d'utilisateurs :
- les étudiants (qui peuvent consulter la liste du matériel restant disponible, faire une demande d'emprunt ou rendre du matériel)
- le personnel affilié au département informatique (qui peut consulter la liste du matériel restant disponible, et emprunter et rendre du matériel mais sans autorisation ; il peut aussi réserver du matériel pour une période afin de garantir la possibilité d'emprunt par des étudiants pendant la période ; enfin, il peut accepter un emprunt ou le refuser)
- les administrateurs (qui ont les mêmes droits que le personnel mais qui peuvent en plus mettre à jour la liste du matériel, ie ajouter, modifier ou supprimer du matériel).
Le matériel (un périphérique, un ordinateur, un smartphone, un livre, un outil, ...) est associé à un nom, un membre du personnel (un membre du personnel responsable de ce matériel), un nombre d'exemplaires. Chaque exemplaire possède un identifiant unique, un état (neuf, très bon état, bon état, état moyen, ...), une situation (emprunté, libre, réservé).
Un emprunt est associé à un nom d'emprunteur, le nom du membre du personnel ayant validé l'emprunt, la date de l'emprunt et la date de retour.
Il vous est demandé de réaliser cette application en respectant le calendrier et les contraintes ci-dessous. La quantité de travail étant importante, il est peu probable que quelqu'un parvienne à terminer l'application. C'est la raison pour laquelle il vous est demandé de respecter l'ordre des tâches ci-dessous qui a été pensé pour son intérêt pédagogique et sa difficulté croissante.
Fourni
Le diagramme de classes du modèle est fourni ainsi qu'une couche d'accès aux données (un stub accessible via un service web).
Calendrier prévisionnel
On distinguera trois phases :
- Réalisation des vues (2 semaines)
- Réalisation de l'application dans le respect du patron d'architecture MVVM (Model-View-ViewModel) (4 semaines). Pour cette partie, vous devrez utiliser votre propre framework.
- Modification de l'application en utilisant le MVVM Community Toolkit (1 semaine).
Évaluation
Vous serez évaluée/évalué à l'oral individuellement sur la base de votre travail.
Cas d'utilisation
Les cas d'utilisation suivants sont donnés dans l'ordre dans lequel il vous est conseillé de les réaliser :
(Tous les utilisateurs) Préférences utilisateur
Changer de thème
L'utilisateur doit pouvoir changer de thème en utilisant l'une des méthodes suivantes (par ordre de difficulté croissante) :
- utiliser le thème du système (light ou dark) : pour changer le thème, l'utilisateur doit donc changer le thème de son appareil,
- sauvegarder la préférence du thème au niveau de l'application avec comme possibilités : thème du système, light ou dark (dans les deux derniers cas, même si c'est différent du thème du système),
- même chose que précédemment avec un ou deux thèmes supplémentaires :
- color-blindness theme : pour augmenter l'accessibilité de l'application, permettre à l'utilisateur de choisir un thème adapté aux personnes ne percevant pas correctement les couleurs (comme les daltoniens par exemple),
- Odin theme : un thème utilisant les couleurs d'Odin
Changer de langue
L'utilisateur doit pouvoir changer la langue de l'application en utilisant l'une des méthodes suivantes (par ordre de difficulté croissante) :
- utiliser la langue du système : pour changer la langue, l'utilisateur doit donc changer celle de son appareil,
- sauvegarder la préférence de la langue au niveau de l'application avec comme possibilités : langue du système, français ou english ou les langues que vous parlez couramment.
Changer la taille de la police
L'utilisateur doit pouvoir changer la taille de la police en utilisant l'une des méthodes suivantes (par ordre de difficulté croissante) :
- utiliser la taille de police du système : pour la changer, l'utilisateur doit donc changer celle de son appareil,
- sauvegarder la préférence de la taille de la police au niveau de l'application avec comme possibilités : je vois bien et je ne vois pas bien.
(Tous les utilisateurs) Connexion/Déconnexion
Se connecter
L'utilisateur doit pouvoir se connecter pour accéder à toutes les autres fonctionnalités. Pour cela, il doit fournir son email et son mot de passe.
Note
On simulera un cas où l'annuaire de l'IUT est utilisé. Il n'y a donc pas besoin de proposer un cas "S'inscrire" ou "J'ai oublié mon mot de passe".
Se déconnecter
L'utilisateur doit pouvoir se déconnecter à tout moment.
(Tous les utilisateurs) Voir le matériel
Accéder à la liste du matériel
L'utilisateur doit pouvoir voir l'intégralité du matériel.
Accéder aux détails d'un élément
L'utilisateur doit pouvoir accéder aux détails d'un élément du matériel.
(Tous les utilisateurs) Voir le matériel emprunté par l'utilisateur
L'utilisateur doit pouvoir voir le matériel qu'il a emprunté. Pour celui-ci, il peut accéder aux détails et voir la date de retour qui avait été donnée lors de l'emprunt.
(Administrateurs) Ajouter/Modifier/Supprimer un périphérique
Un administrateur doit pouvoir ajouter (en remplissant les détails), modifier les détails, ou supprimer un périphérique de la liste.
Les détails associés à un périphérique sont :
- le nom,
- la description,
- une photo (ou icone),
- le nom du responsable,
- le nombre d'exemplaires (s'il y en a plus d'un),
- la liste des exemplaires.
Pour chaque exemplaire :
- l'état d'emprunt (emprunté ou libre),
- l'état du matériel (comme neuf, très bon, bon, moyen)
- la date de retour si déjà emprunté.
(Membres du personnel) Emprunter/Rendre/Réserver
Emprunter du matériel
Un membre du personnel peut emprunter un périphérique sans faire de demande d'autorisation. Pour cela, il doit choisir un exemplaire du périphérique dans la liste du matériel.
Rendre du matériel
Un membre du personnel peut rendre un périphérique. Pour cela, il doit choisir le périphérique à rendre dans la liste du matériel qu'il a emprunté.
Réserver du matériel
Un membre du personnel peut réserver du matériel pour indiquer aux collègues qu'il est préférable de ne pas laisser des étudiants emprunter le matériel durant une période donnée.
Pour cela, l'utilisateur doit donner les informations suivantes :
- le périphérique concerné,
- le nombre d'exemplaires,
- la période (dates de début et de fin)
(Étudiants) Emprunter/Rendre
Faire une demande d'emprunt de matériel
Un étudiant peut faire une demande d'emprunt en précisant :
- le périphérique (type et exemplaire),
- la date de retour,
- une liste de membres du personnel pouvant valider la demande,
- un commentaire (optionnel).
Rendre du matériel
Un étudiant peut indiquer qu'il souhaite rendre du matériel. Les membres du personnel indiqués précédemment recevront la demande. La liste peut être modifiée au moment du rendu.
(Membes du personnel) Valider un emprunt/rendu
Valider un emprunt
Un membre du personnel peut valider une demande d'emprunt qu'il a reçue. Avant de valider la demande, il peut changer éventuellement :
- la date de retour,
- l'exemplaire.
Valider un retour
Un membre du personnel peut valider un retour d'un périphérique.
Note
S'il était dans la liste des membres du personnel lors de la demande de rendu, il recevra la demande.
Mais s'il n'était pas dans la liste, il peut quand même parcourir la liste du matériel, trouver l'exemplaire, et valider le rendu.
Valider un emprunt rapide
Un membre du personnel doit pouvoir réaliser un emprunt rapide en suivant les actions suivantes :
- scanner le qrcode de l'étudiant (qu'on imaginera sur sa carte étudiant),
- scanner le qrcode de l'exemplaire,
- choisir une date de retour,
- valider.
Contraintes sur les vues
Couleurs, thèmes, police
Concernant les thèmes, les couleurs et la police, on s'inspirera des applications classiques comme Musique ou Podcast sur iOS.
Exemples de thèmes et couleurs light et dark pour l'application Musique sur iOS
Affichage des listes et des détails
Pour l'affichage de la liste et du détail, on s'inspirera de l'application Discogs.
Exemples d'affichage de master/detail dans le cas de l'application Discogs.
Gestion de l'orientation
On souhaite avoir un affichage du détail d'un périhérique différent en fonction de l'orientation (plutôt en une colonne en mode portrait ; plutôt sur deux colonnes en mode paysage) comme dans l'exemple ci-dessous :
Exemples de gestion de l'orientation sur une application maison
On peut également gérer l'idiome (téléphone ou tablette) pour un rendu différent et adapté.
Exemples de rendu variant selon l'idiome sur une application maison
Préférences
Pour accéder aux préférences (et au bouton de déconnexion), on pourra choisir l'une des deux méthodes suivantes :
- un menu tiroir comme dans l'application ATP WTA Live :
-
un système classique iOS avec un tap sur l'icône de l'utilisateur suivi d'un parcours entre les différentes écrans de formulaire (comme dans l'application Signal) :
Dans l'exemple ci-dessous, l'utilisateut tape sur son icône (en haut à gauche), puis sur Paramètres dans le menu contextuel, puis sur Apparence, puis sur Thème
Multi-plateformes
L'application doit fonctionner sur Android et iOS.
Contraintes sur MVVM
Il vous est demandé de suivre les conseils donnés en cours quant à l'utilisation du patron d'architecture Model-View-ViewModel, et notamment :
- l'utilisation de VM wrapper et de VM applicatives
- l'utilisation la plus limitée possible de code-behind
- l'utilisation du Data-Binding aussi bien pour les propriétés que pour les actions
- l'utilisation de ContentViews
- l'utilisation de l'injection de dépendance.
L'utilisation du framework MVVM Community Toolkit est interdite pour la partie 2, mais fait l'objet de la partie 3. Une validation de la partie 2 auprès de votre enseignant avant de passer à la partie 3.
Diagramme de classes du modèle
Person
Une personne peut représenter un administrateur (peut tout faire), un membre du personnel (staff, qui peut valider des emprunts et des retours), un étudiant (qui peut faire des demandes d'emprunt et de retour). Ceci est représenté par l'énumération Role
et ces trois valeurs possibles (ADMIN
, STAFF
et STUDENT
).
Une personne possède également :
- un identifiant unique,
- un email (unique),
- un prénom et un nom de famille.
Equipment
Un élément de matériel est représenté par la classe Equipment
, qui possède :
- un identifiant généré lors de l'insertion dans la base,
- un nom
- une éventuelle description,
- une petite image en base64 (qu'il faudra décoder ou coder lors de la récupération ou de l'ajout/modification d'un élément)
- une grande image en base64
Note :
Lors de l'utilisation de la web api, une route rendant plusieurs équipements ne rend jamais les grandes images. Il faut utiliser une route permettant de récupérer unEquipment
en donnant son id pour obtenir cette valeur.
- des propriétés permettant de connaître le nombre d'exemplaires de cet équipement (le nombre total, le nombre d'éléments en stock, le nombre d'éléments réservés, et le nombre d'éléments empruntables)
- un superviseur (une personne avec le rôle
Staff
), qui est le responsable/spécialiste de ce matériel - une collection d'exemplaires (
Copy
, cf. ci-dessous).
Note :
Lors de l'utilisation de la web api, une route rendant plusieurs équipements ne rend jamais la collection d'exemplaires. Il faut utiliser une route permettant de récupérer unEquipment
en donnant son id pour obtenir cette collection.
Copy
Un exemplaire est représenté par la classe Copy
, et possède :
- un identifiant unique,
- l'
Equipment
auquel cet exemplaire se rapporte, - un état (
Condition
),
Note :
L'état représente ... l'état de cet exemplaire (neuf, excellent, très bon état, bon état, usure normale, endommagé, inutilisable)
- une situation (
Situation
)
Note :
La situtation d'un exemplaire permet d'indiquer s'il est : stocké (et donc empruntable), emprunté (donc non stocké), réservé (à l'IUT mais non empruntable), déstocké (il n'est plus utilisable donc plus empruntable).
Borrowing
Un emprunt est représenté par une instance de Borrowing
, et possède :
- un identifiant unique (généré par lors de l'insertion en base),
- l'exemplaire (
Copy
) emprunté - l'emprunteur (
Borrower
de typePerson
, avec n'importe quelRole
) - le responsable de l'emprunt (
StaffMember
de typePerson
, avec le rôleSTAFF
), - la date (
BorrowingDate
) et l'état (OriginalCondition
) au début de l'emprunt, - la date de retour (
ReturningDate
) et l'état (ReturnedCondition
) au retour de l'exemplaire
Note :
La date de retour peut varier jusqu'au retour, en accord avec le responsable de l'emprunt.
L'état du retour est, au démarrage de l'emprunt, par défaut, celui d'origine, mais pourra être ajusté lors du retour par le membre du personnel responsable de l'emprunt. Cette modification entrainera la modification de l'état de l'exemplaire (Copy.Condition
).
- un commentaire (pouvant varier pendant l'emprunt).
Reservation
Une réservation d'exemplaires (pour des TP par exemple), est représentée par la classe Reservation
, et possède :
- un identifiant unique (généré lors de l'insertion en base)
- l'exemplaire réservé (
Copy
)
Note :
Pour simplifier le modèle, pour réserver plusieurs exemplaires, il faut autant d'instances deReservation
.
- l'auteur de la réservation (
Person
avec leRole
STAFF
) - une date de début de réservation (
StartingDate
) et une date de fin de réservation (EndingDate
) - un commentaire (permettant par exemple de donner les créneaux ou le groupe, ce qui pourrait permettre à un collègue d'accepter un emprunt sur un créneau de deux jours si on sait que l'exemplaire ne sera pas utilisé avant).
IDataService
Il vous est conseillé de faire une interface représentant le service d'accès aux données. Vous pourrez en faire une ou deux concrétisations, parmi :
- un stub (pour tester votre modèle, ou parce que vous avez du mal à faire le suivant...)
- un client consommant le web service fourni.
Note :
Vous pouvez placer cette couche abstraite dans une autre bibliothèque partagée, utilisée par le modèle. Pour cela, il faudra bien entendu rendre cette couche abstraite générique.
Manager
Cett façade sera l'interlocuteur privilégié entre votre applications et vos données. Vous pourrez injecter la couche d'accès aux données via constructeur, et utiliser les autres classes du modèle.
Les méthodes de Manager
permettront d'appeler les routes du web service via la couche d'accès aux données (mais pas directement dans le code de Manager
!) et les noms des méthodes pourront donc largement s'inspirer des routes.
classDiagram
direction LR
class Condition{
<<enumeration>>
UNKNOWN
NEW
EXCELLENT
VERY_GOOD
GOOD
USED
DAMAGED
UNUSUABLE
}
class Situation{
<<enumeration>>
UNKNOWN
STORED
BORROWED
RESERVED
UNSTORED
}
class Copy {
Id: string
}
Copy --> "1" Condition
Copy --> "1" Situation
class Equipment {
Id: string
Name: string
Description: string
SmallImage: string
LargeImage: string
NbOfStoredCopies: int
NbOfReservedCopies: int
NbOfFreeCopies: int
TotalNbOfCopies: int
}
Equipment "1" -- "*" Copy
class Role{
<<enumeration>>
ADMIN
STAFF
STUDENT
}
class Person {
Id: string
FirstName: string
LastName: string
Email: string
}
Person --> "1" Role
Equipment --> "1" Person : Supervisor
class Borrowing {
Id: string
BorrowingDate: DateTime
ReturningDate: DateTime
Comment: string
OriginalCondition: Condition
ReturnedCondition: Condition
}
Borrowing --> "1" Copy
Borrowing --> "1" Person : Borrower
Borrowing --> "1" Person : StaffMember
class Reservation {
Id: string
StartingDate: DateTime
EndingDate: DateTime
Comment: string
}
Reservation --> "1" Copy
Reservation --> "1" Person : StaffMember
class Manager {
+Login(email:string, password: string)
+Logout()
+GetEquipments(...)
+GetEquipmentById(...)
+InsertEquipment(...)
+UpdateEquipment(...)
+DeleteEquipment(...)
+GetCopiesOfEquipment(...)
+AddCopy(...)
+UpdateCopy(...)
+DeleteCopy(...)
+BorrowByStaffMember(...)
+ReturnByStaffMember(...)
}
Manager --> "?" Person : CurrentUser
class DataService {
<<interface>>
}
Manager ..> DataService
Web service
Le web service est accessible ici.
La documentation OpenApi de celui-ci, est accessible ici.
Personnes utilisables
Comme on simule l'annuaire de l'établissement, il n'est pas possible d'ajouter de personnes. Vous pourrez pour vos opérations, utiliser les personnes suivantes :
- Odin (
ADMIN
) : odin@uca.fr, mot de passe : Pw1234$ - Cédric Bouhours (
STAFF
) : cedric.bouhours@uca.fr, mot de passe : Pw1234$ - Christelle Mottet (
STAFF
) : christelle.mottet@uca.fr, mot de passe : Pw1234$ - Marc Chevaldonné (
STAFF
) : marc.chevaldonne@uca.fr, mot de passe : Pw1234$ - Alia Atréides (
STUDENT
) : alia.atreides@uca.fr, mot de passe : Pw1234$ - Miles Teg (
STUDENT
) : miles.teg@uca.fr, mot de passe : Pw1234$ - Duncan Idaho (
STUDENT
) : duncan.idaho@uca.fr, mot de passe : Pw1234$
Conseils
Lors du démarrage de la partie 2, je vous conseille de réaliser les tâches dans cet ordre :
- bibliothèque
Model
avec les classesPerson
etEquipment
- bibliothèque
Shared
avec la couche abstraite de service (permettant de se logger, de se dé-logger et de récupérer la liste d'équipements) - ajout du
Manager
dans le modèle avec injection du service abstrait - Stub rapide pour vérification et tests
- VM (
ManagerVM
etEquipmentVM
) afin de pouvoir se logger, et afficher la liste des équipements - DataBinding sur les vues correspondantes
Puis dans un second temps :
- client de la web api
- injection de ce dernier et utilisation
A part, la navigation et l'édition/ajout/suppression, le respect de ces tâches vous permettra d'avoir une bonne vue d'ensemble de l'architecture et de gagner en autonomie pour la suite.
Proposition de diagramme de classes pour le Stub
@startuml
Class Manager {
+ctor(IDataService<Equipment,Copy,Borrowing,Reservation>)
+Login(email:string, password: string)
+Logout()
+GetEquipments(...)
+GetEquipmentById(...)
+InsertEquipment(...)
+UpdateEquipment(...)
+DeleteEquipment(...)
+GetCopiesOfEquipment(...)
+AddCopy(...)
+UpdateCopy(...)
+DeleteCopy(...)
+BorrowByStaffMember(...)
+ReturnByStaffMember(...)
}
Manager --> "?" Person : CurrentUser
namespace Shared #palegreen {
Class IDataService<TEquipment,TCopy,TBorrowing,TReservation> {
<<interface>>
}
Class IEquipmentService<TEquipment> {
<<interface>>
CrudAndOthers()
}
Class ICopyService<TCopy> {
<<interface>>
CrudAndOthers()
}
Class IBorrowingService<TBorrowing> {
<<interface>>
CrudAndOthers()
}
Class IReservationService<TReservation> {
<<interface>>
CrudAndOthers()
}
}
namespace Stub #yellow {
Class StubbedData {
-equipments: Equipment[*]
-copies: Copy[*]
-borrowings: Borrowing[*]
-reservations: Reservation[*]
}
Class StubbedEquipments{
CrudAndOthers()
}
Class StubbedCopies{
CrudAndOthers()
}
Class StubbedBorrowings{
CrudAndOthers()
}
Class StubbedReservations{
CrudAndOthers()
}
}
Shared.IDataService --> Shared.IEquipmentService
Shared.IDataService --> Shared.ICopyService
Shared.IDataService --> Shared.IBorrowingService
Shared.IDataService --> Shared.IReservationService
Manager ..> Shared.IDataService
Shared.IDataService <|.. Stub.StubbedData
Shared.IEquipmentService <|.. Stub.StubbedEquipments
Stub.StubbedData --> Stub.StubbedEquipments
Shared.ICopyService <|.. Stub.StubbedCopies
Stub.StubbedData --> Stub.StubbedCopies
Shared.IBorrowingService <|.. Stub.StubbedBorrowings
Stub.StubbedData --> Stub.StubbedBorrowings
Shared.IReservationService <|.. Stub.StubbedReservations
Stub.StubbedData --> Stub.StubbedReservations
@enduml
J'en ai marre d'utiliser la web api partagée avec les autres...
Vous voulez déployer votre propre web API Njörd et pouvoir la relancer quand bon vous semble ? Vous êtes dans la bonne section ! Suivez le tutoriel ci-dessous :
- Créez un dépôt sous code first
- Suivez les inscriptions sur cette page pour activer votre dépôt sous Drone : https://codefirst.iut.uca.fr/documentation/CodeFirst/docusaurus/GuidesTutorials/docs/CI-CD/createCICDpipeline/activate/
- Ajoutez un fichier
.drone.yml
à la racine de votre dépôt - Ajoutez les lignes suivantes à ce fichier, en modifiant
mynjord
par le nom que vous voulez donner au conteneur (pas la peine d'ajouter votre nom, il est automatiquement ajoué en préfixe), et en modifiantprenomnom
par votre email (en supprimant ce qu'il y a après le@
et en enlevant tous les.
) :
kind: pipeline
type: docker
name: CD
trigger:
event:
- push
steps:
# web API container deployment
- name: deploy-container-webapi-stub
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: hub.codefirst.iut.uca.fr/marc.chevaldonne/njord-api:latest
CONTAINERNAME: mynjord
COMMAND: create
OVERWRITE: true
ADMINS: prenomnom,marcchevaldonne,cedricbouhours
Merci de laisser votre enseignant
marcchevaldonne
oucedricbouhours
en admin pour qu'il puisse tester si besoin.
- Poussez le tout. Lorsque le pipeline sera exécuté, votre conteneur devrait apparaître dans la section
Runners
du menu code first.
Note :
N'oubliez pas de supprimer vos conteneurs non utilisés pour laisser de la place sur code first !
Copyright © 2024-2025 Marc Chevaldonné
En préparant ce travail, j'écoutais...
Breaking Stretch Patricia Brennan (2024) |
Songs My Mom Liked Anthony Branker & Imagine (2024) |
The Messthetics and James Brandon Lewis The Messthetics and James Brandon Lewis (2024) |
Mosaic Nicole McCabe (2024) |
Phoenix Reimagined (Live) Lakecia Benjamin (2024) |
3+3 Tomeka Reid Quartet (2024) |
In Greece Dizzy Gillespie (1957) |