# prepaLoL ## Diagramme de classes du modèle ```mermaid classDiagram class LargeImage{ +/Base64 : string } class Champion{ +/Name : string +/Bio : string +/Icon : string +/Characteristics : Dictionary~string, int~ ~ AddSkin(skin : Skin) bool ~ RemoveSkin(skin: Skin) bool + AddSkill(skill: Skill) bool + RemoveSkill(skill: Skill) bool + AddCharacteristics(someCharacteristics : params Tuple~string, int~[]) + RemoveCharacteristics(label : string) bool + this~label : string~ : int? } Champion --> "1" LargeImage : Image class ChampionClass{ <> Unknown, Assassin, Fighter, Mage, Marksman, Support, Tank, } Champion --> "1" ChampionClass : Class class Skin{ +/Name : string +/Description : string +/Icon : string +/Price : float } Skin --> "1" LargeImage : Image Champion "1" -- "*" Skin class Skill{ +/Name : string +/Description : string } class SkillType{ <> Unknown, Basic, Passive, Ultimate, } Skill --> "1" SkillType : Type Champion --> "*" Skill class Rune{ +/Name : string +/Description : string } Rune --> "1" LargeImage : Image class RuneFamily{ <> Unknown, Precision, Domination } Rune --> "1" RuneFamily : Family class Category{ <> Major, Minor1, Minor2, Minor3, OtherMinor1, OtherMinor2 } class RunePage{ +/Name : string +/this[category : Category] : Rune? - CheckRunes(newRuneCategory : Category) - CheckFamilies(cat1 : Category, cat2 : Category) bool? - UpdateMajorFamily(minor : Category, expectedValue : bool) } RunePage --> "*" Rune : Dictionary~Category,Rune~ ``` ## Diagramme de classes des interfaces de gestion de l'accès aux données ```mermaid classDiagram direction LR; class IGenericDataManager~T~{ <> GetNbItems() Task~int~ GetItems(index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~T~~ GetNbItemsByName(substring : string) GetItemsByName(substring : string, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~T~~ UpdateItem(oldItem : T, newItem : T) Task~T~~ AddItem(item : T) Task~T~ DeleteItem(item : T) Task~bool~ } class IChampionsManager{ <> GetNbItemsByCharacteristic(charName : string) GetItemsByCharacteristic(charName : string, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~ GetNbItemsByClass(championClass : ChampionClass) GetItemsByClass(championClass : ChampionClass, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~ GetNbItemsBySkill(skill : Skill?) GetItemsBySkill(skill : Skill?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~ GetNbItemsBySkill(skill : string) GetItemsBySkill(skill : string, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~ GetNbItemsByRunePage(runePage : RunePage?) GetItemsByRunePage(runePage : RunePage?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Champion?~~ } class ISkinsManager{ <> GetNbItemsByChampion(champion : Champion?) GetItemsByChampion(champion : Champion?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Skin?~~ } class IRunesManager{ <> GetNbItemsByFamily(family : RuneFamily) GetItemsByFamily(family : RuneFamily, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~Rune?~~ } class IRunePagesManager{ <> GetNbItemsByRune(rune : Rune?) GetItemsByRune(rune : Rune?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~RunePage?~~ GetNbItemsByChampion(champion : Champion?) GetItemsByChampion(champion : Champion?, index : int, count : int, orderingPropertyName : string?, descending : bool) Task~IEnumerable~RunePage?~~ } IGenericDataManager~Champion?~ <|.. IChampionsManager : T--Champion? IGenericDataManager~Skin?~ <|.. ISkinsManager : T--Skin? IGenericDataManager~Rune?~ <|.. IRunesManager : T--Rune? IGenericDataManager~RunePage?~ <|.. IRunePagesManager : T--RunePage? class IDataManager{ <> } IChampionsManager <-- IDataManager : ChampionsMgr ISkinsManager <-- IDataManager : SkinsMgr IRunesManager <-- IDataManager : RunesMgr IRunePagesManager <-- IDataManager : RunePagesMgr ``` ## Diagramme de classes simplifié du Stub ```mermaid classDiagram direction TB; IDataManager <|.. StubData ChampionsManager ..|> IChampionsManager StubData --> ChampionsManager RunesManager ..|> IRunesManager StubData --> RunesManager RunePagesManager ..|> IRunePagesManager StubData --> RunePagesManager SkinsManager ..|> ISkinsManager StubData --> SkinsManager StubData --> RunesManager StubData --> "*" Champion StubData --> "*" Rune StubData --> "*" RunePages StubData --> "*" Skins ``` # API LOL ## Diagramme d'architecture ![](https://cdn.discordapp.com/attachments/1070723341725478967/1089668120454639686/image.png) ## Quelques explications L'API que l'on devait mettre en place devait être conçue pour effectuer des opérations CRUD (Create, Read, Update, Delete) sur la base de données Entity Framework (EF). Pour ce faire, il a fallu commencer par mapper les classes métiers du modèle en entités pour la partie EF, afin de pouvoir interagir avec la base de données. Ensuite, il a fallu créer des classes de transfert de données (DTO) pour représenter les mêmes classes métiers du modèle, mais dans un format adapté à la communication avec l'API. L'API a été conçue pour exposer les fonctionnalités CRUD de la base de données aux clients, tels que le client MAUI, qui aurait dû utilisé pour fournir une application mobile. La communication entre l'API et le client devait se faire via des requêtes HTTP, qui auraient été envoyées par le client à l'API pour effectuer des opérations sur la base de données. Lorsqu'un utilisateur effectue une opération dans l'application mobile, telle que la création d'un nouvel objet, le client MAUI aurait dû une requête POST à l'API, contenant les informations sur l'objet à créer. L'API aurait donc dû recevoir cette requête, convertir les données du DTO en entités EF, puis les ajouter à la base de données. Puis, l'API aurait dû renvoyer une réponse HTTP au client, confirmant que l'opération a réussi. De même, si l'utilisateur avait demandé de mettre à jour ou de supprimer un objet, le client MAUI aurait dû envoyer une requête PUT ou DELETE à l'API, qui aurait effectué les opérations correspondantes sur la base de données. L'API aurait ensuite envoyé une réponse HTTP au client pour indiquer si l'opération a réussi ou échoué. ## Client MAUI Il a été installé et testé mais a dû être supprimer car des packages ios et maccatalyst étaients introuvables ce qui empêchait les builds de Drone et Sonar ainsi que les tests unitaires et les updates de la base de données à chaque modification des tables.