@startuml diagramClass_tplant
class Etudiant implements Utilisateur {
    +id: string
    +token: string
    +prenom: string
    +nom: string
    +listeCours: Cours[]
    +isEnseignant(): boolean
    +isAnonyme(): boolean
}
class Enseignant implements Utilisateur {
    +id: string
    +token: string
    +prenom: string
    +nom: string
    +listeCours: Cours[]
    +isAnonyme(): boolean
    +isEnseignant(): boolean
    +getCours(): Cours[]
    +setEtatCours(cours: Cours): void
    +addCours(cours: Cours): void
    +removeCours(cours: Cours): void
}
class LoginControlleur {
    +login(email: string, password: string): Promise<Enseignant | Etudiant>
    +getUtilisateur(token: string): Promise<false | Enseignant | Etudiant>
}
class HoraireCours implements HoraireCoursInterface {
    +group_id: string
    +jours: string
    +heures: string
    +activite: string
    +mode: string
    +local: string
    +enseignant_id: string
}
class Cours implements CoursInterface {
    +id: string
    +group_id: string
    +prealable: string
    +titre: string
    +actif: boolean
    +etudiants_ids: Etudiant[]
    +horaire_cours: HoraireCours[]
    +liste_travaux: TravailInterface[]
    +getEnseignantId(): string
    +setEtat(etat: boolean): void
    +getTravaux(): TravailInterface[]
    +setTravail(travail: TravailInterface, id: string): TravailInterface
    +ajouterTravail(travail: TravailInterface): void
    +retirerTravail(devoir_id: string): void
}
class CoursControlleur {
    -_cours: Cours[]
    +recupererCours(user: Utilisateur): Cours[]
    +recupererCoursDetails(id: string): Cours
    +retirerCours(id: string): void
    +ajouterCours(id: string): void
    +init(): Promise<void>
}
class Question {
    -_cours: string
    -_categorie: string
    -_nom: string
    -_enonce: string
    -_reponse: boolean
    -_retroactionPositive: string
    -_retroactionNegative: string
    -_enseignant: string
    +getCours(): string
    +getCategorie(): string
    +getNom(): string
    +getEnonce(): string
    +getReponse(): boolean
    +getRetroactionPositive(): string
    +getRetroactionNegative(): string
    +getEnseignant(): string
    +toJSON(): { cours: string; categorie: string; nom: string; enonce: string; reponse: boolean; retroactionPositive: string; retroactionNegative: string; }
}
class QuestionControleur {
    -_questions: Map<string, Question>
    +recupererQuestions(): Map<string, Question>
    +recupererQuestion(nom: string, enseignant: string): Question
    +ajouterQuestion(cours: string, categorie: string, nom: string, enonce: string, reponse: boolean, retroactionPostive: string, retroactionNegative: string, auteur: string): string
    +isEmpty(str: string): boolean
    +modifierQuestion(ancienNom: string, cours: string, categorie: string, nom: string, enonce: string, reponse: boolean, retroactionPostive: string, retroactionNegative: string, auteur: string): string
    +supprimerQuestion(nom: string, user: Utilisateur): boolean
}
class Questionnaire implements QuestionnaireInterface {
    +_enseignant: string
    +_cours: string
    +_nom: string
    +_description: string
    +_etat: boolean
    +_questions: Question[]
    +_notes: any[]
    +_questionnaireRemis: boolean
    +ajouterQuestion(question: Question): void
    +retirerQuestion(question: Question): void
    +reordonner(ordreQuestion: string[]): void
    +genererNotes(): any[]
    +setQuestionnaireRemis(): void
    +toJSON(): { nom: string; description: string; questions: Question[]; }
}
class QuestionnaireControleur {
    -_questionnaires: Map<string, Questionnaire>
    +recupererQuestionnaires(): Map<string, Questionnaire>
    +getNbQuestionnairesParCours(cours: string): number
    +getNbQuestionnairesEnseignantParCours(cours: string, user_id: string): number
    +getNbDeFoisQuestionUtilisee(questionOriginale: Question): number
    +recupererQuestionnaire(nom: string): Questionnaire
    +ajouterQuestionnaire(enseignant: string, cours: string, nom: string, description: string, etat: boolean): string
    +isEmpty(str: string): boolean
    +modifierQuestionnaire(enseignant: string, cours: string, nom: string, description: string, etat: boolean, questionAssocier: string, questionDissocier: string, ordreQuestion: string[]): Questionnaire
    +supprimerQuestionnaire(enseignant: string, cours: string, nom: string): boolean
}
class ViewRouter {
    -_router: Router
    +router: Router
    +questionnaires(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): void
    +gestionnaireCours(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +cours(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +testTable(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +init(): void
}
abstract class default extends Error {
    +{abstract} code: number
}
class InvalidParameterError extends AbstractError {
    +code: 400
}
class LoginRouter {
    -_router: Router
    -_loginControleur: LoginControlleur
    +router: Router
    +login(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +logout(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +init(): void
}
class BaseRouter {
    -_router: Router
    +router: Router
    -mainPage(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    -loginPage(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +init(): void
}
class CoursRouter {
    -_router: Router
    +router: Router
    +recupererListeCours(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): void
    +retirerCours(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): void
    +recupererCours(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): void
    +ajouterCours(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): void
    +init(): void
}
class QuestionRouter {
    -_router: Router
    -_loginControleur: LoginControlleur
    +router: Router
    -_errorCode500(error: any, req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>): void
    +getControleur(): QuestionControleur
    +questionnaires(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +visualiserCoursActifs(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +formulerQuestion(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +reformulerQuestion(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +visualiserQuestions(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +visualiserToutesQuestions(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +detaillerQuestion(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +ajouterQuestions(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +modifierQuestion(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +supprimerQuestion(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +question(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    -init(): void
}
class QuestionnaireRouter {
    -_router: Router
    +router: Router
    +questionnaires(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +visualiserCoursActifs(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +formulerQuestionnaire(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +reformulerQuestionnaire(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +ajouterQuestionnaire(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +supprimerQuestionnaire(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +modifierQuestionnaire(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +ajouterQuestion(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +visualiserCategoriesParQuestion(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +visualiserQuestionsDansCategorie(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +visualiserDetails(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    -init(): void
}
class Devoir implements Travail {
    +id: string
    +type: TravailType
    +nom: string
    +description: string
    +dateDebut: Date
    +dateFin: Date
    +noteMax: number
    +actif: boolean
    +edit(description: any, date_debut: any, date_fin: any, note_max: any, actif: any): void
    +{static} idCounter: number
}
class DevoirControleur {
    +recupererDevoir(cours: Cours, devoir_id: string): Travail
    +recupererListeDevoir(cours: Cours): Travail[]
    +recupererTousDevoir(cours: Cours[]): Map<Devoir, Cours>
    +retirerDevoir(cours: Cours, devoir_id: string): void
    +ajouterDevoir(cours: Cours, devoir: Devoir): boolean
    +modifierDevoir(cours: Cours, devoir: Devoir, devoir_id: string): Travail
}
class DevoirRouter {
    -_router: Router
    -_devoirControleur: DevoirControleur
    -_loginControleur: LoginControlleur
    +router: Router
    -_errorCode500(error: any, req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>): void
    +recupererListeCours(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +recupererListeDevoirs(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +formulaireDevoir(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +ajouterDevoir(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +devoir(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +modifierDevoir(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +retirerDevoir(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +visualiserTousDevoir(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    +reformulerDevoir(req: Request<ParamsDictionary, any, any, QueryString.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction): Promise<void>
    -init(): void
}
class App {
    +expressApp: express.Application
    -middleware(): void
    -routes(): void
}
class note
class AlreadyExistsError extends AbstractError {
    +code: 400
}
class NotFoundError extends AbstractError {
    +code: 404
}
interface Error {
    +code: number
    +isAnonymous: boolean
    +message: string
}
@enduml