diff --git a/.github/workflows/create-docs.yml b/.github/workflows/create-docs.yml new file mode 100644 index 0000000..468df44 --- /dev/null +++ b/.github/workflows/create-docs.yml @@ -0,0 +1,31 @@ +name: Creates docs and deploy to gh-pages +on: + workflow_call: + workflow_dispatch: + push: + branches: [ main ] + +jobs: + build: + name: Deploy docs + runs-on: ubuntu-latest + steps: + - name: Checkout main + uses: actions/checkout@v2 + + - name: Setup Python + uses: actions/setup-python@v5 + + - name: Install dependencies + working-directory: ./documentation + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Build docs + working-directory: ./documentation + run: mkdocs build --verbose --clean + + - name: Push docs to gh-pages + working-directory: ./documentation + run: python deploy.py \ No newline at end of file diff --git a/.gitignore b/.gitignore index 41bbba6..551aa14 100644 --- a/.gitignore +++ b/.gitignore @@ -73,7 +73,7 @@ web_modules/ .yarn-integrity # dotenv environment variable files -.env +server/.env .env.development.local .env.test.local .env.production.local @@ -130,4 +130,4 @@ dist .pnp.* db-backup/ -deployments \ No newline at end of file +.venv \ No newline at end of file diff --git a/documentation/.gitignore b/documentation/.gitignore new file mode 100644 index 0000000..d97e100 --- /dev/null +++ b/documentation/.gitignore @@ -0,0 +1 @@ +site \ No newline at end of file diff --git a/documentation/deploy.py b/documentation/deploy.py new file mode 100644 index 0000000..abdc3c4 --- /dev/null +++ b/documentation/deploy.py @@ -0,0 +1,2 @@ +from ghp_import import ghp_import +ghp_import('site', push=True, force=True) \ No newline at end of file diff --git a/documentation/docs/developpeur/backend/api.md b/documentation/docs/developpeur/backend/api.md new file mode 100644 index 0000000..faa9ab4 --- /dev/null +++ b/documentation/docs/developpeur/backend/api.md @@ -0,0 +1,12 @@ +## À Propos + +Ce projet utilise Node.js Express pour créer un backend simple pour l'application. + +## Routes API + +Vous pouvez consulter toutes les routes utilisables du backend ici + +* User : https://documenter.getpostman.com/view/32663805/2sA2rCU28v#e942a4f4-321c-465b-bf88-e6c1f1d6f6c8 +* Quiz : https://documenter.getpostman.com/view/32663805/2sA2rCU28v#732d980b-02fd-4807-b5bc-72725098b9b0 +* Folders : https://documenter.getpostman.com/view/32663805/2sA2rCU28v#49ecd432-ccfc-4c8a-8390-b3962f0d5fd7 +* Images : https://documenter.getpostman.com/view/32663805/2sA2rCU28v#58382180-d6f0-492d-80c3-e09de1c368b8 \ No newline at end of file diff --git a/documentation/docs/developpeur/backend/auth.md b/documentation/docs/developpeur/backend/auth.md new file mode 100644 index 0000000..82b72c9 --- /dev/null +++ b/documentation/docs/developpeur/backend/auth.md @@ -0,0 +1,372 @@ +# Authentification + +## Introduction + +Le but du module d'authentification est de pouvoir facilement faire des blocks de code permettant une authentification personalisée. Il est possible de le faire grâce a cette architecture. Pour la première version de cette fonctionalitée, l'introduction de OICD et de OAuth sont priorisé ainsi que la migration du module d'authentification simple. + + +## Déconstruction simple de la structure +La structure est la suivante : + +Le AuthManager s'occupe de centraliser les requetes d'authentifications. Ce qui veux dire d'initialiser les autres modules et d'être la source de véritée dans au sujet de l'authentification. Les modules sont automatiquement chargé par l'utilisation de variables d'environment. + +Le module s'occupe de creer les routes nécéssaires pour son fonctionnement et de créer les utilisateurs. Ces modules vont appeller le AuthManager afin de confirmer leurs actions avec le login/register de celui-ci + +Dans le cas de modules plus complexe, tels que le module Passport, la chaine peut être prolongée afin de maintenir centralisée les actions. Chaque connecteur de PassportJs est initialisé par le module de PassportJs. + + +## Besoins exprimés + + +Modularité et généricité : + +- Le système d'authentification doit être adaptable à diverses configurations, notamment pour répondre aux exigences spécifiques des différentes universités ou institutions. + +Utilisation de différentes méthodes d'authentification : + +- L'application doit permettre de gérer plusieurs fournisseurs d'authentification (SSO, LDAP, OAuth, etc.) de manière centralisée et flexible. + +Facilité de configuration : + +- Le système doit permettre une configuration simple et flexible, adaptée à différents environnements (développement, production, etc.). + +Gestion des permissions : + +- Il doit être possible de définir et de mapper facilement les permissions et les rôles des utilisateurs pour sécuriser l’accès aux différentes fonctionnalités de l’application. + +Maintien de la connexion : + +- Le système doit garantir la persistance de la connexion pendant toute la durée de l'utilisation de l'application (exemple : quiz), avec la possibilité de se reconnecter sans perte de données en cas de déconnexion temporaire. + +## Recis utilisateurs pris en comptes + +- En tant qu'utilisateur de projet FOSS, je veux que le module d'authentifcation soit modulaire et générique afin de l'adapter a mes besoins. +- En tant qu'administrateur, je veux que les droits des utilisateurs soient inférés par l'authentificateur de l'établissement. +- En tant qu'administrateur, je veux que la configuration des authentificateur soit simple +- En tant qu'administrateur, je veux configurer les connections a partir de variables d'env ou fichier de config. +- En tant qu'utilisateur, je veux que ma connexion soit stable. +- En tant qu'utilisateur, je veux pouvoir me reconnecter a une salle s'il y arrive un problème de connexion. + +## Diagrammes + +### Structure +```plantuml +@startuml + +package Backend { +class AuthManager{ + +IAuthModule[] auths + #userInfos + + -load() + -registerAuths() + +showAuths() + + +authStatus() + +logIn(UserInfos) + +register(UserInfos) + +logOut() +} + +interface IAuthModule{ + +registerAuth() + +authenticate() + +register() + +showAuth() +} + +class SimpleFormAuthModule{ + +} + +class PassportAuthModule{ + IPassportProviderDefinition[] providers +} + +Interface IPassportProviderDefinition{ + +name + +type +} + +class OAuthPassportProvider{ + +clientId + +clientSecret + +configUrl + +authorizeUrl + +tokenUrl + +userinfoUrl + +logoutUrl + +JWKSUrl +} + +IAuthModule <|-- SimpleFormAuthModule +IAuthModule <|-- PassportAuthModule +IPassportProviderDefinition <|-- OAuthPassportProvider + +AuthManager -> IAuthModule +PassportAuthModule -> IPassportProviderDefinition +} + +package Frontend{ + class AuthDrawer{ + +IAuthVisual[] getAuthsVisual() + +drawAuths() + } + + Interface IAuthVisual{ + +draw() + } + + class FormVisual{ + +FormInput[] formInputs + } + + interface FormInput{ + +name + +label + +type + +value + } + + AuthDrawer -> IAuthVisual + IAuthVisual <|-- FormVisual + FormVisual -> FormInput +} + +@enduml +``` + + +### Explication des communications : Passport Js +```plantuml +@startuml + +box "Frontend" +participant User +Participant App +end box + +box "Backend" +participant PassportAuthModule +participant Db +participant AuthManager +end box + +box "Auth Server" +participant AuthServer +end box + +User -> App : Get auth page +App -> User : auth page + +User -> App : click OAuth button +App -> User : redirect to OAuth + +User -> AuthServer: Login +AuthServer -> User: Redirect to Auth endpoint with token + +User -> PassportAuthModule: Authenticate with token + +PassportAuthModule -> AuthServer: get user info +AuthServer -> PassportAuthModule: userInfo + +alt login + PassportAuthModule -> Db : fetch local userInfo + Db->PassportAuthModule: userInfo + PassportAuthModule -> PassportAuthModule: Merge userInfo definition + PassportAuthModule -> Db : update user profile + Db->PassportAuthModule: userInfo +end + +alt register + PassportAuthModule -> Db : fetch local userInfo + Db->PassportAuthModule: null + PassportAuthModule -> Db : create user profile + Db->PassportAuthModule: userInfo +end + +PassportAuthModule -> AuthManager : login(userInfos) + +AuthManager -> User: Give refresh token + Redirect to page +User -> App: get / +App -> User: Show Authenticated / +@enduml +``` + +### Explication des communications : SimpleAuth +```plantuml +@startuml + +box "Frontend" +participant User +Participant App +end box + +box "Backend" +participant SimpleAuthModule +participant Db +participant AuthManager +end box + +User -> App : Get auth page +App -> User : auth page + + +alt Login + User -> App : Send Login/Pass + + App -> SimpleAuthModule: Send login/pass + + SimpleAuthModule -> Db: get user info + Db->SimpleAuthModule: user info + SimpleAuthModule -> SimpleAuthModule: Validate Hash +end + +alt register + User -> App : Send Username + Password + Email + + App -> SimpleAuthModule: Send Username + Password + Email + + SimpleAuthModule -> Db: get user info + Db -> SimpleAuthModule : null + + SimpleAuthModule -> Db: put user info +end + +SimpleAuthModule -> AuthManager: userInfo +AuthManager -> User: Give refresh token + Redirect to page +User -> App: get / +App -> User: Show Authenticated / +@enduml +``` + +### Comment les boutons sont affichés +```plantuml +@startuml + +box "FrontEnd" +participant User +Participant FrontEnd +Participant AuthDrawer +end box + +box "BackEnd" +participant API +participant AuthManager +participant Db +participant IAuthModule +end box + +API -> API : load global configurations + +create AuthManager +API -> AuthManager : instanciate with auth configurations + + +create IAuthModule +AuthManager -> IAuthModule : instanciate array + +loop For each auth in auths + AuthManager -> IAuthModule : register + IAuthModule -> API : register routes + API -> IAuthModule : route registration confirmation + IAuthModule -> AuthManager : module registration confirmation +end + +User -> FrontEnd : get login page + +alt already logged in + FrontEnd -> User: redirected to authenticated page +end + +FrontEnd -> AuthDrawer : get auth visual +AuthDrawer -> API : get auth form data + +API -> AuthManager : get auth form data + + +loop For each auth in auths + AuthManager -> IAuthModule : get form data + IAuthModule -> AuthManager : form data +end + +AuthManager -> API : auth fom data +API -> AuthDrawer : auth form data + +AuthDrawer -> AuthDrawer : make auth html +AuthDrawer -> FrontEnd : auth HTML +FrontEnd -> User : show auth page + + +@enduml +``` + +### Comment les sessions sont conservées +```plantuml +@startuml + box "Frontend" + participant User + Participant App + end box + + box "Backend" + participant AuthManager + participant IAuthModules + end box + + App -> AuthManager : send refresh token + + AuthManager -> IAuthModules: ForEach check if logged + IAuthModules -> AuthManager: is authenticated ? + + alt one logged in + AuthManager -> App : send new token + end + + alt all logged out + AuthManager -> App : send error + App -> App : destroy token + App -> User : redirect to login page + end + +@enduml +``` + +## Configuration des variables d'environnement + +Example de configuration du fichier : `server/auth_config.json` : + +```json +{ + "auth": { + "passportjs": // Module + [ + { + "gmatte": { // Nom du sous-module Passport + "type": "oauth", // type + "OAUTH_AUTHORIZATION_URL": "https://auth.gmatte.xyz/application/o/authorize/", + "OAUTH_TOKEN_URL": "https://auth.gmatte.xyz/application/o/token/", + "OAUTH_USERINFO_URL": "https://auth.gmatte.xyz/application/o/userinfo/", + "OAUTH_CLIENT_ID": "--redacted--", + "OAUTH_CLIENT_SECRET": "--Redacted--", + "OAUTH_ADD_SCOPE": "groups", // scopes supplémentaire nécéssaire pour le pivot + "OAUTH_ROLE_TEACHER_VALUE": "groups_evaluetonsavoir-prof", // valeur de pivot afin de définir un enseignant + "OAUTH_ROLE_STUDENT_VALUE": "groups_evaluetonsavoir" // valeur de pivot afin de définir un étudiant + } + }, + { + "etsmtl":{ + "type":"oidc", + "OIDC_CONFIG_URL":"https://login.microsoftonline.com/70aae3b7-9f3b-484d-8f95-49e8fbb783c0/v2.0/.well-known/openid-configuration", + "OIDC_CLIENT_ID": "--redacted--", + "OIDC_CLIENT_SECRET": "--redacted--", + "OIDC_ADD_SCOPE": "", + "OIDC_ROLE_TEACHER_VALUE": "groups_evaluetonsavoir-prof", + "OIDC_ROLE_STUDENT_VALUE": "groups_evaluetonsavoir" + } + } + ], + "simpleauth":{} + } +} +``` \ No newline at end of file diff --git a/documentation/docs/developpeur/backend/base-de-donnees.md b/documentation/docs/developpeur/backend/base-de-donnees.md new file mode 100644 index 0000000..52bdb12 --- /dev/null +++ b/documentation/docs/developpeur/backend/base-de-donnees.md @@ -0,0 +1,11 @@ +# Type de base de données +La base de données est une mongoDB + +# Collections disponibles +* Files : Ceci est la collection qui contient les différents quiz et leurs questions. +* Folders : Ceci est la collection qui contient les dossiers qui servent à la gestion des différents quiz +* Images : C'est dans cette collection que sont stockées les images utilisées dans les quiz +* Users : Cette collection est utilisée pour la gestion des utilisateurs + +# Information sur la création +Lors du démarrage du projet, la base de données est créée automatiquement. diff --git a/documentation/docs/developpeur/backend/katex.md b/documentation/docs/developpeur/backend/katex.md new file mode 100644 index 0000000..73a6e5d --- /dev/null +++ b/documentation/docs/developpeur/backend/katex.md @@ -0,0 +1,39 @@ +# KaTeX + +KaTeX est le module qui s'occupe de formater les formules mathématiques selon la configuration donnée. + +Les formules entourées de $$ s'afficheront centrées sur leur propre ligne + +`.replace(/\$\$(.*?)\$\$/g, (_, inner) => katex.renderToString(inner, { displayMode: true }))` + +alors que les formules entourées de $ s'afficheront sur la même ligne + +`.replace(/\$(.*?)\$/g, (_, inner) => katex.renderToString(inner, { displayMode: false }))` + +La configuration du formatage peut être trouvée dans le fichier TextType.ts situé dans le dossier EvalueTonSavoir/client/src/components/GiftTemplate/templates + +C'est aussi dans ce fichier que le format markdown est pris en charge. + +## Éditeur de quiz +Pour l'affichage dans l'éditeur de quiz, on peut retrouver la classe TextType être appliquée sur différents éléments du dossier templates, par exemple la classe Numerical.ts. + +On peut voir ici que le TextType est appliqué sur le contenu de la question: +```typescript +

${TextType({text: stem })}

+``` + +Selon ce qui avait été écrit dans la question, la classe s'occupera de formatter les bonnes sections. + +## Affichage de questions + +Le module React-latex était utilisé pour le formatage des questions durant un quiz, mais cela a apporté le problème de disparité d'affichage entre la création et l'affichage des questions avec des formules mathématiques. +Les classes affichant les questions durant un quiz peuvent utiliser ce format, mais avec une manipulation de plus. + +Les variables contenant la question doivent d'abord avoir un type TextFormat pour pouvoir faire appel à la classe qui s'occupe du format sous le module KaTeX. +Puis, étant sur un environnement React, il faut utiliser la propriété dangerouslySetInnerHTML pour afficher la question correctement. + + +`
+ ` + +Ce type de manipulation peut être utilisé dans d'autre environnement React si on veut éviter d'utiliser React-latex. \ No newline at end of file diff --git a/documentation/docs/developpeur/backend/quiz.md b/documentation/docs/developpeur/backend/quiz.md new file mode 100644 index 0000000..ce3c666 --- /dev/null +++ b/documentation/docs/developpeur/backend/quiz.md @@ -0,0 +1,54 @@ +# Example de Quiz + +```gift +//-----------------------------------------// +// Examples from gift/format.php. +//-----------------------------------------// + +Who's buried in Grant's tomb?{~Grant ~Jefferson =no one} + +Grant is {~buried =entombed ~living} in Grant's tomb. + +Grant is buried in Grant's tomb.{FALSE} + +Who's buried in Grant's tomb?{=no one =nobody} + +When was Ulysses S. Grant born?{#1822:5} + +Match the following countries with their corresponding capitals. { + =Canada -> Ottawa + =Italy -> Rome + =Japan -> Tokyo + =India -> New Delhi + ####It's good to know the capitals +} + +//-----------------------------------------// +// More complicated examples. +//-----------------------------------------// + +::Grant's Tomb::Grant is { + ~buried#No one is buried there. + =entombed#Right answer! + ~living#We hope not! +} in Grant's tomb. + +Difficult multiple choice question.{ + ~wrong answer #comment on wrong answer + ~%50%half credit answer #comment on answer + =full credit answer #well done!} + +::Jesus' hometown (Short answer ex.):: Jesus Christ was from { + =Nazareth#Yes! That's right! + =%75%Nazereth#Right, but misspelled. + =%25%Bethlehem#He was born here, but not raised here. +}. + +//this comment will be ignored by the filter +::Numerical example:: +When was Ulysses S. Grant born? {# + =1822:0 #Correct! 100% credit + =%50%1822:2 #He was born in 1822. + You get 50% credit for being close. +} +``` \ No newline at end of file diff --git a/documentation/docs/developpeur/backend/salle-de-quiz-swagger.json b/documentation/docs/developpeur/backend/salle-de-quiz-swagger.json new file mode 100644 index 0000000..2084a39 --- /dev/null +++ b/documentation/docs/developpeur/backend/salle-de-quiz-swagger.json @@ -0,0 +1,146 @@ +{ + "openapi": "3.0.2", + "info": { + "title": "Room API" + }, + "servers":[ + { + "url": "http://localhost", + "description": "Via Docker" + }, + { + "url": "http://localhost:3000", + "description": "Via npm" + } + ], + "security": [ + { + "bearerAuth": [] + } + ], + "paths": { + "/api/room": { + "get": { + "summary": "Get all rooms", + "description": "Returns a list of rooms", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Room" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a new room", + "description": "Creates a new room, returns the created room", + "responses": { + "200": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Room" + } + } + } + } + } + } + }, + "/api/room/{roomId}": { + "get": { + "summary": "Get a room by id", + "description": "Returns a room by id", + "parameters": [ + { + "name": "roomId", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Room" + } + } + } + } + } + }, + "delete": { + "summary": "Delete a room by id", + "description": "Deletes a room by id", + "parameters": [ + { + "name": "roomId", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + } + }, + "components": { + "securitySchemes": { + "bearerAuth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT" + } + }, + "schemas": { + "Room": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "default": "autoincrement" + }, + "name": { + "type": "string" + }, + "host": { + "type": "string" + }, + "nbStudents": { + "type": "integer", + "default": 0 + }, + "mustBeCleaned": { + "type": "boolean", + "default": false + } + }, + "required": [ + "id", + "name", + "host" + ] + } + } + } + } \ No newline at end of file diff --git a/documentation/docs/developpeur/backend/salle-de-quiz.md b/documentation/docs/developpeur/backend/salle-de-quiz.md new file mode 100644 index 0000000..d1adc03 --- /dev/null +++ b/documentation/docs/developpeur/backend/salle-de-quiz.md @@ -0,0 +1,185 @@ +# Salles de Quiz + +## Introduction + +Les salles de quiz ont été extraites dans leur propre container afin de limiter les dégats liés soit a une surutilisation d'une salle ou une attaque sur le logiciel. + +En éffet, le découplement permet a un quiz de: + + - Survivre même si le backend est non-fonctionnel + - Mourir sans entrainer toute l'application avec elle + - Créer/Supprimer des salles automatiquement dépendant de la demande + + Pour éffectuer ceci il faut éffectuer une petite gymnastique. Il y a une route dans l'api servant à gerer les salles. Lorsqu'un utilisateur demande le socket d'une salle : "/api/rooms/{id}/socket", la requette rebondit sur le proxy Nginx. Celui-ci contacte le backend afin d'obtenir l'addresse de l'ordinateur auquel envoyer la requette et redirige le socket vers ce pc. + +## Déconstruction simple de la structure + +Un module supplémnetaire a été ajouté à la structure : Rooms. + +L'objet `room` est la définition d'une salle de façon minimaliste, cette définission est aggrandie avec l'information récotlé du "provider". +Le `provider` est le système gérant les différentes salles. Dans l'implémentation éffectuée, il s'agit de docker. + +Lorsque l'api des salles est instantié, celui-ci est lié avec un "provider", définissant comment les salles seront créées. +L'api des salles permet de les ajouter, les supprimer, et les consulter les salles. + +L'api lance deux "jobs": + +- Une vérification de l'état de santé des salles. Celle-ci roule tous les 10 secondes et met a jour les salles. +- Une suppression des salles. Celle-ci roule tous les 30 secondes et supprimme automatiquement les salles ayant la mention de suppression. + +## Besoins exprimés + +Fiabilite : + +- Nous voulons s'assurer qu'il soit possible d'avoir un grand nombre d'élèves présent sans qu'il y ait des problèmes de déconnexions +- Nous voulons que le temps de réponse soit bas +- Nous voulons que le système soit capable de fonctionner de facon indépendante + +## Recis utilisateurs pris en comptes + +- En tant qu'enseignant, je veux que tous mes élèves soient capable de se connecter a la salle de classe rapidement +- En tant qu'enseignant, je veux que la salle de quiz puisse survivre des pannes liées aux autres modules de l'aplication +- En tant qu'administrateur, je veux que les salles soient indépendantes et qui ne touche pas aux performances des autres salles +- En tant qu'administrateur, je veux que les salles puissent être hébergées séparément du projet + +## Diagrammes + +### Structure +```plantuml +@startuml +class Room{ + +id + +name + +host + +nbStudents + +mustBeCleaned +} + +class RoomRepository { + +get(id) + +create(room) + +delete(id) + +update(room,id) + +getAll() +} + +class RoomController { + +setupRoom(options) + +deleteRoom(roomId) + +listRooms() + +getRoomStatus(roomId) + +updateRoom(room,roomId) +} + +class RoomRouter{ + + / : GET + + /:id : GET + + / : POST + + /:id : PUT + + /:id : DELETE +} + +class BaseRoomProvider { + +createRoom(roomid,options) + +deleteRoom(roomId) + +getRoomInfo(roomId) + +getRoomStatus(roomId) + +listRooms() + -cleanup() + -syncInstantiatedRooms() + #updateRoomInfos() +} + +class DockerRoomProvider +circle Dockerode + + +Room - RoomRepository +BaseRoomProvider o-- RoomRepository +DockerRoomProvider --|> BaseRoomProvider +DockerRoomProvider - Dockerode +Dockerode o-- QuizRoom +RoomController o-- BaseRoomProvider +RoomRouter o-- RoomController + +class QuizRoom{ + +/health: GET + +create-room() + +join-room() + +next-question() + +launch-student-mode() + +end-quiz() + +submit-answers() + -disconnect() +} +@enduml +``` +Remarque: Les signatures de fonctions semblent un peu partout car il y a des fonctions de classes standard, des appels HTTPS et des appels de sockets dans le même diagramme. + +### Diagramme de séquence démontrant les communications +```plantuml +@startuml + actor Teacher + actor Student + entity Nginx + entity Frontend + entity Api + entity Docker + entity Database + +group Quiz Creation + Teacher -> Frontend : Create a quizroom + Frontend -> Api : Create a quizroom + Api -> Docker : Create a quizroom + Docker -> QuizRoom ** + QuizRoom -> Docker : creation successful + Docker -> Api : Creation Successful + + loop every seconds until healthy or 30s: + Api -> QuizRoom : Checking Health via /health + QuizRoom -> Api : Doesn't answer, answer healthy or unhealthy + end + + Api -> Database : Create Room + Database -> Api : Room created + Api -> Teacher : Route to room socket +end + +group Quiz Joining: + Teacher -> Nginx : Join Room + Nginx -> Api : Get room infos from id + Api -> Nginx : Ip:port of room + Nginx -> QuizRoom: Give teacher's connexion + + Student -> Frontend: Join Room X + Frontend -> Nginx : Join Room X + Nginx -> Api : Get room infos from id + Api -> Nginx : Ip:port of room + Nginx -> QuizRoom: Give student's connexion + + QuizRoom -> QuizRoom : Give Quiz ... (Multiple actions) + + Student -> QuizRoom: Disconnect + Teacher -> QuizRoom: Disconect +end + +group QuizManagement (Every 10 seconds) + Api -> QuizRoom : Checking number of people in the room + QuizRoom -> Api : Number of people (0) or Unhealthy + Api -> Database : Mark room to deletion +end + +group Quiz Deletion (Every 30 seconds) + Api -> Database : Give all rooms marked for deletion + Database -> Api : rooms + Api -> Docker : delete rooms + Docker -> QuizRoom : delete + Docker -> Api : Deleted +end + +@enduml +``` + +## API + + diff --git a/documentation/docs/developpeur/deploiements/local.md b/documentation/docs/developpeur/deploiements/local.md new file mode 100644 index 0000000..fff9869 --- /dev/null +++ b/documentation/docs/developpeur/deploiements/local.md @@ -0,0 +1,61 @@ +## Prérequis + +- Assurez-vous d'avoir Node JS installé en téléchargeant la dernière version depuis [https://nodejs.org/en](https://nodejs.org/en). + +- Ensuite, assurez-vous d'avoir accès à un serveur MongoDB de développement + +> Pour plus d'informations sur la base de données, veuillez consulter la documentation [[ici|Base-de-données]] + +- Cloner le projet avec la commande suivante : + ``` + git clone https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git + ``` + +## Étape 1 - démarrage du backend + +1. Naviguez vers le répertoire du projet en utilisant la commande suivante : + ``` + cd .\EvalueTonSavoir\server\ + ``` + +2. Assurez-vous de créer le fichier .env et d'y ajouter les paramètres appropriés. Vous pouvez vous inspirer du fichier .env.example pour connaître les paramètres nécessaires. + + [[Voir ici la documentation des configurations|Configurations]] + +3. Installez les dépendances avec la commande suivante : + ``` + npm install + ``` + +4. Démarrez le serveur en utilisant la commande suivante : + ``` + npm run dev + ``` + +5. Ouvrez votre navigateur et accédez à l'URL indiquée dans la console (par exemple, http://localhost:4400). + +## Étape 2 - Démarrage du frontend + +1. Naviguez vers le répertoire du projet en utilisant la commande suivante : + ``` + cd .\EvalueTonSavoir\client\ + ``` +> [!WARNING] +> Assurez-vous que le backend est en cours d'exécution avant de démarrer le frontend. \ +> Notez également l'URL du serveur pour le fichier `.env`. + +2. Assurez-vous de créer le fichier .env et d'y ajouter les paramètres appropriés. Vous pouvez vous inspirer du fichier .env.example pour connaître les paramètres nécessaires. + + [[Voir ici la documentation des configurations|Configurations]] + +3. Installez les dépendances avec la commande suivante : + ``` + npm install + ``` + +4. Démarrez le frontend avec la commande suivante : + ``` + npm run dev + ``` + +5. Ouvrez votre navigateur et accédez à l'URL indiquée dans la console (par exemple, http://localhost:5173/). diff --git a/documentation/docs/developpeur/deploiements/prod.md b/documentation/docs/developpeur/deploiements/prod.md new file mode 100644 index 0000000..127d083 --- /dev/null +++ b/documentation/docs/developpeur/deploiements/prod.md @@ -0,0 +1,195 @@ + +## Introduction + +Nous avons choisi d'exécuter les composantes de cette application avec Docker, car cela simplifie le processus de gestion des processus d'application. + +Voici un diagramme de déploiement expliquant la relation des composantes et comment les images Docker sont créées et déployées dans un serveur. + +```plantuml + @startuml + [Navigateur moderne (Windows/Android)] as Navigateur + [MongoDB] as MongoDB + Navigateur -> "docker-compose.yml" + [Docker] as Docker + "docker-compose.yml" -> [evaluetonSavoir-backend (Express, Javscript)] + [evaluetonSavoir-backend (Express, Javscript)] -> API_REST + [evaluetonSavoir-backend (Express, Javscript)] -> SOCKET_SALLE + [evaluetonSavoir-routeur (nginx)] as routeur + API_REST -> routeur + SOCKET_SALLE -> routeur + [evaluetonSavoir-frontend (Vue + TypeScript React)] as frontend + routeur -> frontend + [Docker hub] as DockerHub + [image-evaluetonSavoir-backend] -> DockerHub + [image-evaluetonSavoir-routeur] -> DockerHub + [image-evaluetonSavoir-frontend] -> DockerHub + [GitHub] as GitHub + "backend-deploy.yml" <- GitHub + "routeur-deploy.yml" <- GitHub + "frontend-deploy.yml" <- GitHub + Navigateur <--> evalsa.etsmtl.ca : chargée à partir des pages web + @enduml +``` + +## Prérequis + +Les STI nous a fourni un serveur avec les spécifications suivantes : + +- Ubuntu 22.04 LTS +- CPU : 4 cœurs +- RAM : 8 Go +- HDD : 100 Go +- Certificat SSL + +Les STI ont déjà effectué la configuration initiale de la machine selon leurs normes de mise en place d'un serveur pour assurer la bonne maintenance et sécurité au sein de leur infrastructure. Cette configuration inclut un utilisateur non root. + +Vous aurez également besoin d'un compte Docker Hub, ou vous pouvez simplement créer une PR sur le projet principal et elle sera déployée automatiquement. + +## Étape 1 - Installation de Docker + +Connectez-vous avec les informations d'identification de l'ETS : +``` +ssh @ +``` + +Tout d'abord, mettez à jour votre liste existante de packages : +``` +sudo apt update +``` + +Ensuite, installez quelques packages prérequis qui permettent à apt d'utiliser des packages via HTTPS : +> [!WARNING] +> Si vous voyez l'erreur suivante, ARRÊTEZ. Contactez les STI pour résoudre le problème. \ +> `Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 10703 (apt)` +``` +sudo apt install apt-transport-https ca-certificates curl software-properties-common +``` + +Ajoutez la clé GPG du référentiel Docker officiel à votre système : +``` +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg +``` + +Ajoutez le référentiel Docker aux sources APT : +``` +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +``` + +Mettez à jour à nouveau votre liste existante de packages pour que l'ajout soit reconnu : +``` +sudo apt update +``` + +Assurez-vous que vous vous apprêtez à installer à partir du référentiel Docker plutôt que du référentiel Ubuntu par défaut : +``` +apt-cache policy docker-ce +``` + +Vous verrez une sortie comme celle-ci, bien que le numéro de version pour Docker puisse être différent : +```Output +docker-ce: + Installed: (none) + Candidate: 5:26.0.0-1~ubuntu.22.04~jammy + Version table: + 5:26.0.0-1~ubuntu.22.04~jammy 500 + 500 https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages + 5:25.0.5-1~ubuntu.22.04~jammy 500 + 500 https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages +... +``` + +Installez Docker : +``` +sudo apt install docker-ce +``` + +Vérifiez que Docker fonctionne : +``` +sudo systemctl status docker +``` + +La sortie devrait être similaire à ce qui suit, montrant que le service est actif et en cours d'exécution : +```Output +● docker.service - Docker Application Container Engine + Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) + Active: active (running) since Fri 2024-04-05 13:20:12 EDT; 1min 24s ago +TriggeredBy: ● docker.socket + Docs: https://docs.docker.com + Main PID: 19389 (dockerd) + Tasks: 10 + Memory: 28.7M + CPU: 172ms + CGroup: /system.slice/docker.service + └─19389 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock +... +``` + +> [!NOTE] +> Si Docker ne roule pas, p.ex. vous voyez : +> ``` +> ○ docker.service - Docker Application Container Engine +> Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) +> Active: inactive (dead) +> ``` +> Vous devez démarrer Docker : +> ``` +> sudo systemctl start docker +> ``` + +## Étape 2 - Installation de Docker Compose + +Créez un répertoire d'installation Docker Compose : +``` +mkdir -p ~/.docker/cli-plugins/ +``` + +Obtenez Docker Compose : +``` +curl -SL https://github.com/docker/compose/releases/download/v2.26.1/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose +``` + +Ensuite, définissez les permissions correctes pour que la commande docker compose soit exécutable : +``` +chmod +x ~/.docker/cli-plugins/docker-compose +``` + +Pour vérifier que l'installation a réussi, vous pouvez exécuter : +``` +docker compose version +``` + + +## Étape 3 - Ajouter notre projet + + +Commencez par créer un nouveau répertoire dans votre dossier personnel : +``` +mkdir ~/EvalueTonSavoir +``` + +Puis déplacez-vous dans le répertoire : +``` +cd ~/EvalueTonSavoir +``` + +Créez un fichier `docker-compose.yaml` à partir du dépôt GitHub : +``` +curl -SL https://raw.githubusercontent.com/ets-cfuhrman-pfe/EvalueTonSavoir/main/docker-compose.yaml -o docker-compose.yaml +``` + +> [!NOTE] +> Avant de continuer, veuillez noter qu'il est crucial de mettre à jour les variables d'environnement dans le script, car les valeurs actuelles sont des modèles génériques. Assurez-vous de personnaliser ces variables selon les besoins spécifiques de votre environnement avant d'exécuter le script. + +Avec le fichier docker-compose.yml en place, vous pouvez maintenant exécuter Docker Compose pour démarrer votre environnement : +``` +sudo docker compose up -d +``` + +Vérifiez que les services fonctionne : +``` +sudo docker ps -a +``` + +## Conclusion + +Félicitations ! Vous avez maintenant avec succès configuré et lancé EvalueTonSavoir sur votre serveur, prêt à être utilisé. diff --git a/documentation/docs/developpeur/documentation/a-propos.md b/documentation/docs/developpeur/documentation/a-propos.md new file mode 100644 index 0000000..407e09a --- /dev/null +++ b/documentation/docs/developpeur/documentation/a-propos.md @@ -0,0 +1,23 @@ +# A propos + +## Lancer la documentation +Pour lancer la documentation, il faut installer python et entrer dans le dossier documentation. +Il faut ensuite installer les dépendances avec `pip install -r requirements.txt`. +Pour lancer le mode développement il faut executer `python -m mkdocs serve` +Afin d'accellerer le déploiement et ne pas être touché par des érreurs de "rate-limiting", il est préférable d'utiliser une image docker de plantuml. Pour cela, il faut utiliser la commande suivante : `docker run -d --name plantuml -p 8080:8080 plantuml/plantuml-server:tomcat` + +## Deploiement +Le code est automatiquement déployé par la github-action `create-docs.yaml` +Celle-ci ouvre le repo et fait les memes étapes que "lancer la documentation". +Il y a une différence, elle utilise `build` au lieu de `serve` pour ensuite publier avec l'outil [`ghp-import`](https://github.com/c-w/ghp-import). +La page est poussée sur la branche [`gh-pages`](https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir/tree/gh-pages) et ensuite publié en tant que [gh-page](https://pages.github.com/) + +## Themes et Plugins +Si vous ajoutez des plugins, veuillez mettre a jour le fichier `requirements.txt`. + +La documentation utilise [MkDocs](https://www.mkdocs.org/) avec [le theme matérial]((https://squidfunk.github.io/mkdocs-material/)). Il y a bien des fonctionalitées tel que les code-blocks qui peuvent être activés. +Vous pouvez avoir accès a la documentation ici : [https://squidfunk.github.io/mkdocs-material/reference/code-blocks/](https://squidfunk.github.io/mkdocs-material/reference/code-blocks/) + +## Autre méthode de lancement (virtuel) +Si vous avez un probleme avec votre environement et vous avez besoin d'un environement virtuel, il s'agit de faire `python -m venv .venv` dans le dossier document et d'activer cet environemment avec le fichier activate (changeant depedant de votre invite de commande) : `.venv\script\activate` +vous pouvez ensuite continuer les autres étapes. \ No newline at end of file diff --git a/documentation/docs/developpeur/frontend/index.md b/documentation/docs/developpeur/frontend/index.md new file mode 100644 index 0000000..008623c --- /dev/null +++ b/documentation/docs/developpeur/frontend/index.md @@ -0,0 +1,21 @@ +## À Propos + +Ce projet représente une interface utilisateur React pour notre application. + +## GIFT text format render (code source) + +Le code original a été développé pour créer une extension VS afin de prendre en charge le format de texte GIFT. + +Le code peut être trouvé ici: [https://codesandbox.io/s/gift-templates-iny09](https://codesandbox.io/s/gift-templates-iny09) + +Nous avons décidé de réutiliser ce code car il fournit un aperçu proche de ce à quoi ressemblent les quiz dans Moodle. Ce qui est une plateforme bien connue à l'École de technologie supérieure (ÉTS). + +Pour réutiliser le code, nous avons dû installer les packages NPM suivants: + +- [katex](https://www.npmjs.com/package/katex) : Une bibliothèque JavaScript rapide et facile à utiliser pour le rendu mathématique TeX sur le web. +- [marked](https://www.npmjs.com/package/marked) : Un analyseur syntaxique et un compilateur de markdown. Construit pour la vitesse. +- [nanoid](https://www.npmjs.com/package/nanoid) : Un générateur d'identifiants de chaîne unique, sécurisé, convivial pour les URL et minuscule (108 octets) pour JavaScript. +- [gift-pegjs](https://www.npmjs.com/package/gift-pegjs) : Un analyseur GIFT pour JavaScript utilisant PEG.js. +- [@types/katex](https://www.npmjs.com/package/@types/katex) : Définitions TypeScript pour katex. +- [@types/marked](https://www.npmjs.com/package/@types/marked) : Définitions TypeScript pour marked. +- [@types/nanoid](https://www.npmjs.com/package/@types/nanoid) : Définitions TypeScript pour nanoid. diff --git a/documentation/docs/developpeur/index.md b/documentation/docs/developpeur/index.md new file mode 100644 index 0000000..14e4554 --- /dev/null +++ b/documentation/docs/developpeur/index.md @@ -0,0 +1,78 @@ +# Structure haut niveau + +## But du projet +ÉvalueTonSavoir a été créer dû aux gros coûts des versions entreprises des logiciels similaires tels que Socrative et Kahoot. Le bût principal est d’être capable d’avoir une plateforme auto-hébergée et bien intégrée dans les systèmes déjà présents des établissements scolaire. + +## Requis + +Le but du projet étant un outils gratuis/libre afin d'améliorer l'apprentissage, celui-ci a les bûts suivants : + +- Permettre aux personnels enseignant de créer des tests +- Permettre aux enseignant de collecter les résultats des tests +- Permettre aux étudiants de prendre ces tests +- Permettre aux étudiants d'avoir une rétroaction + +Afin de limiter le niveau de difficulté d'intégration du personnel enseignant: + +- L'utilisation du format [`GIFT`](https://docs.moodle.org/405/en/GIFT_format) déja présent dans moodle doit être utilisé +- Le personnel et les étudiants doivent être capable de s'authentifier avec le portail de l'école +- Le démarage du quiz doit se faire de facon rapide et éfficace. + +Afin de faciliter le déploiement de masse : + +- Le logiciel doit être facile a déployer sur des machines locales +- Le logiciel doit être facile a déployer sur le cloud +- Le logiciel doit s'interconnecter à l'infrastructure présente +- Le logiciel doit être performant et fiable + +## Architecture actuelle + +```plantuml +@startuml + + +package Proxy{ + component Nginx +} + +package App{ + component Frontend + component Backend + database MongoDb +} + +cloud Provider{ + component QuizRoom +} + + +Nginx --down-> Backend +Nginx --down-> Frontend +Nginx --down-> Provider + +Backend --right-> MongoDb +Backend --up-> Nginx + +Frontend --up-> Nginx +@enduml +``` + +### Details techniques + +Le tableau ci-dessus est simplifié grandement car toutes les composantes sont individuelles. Ce qui veux dire qu'une toutes les parties pouraient être déployé sur un serveur différent et tout de même fonctionner, permettant de distribuer la charge de travail facilement. + +Le proxy Nginx permet de camoufler la séparation du backend et frontend en réunissant les deux parties sous la même url. Il a aussi la tache de diriger les appels de sockets vers leurs machine interne dans le provider. + +Le frontend déssert la partie visuel de l'application. + +Le backend s'occupe de tous les services tel quel : + +- La gestion des utilisateurs +- La gestion des quizs +- La gestion des médias +- La gestion des salles + + +### Liens vers détails supplémentaires +- [Gestion de l'authentification](./backend/auth.md) +- [Gestion de la salle de Quiz](./backend/salle-de-quiz.md) \ No newline at end of file diff --git a/documentation/docs/index.md b/documentation/docs/index.md new file mode 100644 index 0000000..c9cd0e2 --- /dev/null +++ b/documentation/docs/index.md @@ -0,0 +1,23 @@ +# A propos + +EvalueTonSavoir est une plateforme open source et auto-hébergée qui poursuit le développement du code provenant de [https://github.com/ETS-PFE004-Plateforme-sondage-minitest](https://github.com/ETS-PFE004-Plateforme-sondage-minitest). Cette plateforme minimaliste est conçue comme un outil d'apprentissage et d'enseignement, offrant une solution simple et efficace pour la création de quiz utilisant le format GIFT, similaire à Moodle. + +## Fonctionnalités clés + +* Open Source et Auto-hébergé : Possédez et contrôlez vos données en déployant la plateforme sur votre propre infrastructure. +* Compatibilité GIFT : Créez des quiz facilement en utilisant le format GIFT, permettant une intégration transparente avec d'autres systèmes d'apprentissage. +* Minimaliste et Efficace : Une approche bare bones pour garantir la simplicité et la facilité d'utilisation, mettant l'accent sur l'essentiel de l'apprentissage. + +## Contribution + +Actuellement, il n'y a pas de modèle établi pour les contributions. Si vous constatez quelque chose de manquant ou si vous pensez qu'une amélioration est possible, n'hésitez pas à ouvrir un issue et/ou une PR) + +## Liens utiles + +* [Dépôt d'origine Frontend](https://github.com/ETS-PFE004-Plateforme-sondage-minitest/ETS-PFE004-EvalueTonSavoir-Frontend) +* [Dépôt d'origine Backend](https://github.com/ETS-PFE004-Plateforme-sondage-minitest/ETS-PFE004-EvalueTonSavoir-Backend) +* [Documentation (Wiki)](https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir/wiki) + +## License + +EvalueTonSavoir is open-sourced and licensed under the [MIT License](/LICENSE). \ No newline at end of file diff --git a/documentation/docs/javascripts/katex.js b/documentation/docs/javascripts/katex.js new file mode 100644 index 0000000..3828300 --- /dev/null +++ b/documentation/docs/javascripts/katex.js @@ -0,0 +1,10 @@ +document$.subscribe(({ body }) => { + renderMathInElement(body, { + delimiters: [ + { left: "$$", right: "$$", display: true }, + { left: "$", right: "$", display: false }, + { left: "\\(", right: "\\)", display: false }, + { left: "\\[", right: "\\]", display: true } + ], + }) + }) \ No newline at end of file diff --git a/documentation/docs/utilisateur/configuration.md b/documentation/docs/utilisateur/configuration.md new file mode 100644 index 0000000..8decb56 --- /dev/null +++ b/documentation/docs/utilisateur/configuration.md @@ -0,0 +1,25 @@ +> [!NOTE] +> Chaque projet contient un fichier `.env.example` fournissant des exemples de configuration. Assurez-vous de consulter ce fichier pour vous inspirer des paramètres nécessaires à votre configuration. + +> [!NOTE] +> Ce sont toutes les options de configuration. N'hésitez pas à ouvrir une PR si vous en voyez qui manquent. + +## Options de Configuration Backend + +| Variable d'Environnement | Description | Exemple | Optionnel | +|---|---|---|---| +| `PORT` | Le port sur lequel l'application fonctionne | 4400 | non| +| `MONGO_URI` | La chaîne de connexion pour se connecter à la base de données mongodb | `mongodb://localhost:27017` or `mongodb://127.0.0.1:27017` (the former can cause trouble on Windows depending on hosts files) | non| +| `MONGO_DATABASE` | Le nom souhaité pour la base de données | evaluetonsavoir | non| +| `EMAIL_SERVICE` | Le service utilisé pour les e-mails | gmail | non| +| `SENDER_EMAIL` | L'adresse e-mail utilisée pour l'envoi | monadresse@gmail.com | non| +| `EMAIL_PSW` | Le mot de passe de l'adresse e-mail | 'monmotdepasse' | non| +| `JWT_SECRET` | Le secret utilisé pour la gestion des JWT | monsecretJWT | non| +| `FRONTEND_URL` | URL du frontend, y compris le port | http://localhost:5173 | non| + +## Options de Configuration Frontend + +| Variable d'Environnement | Description | Exemple | Optionnel | +|---|---|---|---| +| `VITE_BACKEND_URL` | URL du backend, y compris le port | http://localhost:4400 | non| +| `VITE_AZURE_BACKEND_URL` | URL du backend, y compris le port | http://localhost:4400 | non| diff --git a/documentation/docs/utilisateur/deploiment.md b/documentation/docs/utilisateur/deploiment.md new file mode 100644 index 0000000..34e0806 --- /dev/null +++ b/documentation/docs/utilisateur/deploiment.md @@ -0,0 +1,13 @@ +# Déploiement + +Les méthodes recommandées de déploiement sont via Ansible et Opentofu. +Ansible est utilisés afin de faire un déploiement sur un serveur local, opentofu sur le cloud. + +## Ansible + +Le déploiement avec ansible est un déploiement simplifié. +Il vous suffis d'avoir un ordinateur linux/mac ou pouvant faire exécuter [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) dans le cas de windows. Il faut ensuite utiliser le gestionnaire de paquet (souvent apt) afin d'installer le paquet `ansible-core`, d'autres méthodes sont indiquées dans la [documentation officielle de ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html). Une fois le tout fais, vous pouvez telécharger [les fichiers nécéssaire](https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir/ansible) et lancer la commande `ansible-playbook -i inventory.ini deploy.yml` + +## OpenTofu +Le déploiement avec OpenTofu est un peu plus complexe mais il permet d'héberger la solution sur votre cloud préféré. +Il suffit [d'installer OpenTofu](https://opentofu.org/docs/intro/install/) et de téléchgarger [les fichiers nécéssaires](https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir/opentofu). Un Readme est inclus afin d'organiser votre grape de serveurs. \ No newline at end of file diff --git a/documentation/mkdocs.yml b/documentation/mkdocs.yml new file mode 100644 index 0000000..4c0909a --- /dev/null +++ b/documentation/mkdocs.yml @@ -0,0 +1,80 @@ +site_name: EvalueTonSavoir +repo_url: https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir +edit_uri: edit/main/documentation/docs + +theme: + language: fr + icon: + repo: fontawesome/brands/github + name: material + palette: + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + primary: deep purple + accent: purple + toggle: + icon: material/brightness-7 + name: Mode sombre + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: deep purple + accent: purple + toggle: + icon: material/brightness-4 + name: Mode clair + features: + - content.code.copy + - content.code.select + - content.code.annotate + - navigation.instant + - navigation.instant.progress + - navigation.tracking + - content.action.edit + highlightjs: true + hljs_languages: + - javascript + - typescript + - css + - react + - yaml + - latex + - katex + - gift + +use_directory_urls: false + +plugins: + - search + - offline + - plantuml: + default: https://www.plantuml.com/plantuml/ # default + puml_url: http://localhost:8080/plantuml # dev + puml_keyword: plantuml + theme: + light: material/deep-purple-light + dark: material/deep-purple-dark + - swagger-ui-tag: + docExpansion: "list" + tryItOutEnabled: false + +markdown_extensions: + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences + - pymdownx.arithmatex: + generic: true + +extra_javascript: + - javascripts/katex.js + - https://unpkg.com/katex@0/dist/katex.min.js + - https://unpkg.com/katex@0/dist/contrib/auto-render.min.js + +extra_css: + - https://unpkg.com/katex@0/dist/katex.min.css \ No newline at end of file diff --git a/documentation/python-version b/documentation/python-version new file mode 100644 index 0000000..fdcfcfd --- /dev/null +++ b/documentation/python-version @@ -0,0 +1 @@ +3.12 \ No newline at end of file diff --git a/documentation/requirements.txt b/documentation/requirements.txt new file mode 100644 index 0000000..ffb48c2 --- /dev/null +++ b/documentation/requirements.txt @@ -0,0 +1,7 @@ +mkdocs +mkdocs[i18n] +mkdocs_puml +mkdocs-material +Pygments +ghp-import +mkdocs-swagger-ui-tag \ No newline at end of file