doc assiduité

This commit is contained in:
Hartmann Matthias 2023-02-14 16:34:52 +01:00
parent ea5c3ae2ef
commit 0c171ae072
3 changed files with 812 additions and 133 deletions

View File

@ -0,0 +1,170 @@
<!-- markdownlint-disable MD024 -->
# Document expérimental sur les données du module Assiduité de ScoDoc
Dans ce document je (Matthias Hartmann) détaillerais plusieurs méthodes pour enregistrer les données du module Assiduité et les utiliser. Je mettrai à jour ce document et je l'utiliserai lors de l'implémentation du cahier des charges.
> Pour la suite du document je nomme `plage` l'objet représentant une absence/présence sur une période donnée.
Dans les diagrammes:
> - les noms précédés par `?` sont des valeurs optionnelles.
> - les noms précédés par `#` sont des clés externes.
> - les noms précédés par `$` sont des clés primaires.
___
> dev note *(11/10/22)*: Les types des données ne sont pas forcément les bons, je n'ai pas encore regardé comment était organisée la BDD de ScoDoc
## Représentation d'une assiduité et d'un justificatif
> voir l'API ScoDoc -> [ScoDoc9 API](ScoDoc9API.md#api-assiduite)
## Représentation des données (Version 4)
```mermaid
classDiagram
class assiduites{
$assiduiteid : Integer
#etuid : Integer
date_debut : DateTime
date_fin : DateTime,
etat : String
#module?: Integer
}
class justificatifs{
$justifid : Integer
#etuid : Integer
date_debut : DateTime
date_fin : DateTime
fichier? : Integer
raison? : String
#etat : Integer DEFAULT=0
}
class etat_justificatif{
$etat_id : Integer
desc : String
}
justificatifs --> etat_justificatif
```
### Explications de la représentation
> - Dans cette version, les objets en base de données suivent la représentation fait en json (dans l'API)
> - Le fichier justificatif est toujours stocker sur le serveur et en base il est stocker sous la forme d'un identifiant unique.
> - le champs `etat` de la table `justificatif` est une clé étrangère vers la table `etat_justificatif` qui contient les différents états (attente, validé, modifié, en cours . . . ), Cette table permettra aux utilisateurs d'ajouter eux même des états en fonction de leurs besoins. (deux états seront obligatoires : 0[Non Validé] 1[Validé] mais leurs noms pourront être changés.)
## Représentation des données (Version 3)
```mermaid
classDiagram
class plage{
plage_id : Integer
date_debut : DateTime
date_fin : DateTime
#etuid : Integer
type : String
? #module_id : Integer
? #enseignant_id : Integer
}
class justificatif{
$#etuid : Integer
$date_debut : DateTime
$date_fin : DateTime
attachement : String
#etat : Integer DEFAULT=0
}
class etat_justificatif{
$etat_id : Integer
desc : String
}
justificatif --> etat_justificatif
```
### Explications de la représentation
> - Dans cette représentation, une plage est complètement dissociée d'une formation / département. Elle repose uniquement sur un étudiant en particulier. On peut néanmoins spécifier l'enseignant et le module concerné par l'absence dans le but de produire des statistiques.
> - Du coté des justificatifs, on a désormais un attribut `etat` plutôt qu'un booléen. Cet attribut est une clé étrangère lié à la table `etat_justificatif`. Cela permet alors d'avoir plusieurs états (Validé, Refusé, En Attente, Incomplet...) l'état `0` étant `Pas encore étudié` par exemple.
### Problèmes de la représentation
> - On utilise une nouvelle table pour stocker les différents états. A moins que cette table ne puisse être modifiée par les administrateurs de ScoDoc (ajouter des états pour des cas précis par IUT), on créer une table pour enregistrer des données statiques.
### Améliorations potentielles
> - A la place d'une table dans la BDD, on pourrait directement hard coder les états de justificatifs. Les états seront plus simple à accéder mais on perd l'aspect modification au cas par cas.
## Représentation des données (Version 2)
```mermaid
classDiagram
class plage{
id_plage : Integer
date_debut : DateTime
date_fin : DateTime
#id_dept : Integer
#formsemestre_id : Integer
#etuid : Integer
type : String
? #id_module : Integer
? #id_enseignant : Integer
}
class justificatif{
$#etuid : Integer
$date_debut : DateTime
$date_fin : DateTime
attachement : String
valide : bool DEFAULT=False
}
```
### Problèmes liés à la représentation
> - L'export de la base de donnée avec les justificatif devient plus complexe (car on doit aller chercher les fichiers du dossier justificatifs)
> - Même problème que la version 1 pour les requêtes
## Représentation des données ( Version 1)
```mermaid
classDiagram
class plage{
id_plage : Integer
date_debut : DateTime
date_fin : DateTime
#id_dept : Integer
#formsemestre_id : Integer
#etuid : Integer
type : String
? #id_module : Integer
? #id_enseignant : Integer
}
class justificatif{
#$id_plage : Integer
attachement : Blob
valide : bool DEFAULT=False
}
```
### Problèmes liés à la représentation
> - Quasiment l'ensemble des données sont stockées dans un même tuple\
> __Conséquence__ : chaque requête utilisant les données sera longue et lourde pour le gestionnaire de BDD
> - Le stockage sour la forme de blob est très lourd pour la bdd ( cf : [Benchmark des différentes méthode de stockage de fichier binaire sur progresql](https://www.cybertec-postgresql.com/en/binary-data-performance-in-postgresql/) )
> - Un justificatif doit être donné pour chaque absence (par exemple un arrêt maladie de plusieurs jours est présent dans la base autant de fois que l'étudiant a été absence à un cours )
### Avantages liés à la représentation
> - Peu ou pas de jointure à faire
> - Ensemble des données facilement accessibles
> - Une absence (`plage: type=absence`) est justifiée si un justificatif (`justificatifs : idPlage={idAbsence}`) est présent dans la base. Une absence peut être justifiée(par un étudiant par exemple) mais pas forcément validé par le corps enseignant / administratif. (`justificatifs : valide=Faux`)
> - l'objet justificatif permet de stocker un fichier / un texte servant de justification (`justificatifs : attachement={Blob}`). L'utilisation d'un __Blob__ permet de stocker virtuellement n'import quel type de fichier dans la bdd.
### Améliorations potentielles
> - Stocker les fichiers justificatifs dans un dossier sur le serveur plutôt que dans la base de donnée. On aurait alors une sauvegarde uniquement d'une chaîne de caractères (le chemin du fichier / la justification textuelle) au lieu de __Blob__ prenant beaucoup de place et étant lourds à traiter.\
> __Le problème est qu'on perd la facilité d'accès et les vérifications opérées automatiquement par le gestionnaire de base de donnée.__
> - Définir une durée de validité pour chaque justificatif au lieu de lier le justificatif à une plage. (et donc lier un justificatif à un étudiant)\
> __Le problème est qu'on perd de la simplicité de selection (utilisation de l'id de la plage dans un cas et utilisation de 2 *datetime* dans un autre) Mais au moins on a pas besoin d'entrer plusieurs fois un même justificatif.__

View File

@ -0,0 +1,119 @@
<!-- markdownlint-disable MD024 -->
# Gestions des fichiers justificatifs pour le module Assiduité
Le fonctionnement de l'importation / lecture des fichiers justificatifs est légèrement plus complexe que l'utilisation de l'API seule. Voici les différentes informations à savoir pour correctement utiliser les fichiers justificatifs.
Afin de bien comprendre les différentes informations, merci de lire d'abord la documentation de l'API Assiduité : [Documentation Assiduité](ScoDoc9API.md#api-assiduite)
## Importer un fichier
L'importation d'un fichier pour un justificatif se fait en deux temps :
* Créer un nouvel objet justificatif à l'aide de l'API
* Envoyer le fichier sur le serveur ScoDoc
### Envoyer le fichier sur le serveur ScoDoc
Dans un premier temps il faut créer un objet justificatif à l'aide de l'API.
Dans un second temps il faut envoyer le fichier sur le serveur à l'aide d'une requête `POST`.
#### Exemple en Python
##### Script d'envoi du justificatif
> `token` est le même token que pour le reste de l'API
```py
data = {
"etat": "attente",
"date_debut": "2022-10-27T08:00",
"date_fin": "2022-10-27T12:00",
}
# la route de l'api est : /justificatif/<etudid:int>/create
r = requests.post(API_URL + "/justificatif/123/create", json=data, headers=token)
print(r.json)
```
##### Réponse
```json
{
"justif_id" : 424242
}
```
##### Script d'envoi du fichier
> `token` est le même token que pour le reste de l'API
```py
with open('exemple.txt', 'rb') as f:
# la route pour importer est : api/justificatif/<justif_id:int>/import
r = requests.post(API_URL + "/justificatif/424242/import", files={"exemple.txt": f}, headers=token)
print(r.json)
```
##### Réponse
```json
{
"filename" : "exemple.txt"
}
```
Veillez à bien noter le nom de fichier renvoyé car c'est le nom coté "server", il sera à utiliser lors que vous souhaitez récupérer le fichier
ou lorsque vous voudrez le supprimer
## Télécharger un fichier
Pour télécharger un fichier de justificatif rien de plus simple
### Une simple requête POST
* **Méthode:** POST
* **Permission: `ScoView`**
* **Paramètres:**
* `justif_id`
* `filename`
* **Routes:** `/justificatif/<justif_id:int>/export/<filename>`
* **Exemple d'utilisation:** `/api/justificatif/424242/export/exemple.txt`
* **Résultat:** télécharge directement le fichier
## Supprimer un fichier
Pour supprimer un fichier il suffit d'envoyer une requête post sur le justificatif, avec un json correct
### Script de suppression du fichier
> `token` est le même token que pour le reste de l'API
```py
# la route pour supprimer est : api/justificatif/<justif_id:int>/remove
d = {
"remove": "list",
"filenames": [
"exemple.txt"
]
}
# ou
d = {
"remove": "al",
}
r = requests.post(API_URL + "/justificatif/424242/remove", data=d, headers=token)
print(r.json)
```
#### Réponse
```json
{
"response" : "removed"
}
```

View File

@ -1,5 +1,6 @@
<!-- markdownlint-disable MD041 MD040 MD033 MD051 -->
## API pour ScoDoc 9
## API pour ScoDoc 9
L'API ScoDoc permet à des applications tierces d'interroger ScoDoc. Elle offre un accès aux informations aux formats XML et JSON. L'API ScoDoc permet à des applications tierces d'interroger ScoDoc. Elle offre un accès aux informations aux formats XML et JSON.
La version ScoDoc 9 a introduit une nouvelle API avec un nouveau mécanisme d'authentification. La version ScoDoc 9 a introduit une nouvelle API avec un nouveau mécanisme d'authentification.
@ -222,75 +223,90 @@ Ce tableau est trié selon le type des informations renvoyées:
* suivi de `:` puis d'un nom en majuscule indique une requête (POST) qui modifie * suivi de `:` puis d'un nom en majuscule indique une requête (POST) qui modifie
les données de ScoDoc. les données de ScoDoc.
| Retour | Remarque | Méthode | Navigation | Permission | | Retour | Remarque | Méthode | Navigation | Permission |
|:------------------------|:----------------------------------------|---------|---------------------------------------------------------------------------|---------------------| | :---------------------- | :----------------------------------------------------- | ------- | ------------------------------------------------------------------------- | ------------------- |
| departement**`*`** | tous les depts | GET | [departements](#departements) | | | assiduite | une assiduité | GET | [assiduité](#assiduite) | ScoView |
| departement**`#`** | tous les ids des depts | GET | [departements-ids](#departements-ids) | ScoView | | assiduite**`*`** | liste d'assiduités d'un étudiant | GET | [assiduités](#assiduites) | ScoView |
| departement | recherche par id | GET | [departement](#departement) | ScoView | | assiduite**`*`** | liste d'assiduités d'un formsemestre | GET | [assiduités-formsemestre](#assiduites-formsemestre) | ScoView |
| departement | recherche par acronyme | GET | [departement](#departement) | ScoView | | assiduite**`#`** | liste d'id d'assiduités justifiées par un justificatif | GET | [justificatif-justifies](#justificatif-justifies) | ScoView |
| departement:CREATE | création d'un département | POST | [departement-create](#departement-create) | ScoSuperAdmin | | assiduite:CREATE | création d'assiduité | POST | [assiduite-create](#assiduite-create) | ScoAssiduiteChange |
| departement:EDIT | modification d'un département | POST | [departement-edit](#departement-edit) | ScoSuperAdmin | | assiduite:EDIT | édition d'assiduité | POST | [assiduite-edit](#assiduite-edit) | ScoAssiduiteChange |
| departementDELETE | suppression d'un département | POST | [departement-delete](#departement-delete) | ScoSuperAdmin | | assiduite:DELETE | suppression d'assiduité | POST | [assiduite-delete](#assiduite-delete) | ScoAssiduiteChange |
| formation**`*`** | toutes les formations accessibles | GET | [formations](#formations) | ScoView | | justificatif | un justificatif | GET | [justificatif](#justificatif) | ScoView |
| formation**`#`** | ids des formations accessibles | GET | [formations-ids](#formations-ids) | ScoView | | justificatif**`*`** | liste de justificatif d'un étudiant | GET | [justificatifs](#justificatifs) | ScoView |
| formation | une formation | GET | [formation](#formation) | ScoView | | justificatif:CREATE | création de justificatif | POST | [justificatif-create](#justificatif-create) | ScoJustifChange |
| export | | GET | [formation-export](#formation-export) | ScoView | | justificatif:EDIT | édition de justificatif | POST | [justificatif-edit](#justificatif-edit) | ScoJustifChange |
| export**`+`** | | GET | [formation-export_with_ids](#formation-export_with_ids) | ScoView | | justificatif:DELETE | suppression de justificatif | POST | [justificatif-delete](#justificatif-delete) | ScoJustifChange |
| referentiel_competences | | GET | [formation-referenciel_competences](#formation-referenciel_competences) | ScoView | | justificatif:IMPORT | importation de fichier justificatif | POST | [justificatif-import](#justificatif-import) | ScoJustifChange |
| formsemestre**`#`** | | GET | [departement-formsemestres_ids](#departement-formsemestres_ids) | ScoView | | justificatif:EXPORT | exportation de fichier justificatif | POST | [justificatif-export](#justificatif-export) | ScoJustifChange |
| formsemestre**`*`** | | GET | [departement-formsemestres_courants](#departement-formsemestres_courants) | ScoView | | justificatif:REMOVE | suppression de fichier justificatif | POST | [justificatif-remove](#justificatif-remove) | ScoJustifChange |
| formsemestre**`*`** | | GET | [formsemestre-query](#formsemestre-query) | ScoView | | departement**`*`** | tous les depts | GET | [departements](#departements) | |
| formsemestre**`*`** | | GET | [etudiant-formsemestres](#etudiant-formsemestres) | ScoView | | departement**`#`** | tous les ids des depts | GET | [departements-ids](#departements-ids) | ScoView |
| formsemestre | | GET | [formsemestre](#formsemestre) | ScoView | | departement | recherche par id | GET | [departement](#departement) | ScoView |
| moduleimpl | | GET | [moduleimpl](#moduleimpl) | ScoView | | departement | recherche par acronyme | GET | [departement](#departement) | ScoView |
| partition**`*`** | | GET | [formsemestre-partitions](#formsemestre-partitions) | ScoView | | departement:CREATE | création d'un département | POST | [departement-create](#departement-create) | ScoSuperAdmin |
| partition | | GET | [partition](#partition) | ScoView | | departement:EDIT | modification d'un département | POST | [departement-edit](#departement-edit) | ScoSuperAdmin |
| partition:CREATE | | POST | [formsemestre-partition-create](#formsemestre-partition-create) | ScoEtudChangeGroups | | departementDELETE | suppression d'un département | POST | [departement-delete](#departement-delete) | ScoSuperAdmin |
| partition:EDIT | | POST | [partition-edit](#partition-edit) | ScoEtudChangeGroups | | formation**`*`** | toutes les formations accessibles | GET | [formations](#formations) | ScoView |
| partition:ACTION | | POST | [formsemestre-partitions-order](#formsemestre-partitions-order) | ScoEtudChangeGroups | | formation**`#`** | ids des formations accessibles | GET | [formations-ids](#formations-ids) | ScoView |
| partition:DELETE | | POST | [partition-delete](#partition-delete) | ScoEtudChangeGroups | | formation | une formation | GET | [formation](#formation) | ScoView |
| partition:ACTION | | POST | [partition-remove_etudiant](#partition-remove_etudiant) | ScoEtudChangeGroups | | export | | GET | [formation-export](#formation-export) | ScoView |
| group:CREATE | | POST | [partition-group-create](#partition-group-create) | ScoEtudChangeGroups | | export**`+`** | | GET | [formation-export_with_ids](#formation-export_with_ids) | ScoView |
| group:EDIT | | POST | [group-edit](#group-edit) | ScoEtudChangeGroups | | referentiel_competences | | GET | [formation-referenciel_competences](#formation-referenciel_competences) | ScoView |
| group:ACTION | | POST | [partition-groups-order](#partition-groups-order) | ScoEtudChangeGroups | | formsemestre**`#`** | | GET | [departement-formsemestres_ids](#departement-formsemestres_ids) | ScoView |
| group:DELETE | | POST | [group-delete](#group-delete) | ScoEtudChangeGroups | | formsemestre**`*`** | | GET | [departement-formsemestres_courants](#departement-formsemestres_courants) | ScoView |
| group* | | GET | [etudiant-formsemestre-groups](#etudiant-formsemestre-groups) | ScoView | | formsemestre**`*`** | | GET | [formsemestre-query](#formsemestre-query) | ScoView |
| group:ACTION | | POST | [group-set_etudiant](#group-set_etudiant) | ScoEtudChangeGroups | | formsemestre**`*`** | | GET | [etudiant-formsemestres](#etudiant-formsemestres) | ScoView |
| group:ACTION | | POST | [group-remove_etudiant](#group-remove_etudiant) | ScoEtudChangeGroups | | formsemestre | | GET | [formsemestre](#formsemestre) | ScoView |
| etudiant**`*`** | recherche par etudid, nip ou ine | GET | [etudiants-clef](#etudiants-clef) | ScoView | | moduleimpl | | GET | [moduleimpl](#moduleimpl) | ScoView |
| etudiant**`*`** | les étudiants actuels | GET | [etudiants-courant](#etudiants-courant) | ScoView | | partition**`*`** | | GET | [formsemestre-partitions](#formsemestre-partitions) | ScoView |
| etudiant**`*`** | | GET | [departement-etudiants](#departement-etudiants) | ScoView | | partition | | GET | [partition](#partition) | ScoView |
| etudiant**`*`** | | GET | [formsemestre-etudiants](#formsemestre-etudiants) | ScoView | | partition:CREATE | | POST | [formsemestre-partition-create](#formsemestre-partition-create) | ScoEtudChangeGroups |
| etudiant**`*`** | | GET | [formsemestre-etudiants-query](#formsemestre-etudiants-query) | ScoView | | partition:EDIT | | POST | [partition-edit](#partition-edit) | ScoEtudChangeGroups |
| etudiant**`*`** | | GET | [group-etudiants-query](#group-etudiants) | ScoView | | partition:ACTION | | POST | [formsemestre-partitions-order](#formsemestre-partitions-order) | ScoEtudChangeGroups |
| etudiant**`*`** | | GET | [group-etudiants-query](#group-etudiants-query) | | partition:DELETE | | POST | [partition-delete](#partition-delete) | ScoEtudChangeGroups |
| etudiant | | GET | [etudiant](#etudiant) | ScoView | | partition:ACTION | | POST | [partition-remove_etudiant](#partition-remove_etudiant) | ScoEtudChangeGroups |
| bulletin**`*`** | | GET | [formsemestre-bulletin](#formsemestre-bulletin) | ScoView | | group:CREATE | | POST | [partition-group-create](#partition-group-create) | ScoEtudChangeGroups |
| bulletin | | GET | [etudiant-formsemestre-bulletin](#etudiant-formsemestre-bulletin) | ScoView | | group:EDIT | | POST | [group-edit](#group-edit) | ScoEtudChangeGroups |
| programme | | GET | [formsemestre-programme](#formsemestre-programme) | ScoView | | group:ACTION | | POST | [partition-groups-order](#partition-groups-order) | ScoEtudChangeGroups |
| | | GET | [formsemestre-etat_evals](#formsemestre-etat_evals) | ScoView | | group:DELETE | | POST | [group-delete](#group-delete) | ScoEtudChangeGroups |
| | | GET | [formsemestre-resultats](#formsemestre-resultats) | ScoView | | group* | | GET | [etudiant-formsemestre-groups](#etudiant-formsemestre-groups) | ScoView |
| jury | | GET | [formsemestre-decisions_jury](#formsemestre-decisions_jury) | ScoView | | group:ACTION | | POST | [group-set_etudiant](#group-set_etudiant) | ScoEtudChangeGroups |
| note* | | GET | [evaluation-notes](#evaluation-notes) | ScoView | | group:ACTION | | POST | [group-remove_etudiant](#group-remove_etudiant) | ScoEtudChangeGroups |
| logo**`*`** | | GET | [logos](#logos) | ScoSuperAdmin | | etudiant**`*`** | recherche par etudid, nip ou ine | GET | [etudiants-clef](#etudiants-clef) | ScoView |
| logo**`*`** | | GET | [departement-logos](#departement-logos) | ScoSuperAdmin | | etudiant**`*`** | les étudiants actuels | GET | [etudiants-courant](#etudiants-courant) | ScoView |
| logo | | GET | [logo](#logo) | ScoSuperAdmin | | etudiant**`*`** | | GET | [departement-etudiants](#departement-etudiants) | ScoView |
| logo | | GET | [departement-logo](#departement-logo) | ScoSuperAdmin | | etudiant**`*`** | | GET | [formsemestre-etudiants](#formsemestre-etudiants) | ScoView |
| user | | GET | [user](#user) | ScoUsView | | etudiant**`*`** | | GET | [formsemestre-etudiants-query](#formsemestre-etudiants-query) | ScoView |
| user**`*`** | | GET | [users-query](#users-query) | ScoUsView | | etudiant**`*`** | | GET | [group-etudiants-query](#group-etudiants) | ScoView |
| user:CREATE | | POST | [user-create](#user-create) | ScoUserAdmin | | etudiant**`*`** | | GET | [group-etudiants-query](#group-etudiants-query) | |
| user:EDIT | | POST | [user-edit](#user-edit) | ScoUserAdmin | | etudiant | | GET | [etudiant](#etudiant) | ScoView |
| user:PASSWORD | change le mot de passe d'un utilisateur | POST | [user-password](#user-password) | ScoUserAdmin | | bulletin**`*`** | | GET | [formsemestre-bulletin](#formsemestre-bulletin) | ScoView |
| user:ACTION | | POST | [user-role-add](#user-role-add) | ScoUserAdmin | | bulletin | | GET | [etudiant-formsemestre-bulletin](#etudiant-formsemestre-bulletin) | ScoView |
| user:ACTION | | POST | [user-role-remove](#user-role-remove) | ScoUserAdmin | | programme | | GET | [formsemestre-programme](#formsemestre-programme) | ScoView |
| permission**`*`** | | GET | [permissions](#permissions) | ScoUsView | | | | GET | [formsemestre-etat_evals](#formsemestre-etat_evals) | ScoView |
| role**`*`** | | GET | [roles](#roles) | ScoUsView | | | | GET | [formsemestre-resultats](#formsemestre-resultats) | ScoView |
| role**`*`** | | GET | [role](#role) | ScoUsView | | jury | | GET | [formsemestre-decisions_jury](#formsemestre-decisions_jury) | ScoView |
| role:ACTION | | POST | [role-add_permission](#role-add_permission) | ScoUserAdmin | | note* | | GET | [evaluation-notes](#evaluation-notes) | ScoView |
| role:ACTION | | POST | [role-remove_permission](#role-remove_permission) | ScoUserAdmin | | logo**`*`** | | GET | [logos](#logos) | ScoSuperAdmin |
| role:CREATE | | POST | [role-create](#role-create) | ScoUserAdmin | | logo**`*`** | | GET | [departement-logos](#departement-logos) | ScoSuperAdmin |
| role:EDIT | | POST | [role-edit](#role-edit) | ScoUserAdmin | | logo | | GET | [logo](#logo) | ScoSuperAdmin |
| role:DELETE | | POST | [role-delete](#role-delete) | ScoUserAdmin | | logo | | GET | [departement-logo](#departement-logo) | ScoSuperAdmin |
| user | | GET | [user](#user) | ScoUsView |
| user**`*`** | | GET | [users-query](#users-query) | ScoUsView |
| user:CREATE | | POST | [user-create](#user-create) | ScoUserAdmin |
| user:EDIT | | POST | [user-edit](#user-edit) | ScoUserAdmin |
| user:PASSWORD | change le mot de passe d'un utilisateur | POST | [user-password](#user-password) | ScoUserAdmin |
| user:ACTION | | POST | [user-role-add](#user-role-add) | ScoUserAdmin |
| user:ACTION | | POST | [user-role-remove](#user-role-remove) | ScoUserAdmin |
| permission**`*`** | | GET | [permissions](#permissions) | ScoUsView |
| role**`*`** | | GET | [roles](#roles) | ScoUsView |
| role**`*`** | | GET | [role](#role) | ScoUsView |
| role:ACTION | | POST | [role-add_permission](#role-add_permission) | ScoUserAdmin |
| role:ACTION | | POST | [role-remove_permission](#role-remove_permission) | ScoUserAdmin |
| role:CREATE | | POST | [role-create](#role-create) | ScoUserAdmin |
| role:EDIT | | POST | [role-edit](#role-edit) | ScoUserAdmin |
| role:DELETE | | POST | [role-delete](#role-delete) | ScoUserAdmin |
#### Note sur les exemples d'utilisation #### Note sur les exemples d'utilisation
@ -300,18 +316,17 @@ Pour uniformiser les résultats des exemples, ceux sont soumis à quelques post-
* les listes de plus de 2 éléments sont tronquées à 2 éléments, la fin de la liste étant représentée par la notation en json '...' * les listes de plus de 2 éléments sont tronquées à 2 éléments, la fin de la liste étant représentée par la notation en json '...'
* les dates (au format ISO) sont systématiquement remplacées par une date fixe (la date de modification d'un mot de passe peut évidement être différente de sa date de création) * les dates (au format ISO) sont systématiquement remplacées par une date fixe (la date de modification d'un mot de passe peut évidement être différente de sa date de création)
### **API Départements**
### **API Départements**
#### Structure Département #### Structure Département
| attribut | type | commentaire | | attribut | type | commentaire |
|:-----------------|:--------|:---------------------------------------| |:-----------------|:--------|:---------------------------------------|
| _id_ | int | identifiant unique | | *id* | int | identifiant unique |
| _acronym_ | string | acronyme du département (fixe et unique) | | *acronym* | string | acronyme du département (fixe et unique) |
| _descripton_ | string | | | *descripton* | string | |
| _visible_ | bool | affiché ou non dans la page d'accueil | | *visible* | bool | affiché ou non dans la page d'accueil |
| _date_creation_ | string | date ISO | | *date_creation* | string | date ISO |
#### **departements** #### **departements**
@ -392,29 +407,29 @@ Pour uniformiser les résultats des exemples, ceux sont soumis à quelques post-
| attribut | type | commentaire | | attribut | type | commentaire |
|:-----------------|:--------------------|:---------------------------------| |:-----------------|:--------------------|:---------------------------------|
| _id_ | int | id unique | | *id* | int | id unique |
| _code_nip_ | string | non unique! | | *code_nip* | string | non unique! |
| _code_ine_ | string | non unique! | | *code_ine* | string | non unique! |
| _dept_id_ | | | | *dept_id* | | |
| _civilite_ | string | "M", "F" ou "X" | | *civilite* | string | "M", "F" ou "X" |
| _nom_ | string | en majuscule | | *nom* | string | en majuscule |
| _nom_usuel_ | string | null si absent | | *nom_usuel* | string | null si absent |
| _prenom_ | string | | | *prenom* | string | |
| _sort_key_ | [ string, string ] | nom-prenom pour trier | | *sort_key* | [ string, string ] | nom-prenom pour trier |
| | | **Format long** | | | | **Format long** |
| _date_naissance_ | string | date ISO | | *date_naissance* | string | date ISO |
| _email_ | string | | | *email* | string | |
| _emailperso_ | string | | | *emailperso* | string | |
| _admission_ | admission | | | *admission* | admission | |
| _adresses_ | adresse* | | | *adresses* | adresse* | |
| _boursier_ | | | | *boursier* | | |
| _dept_acronym_ | string | | | *dept_acronym* | string | |
| _dept_id_ | string | département du lieu de naissance | | *dept_id* | string | département du lieu de naissance |
| _lieu_naissance_ | string | lieu de naissance (ville) | | *lieu_naissance* | string | lieu de naissance (ville) |
| _nationalite_ | string | | | *nationalite* | string | |
| _photo_filename_ | string | | | *photo_filename* | string | |
| _scodoc7_id_ | string | de la forme 'EID9999' | | *scodoc7_id* | string | de la forme 'EID9999' |
| _statut_ | string | 'I', 'D' ou 'X' | | *statut* | string | 'I', 'D' ou 'X' |
#### **`etudiants`** (supprimé) #### **`etudiants`** (supprimé)
@ -531,20 +546,21 @@ Pour uniformiser les résultats des exemples, ceux sont soumis à quelques post-
| attribut | type | commentaire | | attribut | type | commentaire |
|:----------------------------|:------------|:--------------------------------------------------| |:----------------------------|:------------|:--------------------------------------------------|
| _dept_id_ | int | _redondant avec departement.id ?_ | | *dept_id* | int | *redondant avec departement.id ?* |
| _acronyme_ | string | | | *acronyme* | string | |
| _titre_ | string | _URL encoded ?_ | | *titre* | string | *URL encoded ?* |
| _version_ | int | | | *version* | int | |
| _type_parcours_ | int | | | *type_parcours* | int | |
| _referentiel_competence_id_ | int | null si pas de référentiel associé | | *referentiel_competence_id* | int | null si pas de référentiel associé |
| _id_ | int | id unique de formation | | *id* | int | id unique de formation |
| _titre_officiel_ | string | | | *titre_officiel* | string | |
| _formation_code_ | string | défini la compatibilité avec d'autres formations | | *formation_code* | string | défini la compatibilité avec d'autres formations |
| _code_specialité_ | string | | | *code_specialité* | string | |
| _departement_ | Département | _pour `/formations` mais pas pour `/formation` ?_ | | *departement* | Département | _pour `/formations` mais pas pour `/formation` ?_ |
| _formation_id_ | | _redondant avec id ?_ | | *formation_id* | | *redondant avec id ?* |
#### **`formations`** #### **`formations`**
* **Méthode:** GET * **Méthode:** GET
* **Permission: `ScoView`** * **Permission: `ScoView`**
* **Routes:** `/formations` * **Routes:** `/formations`
@ -812,7 +828,7 @@ responsable et ses enseignants). La liste des moduleimpl d'un formsemestre peut
| _**computation_expr**_ | string | unused | | _**computation_expr**_ | string | unused |
| _**module_id**_ | int | id du module | | _**module_id**_ | int | id du module |
| _**formsemestre_id**_ | int | id du formsemestre | | _**formsemestre_id**_ | int | id du formsemestre |
| _**moduleimpl_id**_ | int | _**redondance id_? | | _**moduleimpl_id**_ | int | ***redondance id*? |
| _**ens**_ | User# | liste des ids des enseignants du moduleimpl | | _**ens**_ | User# | liste des ids des enseignants du moduleimpl |
| _**module**_ | Module | | | _**module**_ | Module | |
@ -1048,7 +1064,7 @@ d'un autre).
* **Permission: `ScoUsersView`** * **Permission: `ScoUsersView`**
* **Routes:** * **Routes:**
* `/users/query?departement=dept_acronym&active=1&starts_with=<str:nom>` * `/users/query?departement=dept_acronym&active=1&starts_with=<str:nom>`
* **Résultat:** Liste d'utilisateurs, filtrés par département, statut, début de * **Résultat:** Liste d'utilisateurs, filtrés par département, statut, début de
nom (paramètres tous optionnels). Seuls les utilisateurs que l'on a la nom (paramètres tous optionnels). Seuls les utilisateurs que l'on a la
@ -1088,6 +1104,7 @@ d'un autre).
L'opération peut être rejetée si le mot de passe ne satisfait pas les conditions requises (trop simple par exemple), avec le retour suivant: L'opération peut être rejetée si le mot de passe ne satisfait pas les conditions requises (trop simple par exemple), avec le retour suivant:
> ```json > ```json
>
{ {
"error": "Bad Request", "error": "Bad Request",
"status": 400, "status": 400,
@ -1124,7 +1141,7 @@ d'un autre).
logiciel. Voir [ConfigPermissions](ConfigPermissions.md). logiciel. Voir [ConfigPermissions](ConfigPermissions.md).
* **Exemple de résultat:** [permissions.json](samples/sample_permissions.json.md) * **Exemple de résultat:** [permissions.json](samples/sample_permissions.json.md)
### ** API Bulletin, Évaluations, Notes** ### **API Bulletin, Évaluations, Notes**
#### **formsemestre-bulletins** #### **formsemestre-bulletins**
@ -1141,7 +1158,6 @@ indiquer les matières. Par défaut (version `long`), il est structuré en `UEs
version est `short_mat`ou `long_mat`, il sera structuré en version est `short_mat`ou `long_mat`, il sera structuré en
`UEs / matieres / modules`. `UEs / matieres / modules`.
#### **etudiant-formsemestre-bulletin** #### **etudiant-formsemestre-bulletin**
Récapitulatif par étudiant (état, groupe(s), moyennes d'UEs et de modules Récapitulatif par étudiant (état, groupe(s), moyennes d'UEs et de modules
@ -1174,7 +1190,6 @@ mais pas JSON compliant à cause des `NaN`.
"*Afficher les matières sur les bulletins*" est activée pour le formsemestre "*Afficher les matières sur les bulletins*" est activée pour le formsemestre
considéré (sinon, la note vaut toujours "*nd*"). ` considéré (sinon, la note vaut toujours "*nd*"). `
* **Exemple de résultat:** [etudiant-formsemestre-bulletin.json](samples/sample_etudiant-formsemestre-bulletin.json.md) * **Exemple de résultat:** [etudiant-formsemestre-bulletin.json](samples/sample_etudiant-formsemestre-bulletin.json.md)
#### **formsemestre-programme** #### **formsemestre-programme**
@ -1318,12 +1333,387 @@ valeurs numériques mais pas JSON compliant à cause des `NaN`.
* `/departement/id/<int:departement_id>/logo/<string:nom>` * `/departement/id/<int:departement_id>/logo/<string:nom>`
* **Exemple d'utilisation:** * **Exemple d'utilisation:**
* `/ScoDoc/api/departement/MMI/logo/header` * `/ScoDoc/api/departement/MMI/logo/header`
* `/ScoDoc/api/departement/id/3/logo/header` * `/ScoDoc/api/departement/id/3/logo/header`
* **Résultat :** l'image (format png ou jpg) * **Résultat :** l'image (format png ou jpg)
* **Exemple de résultat:** [departement-logo.json](samples/sample_departement-logo.json.md) * **Exemple de résultat:** [departement-logo.json](samples/sample_departement-logo.json.md)
### **API Assiduités**
<!-- TODO: faire les samples -->
#### Structure Assiduité
| attribut | type | commentaire |
| :-------------- | :------------- | :--------------------------------------------------------------- |
| *assiduite_id* | int | identifiant unique |
| *etudid* | int | identifiant unique de l'étudiant concerné par l'assiduité |
| *moduleimpl_id* | int ou null | identifiant unique du module concerné par l'assiduité si indiqué |
| *date_debut* | string | date ISO du début de la période d'assiduité |
| *date_fin* | string | date ISO de la fin de la période d'assiduité |
| *etat* | string | état de l'assiduité (present, absent, retard) |
| *desc* | string ou null | description de l'assiduité |
| *entry_date* | string | la date d'entrée de l'assiduité |
> Rappel du format de date ISO : yyyy-mm-jjTHH:MM:SS
> Vous pouvez aussi spécifier le temps UTC en ajoutant '+HH:MM' à la fin
#### **assiduite**
* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `assiduite_id`
* **Routes:** `/assiduite/<int:assiduite_id>`
* **Exemple d'utilisation:** `/api/assiduite/1`
* **Résultat:** Retourne un objet assiduité ou une erreur si l'id n'est pas connu
* **Exemple de résultat:** [assiduite.json](samples/sample_assiduite.json.md)
#### **assiduites[-query]**
* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `etudid`
* **Query string:**
* `etat` ('present','retard','absent)
* `moduleimpl_id` (X : id du moduleimpl concerné)
* `date_debut` (X : date format iso)
* `date_fin` (X : date format iso)
* `formsemestre_id` (X : id du formsemestre)
* **Routes:**
* `/assiduites/<int:etudid>`
* `/assiduites/<int:etudid>/query?`
* **Exemple d'utilisation:**
* `/api/assiduites/1`
* `/api/assiduites/1/query?etat=retard`
* `/api/assiduites/1/query?moduleimpl_id=1`
* **Résultat:** Liste de toutes les objets assiduité qui correspondent aux critères sélectionnés
* **Exemple de résultat:** [assiduites.json](samples/sample_assiduites.json.md)
#### **assiduites-count[-query]**
* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `etudid`
* **Query string:**
* `etat` ('present','retard','absent)
* `moduleimpl_id` (X : id du moduleimpl concerné)
* `date_debut` (X : date format iso)
* `date_fin` (X : date format iso)
* `formsemestre_id` (X : id du formsemestre)
* `metric` ('compte', 'demi', 'journee', 'heure')
* **Routes:**
* `/assiduites/<int:etudid>/count`
* `/assiduites/<int:etudid>/count/query?`
* **Exemple d'utilisation:**
* `/api/assiduites/1`
* `/api/assiduites/1/count/query?etat=retard`
* `/api/assiduites/1/count/query?moduleimpl_id=1`
* `/api/assiduites/1/count/query?etat=present,retard&metric=compte,heure`
* **Résultat:** les métriques obtenu à partir des assiduitées correspondant aux critères sélectionnés
* **Exemple de résultat:** [assiduites.json](samples/sample_assiduites.json.md)
#### **assiduites-formsemestre[-query]**
* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `etudid`
* **Query string:**
* `etat` ('present','retard','absent)
* `moduleimpl_id` (X : id du moduleimpl concerné)
* `date_debut` (X : date format iso)
* `date_fin` (X : date format iso)
* **Routes:**
* `/assiduites/formsemestre/<int:formsemestre_id>`
* `/assiduites/formsemestre/<int:formsemestre_id>/query?`
* **Exemple d'utilisation:**
* `/api/assiduites/formsemestre/1`
* `/api/assiduites/formsemestre/1/query?etat=retard`
* `/api/assiduites/formsemestre/1/query?moduleimpl=1`
* **Résultat:** Liste de toutes les objets assiduité des étudiants du formsemestre qui correspondent aux critères sélectionnés
* **Exemple de résultat:** [assiduites_formsemestre.json](samples/sample_assiduites_formsemestre.json.md)
#### **assiduites-formsemestre-count[-query]**
* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `etudid`
* **Query string:**
* `etat` ('present','retard','absent)
* `moduleimpl_id` (X : id du moduleimpl concerné)
* `date_debut` (X : date format iso)
* `date_fin` (X : date format iso)
* **Routes:**
* `/assiduites/formsemestre/<int:formsemestre_id>/count`
* `/assiduites/formsemestre/<int:formsemestre_id>/count/query?`
* **Exemple d'utilisation:**
* `/api/assiduites/formsemestre/1/count`
* `/api/assiduites/formsemestre/1/count/query?etat=retard`
* `/api/assiduites/formsemestre/1/count/query?moduleimpl=1&metric=demi,journee`
* **Résultat:** les métriques obtenu à partir des assiduitées de tous les étudiants du formsemestre correspondant aux critères sélectionnés
* **Exemple de résultat:** [assiduites_formsemestre.json](samples/sample_assiduites_formsemestre.json.md)
#### **assiduite-create**
* **Méthode:** POST
* **Permission: `ScoAssiduiteChange`**
* **Paramètres:** `etudid`
* **Data:**
```json
[
{
"date_debut": <string>,
"date_fin": <string>,
"etat": <string>,
"moduleimpl_id"?: <int>
},
...
]
```
* **Routes:**
* `/assiduite/<int:etudid>/create`
* **Exemple d'utilisation:** `/api/assiduite/1/create`
> `[{date_debut: "2022-10-27T08:00",date_fin: "2022-10-27T10:00",etat: "absent"}]`
* **Résultat:** Retourne un objet en deux partie (errors et success) contenant le retour de chaque objet donné dans la requête post.
* **Exemple de résultat:** [assiduite_create.json](samples/sample_assiduite_create.json.md)
#### **assiduite-edit**
* **Méthode:** POST
* **Permission: `ScoAssiduiteChange`**
* **Paramètres:** `assiduite_id`
* **Data:**
```json
{
"etat": <string>,
"moduleimpl_id": <int>
}
```
* **Routes:** `/assiduite/<int:assiduite_id>/edit`
* **Exemple d'utilisation:** `/api/assiduite/1/edit`
> `{etat: "absent"}`
* **Résultat:** Modifie l'assiduité désignée. Renvoie une erreur si la modification rend incompatible la plage de l'assiduité par rapport aux autres assiduités du même étudiant
* **Exemple de résultat:** [assiduite_edit.json](samples/sample_assiduite_edit.json.md)
#### **assiduite-delete**
* **Méthode:** POST
* **Permission: `ScoAssiduiteChange`**
* **Data:**
```json
[
<int:assiduite_id>,
...
]
```
* **Routes:**
* `/assiduite/delete`
* **Exemple d'utilisation:** `/api/assiduite/delete`
> `[2,3,5,7]`
* **Résultat:** Retourne un objet en deux partie (errors et success) contenant le retour de chaque objet donné dans la requête post.
* **Exemple de résultat:** [assiduite_delete.json](samples/sample_assiduite_delete.json.md)
#### Structure Justificatif
| attribut | type | commentaire |
| :----------- | :------------- | :------------------------------------------------------------ |
| *justif_id* | int | identifiant unique |
| *etudid* | int | identifiant unique de l'étudiant concerné par le justificatif |
| *date_debut* | string | date ISO du début de la période du justificatif |
| *date_fin* | string | date ISO de la fin de la période du justificatif |
| *etat* | string | état du justificatif ( attente, valide, non_valide, modifie) |
| *raison* | string ou null | explication du justificatif si présente |
| *fichier* | string | identifiant de l'archivage des fichiers |
| *entry_date* | string | date ISO de l'entrée du justificatif |
#### **justificatif**
* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `justif_id`
* **Routes:** `/justificatif/<int:justif_id>`
* **Exemple d'utilisation:** `/api/justificatif/1`
* **Résultat:** Retourne un objet justificatif ou une erreur si l'id n'est pas connu
* **Exemple de résultat:** [justificatif.json](samples/sample_justificatif.json.md)
#### **justificatifs[-query]**
* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `etudid`
* **Query string:**
* `etat` ( attente, valide, non_valide, modifie)
* `date_debut` (X : date format iso)
* `date_fin` (X : date format iso)
* **Routes:**
* `/justificatifs/<int:etudid>`
* `/justificatifs/<int:etudid>/query?etat=VALIDE`
* **Exemple d'utilisation:**
* `/api/justificatifs/1`
* `/api/justificatifs/1/query?etat=modifie`
* `/api/justificatifs/1/query?date_debut=2022-10-27T08:00`
* **Résultat:** Liste de toutes les objets justificatifs qui correspondent aux critères sélectionnés
* **Exemple de résultat:** [justificatifs.json](samples/sample_justificatifs.json.md)
#### **justificatif-create**
* **Méthode:** POST
* **Permission: `ScoJustifChange`**
* **Paramètres:** `etudid`
* **Data:**
```json
[
{
"etat": <string>,
"date_debut": <string>,
"date_fin": <string>,
"raison"?: <string>,
},
...
]
```
> Un fichier justificatif peut être importé dans scodoc après avoir créer l'objet justificatif voir [importer un justificatif](FichiersJustificatifs.md#importer-un-fichier)
* **Routes:** `/justificatif/<int:etudid>/create`
* **Exemple d'utilisation:** `/api/justificatif/1/create`
```json
[
{
"etat": "attente",
"date_debut": "2022-10-27T08:00",
"date_fin": "2022-10-27T12:00",
"raison": "Opération médicale",
}
]
```
* **Résultat:** Retourne un objet en deux partie (errors et success) contenant le retour de chaque objet donné dans la requête post.
* **Exemple de résultat:** [justificatif-create.json](samples/sample_justificatif-create.json.md)
#### **justificatif-edit**
* **Méthode:** POST
* **Permission: `ScoJustifChange`**
* **Paramètres:** `justif_id`
* **Data:**
```json
{
"etat": <string>,
"raison": <string>,
"date_debut": <string>,
"date_fin": <string>,
}
```
* **Routes:** `/justificatif/<int:justif_id>/edit`
* **Exemple d'utilisation:** `/api/justificatif/1/edit`
> `{etat: "valide"}`
* **Résultat:** Modifie le justificatif désignée.
* **Exemple de résultat:** [justificatif-edit.json](samples/sample_justificatif-edit.json.md)
#### **justificatif-delete**
* **Méthode:** POST
* **Permission: `ScoJustifChange`**
* **Paramètres:** `etudid`
* **Data:**
```json
[
<int:justif_id>,
...
]
```
* **Routes:** `/justificatif/delete`
* **Exemple d'utilisation:** `/api/justificatif/delete`
```json
[
2,3,5,7
]
```
* **Résultat:** Retourne un objet en deux partie (errors et success) contenant le retour de chaque objet donné dans la requête post.
* **Exemple de résultat:** [justificatif-delete.json](samples/sample_justificatif-delete.json.md)
#### **justificatif-import**
* **Méthode:** POST
* **Permission: `ScoJustifChange`**
* **Paramètres:** `justif_id`
> Procédure d'importation de fichier : [importer un justificatif](FichiersJustificatifs.md#importer-un-fichier)
* **Routes:** `/justificatif/<int:justif_id>/import`
* **Résultat:** Le nom du fichier archivé (nom coté serveur)
* **Exemple de résultat:** [justificatif-import.json](samples/sample_justificatif-import.json.md)
#### **justificatif-export**
* **Méthode:** POST
* **Permission: `ScoJustifChange`**
* **Paramètres:**
* `justif_id`
* `filename`
> Procédure de téléchargement de fichier : [télécharger un justificatif](FichiersJustificatifs.md#télécharger-un-fichier)
* **Routes:** `/justificatif/<int:justif_id>/export/<str:filename>`
* **Résultat:** le fichier (téléchargement direct / renvoie octets)
* **Exemple de résultat:** [justificatif-export.json](samples/sample_justificatif-export.json.md)
#### **justificatif-remove**
* **Méthode:** POST
* **Permission: `ScoJustifChange`**
* **Paramètres:** `justif_id`
> Procédure de suppression de fichier : [supprimer un justificatif](FichiersJustificatifs.md#supprimer-un-fichier)
* **Routes:** `/justificatif/<int:justif_id>/remove`
* **Résultat:** `{response:"removed"}` ou une erreur
* **Exemple de résultat:** [justificatif-remove.json](samples/sample_justificatif-remove.json.md)
#### **justificatif-list**
* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `justif_id`
* **Routes:** `/justificatif/<int:justif_id>/list`
* **Exemple d'utilisation:** `/api/justificatif/1/list`
* **Résultat:** Retourne la liste des fichiers archivés une erreur si l'id n'est pas connu
* **Exemple de résultat:** [justificatif-list.json](samples/sample_justificatif-list.json.md)
#### **justificatif-justifies**
* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `justif_id`
* **Routes:** `/justificatif/<int:justif_id>/justifies`
* **Exemple d'utilisation:** `/api/justificatif/1/justifies`
* **Résultat:** Retourne la liste des assiduite_id qui sont justifiés par le justificatif ou une erreur si l'id n'est pas connu
* **Exemple de résultat:** [justificatif-justifies.json](samples/sample_justificatif-justifies.json.md)
--------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------
### En savoir plus ### En savoir plus
@ -1357,4 +1747,4 @@ en POST.
Note: Note:
- `Absences/listeBillets` est un formulaire et ne fait pas partie de l'API. * `Absences/listeBillets` est un formulaire et ne fait pas partie de l'API.